diff options
-rw-r--r-- | docs/configuration.md | 3 | ||||
-rw-r--r-- | scripts/package.js | 66 |
2 files changed, 64 insertions, 5 deletions
diff --git a/docs/configuration.md b/docs/configuration.md index 081b7ad..6a20d3a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md | |||
@@ -32,6 +32,9 @@ Link to your Github, Gitlab or Bitbucket public repository. Not used in the appl | |||
32 | `array[string]` **aliases**<br /> | 32 | `array[string]` **aliases**<br /> |
33 | The list of alternate names that this recipe can be called | 33 | The list of alternate names that this recipe can be called |
34 | 34 | ||
35 | `string` **defaultIcon**<br /> (DEFAULT: undefined) | ||
36 | A URL for the default icon of the recipe. If not provided, then the user must add an SVG file to the root with the name `icon.svg` to serve as the default icon. | ||
37 | |||
35 | `object` **config** _mandatory_<br /> | 38 | `object` **config** _mandatory_<br /> |
36 | This is the Ferdium-specific integration config. | 39 | This is the Ferdium-specific integration config. |
37 | 40 | ||
diff --git a/scripts/package.js b/scripts/package.js index c2e2ab7..7ccb466 100644 --- a/scripts/package.js +++ b/scripts/package.js | |||
@@ -1,5 +1,8 @@ | |||
1 | /* eslint-disable no-console */ | 1 | /* eslint-disable no-console */ |
2 | 2 | ||
3 | // Capture the start time | ||
4 | const startTime = new Date(); | ||
5 | |||
3 | /** | 6 | /** |
4 | * Package all recipes | 7 | * Package all recipes |
5 | */ | 8 | */ |
@@ -13,7 +16,8 @@ const pkgVersionChangedMatcher = /\n\+.*version.*/; | |||
13 | 16 | ||
14 | // Publicly availible link to this repository's recipe folder | 17 | // Publicly availible link to this repository's recipe folder |
15 | // Used for generating public icon URLs | 18 | // Used for generating public icon URLs |
16 | const repo = 'https://cdn.jsdelivr.net/gh/ferdium/ferdium-recipes/recipes/'; | 19 | const repo = |
20 | 'https://cdn.jsdelivr.net/gh/ferdium/ferdium-recipes@main/recipes/'; | ||
17 | 21 | ||
18 | // Helper: Compress src folder into dest file | 22 | // Helper: Compress src folder into dest file |
19 | const compress = (src, dest) => | 23 | const compress = (src, dest) => |
@@ -25,7 +29,11 @@ const compress = (src, dest) => | |||
25 | tar: { | 29 | tar: { |
26 | // Don't package .DS_Store files and .md files | 30 | // Don't package .DS_Store files and .md files |
27 | ignore(name) { | 31 | ignore(name) { |
28 | return path.basename(name) === '.DS_Store' || name.endsWith('.md'); | 32 | return ( |
33 | path.basename(name) === '.DS_Store' || | ||
34 | name.endsWith('.md') || | ||
35 | name.endsWith('.svg') | ||
36 | ); | ||
29 | }, | 37 | }, |
30 | }, | 38 | }, |
31 | }, | 39 | }, |
@@ -43,6 +51,7 @@ const compress = (src, dest) => | |||
43 | (async () => { | 51 | (async () => { |
44 | // Create paths to important files | 52 | // Create paths to important files |
45 | const repoRoot = path.join(__dirname, '..'); | 53 | const repoRoot = path.join(__dirname, '..'); |
54 | const tempFolder = path.join(repoRoot, 'temp'); | ||
46 | const recipesFolder = path.join(repoRoot, 'recipes'); | 55 | const recipesFolder = path.join(repoRoot, 'recipes'); |
47 | const outputFolder = path.join(repoRoot, 'archives'); | 56 | const outputFolder = path.join(repoRoot, 'archives'); |
48 | const allJson = path.join(repoRoot, 'all.json'); | 57 | const allJson = path.join(repoRoot, 'all.json'); |
@@ -53,6 +62,8 @@ const compress = (src, dest) => | |||
53 | 62 | ||
54 | await fs.ensureDir(outputFolder); | 63 | await fs.ensureDir(outputFolder); |
55 | await fs.emptyDir(outputFolder); | 64 | await fs.emptyDir(outputFolder); |
65 | await fs.ensureDir(tempFolder); | ||
66 | await fs.emptyDir(tempFolder); | ||
56 | await fs.remove(allJson); | 67 | await fs.remove(allJson); |
57 | 68 | ||
58 | const git = await simpleGit(repoRoot); | 69 | const git = await simpleGit(repoRoot); |
@@ -68,7 +79,7 @@ const compress = (src, dest) => | |||
68 | 79 | ||
69 | for (const recipe of availableRecipes) { | 80 | for (const recipe of availableRecipes) { |
70 | const recipeSrc = path.join(recipesFolder, recipe); | 81 | const recipeSrc = path.join(recipesFolder, recipe); |
71 | const mandatoryFiles = ['package.json', 'icon.svg', 'webview.js']; | 82 | const mandatoryFiles = ['package.json', 'webview.js']; |
72 | 83 | ||
73 | // Check that each mandatory file exists | 84 | // Check that each mandatory file exists |
74 | for (const file of mandatoryFiles) { | 85 | for (const file of mandatoryFiles) { |
@@ -179,6 +190,7 @@ const compress = (src, dest) => | |||
179 | 'repository', | 190 | 'repository', |
180 | 'aliases', | 191 | 'aliases', |
181 | 'config', | 192 | 'config', |
193 | 'defaultIcon', | ||
182 | ]); | 194 | ]); |
183 | const unrecognizedKeys = topLevelKeys.filter( | 195 | const unrecognizedKeys = topLevelKeys.filter( |
184 | x => !knownTopLevelKeys.has(x), | 196 | x => !knownTopLevelKeys.has(x), |
@@ -276,8 +288,46 @@ const compress = (src, dest) => | |||
276 | unsuccessful += 1; | 288 | unsuccessful += 1; |
277 | } | 289 | } |
278 | 290 | ||
291 | // Copy recipe to temp folder | ||
292 | // eslint-disable-next-line no-await-in-loop | ||
293 | await fs.copy(recipeSrc, path.join(tempFolder, config.id), { | ||
294 | filter: src => !src.endsWith('icon.svg'), | ||
295 | }); | ||
296 | |||
297 | if (!config.defaultIcon) { | ||
298 | // Check if icon.svg exists | ||
299 | // eslint-disable-next-line no-await-in-loop | ||
300 | if (!(await fs.exists(path.join(recipeSrc, 'icon.svg')))) { | ||
301 | console.log( | ||
302 | `⚠️ Couldn't package "${recipe}": The recipe doesn't contain a "icon.svg" or "defaultIcon" in package.json`, | ||
303 | ); | ||
304 | unsuccessful += 1; | ||
305 | } | ||
306 | |||
307 | // eslint-disable-next-line no-await-in-loop | ||
308 | const tempPackage = await fs.readJSON( | ||
309 | path.join(tempFolder, config.id, 'package.json'), | ||
310 | ); | ||
311 | tempPackage.defaultIcon = `${repo}${config.id}/icon.svg`; | ||
312 | |||
313 | // eslint-disable-next-line no-await-in-loop | ||
314 | await fs.writeJSON( | ||
315 | path.join(tempFolder, config.id, 'package.json'), | ||
316 | tempPackage, | ||
317 | // JSON.stringify(tempPackage, null, 2), | ||
318 | { | ||
319 | spaces: 2, | ||
320 | EOL: '\n', | ||
321 | }, | ||
322 | ); | ||
323 | } | ||
324 | |||
279 | // Package to .tar.gz | 325 | // Package to .tar.gz |
280 | compress(recipeSrc, path.join(outputFolder, `${config.id}.tar.gz`)); | 326 | // eslint-disable-next-line no-await-in-loop |
327 | await compress( | ||
328 | path.join(tempFolder, config.id), | ||
329 | path.join(outputFolder, `${config.id}.tar.gz`), | ||
330 | ); | ||
281 | 331 | ||
282 | // Add recipe to all.json | 332 | // Add recipe to all.json |
283 | const isFeatured = featuredRecipes.includes(config.id); | 333 | const isFeatured = featuredRecipes.includes(config.id); |
@@ -305,8 +355,14 @@ const compress = (src, dest) => | |||
305 | EOL: '\n', | 355 | EOL: '\n', |
306 | }); | 356 | }); |
307 | 357 | ||
358 | // Clean up | ||
359 | await fs.remove(tempFolder); | ||
360 | |||
361 | // Capture the end time | ||
362 | const endTime = new Date(); | ||
363 | |||
308 | console.log( | 364 | console.log( |
309 | `✅ Successfully packaged and added ${recipeList.length} recipes (${unsuccessful} unsuccessful recipes)`, | 365 | `✅ Successfully packaged and added ${recipeList.length} recipes (${unsuccessful} unsuccessful recipes) in ${(endTime - startTime) / 1000} seconds`, |
310 | ); | 366 | ); |
311 | 367 | ||
312 | if (unsuccessful > 0) { | 368 | if (unsuccessful > 0) { |