@sprucelabs/spruce-cli 18.1.4 → 18.1.6
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/WatchingSkillViews.test.d.ts +1 -9
- package/build/__tests__/behavioral/WatchingSkillViews.test.js +25 -463
- package/build/__tests__/behavioral/WatchingSkillViews.test.js.map +1 -1
- package/build/features/AbstractAction.d.ts +1 -1
- package/build/features/AbstractAction.js +4 -4
- package/build/features/AbstractAction.js.map +1 -1
- package/build/features/dependencies/actions/AddAction.js +1 -1
- package/build/features/dependencies/actions/AddAction.js.map +1 -1
- package/build/features/deploy/actions/HerokuAction.js +2 -2
- package/build/features/deploy/actions/HerokuAction.js.map +1 -1
- package/build/features/node/actions/UpdateDependenciesAction.js +1 -1
- package/build/features/node/actions/UpdateDependenciesAction.js.map +1 -1
- package/build/features/node/actions/UpgradeAction.js +1 -1
- package/build/features/node/actions/UpgradeAction.js.map +1 -1
- package/build/features/test/actions/CreateAction.js +2 -2
- package/build/features/test/actions/CreateAction.js.map +1 -1
- package/build/features/view/actions/WatchAction.d.ts +3 -16
- package/build/features/view/actions/WatchAction.js +32 -165
- package/build/features/view/actions/WatchAction.js.map +1 -1
- package/build/services/CommandService.d.ts +6 -6
- package/build/services/CommandService.js.map +1 -1
- package/node_modules/@typescript-eslint/parser/package.json +5 -5
- package/node_modules/@typescript-eslint/scope-manager/package.json +5 -5
- package/node_modules/@typescript-eslint/types/_ts3.4/dist/generated/ast-spec.d.ts +2 -2
- package/node_modules/@typescript-eslint/types/dist/generated/ast-spec.d.ts +2 -2
- package/node_modules/@typescript-eslint/types/dist/generated/ast-spec.d.ts.map +1 -1
- package/node_modules/@typescript-eslint/types/package.json +2 -2
- package/node_modules/@typescript-eslint/typescript-estree/package.json +5 -5
- package/node_modules/@typescript-eslint/visitor-keys/package.json +3 -3
- package/package.json +25 -25
- package/src/__tests__/behavioral/WatchingSkillViews.test.ts +14 -227
- package/src/features/AbstractAction.ts +4 -4
- package/src/features/dependencies/actions/AddAction.ts +1 -1
- package/src/features/deploy/actions/HerokuAction.ts +2 -2
- package/src/features/node/actions/UpdateDependenciesAction.ts +1 -1
- package/src/features/node/actions/UpgradeAction.ts +1 -1
- package/src/features/test/actions/CreateAction.ts +2 -4
- package/src/features/view/actions/WatchAction.ts +25 -89
- package/src/services/CommandService.ts +7 -7
|
@@ -39,7 +39,7 @@ export default abstract class AbstractAction<S extends Schema = Schema>
|
|
|
39
39
|
public abstract invocationMessage: string
|
|
40
40
|
|
|
41
41
|
protected parent: AbstractFeature
|
|
42
|
-
protected
|
|
42
|
+
protected features: FeatureInstaller
|
|
43
43
|
protected cwd: string
|
|
44
44
|
protected templates: Templates
|
|
45
45
|
protected ui: GraphicsInterface
|
|
@@ -57,7 +57,7 @@ export default abstract class AbstractAction<S extends Schema = Schema>
|
|
|
57
57
|
this.parent = options.parent
|
|
58
58
|
this.storeFactory = options.storeFactory
|
|
59
59
|
this.serviceFactory = options.serviceFactory
|
|
60
|
-
this.
|
|
60
|
+
this.features = options.featureInstaller
|
|
61
61
|
this.ui = options.ui
|
|
62
62
|
this.writerFactory = options.writerFactory
|
|
63
63
|
this.apiClientFactory = options.apiClientFactory
|
|
@@ -96,11 +96,11 @@ export default abstract class AbstractAction<S extends Schema = Schema>
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
protected getFeature<C extends FeatureCode>(code: C) {
|
|
99
|
-
return this.
|
|
99
|
+
return this.features.getFeature(code)
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
protected getFeatureCodes(): FeatureCode[] {
|
|
103
|
-
return this.
|
|
103
|
+
return this.features.getAllCodes()
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
protected validateAndNormalizeOptions(options: SchemaPartialValues<S>) {
|
|
@@ -64,7 +64,7 @@ export default class DeployAction extends AbstractAction<OptionsSchema> {
|
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
const summaryLines = [`Added "${skill.name}" as a dependency!`]
|
|
67
|
-
const isEventInstalled = await this.
|
|
67
|
+
const isEventInstalled = await this.features.isInstalled('event')
|
|
68
68
|
if (isEventInstalled) {
|
|
69
69
|
summaryLines.push(
|
|
70
70
|
'You will need to run `spruce sync.events` before accessing any new events.'
|
|
@@ -295,7 +295,7 @@ export default class DeployAction extends AbstractAction<OptionsSchema> {
|
|
|
295
295
|
private async runTests() {
|
|
296
296
|
let results: FeatureActionResponse = {}
|
|
297
297
|
|
|
298
|
-
const isTestInstalled = await this.
|
|
298
|
+
const isTestInstalled = await this.features.isInstalled('test')
|
|
299
299
|
|
|
300
300
|
if (isTestInstalled) {
|
|
301
301
|
try {
|
|
@@ -321,7 +321,7 @@ export default class DeployAction extends AbstractAction<OptionsSchema> {
|
|
|
321
321
|
private async buildAndLint() {
|
|
322
322
|
let results: FeatureActionResponse = {}
|
|
323
323
|
|
|
324
|
-
const isSkillInstalled = await this.
|
|
324
|
+
const isSkillInstalled = await this.features.isInstalled('skill')
|
|
325
325
|
|
|
326
326
|
if (isSkillInstalled) {
|
|
327
327
|
try {
|
|
@@ -52,7 +52,7 @@ export default class UpdateDependenciesAction extends AbstractAction<OptionsSche
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
private async installDependencies() {
|
|
55
|
-
const features = await this.
|
|
55
|
+
const features = await this.features.getInstalledFeatures()
|
|
56
56
|
|
|
57
57
|
const pkg = this.Service('pkg')
|
|
58
58
|
const pkgContents = pkg.readPackage()
|
|
@@ -55,7 +55,7 @@ export default class UpgradeAction extends AbstractAction<OptionsSchema> {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
private async updateScripts(options: { shouldConfirm: boolean }) {
|
|
58
|
-
const features = await this.
|
|
58
|
+
const features = await this.features.getInstalledFeatures()
|
|
59
59
|
|
|
60
60
|
let scripts: Record<string, any> = {}
|
|
61
61
|
|
|
@@ -142,13 +142,11 @@ export default class CreateAction extends AbstractAction<OptionsSchema> {
|
|
|
142
142
|
match: ParentClassCandidate
|
|
143
143
|
) {
|
|
144
144
|
if (match.featureCode) {
|
|
145
|
-
const isInstalled = await this.
|
|
146
|
-
match.featureCode
|
|
147
|
-
)
|
|
145
|
+
const isInstalled = await this.features.isInstalled(match.featureCode)
|
|
148
146
|
|
|
149
147
|
if (!isInstalled) {
|
|
150
148
|
this.ui.startLoading(`Installing ${match.name}...`)
|
|
151
|
-
await this.
|
|
149
|
+
await this.features.install({
|
|
152
150
|
features: [{ code: match.featureCode as any }],
|
|
153
151
|
})
|
|
154
152
|
this.ui.stopLoading()
|
|
@@ -1,112 +1,58 @@
|
|
|
1
|
-
import { buildSchema
|
|
1
|
+
import { buildSchema } from '@sprucelabs/schema'
|
|
2
2
|
import { heartwoodRemoteUtil } from '@sprucelabs/spruce-event-utils'
|
|
3
|
-
import { GraphicsTextEffect } from '@sprucelabs/spruce-skill-utils'
|
|
4
3
|
import AbstractAction from '../../AbstractAction'
|
|
5
4
|
import { FeatureActionResponse } from '../../features.types'
|
|
6
|
-
import { BootMeta } from '../../skill/actions/BootAction'
|
|
7
|
-
import WatchFeature from '../../watch/WatchFeature'
|
|
8
5
|
|
|
9
6
|
const optionsSchema = buildSchema({
|
|
10
7
|
id: 'watchViewsOptions',
|
|
11
8
|
description: 'Watch for view changes and preview them in real time.',
|
|
12
|
-
fields: {
|
|
13
|
-
shouldReturnImmediately: {
|
|
14
|
-
type: 'boolean',
|
|
15
|
-
hint: "For testing so we don't wait until the process is killed to get the results.",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
9
|
+
fields: {},
|
|
18
10
|
})
|
|
19
11
|
|
|
20
12
|
type OptionsSchema = typeof optionsSchema
|
|
21
|
-
type Options = SchemaValues<OptionsSchema>
|
|
22
13
|
|
|
23
14
|
export default class WatchAction extends AbstractAction<OptionsSchema> {
|
|
24
15
|
public commandAliases = ['watch.views']
|
|
25
16
|
public optionsSchema: OptionsSchema = optionsSchema
|
|
26
17
|
public invocationMessage = 'Watching views... 🤩'
|
|
27
|
-
private resolve?: () => void
|
|
28
|
-
private bootControls?: BootMeta
|
|
29
18
|
private skillName!: string
|
|
30
|
-
private bootMessage!: string
|
|
31
|
-
private watchFeature!: WatchFeature
|
|
32
|
-
|
|
33
|
-
public async execute(options?: Options): Promise<FeatureActionResponse> {
|
|
34
|
-
const { shouldReturnImmediately } = this.validateAndNormalizeOptions(
|
|
35
|
-
options ?? {}
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
this.watchFeature = this.featureInstaller.getFeature('watch')
|
|
39
|
-
await this.watchFeature.startWatching({ delay: 2000 })
|
|
40
19
|
|
|
20
|
+
public async execute(): Promise<FeatureActionResponse> {
|
|
41
21
|
const skill = await this.Store('skill').loadCurrentSkill()
|
|
42
|
-
|
|
43
22
|
this.skillName = skill.name
|
|
44
|
-
this.bootControls = await this.boot()
|
|
45
|
-
|
|
46
|
-
await this.emitter.on('watcher.did-detect-change', async () => {
|
|
47
|
-
this.bootControls?.kill()
|
|
48
|
-
this.bootControls = await this.boot(
|
|
49
|
-
'Changes detected, rebooting skill...'
|
|
50
|
-
)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
if (!shouldReturnImmediately) {
|
|
54
|
-
await new Promise((resolve) => {
|
|
55
|
-
//@ts-ignore
|
|
56
|
-
this.resolve = resolve
|
|
57
|
-
})
|
|
58
23
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
24
|
+
this.resetUi()
|
|
25
|
+
const commands = this.Service('command')
|
|
26
|
+
await commands.execute(
|
|
27
|
+
'ENABLED_SKILL_FEATURES=view,event SHOULD_REGISTER_EVENTS_AND_LISTENERS=false SHOULD_WATCH_VIEWS=true MAXIMUM_LOG_PREFIXES_LENGTH=0 yarn boot',
|
|
28
|
+
{
|
|
29
|
+
onData: (data) => {
|
|
30
|
+
const line = this.popLastLine(data)
|
|
31
|
+
this.ui.startLoading(line)
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
)
|
|
62
35
|
|
|
63
36
|
return {
|
|
64
37
|
summaryLines: [`Done watching...`],
|
|
65
|
-
meta: {
|
|
66
|
-
bootPromise: this.bootControls.bootPromise,
|
|
67
|
-
},
|
|
68
38
|
}
|
|
69
39
|
}
|
|
70
40
|
|
|
41
|
+
private popLastLine(data: string) {
|
|
42
|
+
const line = data
|
|
43
|
+
.trim()
|
|
44
|
+
.split('\n')
|
|
45
|
+
.filter((s) => !!s)
|
|
46
|
+
.pop()
|
|
47
|
+
|
|
48
|
+
return line && line.length > 0 ? line.trim() : 'Waiting for changes'
|
|
49
|
+
}
|
|
50
|
+
|
|
71
51
|
private getPreviewUrl() {
|
|
72
52
|
const remote = this.Service('remote').getRemote() as any
|
|
73
53
|
return heartwoodRemoteUtil.buildUrl(remote) + '/#views/heartwood.watch'
|
|
74
54
|
}
|
|
75
55
|
|
|
76
|
-
private async boot(bootMessage = 'Booting skill...') {
|
|
77
|
-
this.bootMessage = bootMessage
|
|
78
|
-
this.resetUi()
|
|
79
|
-
|
|
80
|
-
const results = await this.Action('skill', 'boot').execute({
|
|
81
|
-
shouldReturnImmediately: true,
|
|
82
|
-
onData: (msg: string) => {
|
|
83
|
-
if (!msg.includes('node build/index') && !msg.includes('yarn run')) {
|
|
84
|
-
this.ui.stopLoading()
|
|
85
|
-
this.ui.renderLine(msg.trim())
|
|
86
|
-
this.ui.startLoading(this.bootMessage)
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
onError: (msg: string) => {
|
|
90
|
-
if (!msg.includes('No license field')) {
|
|
91
|
-
this.ui.stopLoading()
|
|
92
|
-
this.ui.renderLine(msg, [GraphicsTextEffect.Red])
|
|
93
|
-
this.ui.startLoading()
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
results.meta?.bootPromise?.then(() => {
|
|
99
|
-
this.bootMessage = 'Skill booted. Waiting for changes...'
|
|
100
|
-
this.ui.startLoading(this.bootMessage)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
if (results.errors) {
|
|
104
|
-
throw results.errors[0]
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return results.meta as BootMeta
|
|
108
|
-
}
|
|
109
|
-
|
|
110
56
|
private resetUi() {
|
|
111
57
|
this.ui.clear()
|
|
112
58
|
this.ui.renderHero('Heartwood')
|
|
@@ -119,16 +65,6 @@ export default class WatchAction extends AbstractAction<OptionsSchema> {
|
|
|
119
65
|
])
|
|
120
66
|
this.ui.renderDivider()
|
|
121
67
|
this.ui.renderLine('')
|
|
122
|
-
this.ui.startLoading(
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public async kill() {
|
|
126
|
-
await this.watchFeature.stopWatching()
|
|
127
|
-
this.bootControls?.kill()
|
|
128
|
-
this.resolve?.()
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
public getPid() {
|
|
132
|
-
return this.bootControls?.pid
|
|
68
|
+
this.ui.startLoading('Watching for changes')
|
|
133
69
|
}
|
|
134
70
|
}
|
|
@@ -9,13 +9,6 @@ import SpruceError from '../errors/SpruceError'
|
|
|
9
9
|
|
|
10
10
|
process.setMaxListeners(100)
|
|
11
11
|
|
|
12
|
-
interface MockResponse {
|
|
13
|
-
code: number
|
|
14
|
-
stdout?: string
|
|
15
|
-
stderr?: string
|
|
16
|
-
callback?: (executable: string, args: any[]) => void
|
|
17
|
-
}
|
|
18
|
-
|
|
19
12
|
export default class CommandService {
|
|
20
13
|
public cwd: string
|
|
21
14
|
private activeChildProcess: ChildProcess | undefined
|
|
@@ -195,3 +188,10 @@ export default class CommandService {
|
|
|
195
188
|
this.mockResponses = []
|
|
196
189
|
}
|
|
197
190
|
}
|
|
191
|
+
|
|
192
|
+
interface MockResponse {
|
|
193
|
+
code: number
|
|
194
|
+
stdout?: string
|
|
195
|
+
stderr?: string
|
|
196
|
+
callback?: (executable: string, args: any[]) => void
|
|
197
|
+
}
|