@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.
- package/README.md +39 -66
- package/bin/openwhisk-standalone-config/get-runtimes.js +28 -26
- package/bin/openwhisk-standalone-config/runtimes.json +13 -5
- package/oclif.manifest.json +44 -68
- package/package.json +19 -16
- package/src/BaseCommand.js +1 -14
- package/src/commands/app/add/event.js +13 -36
- package/src/commands/app/build.js +2 -0
- package/src/commands/app/deploy.js +12 -22
- package/src/commands/app/init.js +117 -36
- package/src/commands/app/install.js +8 -1
- package/src/commands/app/pack.js +64 -19
- package/src/commands/app/undeploy.js +4 -13
- package/src/commands/app/delete/event.js +0 -67
package/package.json
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/aio-cli-plugin-app",
|
|
3
3
|
"description": "Create, Build and Deploy Adobe I/O Applications",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "11.1.0-pre.2024-01-09.2e4115c3",
|
|
5
5
|
"author": "Adobe Inc.",
|
|
6
6
|
"bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@adobe/aio-cli-lib-app-config": "
|
|
8
|
+
"@adobe/aio-cli-lib-app-config": "next",
|
|
9
9
|
"@adobe/aio-cli-lib-app-config-next": "npm:@adobe/aio-cli-lib-app-config@^3.0.0",
|
|
10
|
-
"@adobe/aio-cli-lib-console": "
|
|
11
|
-
"@adobe/aio-lib-core-config": "
|
|
12
|
-
"@adobe/aio-lib-core-logging": "
|
|
13
|
-
"@adobe/aio-lib-core-networking": "
|
|
14
|
-
"@adobe/aio-lib-env": "
|
|
15
|
-
"@adobe/aio-lib-ims": "
|
|
16
|
-
"@adobe/aio-lib-runtime": "
|
|
10
|
+
"@adobe/aio-cli-lib-console": "next",
|
|
11
|
+
"@adobe/aio-lib-core-config": "next",
|
|
12
|
+
"@adobe/aio-lib-core-logging": "next",
|
|
13
|
+
"@adobe/aio-lib-core-networking": "next",
|
|
14
|
+
"@adobe/aio-lib-env": "next",
|
|
15
|
+
"@adobe/aio-lib-ims": "next",
|
|
16
|
+
"@adobe/aio-lib-runtime": "next",
|
|
17
17
|
"@adobe/aio-lib-templates": "^2.2.0",
|
|
18
|
-
"@adobe/aio-lib-web": "
|
|
19
|
-
"@adobe/generator-aio-app": "
|
|
20
|
-
"@adobe/generator-app-common-lib": "^0.
|
|
18
|
+
"@adobe/aio-lib-web": "next",
|
|
19
|
+
"@adobe/generator-aio-app": "next",
|
|
20
|
+
"@adobe/generator-app-common-lib": "^1.0.0",
|
|
21
21
|
"@adobe/inquirer-table-checkbox": "^1.2.0",
|
|
22
|
+
"@octokit/rest": "^19.0.11",
|
|
22
23
|
"@oclif/core": "^2.11.6",
|
|
23
24
|
"@parcel/core": "^2.7.0",
|
|
24
25
|
"@parcel/reporter-cli": "^2.7.0",
|
|
@@ -48,12 +49,13 @@
|
|
|
48
49
|
"term-size": "^2.2.1",
|
|
49
50
|
"unzipper": "^0.10.11",
|
|
50
51
|
"upath": "^2",
|
|
52
|
+
"junk": "^3.1.0",
|
|
51
53
|
"which": "^3.0.0",
|
|
52
54
|
"yeoman-environment": "^3.2.0"
|
|
53
55
|
},
|
|
54
56
|
"devDependencies": {
|
|
55
57
|
"@adobe/aio-lib-test-proxy": "^1.0.0",
|
|
56
|
-
"@adobe/eslint-config-aio-lib-config": "^2.0.
|
|
58
|
+
"@adobe/eslint-config-aio-lib-config": "^2.0.2",
|
|
57
59
|
"@types/jest": "^29",
|
|
58
60
|
"babel-runtime": "^6.26.0",
|
|
59
61
|
"core-js": "^3",
|
|
@@ -73,7 +75,7 @@
|
|
|
73
75
|
"typescript": "^5.1.6"
|
|
74
76
|
},
|
|
75
77
|
"engines": {
|
|
76
|
-
"node": "
|
|
78
|
+
"node": ">=18"
|
|
77
79
|
},
|
|
78
80
|
"files": [
|
|
79
81
|
"bin/run",
|
|
@@ -106,5 +108,6 @@
|
|
|
106
108
|
},
|
|
107
109
|
"bin": {
|
|
108
110
|
"aio-next": "./bin/run"
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
+
},
|
|
112
|
+
"prereleaseSha": "2e4115c3814afd05bf049bc66b1a491cc5833a6a"
|
|
113
|
+
}
|
package/src/BaseCommand.js
CHANGED
|
@@ -35,20 +35,7 @@ class BaseCommand extends Command {
|
|
|
35
35
|
async catch (error) {
|
|
36
36
|
const { flags } = await this.parse(this.prototype)
|
|
37
37
|
aioLogger.error(error) // debug log
|
|
38
|
-
this.
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
handleError (error, verbose) {
|
|
42
|
-
const errorMessages = ['no such file or directory', 'find configuration']
|
|
43
|
-
if (errorMessages.find(msg => error.message.includes(msg))) {
|
|
44
|
-
const errorList = [
|
|
45
|
-
'Not a valid application root folder.',
|
|
46
|
-
'Please run \'aio app\' commands from a folder generated by aio app init',
|
|
47
|
-
verbose ? error.stack : error.message
|
|
48
|
-
]
|
|
49
|
-
this.error(errorList.join('\n'))
|
|
50
|
-
}
|
|
51
|
-
this.error(error.message)
|
|
38
|
+
this.error(flags.verbose ? error.stack : error.message)
|
|
52
39
|
}
|
|
53
40
|
|
|
54
41
|
async init () {
|
|
@@ -11,12 +11,9 @@ governing permissions and limitations under the License.
|
|
|
11
11
|
|
|
12
12
|
const AddCommand = require('../../../AddCommand')
|
|
13
13
|
const TemplatesCommand = require('../../../TemplatesCommand')
|
|
14
|
-
const yeoman = require('yeoman-environment')
|
|
15
14
|
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:add:event', { provider: 'debug' })
|
|
16
15
|
const { Flags } = require('@oclif/core')
|
|
17
|
-
const ora = require('ora')
|
|
18
16
|
const path = require('path')
|
|
19
|
-
const generators = require('@adobe/generator-aio-app')
|
|
20
17
|
const TemplateRegistryAPI = require('@adobe/aio-lib-templates')
|
|
21
18
|
|
|
22
19
|
class AddEventCommand extends TemplatesCommand {
|
|
@@ -24,7 +21,6 @@ class AddEventCommand extends TemplatesCommand {
|
|
|
24
21
|
const { flags } = await this.parse(AddEventCommand)
|
|
25
22
|
|
|
26
23
|
aioLogger.debug(`add events with flags: ${JSON.stringify(flags)}`)
|
|
27
|
-
const spinner = ora()
|
|
28
24
|
|
|
29
25
|
// guaranteed to have at least one, otherwise would throw in config load or in matching the ext name
|
|
30
26
|
const entries = Object.entries(this.getAppExtConfigs(flags))
|
|
@@ -36,42 +32,27 @@ class AddEventCommand extends TemplatesCommand {
|
|
|
36
32
|
const config = entries[0][1]
|
|
37
33
|
const actionFolder = path.relative(config.root, config.actions.src)
|
|
38
34
|
const runtimeManifestData = this.getRuntimeManifestConfigFile(configName)
|
|
39
|
-
|
|
35
|
+
const eventsData = this.getEventsConfigFile(configName)
|
|
40
36
|
const templateOptions = {
|
|
41
37
|
'skip-prompt': false,
|
|
42
38
|
'action-folder': actionFolder,
|
|
43
39
|
'config-path': runtimeManifestData.file,
|
|
44
|
-
'full-key-to-manifest': runtimeManifestData.key
|
|
40
|
+
'full-key-to-manifest': runtimeManifestData.key,
|
|
41
|
+
'full-key-to-events-manifest': eventsData.key,
|
|
42
|
+
'events-config-path': eventsData.file
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const [searchCriteria, orderByCriteria] = await this.getSearchCriteria()
|
|
52
|
-
const templates = await this.selectTemplates(searchCriteria, orderByCriteria)
|
|
53
|
-
if (templates.length === 0) {
|
|
54
|
-
this.error('No events templates were chosen to be installed.')
|
|
55
|
-
} else {
|
|
56
|
-
await this.installTemplates({
|
|
57
|
-
useDefaultValues: flags.yes,
|
|
58
|
-
installNpm: flags.install,
|
|
59
|
-
templateOptions,
|
|
60
|
-
templates
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
// by default yeoman runs the install, we control installation from the app plugin
|
|
45
|
+
const [searchCriteria, orderByCriteria] = await this.getSearchCriteria()
|
|
46
|
+
const templates = await this.selectTemplates(searchCriteria, orderByCriteria)
|
|
47
|
+
if (templates.length === 0) {
|
|
48
|
+
this.error('No events templates were chosen to be installed.')
|
|
64
49
|
} else {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
options: templateOptions
|
|
50
|
+
await this.installTemplates({
|
|
51
|
+
useDefaultValues: flags.yes,
|
|
52
|
+
installNpm: flags.install,
|
|
53
|
+
templateOptions,
|
|
54
|
+
templates
|
|
71
55
|
})
|
|
72
|
-
await env.runGenerator(eventsGen)
|
|
73
|
-
|
|
74
|
-
await this.runInstallPackages(flags, spinner)
|
|
75
56
|
}
|
|
76
57
|
}
|
|
77
58
|
|
|
@@ -107,10 +88,6 @@ AddEventCommand.flags = {
|
|
|
107
88
|
multiple: false,
|
|
108
89
|
parse: str => [str]
|
|
109
90
|
}),
|
|
110
|
-
'experimental-allow-events-templates': Flags.boolean({
|
|
111
|
-
description: 'Feature flag to enable events templates. NOTE: skip-prompt will have no effect if this flag is enabled.',
|
|
112
|
-
default: false
|
|
113
|
-
}),
|
|
114
91
|
...AddCommand.flags
|
|
115
92
|
}
|
|
116
93
|
|
|
@@ -116,6 +116,8 @@ class Build extends BaseCommand {
|
|
|
116
116
|
shouldOptimize: flags['web-optimize'],
|
|
117
117
|
logLevel: flags.verbose ? 'verbose' : 'warn'
|
|
118
118
|
}
|
|
119
|
+
// empty the dist folder to prevent an S3 explosion
|
|
120
|
+
fs.emptyDirSync(config.web.distProd)
|
|
119
121
|
const bundler = await bundle(entries, config.web.distProd, bundleOptions, onProgress)
|
|
120
122
|
await bundler.run()
|
|
121
123
|
spinner.succeed(chalk.green(`Building web assets for '${name}'`))
|
|
@@ -22,6 +22,9 @@ const { createWebExportFilter, runInProcess, buildExtensionPointPayloadWoMetadat
|
|
|
22
22
|
const rtLib = require('@adobe/aio-lib-runtime')
|
|
23
23
|
const LogForwarding = require('../../lib/log-forwarding')
|
|
24
24
|
|
|
25
|
+
const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
|
|
26
|
+
const POST_DEPLOY_EVENT_REG = 'post-deploy-event-reg'
|
|
27
|
+
|
|
25
28
|
class Deploy extends BuildCommand {
|
|
26
29
|
async run () {
|
|
27
30
|
// cli input
|
|
@@ -142,13 +145,10 @@ class Deploy extends BuildCommand {
|
|
|
142
145
|
|
|
143
146
|
try {
|
|
144
147
|
await runInProcess(config.hooks['pre-app-deploy'], config)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// output should be "Error : <plugin-name> : <error-message>\n" for each failure
|
|
150
|
-
this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
|
|
151
|
-
}
|
|
148
|
+
const hookResults = await this.config.runHook(PRE_DEPLOY_EVENT_REG, { appConfig: config, force: flags['force-events'] })
|
|
149
|
+
if (hookResults?.failures?.length > 0) {
|
|
150
|
+
// output should be "Error : <plugin-name> : <error-message>\n" for each failure
|
|
151
|
+
this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
|
|
152
152
|
}
|
|
153
153
|
} catch (err) {
|
|
154
154
|
this.error(err)
|
|
@@ -250,13 +250,10 @@ class Deploy extends BuildCommand {
|
|
|
250
250
|
|
|
251
251
|
try {
|
|
252
252
|
await runInProcess(config.hooks['post-app-deploy'], config)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// output should be "Error : <plugin-name> : <error-message>\n" for each failure
|
|
258
|
-
this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
|
|
259
|
-
}
|
|
253
|
+
const hookResults = await this.config.runHook(POST_DEPLOY_EVENT_REG, { appConfig: config, force: flags['force-events'] })
|
|
254
|
+
if (hookResults?.failures?.length > 0) {
|
|
255
|
+
// output should be "Error : <plugin-name> : <error-message>\n" for each failure
|
|
256
|
+
this.error(hookResults.failures.map(f => `${f.plugin.name} : ${f.error.message}`).join('\nError: '), { exit: 1 })
|
|
260
257
|
}
|
|
261
258
|
} catch (err) {
|
|
262
259
|
this.error(err)
|
|
@@ -353,10 +350,9 @@ Deploy.flags = {
|
|
|
353
350
|
exclusive: ['action', 'publish'] // no-publish is excluded
|
|
354
351
|
}),
|
|
355
352
|
'force-events': Flags.boolean({
|
|
356
|
-
description: '[default: false] Force event registrations and
|
|
353
|
+
description: '[default: false] Force event registrations and delete any registrations not part of the config file',
|
|
357
354
|
default: false,
|
|
358
355
|
allowNo: true,
|
|
359
|
-
dependsOn: ['feature-event-hooks'],
|
|
360
356
|
exclusive: ['action', 'publish'] // no-publish is excluded
|
|
361
357
|
}),
|
|
362
358
|
'web-optimize': Flags.boolean({
|
|
@@ -367,12 +363,6 @@ Deploy.flags = {
|
|
|
367
363
|
description: '[default: true] Update log forwarding configuration on server',
|
|
368
364
|
default: true,
|
|
369
365
|
allowNo: true
|
|
370
|
-
}),
|
|
371
|
-
'feature-event-hooks': Flags.boolean({
|
|
372
|
-
description: '[default: false] Enable event hooks feature',
|
|
373
|
-
default: false,
|
|
374
|
-
allowNo: true,
|
|
375
|
-
hidden: true
|
|
376
366
|
})
|
|
377
367
|
}
|
|
378
368
|
|
package/src/commands/app/init.js
CHANGED
|
@@ -20,9 +20,10 @@ const generators = require('@adobe/generator-aio-app')
|
|
|
20
20
|
const TemplateRegistryAPI = require('@adobe/aio-lib-templates')
|
|
21
21
|
const inquirer = require('inquirer')
|
|
22
22
|
const hyperlinker = require('hyperlinker')
|
|
23
|
-
|
|
24
23
|
const { importConsoleConfig } = require('../../lib/import')
|
|
25
24
|
const { loadAndValidateConfigFile } = require('../../lib/import-helper')
|
|
25
|
+
const { Octokit } = require('@octokit/rest')
|
|
26
|
+
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:init', { provider: 'debug' })
|
|
26
27
|
|
|
27
28
|
const DEFAULT_WORKSPACE = 'Stage'
|
|
28
29
|
|
|
@@ -102,24 +103,28 @@ class InitCommand extends TemplatesCommand {
|
|
|
102
103
|
this.log(chalk.green(`Loaded Adobe Developer Console configuration file for the Project '${consoleConfig.project.title}' in the Organization '${consoleConfig.project.org.name}'`))
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
if (flags.repo) {
|
|
107
|
+
await this.withQuickstart(flags.repo)
|
|
108
|
+
} else {
|
|
109
|
+
// 2. prompt for templates to be installed
|
|
110
|
+
const templates = await this.getTemplatesForFlags(flags)
|
|
111
|
+
// If no templates selected, init a standalone app
|
|
112
|
+
if (templates.length <= 0) {
|
|
113
|
+
flags['standalone-app'] = true
|
|
114
|
+
}
|
|
111
115
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
// 3. run base code generators
|
|
117
|
+
const projectName = (consoleConfig && consoleConfig.project.name) || path.basename(process.cwd())
|
|
118
|
+
await this.runCodeGenerators(this.getInitialGenerators(flags), flags.yes, projectName)
|
|
115
119
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
// 4. install templates
|
|
121
|
+
await this.installTemplates({
|
|
122
|
+
useDefaultValues: flags.yes,
|
|
123
|
+
installNpm: flags.install,
|
|
124
|
+
installConfig: flags.login,
|
|
125
|
+
templates
|
|
126
|
+
})
|
|
127
|
+
}
|
|
123
128
|
|
|
124
129
|
// 5. import config - if any
|
|
125
130
|
if (flags.import) {
|
|
@@ -128,40 +133,50 @@ class InitCommand extends TemplatesCommand {
|
|
|
128
133
|
}
|
|
129
134
|
|
|
130
135
|
async initWithLogin (flags) {
|
|
136
|
+
if (flags.repo) {
|
|
137
|
+
await this.withQuickstart(flags.repo)
|
|
138
|
+
}
|
|
131
139
|
// this will trigger a login
|
|
132
140
|
const consoleCLI = await this.getLibConsoleCLI()
|
|
133
141
|
|
|
134
142
|
// 1. select org
|
|
135
|
-
const org = await this.selectConsoleOrg(consoleCLI)
|
|
143
|
+
const org = await this.selectConsoleOrg(consoleCLI, flags)
|
|
136
144
|
// 2. get supported services
|
|
137
145
|
const orgSupportedServices = await consoleCLI.getEnabledServicesForOrg(org.id)
|
|
138
146
|
// 3. select or create project
|
|
139
|
-
const project = await this.selectOrCreateConsoleProject(consoleCLI, org)
|
|
147
|
+
const project = await this.selectOrCreateConsoleProject(consoleCLI, org, flags)
|
|
140
148
|
// 4. retrieve workspace details, defaults to Stage
|
|
141
149
|
const workspace = await this.retrieveWorkspaceFromName(consoleCLI, org, project, flags)
|
|
142
150
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
let templates
|
|
152
|
+
if (!flags.repo) {
|
|
153
|
+
// 5. get list of templates to install
|
|
154
|
+
templates = await this.getTemplatesForFlags(flags, orgSupportedServices)
|
|
155
|
+
// If no templates selected, init a standalone app
|
|
156
|
+
if (templates.length <= 0) {
|
|
157
|
+
flags['standalone-app'] = true
|
|
158
|
+
}
|
|
148
159
|
}
|
|
149
160
|
|
|
150
161
|
// 6. download workspace config
|
|
151
162
|
const consoleConfig = await consoleCLI.getWorkspaceConfig(org.id, project.id, workspace.id, orgSupportedServices)
|
|
152
163
|
|
|
153
164
|
// 7. run base code generators
|
|
154
|
-
|
|
165
|
+
if (!flags.repo) {
|
|
166
|
+
await this.runCodeGenerators(this.getInitialGenerators(flags), flags.yes, consoleConfig.project.name)
|
|
167
|
+
}
|
|
155
168
|
|
|
156
169
|
// 8. import config
|
|
157
170
|
await this.importConsoleConfig(consoleConfig, flags)
|
|
158
171
|
|
|
159
172
|
// 9. install templates
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
173
|
+
if (!flags.repo) {
|
|
174
|
+
await this.installTemplates({
|
|
175
|
+
useDefaultValues: flags.yes,
|
|
176
|
+
installNpm: flags.install,
|
|
177
|
+
templates
|
|
178
|
+
})
|
|
179
|
+
}
|
|
165
180
|
|
|
166
181
|
this.log(chalk.blue(chalk.bold(`Project initialized for Workspace ${workspace.name}, you can run 'aio app use -w <workspace>' to switch workspace.`)))
|
|
167
182
|
}
|
|
@@ -275,21 +290,24 @@ class InitCommand extends TemplatesCommand {
|
|
|
275
290
|
return [searchCriteria, orderByCriteria, selection, selectionLabel]
|
|
276
291
|
}
|
|
277
292
|
|
|
278
|
-
async selectConsoleOrg (consoleCLI) {
|
|
293
|
+
async selectConsoleOrg (consoleCLI, flags) {
|
|
279
294
|
const organizations = await consoleCLI.getOrganizations()
|
|
280
|
-
const selectedOrg = await consoleCLI.promptForSelectOrganization(organizations)
|
|
295
|
+
const selectedOrg = await consoleCLI.promptForSelectOrganization(organizations, { orgId: flags.org, orgCode: flags.org })
|
|
281
296
|
await this.ensureDevTermAccepted(consoleCLI, selectedOrg.id)
|
|
282
297
|
return selectedOrg
|
|
283
298
|
}
|
|
284
299
|
|
|
285
|
-
async selectOrCreateConsoleProject (consoleCLI, org) {
|
|
300
|
+
async selectOrCreateConsoleProject (consoleCLI, org, flags) {
|
|
286
301
|
const projects = await consoleCLI.getProjects(org.id)
|
|
287
302
|
let project = await consoleCLI.promptForSelectProject(
|
|
288
303
|
projects,
|
|
289
|
-
{},
|
|
304
|
+
{ projectId: flags.project, projectName: flags.project },
|
|
290
305
|
{ allowCreate: true }
|
|
291
306
|
)
|
|
292
307
|
if (!project) {
|
|
308
|
+
if (flags.project) {
|
|
309
|
+
this.error(`--project ${flags.project} not found`)
|
|
310
|
+
}
|
|
293
311
|
// user has escaped project selection prompt, let's create a new one
|
|
294
312
|
const projectDetails = await consoleCLI.promptForCreateProjectDetails()
|
|
295
313
|
project = await consoleCLI.createProject(org.id, projectDetails)
|
|
@@ -348,7 +366,56 @@ class InitCommand extends TemplatesCommand {
|
|
|
348
366
|
}
|
|
349
367
|
)
|
|
350
368
|
}
|
|
369
|
+
|
|
370
|
+
async withQuickstart (fullRepo) {
|
|
371
|
+
const octokit = new Octokit({
|
|
372
|
+
auth: ''
|
|
373
|
+
})
|
|
374
|
+
const spinner = ora('Downloading quickstart repo').start()
|
|
375
|
+
/** @private */
|
|
376
|
+
async function downloadRepoDirRecursive (owner, repo, filePath, basePath) {
|
|
377
|
+
const { data } = await octokit.repos.getContent({ owner, repo, path: filePath })
|
|
378
|
+
for (const fileOrDir of data) {
|
|
379
|
+
if (fileOrDir.type === 'dir') {
|
|
380
|
+
const destDir = path.relative(basePath, fileOrDir.path)
|
|
381
|
+
fs.ensureDirSync(destDir)
|
|
382
|
+
await downloadRepoDirRecursive(owner, repo, fileOrDir.path, basePath)
|
|
383
|
+
} else {
|
|
384
|
+
// todo: use a spinner
|
|
385
|
+
spinner.text = `Downloading ${fileOrDir.path}`
|
|
386
|
+
const response = await fetch(fileOrDir.download_url)
|
|
387
|
+
const jsonResponse = await response.text()
|
|
388
|
+
fs.writeFileSync(path.relative(basePath, fileOrDir.path), jsonResponse)
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// we need to handle n-deep paths, <owner>/<repo>/<path>/<path>
|
|
393
|
+
const [owner, repo, ...restOfPath] = fullRepo.split('/')
|
|
394
|
+
const basePath = restOfPath.join('/')
|
|
395
|
+
try {
|
|
396
|
+
const response = await octokit.repos.getContent({ owner, repo, path: `${basePath}/app.config.yaml` })
|
|
397
|
+
aioLogger.debug(`github headers: ${JSON.stringify(response.headers, 0, 2)}`)
|
|
398
|
+
await downloadRepoDirRecursive(owner, repo, basePath, basePath)
|
|
399
|
+
spinner.succeed('Downloaded quickstart repo')
|
|
400
|
+
} catch (e) {
|
|
401
|
+
if (e.status === 404) {
|
|
402
|
+
spinner.fail('Quickstart repo not found')
|
|
403
|
+
this.error('--repo does not point to a valid Adobe App Builder app')
|
|
404
|
+
}
|
|
405
|
+
if (e.status === 403) {
|
|
406
|
+
// This is helpful for debugging, but by default we don't show it
|
|
407
|
+
// github rate limit is 60 requests per hour for unauthenticated users
|
|
408
|
+
const resetTime = new Date(e.response.headers['x-ratelimit-reset'] * 1000)
|
|
409
|
+
aioLogger.debug(`too many requests, resetTime : ${resetTime.toLocaleTimeString()}`)
|
|
410
|
+
spinner.fail()
|
|
411
|
+
this.error('too many requests, please try again later')
|
|
412
|
+
} else {
|
|
413
|
+
this.error(e)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
351
417
|
}
|
|
418
|
+
|
|
352
419
|
InitCommand.description = `Create a new Adobe I/O App
|
|
353
420
|
`
|
|
354
421
|
|
|
@@ -372,18 +439,28 @@ InitCommand.flags = {
|
|
|
372
439
|
description: 'Extension point(s) to implement',
|
|
373
440
|
char: 'e',
|
|
374
441
|
multiple: true,
|
|
375
|
-
exclusive: ['template']
|
|
442
|
+
exclusive: ['template', 'repo']
|
|
376
443
|
}),
|
|
377
444
|
'standalone-app': Flags.boolean({
|
|
378
445
|
description: 'Create a stand-alone application',
|
|
379
446
|
default: false,
|
|
380
|
-
exclusive: ['template']
|
|
447
|
+
exclusive: ['template', 'repo']
|
|
381
448
|
}),
|
|
382
449
|
template: Flags.string({
|
|
383
450
|
description: 'Specify a link to a template that will be installed',
|
|
384
451
|
char: 't',
|
|
385
452
|
multiple: true
|
|
386
453
|
}),
|
|
454
|
+
org: Flags.string({
|
|
455
|
+
description: 'Specify the Adobe Developer Console Org to init from',
|
|
456
|
+
hidden: true,
|
|
457
|
+
exclusive: ['import'] // also no-login
|
|
458
|
+
}),
|
|
459
|
+
project: Flags.string({
|
|
460
|
+
description: 'Specify the Adobe Developer Console Project to init from',
|
|
461
|
+
hidden: true,
|
|
462
|
+
exclusive: ['import'] // also no-login
|
|
463
|
+
}),
|
|
387
464
|
workspace: Flags.string({
|
|
388
465
|
description: 'Specify the Adobe Developer Console Workspace to init from, defaults to Stage',
|
|
389
466
|
default: DEFAULT_WORKSPACE,
|
|
@@ -394,6 +471,10 @@ InitCommand.flags = {
|
|
|
394
471
|
description: 'Skip and confirm prompt for creating a new workspace',
|
|
395
472
|
default: false
|
|
396
473
|
}),
|
|
474
|
+
repo: Flags.string({
|
|
475
|
+
description: 'Init from gh quick-start repo. Expected to be of the form <owner>/<repo>/<path>',
|
|
476
|
+
exclusive: ['template', 'extension', 'standalone-app']
|
|
477
|
+
}),
|
|
397
478
|
'use-jwt': Flags.boolean({
|
|
398
479
|
description: 'if the config has both jwt and OAuth Server to Server Credentials (while migrating), prefer the JWT credentials',
|
|
399
480
|
default: false
|
|
@@ -55,7 +55,9 @@ class InstallCommand extends BaseCommand {
|
|
|
55
55
|
await this.validateAppConfig(outputPath, USER_CONFIG_FILE)
|
|
56
56
|
await this.validateDeployConfig(outputPath, DEPLOY_CONFIG_FILE)
|
|
57
57
|
await this.npmInstall(flags.verbose)
|
|
58
|
-
|
|
58
|
+
if (flags.tests) {
|
|
59
|
+
await this.runTests()
|
|
60
|
+
}
|
|
59
61
|
this.spinner.succeed('Install done.')
|
|
60
62
|
} catch (e) {
|
|
61
63
|
this.spinner.fail(e.message)
|
|
@@ -164,6 +166,11 @@ InstallCommand.flags = {
|
|
|
164
166
|
description: 'The packaged app output folder path',
|
|
165
167
|
char: 'o',
|
|
166
168
|
default: '.'
|
|
169
|
+
}),
|
|
170
|
+
tests: Flags.boolean({
|
|
171
|
+
description: 'Run packaged app unit tests (e.g. aio app:test)',
|
|
172
|
+
default: true,
|
|
173
|
+
allowNo: true
|
|
167
174
|
})
|
|
168
175
|
}
|
|
169
176
|
|