@adobe/aio-cli-plugin-app 10.7.2 → 11.1.0-pre.2024-01-09.2e4115c3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,14 +21,16 @@ const { loadConfigFile, writeFile } = require('../../lib/import-helper')
21
21
  const { getObjectValue } = require('../../lib/app-helper')
22
22
  const ora = require('ora')
23
23
  const chalk = require('chalk')
24
+ const junk = require('junk')
24
25
 
25
26
  // eslint-disable-next-line node/no-missing-require
26
27
  const libConfigNext = require('@adobe/aio-cli-lib-app-config-next')
27
28
 
29
+ const DIST_FOLDER = 'dist'
28
30
  const DEFAULTS = {
29
- OUTPUT_ZIP_FILE: 'app.zip',
30
- ARTIFACTS_FOLDER: 'app-package',
31
- DEPLOY_YAML_FILE: 'deploy.yaml'
31
+ OUTPUT_ZIP_FILE_PATH: path.join(DIST_FOLDER, 'app.zip'),
32
+ ARTIFACTS_FOLDER_PATH: path.join(DIST_FOLDER, 'app-package'),
33
+ DEPLOY_YAML_FILE_NAME: 'deploy.yaml'
32
34
  }
33
35
 
34
36
  class Pack extends BaseCommand {
@@ -53,20 +55,37 @@ class Pack extends BaseCommand {
53
55
  aioLogger.debug(`changed current working directory to: ${resolvedPath}`)
54
56
  }
55
57
 
58
+ // get all 'dist' locations of all extensions (relative to the current working directory)
59
+ const distLocations = Object.entries(appConfig.all)
60
+ .map(([, extConfig]) => path.relative(process.cwd(), extConfig.app.dist))
61
+
56
62
  try {
57
63
  // 1. create artifacts phase
58
- this.spinner.start(`Creating package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER}'...`)
59
- await fs.emptyDir(DEFAULTS.ARTIFACTS_FOLDER)
60
- this.spinner.succeed(`Created package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER}'`)
64
+ this.spinner.start(`Creating package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER_PATH}'...`)
65
+ await fs.emptyDir(DEFAULTS.ARTIFACTS_FOLDER_PATH)
66
+ this.spinner.succeed(`Created package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER_PATH}'`)
61
67
 
62
68
  // ACNA-2038
63
69
  // not artifacts folder should exist before we fire the event
64
- await this.config.runHook('pre-pack', { appConfig, artifactsFolder: DEFAULTS.ARTIFACTS_FOLDER })
70
+
71
+ const hookResults = await this.config.runHook('pre-pack', { appConfig, artifactsFolder: DEFAULTS.ARTIFACTS_FOLDER_PATH })
72
+ if (hookResults?.failures?.length > 0) {
73
+ // output should be "Error : <plugin-name> : <error-message>\n" for each failure
74
+ this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
75
+ }
76
+
77
+ // 1a. Get file list to pack
78
+ const fileList = await this.filesToPack({ filesToExclude: [flags.output, DEFAULTS.DIST_FOLDER, ...distLocations] })
79
+ this.log('=== Files to pack ===')
80
+ fileList.forEach((file) => {
81
+ this.log(` ${file}`)
82
+ })
83
+ this.log('=====================')
65
84
 
66
85
  // 2. copy files to package phase
67
86
  this.spinner.start('Copying project files...')
68
- const fileList = await this.filesToPack([flags.output])
69
- await this.copyPackageFiles(DEFAULTS.ARTIFACTS_FOLDER, fileList)
87
+
88
+ await this.copyPackageFiles(DEFAULTS.ARTIFACTS_FOLDER_PATH, fileList)
70
89
  this.spinner.succeed('Copied project files')
71
90
 
72
91
  // 3. add/modify artifacts phase
@@ -79,13 +98,18 @@ class Pack extends BaseCommand {
79
98
  this.spinner.succeed('Added code-download annotations')
80
99
 
81
100
  // doing this before zip so other things can be added to the zip
82
- await this.config.runHook('post-pack', { appConfig, artifactsFolder: DEFAULTS.ARTIFACTS_FOLDER })
101
+ await this.config.runHook('post-pack', { appConfig, artifactsFolder: DEFAULTS.ARTIFACTS_FOLDER_PATH })
83
102
 
84
103
  // 4. zip package phase
85
- this.spinner.start(`Zipping package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER}' to '${outputZipFile}'...`)
104
+ this.spinner.start(`Zipping package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER_PATH}' to '${outputZipFile}'...`)
86
105
  await fs.remove(outputZipFile)
87
- await this.zipHelper(DEFAULTS.ARTIFACTS_FOLDER, outputZipFile)
88
- this.spinner.succeed(`Zipped package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER}' to '${outputZipFile}'`)
106
+ await this.zipHelper(DEFAULTS.ARTIFACTS_FOLDER_PATH, outputZipFile)
107
+ this.spinner.succeed(`Zipped package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER_PATH}' to '${outputZipFile}'`)
108
+
109
+ // 5. finally delete the artifacts folder
110
+ this.spinner.start(`Deleting package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER_PATH}'...`)
111
+ await fs.remove(DEFAULTS.ARTIFACTS_FOLDER_PATH)
112
+ this.spinner.succeed(`Deleted package artifacts folder '${DEFAULTS.ARTIFACTS_FOLDER_PATH}'`)
89
113
  } catch (e) {
90
114
  this.spinner.fail(e.message)
91
115
  this.error(flags.verbose ? e : e.message)
@@ -176,7 +200,7 @@ class Pack extends BaseCommand {
176
200
  }
177
201
 
178
202
  await writeFile(
179
- path.join(DEFAULTS.ARTIFACTS_FOLDER, DEFAULTS.DEPLOY_YAML_FILE),
203
+ path.join(DEFAULTS.ARTIFACTS_FOLDER_PATH, DEFAULTS.DEPLOY_YAML_FILE_NAME),
180
204
  yaml.dump(deployJson),
181
205
  { overwrite: true })
182
206
  }
@@ -239,17 +263,38 @@ class Pack extends BaseCommand {
239
263
  *
240
264
  * This runs `npm pack` to get the list.
241
265
  *
242
- * @param {Array<string>} filesToExclude a list of files to exclude
243
- * @param {string} workingDirectory the working directory to run `npm pack` in
266
+ * @param {object} options the options for the method
267
+ * @param {Array<string>} options.filesToExclude a list of files to exclude
268
+ * @param {string} options.workingDirectory the working directory to run `npm pack` in
244
269
  * @returns {Array<string>} a list of files that are to be packed
245
270
  */
246
- async filesToPack (filesToExclude = [], workingDirectory = process.cwd()) {
271
+ async filesToPack ({ filesToExclude = [], workingDirectory = process.cwd() } = {}) {
247
272
  const { stdout } = await execa('npm', ['pack', '--dry-run', '--json'], { cwd: workingDirectory })
248
273
 
274
+ const noJunkFiles = (file) => {
275
+ const isJunkFile = junk.is(file)
276
+ if (isJunkFile) {
277
+ aioLogger.debug(`junk file (omitted from pack): ${file}`)
278
+ }
279
+
280
+ return !isJunkFile
281
+ }
282
+
283
+ const noDotFiles = (file) => {
284
+ const isDotFile = /^\..*/.test(file)
285
+ if (isDotFile) {
286
+ aioLogger.debug(`hidden dotfile (omitted from pack): ${file}`)
287
+ }
288
+
289
+ return !isDotFile
290
+ }
291
+
249
292
  const { files } = JSON.parse(stdout)[0]
250
293
  return files
251
294
  .map(file => file.path)
252
295
  .filter(file => !filesToExclude.includes(file))
296
+ .filter(noJunkFiles) // no junk files like .DS_Store
297
+ .filter(noDotFiles) // no files that start with a '.'
253
298
  }
254
299
 
255
300
  /**
@@ -291,7 +336,7 @@ class Pack extends BaseCommand {
291
336
 
292
337
  // rewrite config files
293
338
  for (const [file, keys] of Object.entries(fileToAnnotationKey)) {
294
- const configFilePath = path.join(DEFAULTS.ARTIFACTS_FOLDER, file)
339
+ const configFilePath = path.join(DEFAULTS.ARTIFACTS_FOLDER_PATH, file)
295
340
  const { values } = loadConfigFile(configFilePath)
296
341
 
297
342
  keys.forEach(key => {
@@ -321,7 +366,7 @@ Pack.flags = {
321
366
  output: Flags.string({
322
367
  description: 'The packaged app output file path',
323
368
  char: 'o',
324
- default: DEFAULTS.OUTPUT_ZIP_FILE
369
+ default: DEFAULTS.OUTPUT_ZIP_FILE_PATH
325
370
  })
326
371
  }
327
372
 
@@ -78,13 +78,10 @@ class Undeploy extends BaseCommand {
78
78
  // undeploy
79
79
  try {
80
80
  await runInProcess(config.hooks['pre-app-undeploy'], config)
81
- if (flags['feature-event-hooks'] && flags.events) {
82
- this.log('feature-event-hooks is enabled, running pre-undeploy-event-reg hook')
83
- const hookResults = await this.config.runHook('pre-undeploy-event-reg', { appConfig: config })
84
- if (hookResults?.failures?.length > 0) {
85
- // output should be "Error : <plugin-name> : <error-message>\n" for each failure
86
- this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
87
- }
81
+ const hookResults = await this.config.runHook('pre-undeploy-event-reg', { appConfig: config })
82
+ if (hookResults?.failures?.length > 0) {
83
+ // output should be "Error : <plugin-name> : <error-message>\n" for each failure
84
+ this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
88
85
  }
89
86
  } catch (err) {
90
87
  this.log(err)
@@ -178,12 +175,6 @@ Undeploy.flags = {
178
175
  description: 'Force unpublish extension(s) from Exchange, will delete all extension points',
179
176
  default: false,
180
177
  exclusive: ['unpublish'] // unpublish is excluded
181
- }),
182
- 'feature-event-hooks': Flags.boolean({
183
- description: '[default: false] Enable event hooks feature',
184
- default: false,
185
- allowNo: true,
186
- hidden: true
187
178
  })
188
179
  }
189
180
 
@@ -1,67 +0,0 @@
1
- /*
2
- Copyright 2020 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- Unless required by applicable law or agreed to in writing, software distributed under
7
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
8
- OF ANY KIND, either express or implied. See the License for the specific language
9
- governing permissions and limitations under the License.
10
- */
11
-
12
- const BaseCommand = require('../../../BaseCommand')
13
- const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:delete:event', { provider: 'debug' })
14
- const { Flags, Args } = require('@oclif/core')
15
- const DeleteActionCommand = require('./action')
16
- const chalk = require('chalk')
17
-
18
- class DeleteEventCommand extends BaseCommand {
19
- async run () {
20
- const { args, flags } = await this.parse(DeleteEventCommand)
21
-
22
- aioLogger.debug(`deleting events from the project, with args ${JSON.stringify(args)}, and flags: ${JSON.stringify(flags)}`)
23
-
24
- // NOTE: this command only wraps app delete action, events will have more than actions later on
25
- if (flags.yes && !args['event-action-name']) {
26
- this.error('<event-action-name> must also be provided when using --yes')
27
- }
28
-
29
- if (!args['event-action-name']) {
30
- this.log(chalk.bold(chalk.blue('NOTE: this is running the \'app delete action\' command, please select events actions.')))
31
- this.log()
32
- }
33
-
34
- const cmdLineArgs = []
35
- if (args['event-action-name']) {
36
- cmdLineArgs.push(args['event-action-name'])
37
- }
38
- if (flags.yes) {
39
- cmdLineArgs.push('--yes')
40
- }
41
- await DeleteActionCommand.run(cmdLineArgs)
42
- }
43
- }
44
-
45
- DeleteEventCommand.description = `Delete existing Adobe I/O Events actions
46
- `
47
-
48
- DeleteEventCommand.flags = {
49
- yes: Flags.boolean({
50
- description: 'Skip questions, and use all default values',
51
- char: 'y',
52
- default: false
53
- }),
54
- ...BaseCommand.flags
55
- }
56
-
57
- DeleteEventCommand.args =
58
- {
59
- 'event-action-name': Args.string({
60
- description: 'Action `pkg/name` to delete, you can specify multiple actions via a comma separated list',
61
- required: false
62
- })
63
- }
64
-
65
- DeleteEventCommand.aliases = ['app:delete:events']
66
-
67
- module.exports = DeleteEventCommand