@sprucelabs/spruce-cli 14.26.18 → 14.28.1
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/CHANGELOG.md +38 -0
- package/build/.spruce/errors/errors.types.d.ts +19 -0
- package/build/.spruce/errors/options.types.d.ts +4 -1
- package/build/.spruce/errors/spruceCli/dependencyExists.schema.d.ts +3 -0
- package/build/.spruce/errors/spruceCli/dependencyExists.schema.js +28 -0
- package/build/.spruce/errors/spruceCli/dependencyExists.schema.js.map +1 -0
- package/build/__tests__/behavioral/AddingADependency.test.d.ts +6 -3
- package/build/__tests__/behavioral/AddingADependency.test.js +116 -44
- package/build/__tests__/behavioral/AddingADependency.test.js.map +1 -1
- package/build/__tests__/behavioral/InstallingASkillAtAnOrg.test.js +2 -2
- package/build/__tests__/behavioral/InstallingASkillAtAnOrg.test.js.map +1 -1
- package/build/__tests__/behavioral/LoggingInAsASkill.test.js +4 -4
- package/build/__tests__/behavioral/LoggingInAsASkill.test.js.map +1 -1
- package/build/__tests__/behavioral/ManagingDependencies.test.js +3 -3
- package/build/__tests__/behavioral/ManagingDependencies.test.js.map +1 -1
- package/build/__tests__/behavioral/RememberingUpgradeSelections.test.js +1 -1
- package/build/__tests__/behavioral/RememberingUpgradeSelections.test.js.map +1 -1
- package/build/__tests__/behavioral/SettingRemote.test.js +1 -1
- package/build/__tests__/behavioral/SettingRemote.test.js.map +1 -1
- package/build/__tests__/behavioral/SettingUpVscode.test.js +3 -3
- package/build/__tests__/behavioral/SettingUpVscode.test.js.map +1 -1
- package/build/__tests__/behavioral/TestingDataStores.test.js +2 -2
- package/build/__tests__/behavioral/TestingDataStores.test.js.map +1 -1
- package/build/__tests__/behavioral/UpgradingANodeModule.test.d.ts +1 -0
- package/build/__tests__/behavioral/UpgradingANodeModule.test.js +50 -3
- package/build/__tests__/behavioral/UpgradingANodeModule.test.js.map +1 -1
- package/build/__tests__/behavioral/events/CreatingAListener.test.js +2 -2
- package/build/__tests__/behavioral/events/CreatingAListener.test.js.map +1 -1
- package/build/__tests__/behavioral/events/CreatingAnEvent.test.d.ts +3 -2
- package/build/__tests__/behavioral/events/CreatingAnEvent.test.js +156 -106
- package/build/__tests__/behavioral/events/CreatingAnEvent.test.js.map +1 -1
- package/build/__tests__/behavioral/events/KeepingEventsInSync2.test.js +6 -9
- package/build/__tests__/behavioral/events/KeepingEventsInSync2.test.js.map +1 -1
- package/build/__tests__/behavioral/schemas/KeepingSchemasInSync.test.js +7 -4
- package/build/__tests__/behavioral/schemas/KeepingSchemasInSync.test.js.map +1 -1
- package/build/__tests__/behavioral/skill/UpgradingASkill.test.js +7 -7
- package/build/__tests__/behavioral/skill/UpgradingASkill.test.js.map +1 -1
- package/build/__tests__/behavioral/skill/UpgradingASkill3.test.js +2 -2
- package/build/__tests__/behavioral/skill/UpgradingASkill3.test.js.map +1 -1
- package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js +1 -1
- package/build/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.js.map +1 -1
- package/build/__tests__/behavioral/views/CreatingASkillView.test.js +3 -3
- package/build/__tests__/behavioral/views/CreatingASkillView.test.js.map +1 -1
- package/build/__tests__/behavioral/views/TestingViewControllers.test.js +2 -2
- package/build/__tests__/behavioral/views/TestingViewControllers.test.js.map +1 -1
- package/build/__tests__/implementation/ActionExecuter2.test.js +3 -3
- package/build/__tests__/implementation/ActionExecuter2.test.js.map +1 -1
- package/build/errors/SpruceError.js +4 -0
- package/build/errors/SpruceError.js.map +1 -1
- package/build/errors/dependencyExists.builder.d.ts +11 -0
- package/build/errors/dependencyExists.builder.js +22 -0
- package/build/errors/dependencyExists.builder.js.map +1 -0
- package/build/features/AbstractAction.js +1 -1
- package/build/features/AbstractAction.js.map +1 -1
- package/build/features/dependencies/actions/AddAction.js +22 -15
- package/build/features/dependencies/actions/AddAction.js.map +1 -1
- package/build/features/event/actions/CreateAction.js +1 -1
- package/build/features/event/actions/CreateAction.js.map +1 -1
- package/build/features/node/NodeFeature.d.ts +1 -0
- package/build/features/node/NodeFeature.js +83 -64
- package/build/features/node/NodeFeature.js.map +1 -1
- package/build/features/node/actions/UpgradeAction.js +20 -9
- package/build/features/node/actions/UpgradeAction.js.map +1 -1
- package/build/features/node/writers/NodeWriter.d.ts +5 -2
- package/build/features/node/writers/NodeWriter.js +37 -22
- package/build/features/node/writers/NodeWriter.js.map +1 -1
- package/build/features/skill/updaters/Updater.js +3 -1
- package/build/features/skill/updaters/Updater.js.map +1 -1
- package/build/interfaces/SpyInterface.d.ts +1 -1
- package/build/interfaces/SpyInterface.js +2 -2
- package/build/interfaces/SpyInterface.js.map +1 -1
- package/build/services/DependencyService.d.ts +1 -0
- package/build/services/DependencyService.js +18 -0
- package/build/services/DependencyService.js.map +1 -1
- package/build/tests/AbstractCliTest.js +1 -1
- package/build/tests/AbstractCliTest.js.map +1 -1
- package/build/tests/utilities/uiAssert.utility.d.ts +7 -0
- package/build/tests/utilities/uiAssert.utility.js +85 -0
- package/build/tests/utilities/uiAssert.utility.js.map +1 -0
- package/build/writers/AbstractWriter.d.ts +10 -10
- package/build/writers/AbstractWriter.js.map +1 -1
- package/package.json +34 -32
- package/src/.spruce/errors/errors.types.ts +29 -0
- package/src/.spruce/errors/options.types.ts +4 -1
- package/src/.spruce/errors/spruceCli/dependencyExists.schema.ts +22 -0
- package/src/__tests__/behavioral/AddingADependency.test.ts +45 -8
- package/src/__tests__/behavioral/InstallingASkillAtAnOrg.test.ts +3 -3
- package/src/__tests__/behavioral/LoggingInAsASkill.test.ts +4 -4
- package/src/__tests__/behavioral/ManagingDependencies.test.ts +3 -3
- package/src/__tests__/behavioral/RememberingUpgradeSelections.test.ts +1 -1
- package/src/__tests__/behavioral/SettingRemote.test.ts +1 -1
- package/src/__tests__/behavioral/SettingUpVscode.test.ts +3 -3
- package/src/__tests__/behavioral/TestingDataStores.test.ts +2 -2
- package/src/__tests__/behavioral/UpgradingANodeModule.test.ts +24 -0
- package/src/__tests__/behavioral/events/CreatingAListener.test.ts +2 -2
- package/src/__tests__/behavioral/events/CreatingAnEvent.test.ts +44 -22
- package/src/__tests__/behavioral/events/KeepingEventsInSync2.test.ts +1 -1
- package/src/__tests__/behavioral/schemas/KeepingSchemasInSync.test.ts +2 -0
- package/src/__tests__/behavioral/skill/UpgradingASkill.test.ts +7 -7
- package/src/__tests__/behavioral/skill/UpgradingASkill3.test.ts +2 -2
- package/src/__tests__/behavioral/tests/SelectingAnAbstractTestClass.test.ts +1 -1
- package/src/__tests__/behavioral/views/CreatingASkillView.test.ts +3 -3
- package/src/__tests__/behavioral/views/TestingViewControllers.test.ts +2 -2
- package/src/__tests__/implementation/ActionExecuter2.test.ts +3 -3
- package/src/errors/SpruceError.ts +4 -0
- package/src/errors/dependencyExists.builder.ts +12 -0
- package/src/features/AbstractAction.ts +1 -4
- package/src/features/dependencies/actions/AddAction.ts +12 -5
- package/src/features/event/actions/CreateAction.ts +4 -1
- package/src/features/node/NodeFeature.ts +31 -25
- package/src/features/node/actions/UpgradeAction.ts +8 -1
- package/src/features/node/writers/NodeWriter.ts +38 -23
- package/src/features/skill/updaters/Updater.ts +2 -1
- package/src/interfaces/SpyInterface.ts +1 -1
- package/src/services/DependencyService.ts +14 -0
- package/src/tests/AbstractCliTest.ts +1 -1
- package/src/tests/utilities/uiAssert.utility.ts +45 -0
- package/src/writers/AbstractWriter.ts +15 -10
|
@@ -117,7 +117,7 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
117
117
|
|
|
118
118
|
await this.assertFailedHealthCheck(cli)
|
|
119
119
|
|
|
120
|
-
const last = this.ui.
|
|
120
|
+
const last = this.ui.getLastInvocation()
|
|
121
121
|
|
|
122
122
|
assert.doesInclude(last, {
|
|
123
123
|
'options.options.choices[].value': FILE_ACTION_OVERWRITE,
|
|
@@ -251,7 +251,7 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
251
251
|
|
|
252
252
|
await this.waitForInput()
|
|
253
253
|
|
|
254
|
-
const last = this.ui.
|
|
254
|
+
const last = this.ui.getLastInvocation()
|
|
255
255
|
|
|
256
256
|
assert.isEqual(last.command, 'prompt')
|
|
257
257
|
assert.doesInclude(last.options.options.choices, { value: 'skip' })
|
|
@@ -277,14 +277,14 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
277
277
|
|
|
278
278
|
await this.waitForInput()
|
|
279
279
|
|
|
280
|
-
let last = this.ui.
|
|
280
|
+
let last = this.ui.getLastInvocation()
|
|
281
281
|
|
|
282
282
|
assert.isEqual(last.command, 'prompt')
|
|
283
283
|
await this.ui.sendInput('skip')
|
|
284
284
|
|
|
285
285
|
await this.waitForInput()
|
|
286
286
|
|
|
287
|
-
last = this.ui.
|
|
287
|
+
last = this.ui.getLastInvocation()
|
|
288
288
|
|
|
289
289
|
assert.isEqual(last.command, 'prompt')
|
|
290
290
|
await this.ui.sendInput('skip')
|
|
@@ -307,7 +307,7 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
307
307
|
|
|
308
308
|
await this.waitForInput()
|
|
309
309
|
|
|
310
|
-
let last = this.ui.
|
|
310
|
+
let last = this.ui.getLastInvocation()
|
|
311
311
|
|
|
312
312
|
assert.isEqual(last.command, 'prompt')
|
|
313
313
|
await this.ui.sendInput('skipAll')
|
|
@@ -329,7 +329,7 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
329
329
|
|
|
330
330
|
await this.waitForInput()
|
|
331
331
|
|
|
332
|
-
let last = this.ui.
|
|
332
|
+
let last = this.ui.getLastInvocation()
|
|
333
333
|
|
|
334
334
|
assert.isEqual(last.command, 'prompt')
|
|
335
335
|
await this.ui.sendInput('overwrite')
|
|
@@ -431,7 +431,7 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
431
431
|
|
|
432
432
|
await this.waitForInput()
|
|
433
433
|
|
|
434
|
-
const last = this.ui.
|
|
434
|
+
const last = this.ui.getLastInvocation()
|
|
435
435
|
return { last, promise }
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -96,12 +96,12 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
96
96
|
|
|
97
97
|
await this.waitForInput()
|
|
98
98
|
|
|
99
|
-
let last = this.ui.
|
|
99
|
+
let last = this.ui.getLastInvocation()
|
|
100
100
|
|
|
101
101
|
assert.isEqual(last.command, 'prompt')
|
|
102
102
|
await this.ui.sendInput('overwrite')
|
|
103
103
|
|
|
104
|
-
last = this.ui.
|
|
104
|
+
last = this.ui.getLastInvocation()
|
|
105
105
|
|
|
106
106
|
assert.isEqual(last.command, 'prompt')
|
|
107
107
|
await this.ui.sendInput('overwrite')
|
|
@@ -185,7 +185,7 @@ export default class SelectingAnAbstractTestClassTest extends AbstractTestTest {
|
|
|
185
185
|
|
|
186
186
|
await this.waitForInput()
|
|
187
187
|
|
|
188
|
-
const last = this.ui.
|
|
188
|
+
const last = this.ui.getLastInvocation()
|
|
189
189
|
const { choices } = last.options.options ?? {}
|
|
190
190
|
|
|
191
191
|
return { promise, choices } as {
|
|
@@ -30,7 +30,7 @@ export default class CreatingASkillViewTest extends AbstractSkillTest {
|
|
|
30
30
|
|
|
31
31
|
await this.waitForInput()
|
|
32
32
|
|
|
33
|
-
const last = this.ui.
|
|
33
|
+
const last = this.ui.getLastInvocation()
|
|
34
34
|
|
|
35
35
|
assert.isEqual(last.command, 'confirm')
|
|
36
36
|
|
|
@@ -90,7 +90,7 @@ export default class CreatingASkillViewTest extends AbstractSkillTest {
|
|
|
90
90
|
|
|
91
91
|
await this.waitForInput()
|
|
92
92
|
|
|
93
|
-
let last = this.ui.
|
|
93
|
+
let last = this.ui.getLastInvocation()
|
|
94
94
|
|
|
95
95
|
assert.isEqual(last.command, 'prompt')
|
|
96
96
|
|
|
@@ -120,7 +120,7 @@ export default class CreatingASkillViewTest extends AbstractSkillTest {
|
|
|
120
120
|
|
|
121
121
|
await this.waitForInput()
|
|
122
122
|
|
|
123
|
-
const last = this.ui.
|
|
123
|
+
const last = this.ui.getLastInvocation()
|
|
124
124
|
|
|
125
125
|
assert.isEqual(last.command, 'prompt')
|
|
126
126
|
assert.doesInclude(last.options.options.choices, {
|
|
@@ -15,7 +15,7 @@ export default class TestingViewControllersTest extends AbstractSkillTest {
|
|
|
15
15
|
|
|
16
16
|
await this.waitForInput()
|
|
17
17
|
|
|
18
|
-
const last = this.ui.
|
|
18
|
+
const last = this.ui.getLastInvocation()
|
|
19
19
|
assert.doesInclude(last.options.options.choices, {
|
|
20
20
|
label: 'AbstractViewControllerTest (requires install)',
|
|
21
21
|
})
|
|
@@ -29,7 +29,7 @@ export default class TestingViewControllersTest extends AbstractSkillTest {
|
|
|
29
29
|
|
|
30
30
|
await this.waitForInput()
|
|
31
31
|
|
|
32
|
-
const last = this.ui.
|
|
32
|
+
const last = this.ui.getLastInvocation()
|
|
33
33
|
assert.doesInclude(last.options.options.choices, {
|
|
34
34
|
label: 'AbstractViewControllerTest',
|
|
35
35
|
})
|
|
@@ -107,7 +107,7 @@ export default class FeatureCommandExecuterContTest extends AbstractSchemaTest {
|
|
|
107
107
|
|
|
108
108
|
await this.waitForInput()
|
|
109
109
|
|
|
110
|
-
assert.doesNotInclude(this.ui.
|
|
110
|
+
assert.doesNotInclude(this.ui.getLastInvocation(), {
|
|
111
111
|
command: 'prompt',
|
|
112
112
|
options: {
|
|
113
113
|
type: 'select',
|
|
@@ -158,7 +158,7 @@ export default class FeatureCommandExecuterContTest extends AbstractSchemaTest {
|
|
|
158
158
|
await this.waitForInput()
|
|
159
159
|
|
|
160
160
|
this.ui.reset()
|
|
161
|
-
const lastQuestion = this.ui.
|
|
161
|
+
const lastQuestion = this.ui.getLastInvocation()
|
|
162
162
|
|
|
163
163
|
assert.isEqual(lastQuestion.command, 'prompt')
|
|
164
164
|
assert.doesInclude(
|
|
@@ -227,7 +227,7 @@ export default class FeatureCommandExecuterContTest extends AbstractSchemaTest {
|
|
|
227
227
|
assert.doesInclude(message, /2 required/gi)
|
|
228
228
|
assert.doesInclude(message, /1 optional/gi)
|
|
229
229
|
|
|
230
|
-
assert.doesInclude(this.ui.
|
|
230
|
+
assert.doesInclude(this.ui.getLastInvocation(), {
|
|
231
231
|
command: 'prompt',
|
|
232
232
|
options: {
|
|
233
233
|
type: 'select',
|
|
@@ -252,6 +252,10 @@ export default class SpruceError extends AbstractSpruceError<ErrorOptions> {
|
|
|
252
252
|
message = `A transport named '${options.name}' already exists!`
|
|
253
253
|
break
|
|
254
254
|
|
|
255
|
+
case 'DEPENDENCY_EXISTS':
|
|
256
|
+
message = `You already have ${options.namespace} as a dependency!`
|
|
257
|
+
break
|
|
258
|
+
|
|
255
259
|
default:
|
|
256
260
|
message = super.friendlyMessage()
|
|
257
261
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Schema, SchemaValues, SchemaPartialValues } from '@sprucelabs/schema'
|
|
2
2
|
import { versionUtil } from '@sprucelabs/spruce-skill-utils'
|
|
3
|
-
import { diskUtil } from '@sprucelabs/spruce-skill-utils'
|
|
4
3
|
import { Templates } from '@sprucelabs/spruce-templates'
|
|
5
4
|
import { GlobalEmitter } from '../GlobalEmitter'
|
|
6
5
|
import ServiceFactory, {
|
|
@@ -132,9 +131,7 @@ export default abstract class AbstractAction<S extends Schema = Schema>
|
|
|
132
131
|
resolvedDestination: string,
|
|
133
132
|
fallbackVersion: string
|
|
134
133
|
) {
|
|
135
|
-
const versions =
|
|
136
|
-
? versionUtil.getAllVersions(resolvedDestination)
|
|
137
|
-
: []
|
|
134
|
+
const versions = versionUtil.getAllVersions(resolvedDestination)
|
|
138
135
|
const todaysVersion = versionUtil.generateVersion()
|
|
139
136
|
|
|
140
137
|
let version = fallbackVersion
|
|
@@ -27,17 +27,24 @@ export default class DeployAction extends AbstractAction<OptionsSchema> {
|
|
|
27
27
|
let { namespace } = this.validateAndNormalizeOptions(options)
|
|
28
28
|
|
|
29
29
|
const skills = await this.Store('skill').fetchAllSkills()
|
|
30
|
+
const dependencyService = this.Service('dependency')
|
|
30
31
|
|
|
31
32
|
if (!namespace) {
|
|
33
|
+
const dependencies = dependencyService.get().map((d) => d.namespace)
|
|
34
|
+
|
|
35
|
+
const choices = skills
|
|
36
|
+
.filter((s) => dependencies.indexOf(s.slug) === -1)
|
|
37
|
+
.map((s) => ({
|
|
38
|
+
value: s.slug,
|
|
39
|
+
label: s.name,
|
|
40
|
+
}))
|
|
41
|
+
|
|
32
42
|
namespace = await this.ui.prompt({
|
|
33
43
|
type: 'select',
|
|
34
44
|
label: 'Which skill would you like to add as a dependency?',
|
|
35
45
|
isRequired: true,
|
|
36
46
|
options: {
|
|
37
|
-
choices
|
|
38
|
-
value: s.slug,
|
|
39
|
-
label: s.name,
|
|
40
|
-
})),
|
|
47
|
+
choices,
|
|
41
48
|
},
|
|
42
49
|
})
|
|
43
50
|
}
|
|
@@ -51,7 +58,7 @@ export default class DeployAction extends AbstractAction<OptionsSchema> {
|
|
|
51
58
|
})
|
|
52
59
|
}
|
|
53
60
|
|
|
54
|
-
|
|
61
|
+
dependencyService.add({
|
|
55
62
|
id: skill.id,
|
|
56
63
|
namespace: skill.slug,
|
|
57
64
|
})
|
|
@@ -68,7 +68,10 @@ export default class CreateAction extends AbstractAction<OptionsSchema> {
|
|
|
68
68
|
|
|
69
69
|
try {
|
|
70
70
|
const destinationDir = diskUtil.resolvePath(this.cwd, 'src', 'events')
|
|
71
|
-
const resolvedVersion = await this.resolveVersion(
|
|
71
|
+
const resolvedVersion = await this.resolveVersion(
|
|
72
|
+
version,
|
|
73
|
+
diskUtil.resolvePath(destinationDir, '**', '*')
|
|
74
|
+
)
|
|
72
75
|
|
|
73
76
|
const files = await this.Writer('event').writeEvent(destinationDir, {
|
|
74
77
|
nameKebab,
|
|
@@ -5,7 +5,11 @@ import nodeFeatureOptionsSchema from '#spruce/schemas/spruceCli/v2020_07_22/node
|
|
|
5
5
|
import { FileDescription, GeneratedFile } from '../../types/cli.types'
|
|
6
6
|
import ScriptUpdater from '../../updaters/ScriptUpdater'
|
|
7
7
|
import AbstractFeature, { FeatureDependency } from '../AbstractFeature'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ActionOptions,
|
|
10
|
+
FeatureActionResponse,
|
|
11
|
+
FeatureCode,
|
|
12
|
+
} from '../features.types'
|
|
9
13
|
import universalDevDependencies from '../universalDevDependencies'
|
|
10
14
|
import universalFileDescriptions from '../universalFileDescriptions'
|
|
11
15
|
import universalScripts from '../universalScripts'
|
|
@@ -49,33 +53,36 @@ export default class NodeFeature<
|
|
|
49
53
|
|
|
50
54
|
void this.emitter.on('feature.did-execute', async (payload) => {
|
|
51
55
|
if (payload.featureCode === 'node' && payload.actionCode === 'upgrade') {
|
|
52
|
-
|
|
53
|
-
this.ui.startLoading('Cleaning build...')
|
|
54
|
-
await this.Service('command').execute('yarn clean.build')
|
|
55
|
-
|
|
56
|
-
this.ui.startLoading('Applying lint rules to all files...')
|
|
57
|
-
await this.Service('command').execute('yarn fix.lint')
|
|
58
|
-
|
|
59
|
-
this.ui.startLoading('Rebuilding...')
|
|
60
|
-
await this.Service('command').execute('yarn build.dev')
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
summaryLines: [
|
|
64
|
-
'Build cleared.',
|
|
65
|
-
'Lint rules applied to source.',
|
|
66
|
-
'Code rebuilt successfully.',
|
|
67
|
-
],
|
|
68
|
-
}
|
|
69
|
-
} catch (err) {
|
|
70
|
-
return {
|
|
71
|
-
errors: [err],
|
|
72
|
-
}
|
|
73
|
-
}
|
|
56
|
+
return this.handleUpgrade()
|
|
74
57
|
}
|
|
75
58
|
|
|
76
59
|
return {}
|
|
77
60
|
})
|
|
78
61
|
}
|
|
62
|
+
private async handleUpgrade(): Promise<FeatureActionResponse> {
|
|
63
|
+
try {
|
|
64
|
+
this.ui.startLoading('Cleaning build...')
|
|
65
|
+
await this.Service('command').execute('yarn clean.build')
|
|
66
|
+
|
|
67
|
+
this.ui.startLoading('Applying lint rules to all files...')
|
|
68
|
+
await this.Service('command').execute('yarn fix.lint')
|
|
69
|
+
|
|
70
|
+
this.ui.startLoading('Rebuilding...')
|
|
71
|
+
await this.Service('command').execute('yarn build.dev')
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
summaryLines: [
|
|
75
|
+
'Build cleared.',
|
|
76
|
+
'Lint rules applied to source.',
|
|
77
|
+
'Code rebuilt successfully.',
|
|
78
|
+
],
|
|
79
|
+
}
|
|
80
|
+
} catch (err) {
|
|
81
|
+
return {
|
|
82
|
+
errors: [err],
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
79
86
|
|
|
80
87
|
public async beforePackageInstall(options: Options) {
|
|
81
88
|
const destination = this.resolveDestination(options)
|
|
@@ -94,8 +101,7 @@ export default class NodeFeature<
|
|
|
94
101
|
|
|
95
102
|
await this.Service('command', destination).execute('yarn init -y')
|
|
96
103
|
|
|
97
|
-
const
|
|
98
|
-
const written = await nodeWriter.writeNodeModule(destination)
|
|
104
|
+
const written = await this.Writer('node').writeNodeModule(destination)
|
|
99
105
|
|
|
100
106
|
files.push(...written)
|
|
101
107
|
|
|
@@ -24,6 +24,13 @@ export default class UpgradeAction extends AbstractAction<OptionsSchema> {
|
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
try {
|
|
27
|
+
const files = await this.Writer('node', {
|
|
28
|
+
upgradeMode: normalizedOptions.upgradeMode,
|
|
29
|
+
}).writeNodeModule(this.cwd, {
|
|
30
|
+
shouldConfirmBeforeWriting: true,
|
|
31
|
+
shouldWriteIndex: false,
|
|
32
|
+
})
|
|
33
|
+
|
|
27
34
|
InFlightEntertainment.start([
|
|
28
35
|
"Let's start the upgrade!",
|
|
29
36
|
'While things are going, see if you can beat 1k points!',
|
|
@@ -34,10 +41,10 @@ export default class UpgradeAction extends AbstractAction<OptionsSchema> {
|
|
|
34
41
|
|
|
35
42
|
return actionUtil.mergeActionResults(dependencyResults, {
|
|
36
43
|
headline: 'Upgrade',
|
|
44
|
+
files,
|
|
37
45
|
})
|
|
38
46
|
} finally {
|
|
39
47
|
InFlightEntertainment.stop()
|
|
40
|
-
|
|
41
48
|
this.ui.renderHero('Upgrade')
|
|
42
49
|
}
|
|
43
50
|
}
|
|
@@ -1,35 +1,50 @@
|
|
|
1
1
|
import { diskUtil } from '@sprucelabs/spruce-skill-utils'
|
|
2
2
|
import { DirectoryTemplateCode } from '@sprucelabs/spruce-templates'
|
|
3
|
-
import
|
|
3
|
+
import { GeneratedFile } from '../../../types/cli.types'
|
|
4
|
+
import AbstractWriter, {
|
|
5
|
+
WriteDirectoryTemplateOptions,
|
|
6
|
+
WriteResults,
|
|
7
|
+
} from '../../../writers/AbstractWriter'
|
|
4
8
|
|
|
9
|
+
export const NODE_FILES_TO_UPGRADE = [
|
|
10
|
+
'tsconfig.json',
|
|
11
|
+
'.eslintrc.js',
|
|
12
|
+
'.eslintignore',
|
|
13
|
+
'.gitignore',
|
|
14
|
+
'.nvmrc',
|
|
15
|
+
]
|
|
5
16
|
export default class NodeWriter extends AbstractWriter {
|
|
6
|
-
public async writeNodeModule(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
public async writeNodeModule(
|
|
18
|
+
destinationDir: string,
|
|
19
|
+
options?: Partial<WriteDirectoryTemplateOptions> & {
|
|
20
|
+
shouldWriteIndex?: boolean
|
|
21
|
+
}
|
|
22
|
+
): Promise<WriteResults> {
|
|
23
|
+
let files: GeneratedFile[] = []
|
|
24
|
+
if (options?.shouldWriteIndex !== false) {
|
|
25
|
+
const contents = '//exports go here\n'
|
|
26
|
+
const destination = diskUtil.resolvePath(
|
|
27
|
+
destinationDir,
|
|
28
|
+
'src',
|
|
29
|
+
'index.ts'
|
|
30
|
+
)
|
|
31
|
+
diskUtil.writeFile(destination, contents)
|
|
32
|
+
files.push({
|
|
33
|
+
name: 'src/index.ts',
|
|
34
|
+
description: 'Placeholder entry file!',
|
|
35
|
+
action: 'generated',
|
|
36
|
+
path: destination,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
11
39
|
|
|
12
|
-
const
|
|
40
|
+
const directoryTemplateFiles = await this.writeDirectoryTemplate({
|
|
13
41
|
destinationDir,
|
|
14
42
|
code: DirectoryTemplateCode.Skill,
|
|
15
|
-
filesToWrite:
|
|
16
|
-
'tsconfig.json',
|
|
17
|
-
'.eslintrc.js',
|
|
18
|
-
'.eslintignore',
|
|
19
|
-
'.gitignore',
|
|
20
|
-
'.nvmrc',
|
|
21
|
-
],
|
|
43
|
+
filesToWrite: NODE_FILES_TO_UPGRADE,
|
|
22
44
|
context: { name: 'ignored', description: 'ignored' },
|
|
45
|
+
...options,
|
|
23
46
|
})
|
|
24
47
|
|
|
25
|
-
return [
|
|
26
|
-
{
|
|
27
|
-
name: 'src/index.ts',
|
|
28
|
-
description: 'Placeholder entry file!',
|
|
29
|
-
action: 'generated',
|
|
30
|
-
path: destination,
|
|
31
|
-
},
|
|
32
|
-
...files,
|
|
33
|
-
]
|
|
48
|
+
return [...files, ...directoryTemplateFiles]
|
|
34
49
|
}
|
|
35
50
|
}
|
|
@@ -3,6 +3,7 @@ import { SpruceSchemas } from '#spruce/schemas/schemas.types'
|
|
|
3
3
|
import SpruceError from '../../../errors/SpruceError'
|
|
4
4
|
import { GlobalEmitter } from '../../../GlobalEmitter'
|
|
5
5
|
import AbstractFeature from '../../AbstractFeature'
|
|
6
|
+
import { NODE_FILES_TO_UPGRADE } from '../../node/writers/NodeWriter'
|
|
6
7
|
|
|
7
8
|
type UpgradeOptions = SpruceSchemas.SpruceCli.v2020_07_22.UpgradeSkillOptions
|
|
8
9
|
|
|
@@ -35,7 +36,7 @@ export default class Updater {
|
|
|
35
36
|
SpruceError
|
|
36
37
|
)
|
|
37
38
|
|
|
38
|
-
const filesToSkip = ['package.json']
|
|
39
|
+
const filesToSkip = [...NODE_FILES_TO_UPGRADE, 'package.json']
|
|
39
40
|
|
|
40
41
|
for (const payload of payloads) {
|
|
41
42
|
if (payload.filesToSkip) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SettingsService } from '@sprucelabs/spruce-skill-utils'
|
|
2
|
+
import SpruceError from '../errors/SpruceError'
|
|
2
3
|
|
|
3
4
|
interface Dependency {
|
|
4
5
|
id: string
|
|
@@ -16,10 +17,23 @@ export default class DependencyService {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
public add(dependency: Dependency) {
|
|
20
|
+
this.assertDependencyDoesNotExist(dependency.namespace)
|
|
21
|
+
|
|
19
22
|
const dependencies = this.settings.get('dependencies') ?? []
|
|
20
23
|
dependencies.push(dependency)
|
|
21
24
|
this.settings.set('dependencies', dependencies)
|
|
22
25
|
}
|
|
26
|
+
private assertDependencyDoesNotExist(namespace: string) {
|
|
27
|
+
const dependencies = this.get()
|
|
28
|
+
const match = dependencies.find((d) => d.namespace === namespace)
|
|
29
|
+
|
|
30
|
+
if (match) {
|
|
31
|
+
throw new SpruceError({
|
|
32
|
+
code: 'DEPENDENCY_EXISTS',
|
|
33
|
+
namespace,
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
23
37
|
|
|
24
38
|
public get(): Dependency[] {
|
|
25
39
|
return this.settings.get('dependencies') ?? []
|
|
@@ -465,7 +465,7 @@ export default abstract class AbstractCliTest extends AbstractSpruceTest {
|
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
protected static selectOptionBasedOnLabel(label: string) {
|
|
468
|
-
const last = this.ui.
|
|
468
|
+
const last = this.ui.getLastInvocation()
|
|
469
469
|
assert.doesInclude(last.options.options.choices, {
|
|
470
470
|
label,
|
|
471
471
|
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { assert } from '@sprucelabs/test'
|
|
2
|
+
import SpyInterface from '../../interfaces/SpyInterface'
|
|
3
|
+
|
|
4
|
+
const uiAssertUtil = {
|
|
5
|
+
async assertRendersSelect(ui: SpyInterface) {
|
|
6
|
+
await ui.waitForInput()
|
|
7
|
+
|
|
8
|
+
const last = ui.getLastInvocation()
|
|
9
|
+
assert.isTruthy(
|
|
10
|
+
last.options.options.choices,
|
|
11
|
+
`I expected a select, I did not find one!`
|
|
12
|
+
)
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
assertSelectDidNotRenderChoice(
|
|
16
|
+
ui: SpyInterface,
|
|
17
|
+
value: string,
|
|
18
|
+
label: string
|
|
19
|
+
) {
|
|
20
|
+
const last = ui.getLastInvocation()
|
|
21
|
+
|
|
22
|
+
assert.doesNotInclude(last.options.options.choices, {
|
|
23
|
+
value,
|
|
24
|
+
label,
|
|
25
|
+
})
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
async assertRendersConfirmWriteFile(ui: SpyInterface) {
|
|
29
|
+
await ui.waitForInput()
|
|
30
|
+
|
|
31
|
+
const last = ui.getLastInvocation()
|
|
32
|
+
|
|
33
|
+
assert.isEqual(last.options.type, 'select')
|
|
34
|
+
assert.isEqualDeep(last.options.options.choices, [
|
|
35
|
+
{
|
|
36
|
+
label: 'Overwrite',
|
|
37
|
+
value: 'overwrite',
|
|
38
|
+
},
|
|
39
|
+
{ value: 'skip', label: 'Skip' },
|
|
40
|
+
{ value: 'alwaysSkip', label: 'Always skip' },
|
|
41
|
+
])
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default uiAssertUtil
|
|
@@ -16,13 +16,22 @@ export type WriteResults = GeneratedFile[]
|
|
|
16
16
|
export interface WriterOptions {
|
|
17
17
|
templates: Templates
|
|
18
18
|
term: GraphicsInterface
|
|
19
|
-
askBeforeUpdating?: boolean
|
|
20
19
|
upgradeMode?: UpgradeMode
|
|
21
20
|
fileDescriptions: FileDescription[]
|
|
22
21
|
linter?: LintService
|
|
23
22
|
settings: SettingsService
|
|
24
23
|
}
|
|
25
24
|
|
|
25
|
+
export interface WriteDirectoryTemplateOptions {
|
|
26
|
+
destinationDir: string
|
|
27
|
+
code: DirectoryTemplateCode
|
|
28
|
+
filesToWrite?: string[]
|
|
29
|
+
filesToSkip?: string[]
|
|
30
|
+
context: any
|
|
31
|
+
shouldConfirmBeforeWriting?: boolean
|
|
32
|
+
firstFileWriteMessage?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
export default abstract class AbstractWriter {
|
|
27
36
|
protected templates: Templates
|
|
28
37
|
protected ui: GraphicsInterface
|
|
@@ -59,15 +68,9 @@ export default abstract class AbstractWriter {
|
|
|
59
68
|
this.isLintingEnabled = true
|
|
60
69
|
}
|
|
61
70
|
|
|
62
|
-
protected async writeDirectoryTemplate(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
filesToWrite?: string[]
|
|
66
|
-
filesToSkip?: string[]
|
|
67
|
-
context: any
|
|
68
|
-
shouldConfirmBeforeWriting?: boolean
|
|
69
|
-
firstFileWriteMessage?: string
|
|
70
|
-
}) {
|
|
71
|
+
protected async writeDirectoryTemplate(
|
|
72
|
+
options: WriteDirectoryTemplateOptions
|
|
73
|
+
) {
|
|
71
74
|
const {
|
|
72
75
|
context,
|
|
73
76
|
destinationDir,
|
|
@@ -93,6 +96,7 @@ export default abstract class AbstractWriter {
|
|
|
93
96
|
!filesToWrite || filesToWrite.indexOf(generated.filename) > -1
|
|
94
97
|
const shouldSkip =
|
|
95
98
|
filesToSkip && filesToSkip.indexOf(generated.filename) > -1
|
|
99
|
+
|
|
96
100
|
if (shouldWrite && !shouldSkip) {
|
|
97
101
|
results = await this.writeFileIfChangedMixinResults(
|
|
98
102
|
pathUtil.join(destinationDir, generated.relativePath),
|
|
@@ -128,6 +132,7 @@ export default abstract class AbstractWriter {
|
|
|
128
132
|
|
|
129
133
|
if (!diskUtil.doesFileExist(destination)) {
|
|
130
134
|
let write = true
|
|
135
|
+
|
|
131
136
|
if (
|
|
132
137
|
this.shouldConfirmBeforeWriting &&
|
|
133
138
|
fileDescription?.confirmPromptOnFirstWrite
|