@sprucelabs/spruce-cli 14.24.4 → 14.24.5
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 +8 -0
- package/build/__tests__/behavioral/RegisteringEventsOnBoot.test.js +24 -28
- package/build/__tests__/behavioral/RegisteringEventsOnBoot.test.js.map +1 -1
- package/build/__tests__/behavioral/events/KeepingEventsInSync2.test.d.ts +1 -1
- package/build/__tests__/behavioral/events/KeepingEventsInSync2.test.js +10 -14
- package/build/__tests__/behavioral/events/KeepingEventsInSync2.test.js.map +1 -1
- package/build/__tests__/behavioral/skill/UpgradingASkill.test.d.ts +1 -1
- package/build/__tests__/behavioral/skill/UpgradingASkill.test.js +23 -12
- package/build/__tests__/behavioral/skill/UpgradingASkill.test.js.map +1 -1
- package/build/__tests__/behavioral/skill/UpgradingASkill2.test.d.ts +1 -1
- package/build/__tests__/behavioral/skill/UpgradingASkill2.test.js +20 -10
- package/build/__tests__/behavioral/skill/UpgradingASkill2.test.js.map +1 -1
- package/build/features/error/ErrorFeature.js.map +1 -1
- package/build/features/error/writers/ErrorWriter.js +29 -6
- package/build/features/error/writers/ErrorWriter.js.map +1 -1
- package/build/features/event/EventFeature.d.ts +3 -1
- package/build/features/event/EventFeature.js +46 -29
- package/build/features/event/EventFeature.js.map +1 -1
- package/build/features/event/stores/EventStore.d.ts +2 -1
- package/build/features/event/stores/EventStore.js +33 -22
- package/build/features/event/stores/EventStore.js.map +1 -1
- package/build/features/node/NodeFeature.d.ts +2 -1
- package/build/features/node/NodeFeature.js +86 -34
- package/build/features/node/NodeFeature.js.map +1 -1
- package/build/features/node/actions/UpgradeAction.js +9 -21
- package/build/features/node/actions/UpgradeAction.js.map +1 -1
- package/build/features/test/actions/TestAction.js +1 -1
- package/build/features/test/actions/TestAction.js.map +1 -1
- package/build/interfaces/TerminalInterface.js +7 -7
- package/build/interfaces/TerminalInterface.js.map +1 -1
- package/package.json +29 -29
- package/src/__tests__/behavioral/RegisteringEventsOnBoot.test.ts +20 -23
- package/src/__tests__/behavioral/events/KeepingEventsInSync2.test.ts +2 -5
- package/src/__tests__/behavioral/skill/UpgradingASkill.test.ts +30 -7
- package/src/__tests__/behavioral/skill/UpgradingASkill2.test.ts +10 -1
- package/src/features/error/ErrorFeature.ts +2 -0
- package/src/features/error/writers/ErrorWriter.ts +3 -1
- package/src/features/event/EventFeature.ts +32 -14
- package/src/features/event/stores/EventStore.ts +12 -4
- package/src/features/node/NodeFeature.ts +34 -1
- package/src/features/node/actions/UpgradeAction.ts +2 -11
- package/src/features/test/actions/TestAction.ts +4 -1
- package/src/interfaces/TerminalInterface.ts +5 -5
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
versionUtil,
|
|
17
17
|
} from '@sprucelabs/spruce-skill-utils'
|
|
18
18
|
import { test, assert } from '@sprucelabs/test'
|
|
19
|
-
import EventStore from '../../../features/event/stores/EventStore'
|
|
20
19
|
import { generateEventContractFileName } from '../../../features/event/writers/EventWriter'
|
|
21
20
|
import { FeatureActionResponse } from '../../../features/features.types'
|
|
22
21
|
import AbstractEventTest from '../../../tests/AbstractEventTest'
|
|
@@ -34,8 +33,8 @@ export default class KeepingEventsInSyncTest extends AbstractEventTest {
|
|
|
34
33
|
return versionUtil.generateVersion()
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
@test()
|
|
38
|
-
protected static async
|
|
36
|
+
@test.skip('find how to simulate connection errors')
|
|
37
|
+
protected static async syncingSchemasWithDisconnectedStopsWithError() {
|
|
39
38
|
await this.FeatureFixture().installCachedFeatures('events')
|
|
40
39
|
|
|
41
40
|
await this.syncCoreEventsPretendingToBeMercuryTypes()
|
|
@@ -55,8 +54,6 @@ export default class KeepingEventsInSyncTest extends AbstractEventTest {
|
|
|
55
54
|
|
|
56
55
|
await client.disconnect()
|
|
57
56
|
|
|
58
|
-
EventStore.clearCache()
|
|
59
|
-
|
|
60
57
|
const results2 = await this.Action('schema', 'sync').execute({})
|
|
61
58
|
|
|
62
59
|
assert.isTruthy(results2.errors)
|
|
@@ -191,30 +191,53 @@ export default class UpgradingASkillTest extends AbstractCliTest {
|
|
|
191
191
|
assert.isEqual(passedHealth.skill.status, 'passed')
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
@test('Upgrades error.plugin', 'error.plugin.ts', 'errors')
|
|
195
|
-
@test('Upgrades schema.plugin', 'schema.plugin.ts', 'schemas')
|
|
196
194
|
@test(
|
|
197
|
-
'Upgrades
|
|
195
|
+
'Upgrades error.plugin (even if skill is broken)',
|
|
196
|
+
'error.plugin.ts',
|
|
197
|
+
'errors'
|
|
198
|
+
)
|
|
199
|
+
@test(
|
|
200
|
+
'Upgrades schema.plugin (even if skill is broken)',
|
|
201
|
+
'schema.plugin.ts',
|
|
202
|
+
'schemas'
|
|
203
|
+
)
|
|
204
|
+
@test(
|
|
205
|
+
'Upgrades conversation.plugin (even if skill is broken)',
|
|
198
206
|
'conversation.plugin.ts',
|
|
199
|
-
'conversation'
|
|
207
|
+
'conversation',
|
|
208
|
+
false
|
|
209
|
+
)
|
|
210
|
+
@test(
|
|
211
|
+
'Upgrades view.plugin (even if skill is broken)',
|
|
212
|
+
'view.plugin.ts',
|
|
213
|
+
'views',
|
|
214
|
+
false
|
|
200
215
|
)
|
|
201
|
-
protected static async upgradesPlugins(
|
|
216
|
+
protected static async upgradesPlugins(
|
|
217
|
+
pluginName: string,
|
|
218
|
+
cacheKey: string,
|
|
219
|
+
shouldMockYarn = true
|
|
220
|
+
) {
|
|
202
221
|
await this.FeatureFixture().installCachedFeatures(cacheKey)
|
|
203
222
|
|
|
204
|
-
CommandService.setMockResponse(/yarn/, { code: 0 })
|
|
223
|
+
shouldMockYarn && CommandService.setMockResponse(/yarn/, { code: 0 })
|
|
205
224
|
|
|
206
225
|
const pluginPath = this.resolveHashSprucePath(`features/${pluginName}`)
|
|
207
226
|
const originalContents = diskUtil.readFile(pluginPath)
|
|
208
227
|
|
|
209
|
-
diskUtil.writeFile(pluginPath, '')
|
|
228
|
+
diskUtil.writeFile(pluginPath, 'aoeuaoeuaoeuaoeu')
|
|
210
229
|
|
|
211
230
|
const results = await this.Action('node', 'upgrade').execute({})
|
|
212
231
|
|
|
232
|
+
assert.isFalsy(results.errors)
|
|
233
|
+
|
|
213
234
|
testUtil.assertFileByNameInGeneratedFiles(pluginName, results.files)
|
|
214
235
|
|
|
215
236
|
const updatedContents = diskUtil.readFile(pluginPath)
|
|
216
237
|
|
|
217
238
|
assert.isEqual(updatedContents, originalContents)
|
|
239
|
+
|
|
240
|
+
assert.doesInclude(results.summaryLines ?? [], 'Rebuild Complete')
|
|
218
241
|
}
|
|
219
242
|
|
|
220
243
|
@test()
|
|
@@ -84,7 +84,7 @@ export default class UpgradingASkill2Test extends AbstractCliTest {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
@test()
|
|
87
|
-
protected static async
|
|
87
|
+
protected static async callsCleanFixLintAndBuildDev() {
|
|
88
88
|
await this.FeatureFixture().installCachedFeatures('skills')
|
|
89
89
|
|
|
90
90
|
let wasCleanBuildCalled = false
|
|
@@ -92,6 +92,7 @@ export default class UpgradingASkill2Test extends AbstractCliTest {
|
|
|
92
92
|
return {}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
let wasFixLintCalled = false
|
|
95
96
|
CommandService.setMockResponse('yarn clean.build', {
|
|
96
97
|
code: 0,
|
|
97
98
|
callback: () => {
|
|
@@ -99,6 +100,13 @@ export default class UpgradingASkill2Test extends AbstractCliTest {
|
|
|
99
100
|
},
|
|
100
101
|
})
|
|
101
102
|
|
|
103
|
+
CommandService.setMockResponse('yarn fix.lint', {
|
|
104
|
+
code: 0,
|
|
105
|
+
callback: () => {
|
|
106
|
+
wasFixLintCalled = true
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
|
|
102
110
|
let wasBuildDevCalled = false
|
|
103
111
|
|
|
104
112
|
CommandService.setMockResponse('yarn build.dev', {
|
|
@@ -113,6 +121,7 @@ export default class UpgradingASkill2Test extends AbstractCliTest {
|
|
|
113
121
|
assert.isFalsy(results.errors)
|
|
114
122
|
assert.isTrue(wasCleanBuildCalled)
|
|
115
123
|
assert.isTrue(wasBuildDevCalled)
|
|
124
|
+
assert.isTrue(wasFixLintCalled)
|
|
116
125
|
}
|
|
117
126
|
|
|
118
127
|
@test()
|
|
@@ -73,7 +73,9 @@ export default class ErrorFeature extends AbstractFeature {
|
|
|
73
73
|
actionCode: string
|
|
74
74
|
}) {
|
|
75
75
|
const { featureCode, actionCode } = payload
|
|
76
|
+
|
|
76
77
|
const isInstalled = await this.featureInstaller.isInstalled('error')
|
|
78
|
+
|
|
77
79
|
const isSkillInstalled = await this.featureInstaller.isInstalled('skill')
|
|
78
80
|
|
|
79
81
|
if (isInstalled && featureCode === 'node' && actionCode === 'upgrade') {
|
|
@@ -135,7 +135,7 @@ export default class ErrorWriter extends AbstractWriter {
|
|
|
135
135
|
return results
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
public writePlugin(cwd: string) {
|
|
138
|
+
public async writePlugin(cwd: string) {
|
|
139
139
|
const destination = diskUtil.resolveHashSprucePath(
|
|
140
140
|
cwd,
|
|
141
141
|
'features',
|
|
@@ -150,6 +150,8 @@ export default class ErrorWriter extends AbstractWriter {
|
|
|
150
150
|
'Supports your skill with Error generation and handling.'
|
|
151
151
|
)
|
|
152
152
|
|
|
153
|
+
await this.lint(destination)
|
|
154
|
+
|
|
153
155
|
return results
|
|
154
156
|
}
|
|
155
157
|
}
|
|
@@ -9,6 +9,7 @@ import AbstractFeature, {
|
|
|
9
9
|
} from '../AbstractFeature'
|
|
10
10
|
import { FeatureActionResponse, FeatureCode } from '../features.types'
|
|
11
11
|
import EventContractBuilder from './builders/EventContractBuilder'
|
|
12
|
+
import EventStore from './stores/EventStore'
|
|
12
13
|
|
|
13
14
|
declare module '../../features/features.types' {
|
|
14
15
|
interface FeatureMap {
|
|
@@ -49,6 +50,7 @@ export default class EventFeature extends AbstractFeature {
|
|
|
49
50
|
|
|
50
51
|
public readonly fileDescriptions: FileDescription[] = []
|
|
51
52
|
private contractBuilder?: EventContractBuilder
|
|
53
|
+
private initiatingAction?: string
|
|
52
54
|
|
|
53
55
|
public constructor(options: FeatureOptions) {
|
|
54
56
|
super(options)
|
|
@@ -74,26 +76,18 @@ export default class EventFeature extends AbstractFeature {
|
|
|
74
76
|
return {}
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
private async handleDidExecute(payload: {
|
|
78
|
-
featureCode: string
|
|
79
|
-
actionCode: string
|
|
80
|
-
}) {
|
|
81
|
-
const { featureCode, actionCode } = payload
|
|
82
|
-
const isInstalled = await this.featureInstaller.isInstalled('event')
|
|
83
|
-
|
|
84
|
-
if (isInstalled && featureCode === 'node' && actionCode === 'upgrade') {
|
|
85
|
-
return this.Action('event', 'sync').execute({})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return {}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
79
|
private async handleWillExecute(payload: {
|
|
92
80
|
featureCode: string
|
|
93
81
|
actionCode: string
|
|
94
82
|
}): Promise<FeatureActionResponse> {
|
|
95
83
|
const { featureCode, actionCode } = payload
|
|
96
84
|
|
|
85
|
+
if (!this.initiatingAction) {
|
|
86
|
+
EventStore.clearCache()
|
|
87
|
+
const combined = this.combineCodes(featureCode, actionCode)
|
|
88
|
+
this.initiatingAction = combined
|
|
89
|
+
}
|
|
90
|
+
|
|
97
91
|
const isInstalled = await this.featureInstaller.isInstalled('event')
|
|
98
92
|
|
|
99
93
|
if (featureCode === 'node' || featureCode === 'upgrade') {
|
|
@@ -114,6 +108,30 @@ export default class EventFeature extends AbstractFeature {
|
|
|
114
108
|
return {}
|
|
115
109
|
}
|
|
116
110
|
|
|
111
|
+
private async handleDidExecute(payload: {
|
|
112
|
+
featureCode: string
|
|
113
|
+
actionCode: string
|
|
114
|
+
}) {
|
|
115
|
+
const { featureCode, actionCode } = payload
|
|
116
|
+
const isInstalled = await this.featureInstaller.isInstalled('event')
|
|
117
|
+
|
|
118
|
+
let results = {}
|
|
119
|
+
|
|
120
|
+
if (isInstalled && featureCode === 'node' && actionCode === 'upgrade') {
|
|
121
|
+
results = this.Action('event', 'sync').execute({})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (this.initiatingAction === this.combineCodes(featureCode, actionCode)) {
|
|
125
|
+
EventStore.clearCache()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return results
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private combineCodes(featureCode: string, actionCode: string) {
|
|
132
|
+
return `${featureCode}.${actionCode}`
|
|
133
|
+
}
|
|
134
|
+
|
|
117
135
|
private async appendRemoteToResultsOrPrompt(): Promise<FeatureActionResponse> {
|
|
118
136
|
const remote = this.Service('remote')
|
|
119
137
|
const r = remote.getRemote()
|
|
@@ -56,6 +56,12 @@ const eventFileNamesImportKeyMap = {
|
|
|
56
56
|
export default class EventStore extends AbstractStore {
|
|
57
57
|
public name = 'event'
|
|
58
58
|
protected static contractCache: Record<string, any> = {}
|
|
59
|
+
private static localEventCache?: SpruceSchemas.Mercury.v2020_12_25.EventContract
|
|
60
|
+
|
|
61
|
+
public static clearCache() {
|
|
62
|
+
EventStore.localEventCache = undefined
|
|
63
|
+
EventStore.contractCache = {}
|
|
64
|
+
}
|
|
59
65
|
|
|
60
66
|
public async fetchEventContracts(options?: {
|
|
61
67
|
localNamespace?: string
|
|
@@ -89,10 +95,6 @@ export default class EventStore extends AbstractStore {
|
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
|
|
92
|
-
public static clearCache() {
|
|
93
|
-
EventStore.contractCache = {}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
98
|
private async fetchRemoteContracts(namespaces?: string[]) {
|
|
97
99
|
const key = namespaces?.join('|') ?? '_'
|
|
98
100
|
|
|
@@ -133,6 +135,10 @@ export default class EventStore extends AbstractStore {
|
|
|
133
135
|
localNamespace: string,
|
|
134
136
|
didUpdateHandler?: InternalUpdateHandler
|
|
135
137
|
): Promise<EventContract | null> {
|
|
138
|
+
if (EventStore.localEventCache) {
|
|
139
|
+
return EventStore.localEventCache
|
|
140
|
+
}
|
|
141
|
+
|
|
136
142
|
const localMatches = await globby(
|
|
137
143
|
diskUtil.resolvePath(
|
|
138
144
|
this.cwd,
|
|
@@ -254,6 +260,8 @@ export default class EventStore extends AbstractStore {
|
|
|
254
260
|
|
|
255
261
|
validateEventContract(cleaned)
|
|
256
262
|
|
|
263
|
+
EventStore.localEventCache = cleaned
|
|
264
|
+
|
|
257
265
|
return cleaned
|
|
258
266
|
}
|
|
259
267
|
|
|
@@ -5,7 +5,7 @@ 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 { FeatureCode } from '../features.types'
|
|
8
|
+
import { ActionOptions, FeatureCode } from '../features.types'
|
|
9
9
|
import universalDevDependencies from '../universalDevDependencies'
|
|
10
10
|
import universalFileDescriptions from '../universalFileDescriptions'
|
|
11
11
|
import universalScripts from '../universalScripts'
|
|
@@ -44,6 +44,39 @@ export default class NodeFeature<
|
|
|
44
44
|
|
|
45
45
|
public actionsDir = diskUtil.resolvePath(__dirname, 'actions')
|
|
46
46
|
|
|
47
|
+
public constructor(options: ActionOptions) {
|
|
48
|
+
super(options)
|
|
49
|
+
|
|
50
|
+
void this.emitter.on('feature.did-execute', async (payload) => {
|
|
51
|
+
if (payload.featureCode === 'node' && payload.actionCode === 'upgrade') {
|
|
52
|
+
try {
|
|
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 folder cleared.',
|
|
65
|
+
'Lint rules applied.',
|
|
66
|
+
'Rebuild Complete',
|
|
67
|
+
],
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
return {
|
|
71
|
+
errors: [err],
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {}
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
47
80
|
public async beforePackageInstall(options: Options) {
|
|
48
81
|
const destination = this.resolveDestination(options)
|
|
49
82
|
|
|
@@ -32,22 +32,13 @@ export default class UpgradeAction extends AbstractAction<OptionsSchema> {
|
|
|
32
32
|
|
|
33
33
|
const dependencyResults = await this.reInstallPackageDependencies()
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
await this.Service('command').execute('yarn build.dev')
|
|
37
|
-
|
|
38
|
-
let results = {
|
|
39
|
-
summaryLines: ['Build folder cleared.', 'Build complete.'],
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
results = actionUtil.mergeActionResults(results, dependencyResults, {
|
|
35
|
+
return actionUtil.mergeActionResults(dependencyResults, {
|
|
43
36
|
headline: 'Upgrade',
|
|
44
37
|
})
|
|
45
|
-
|
|
46
|
-
return results
|
|
47
38
|
} finally {
|
|
48
39
|
InFlightEntertainment.stop()
|
|
49
40
|
|
|
50
|
-
this.ui.renderHero('
|
|
41
|
+
this.ui.renderHero('Upgrade')
|
|
51
42
|
}
|
|
52
43
|
}
|
|
53
44
|
|
|
@@ -199,7 +199,10 @@ export default class TestAction extends AbstractAction<OptionsSchema> {
|
|
|
199
199
|
private doWeCareAboutThisFileChanging(path: string) {
|
|
200
200
|
const ext = pathUtil.extname(path)
|
|
201
201
|
|
|
202
|
-
if (
|
|
202
|
+
if (
|
|
203
|
+
path.search('testDirsAndFiles') > -1 ||
|
|
204
|
+
path.search('.change_cache') > -1
|
|
205
|
+
) {
|
|
203
206
|
return false
|
|
204
207
|
}
|
|
205
208
|
|
|
@@ -204,11 +204,6 @@ export default class TerminalInterface implements GraphicsInterface {
|
|
|
204
204
|
lines: summaryLines,
|
|
205
205
|
})
|
|
206
206
|
|
|
207
|
-
if (errors.length > 0) {
|
|
208
|
-
this.renderHeadline('Errors')
|
|
209
|
-
errors.forEach((err) => this.renderError(err))
|
|
210
|
-
}
|
|
211
|
-
|
|
212
207
|
if (packagesInstalled.length > 0) {
|
|
213
208
|
const table = new Table({
|
|
214
209
|
head: ['Name', 'Dev'],
|
|
@@ -255,6 +250,11 @@ export default class TerminalInterface implements GraphicsInterface {
|
|
|
255
250
|
})
|
|
256
251
|
}
|
|
257
252
|
|
|
253
|
+
if (errors.length > 0) {
|
|
254
|
+
this.renderHeadline('Errors')
|
|
255
|
+
errors.forEach((err) => this.renderError(err))
|
|
256
|
+
}
|
|
257
|
+
|
|
258
258
|
if (results.totalTime) {
|
|
259
259
|
this.renderLine(
|
|
260
260
|
`Total time: ${durationUtil.msToFriendly(results.totalTime)}`
|