@hubspot/cli 4.2.1-beta.1 → 4.2.1-beta.3
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/bin/cli.js +1 -1
- package/commands/accounts/clean.js +139 -0
- package/commands/accounts/list.js +1 -1
- package/commands/accounts.js +2 -0
- package/commands/project/add.js +1 -1
- package/commands/project/dev.js +84 -98
- package/commands/project/download.js +10 -19
- package/commands/project/listBuilds.js +4 -1
- package/commands/project/upload.js +3 -0
- package/commands/project/watch.js +3 -0
- package/commands/project.js +9 -6
- package/commands/sandbox/create.js +10 -1
- package/commands/sandbox/delete.js +8 -12
- package/commands/sandbox.js +3 -2
- package/lang/en.lyaml +55 -59
- package/lib/DevServerManager.js +82 -80
- package/lib/LocalDevManager.js +240 -561
- package/lib/SpinniesManager.js +2 -82
- package/lib/projectStructure.js +107 -0
- package/lib/projects.js +70 -22
- package/lib/prompts/downloadProjectPrompt.js +1 -4
- package/lib/prompts/projectDevTargetAccountPrompt.js +15 -0
- package/lib/ui.js +13 -1
- package/lib/usageTracking.js +57 -0
- package/package.json +5 -8
- package/lib/LocalDevManagerV2.js +0 -129
package/bin/cli.js
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const { logger } = require('@hubspot/cli-lib/logger');
|
|
2
|
+
const {
|
|
3
|
+
accessTokenForPersonalAccessKey,
|
|
4
|
+
} = require('@hubspot/cli-lib/personalAccessKey');
|
|
5
|
+
const { getConfig } = require('@hubspot/cli-lib');
|
|
6
|
+
|
|
7
|
+
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
8
|
+
const { i18n } = require('../../lib/lang');
|
|
9
|
+
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
10
|
+
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
11
|
+
const {
|
|
12
|
+
addConfigOptions,
|
|
13
|
+
addAccountOptions,
|
|
14
|
+
addUseEnvironmentOptions,
|
|
15
|
+
addTestingOptions,
|
|
16
|
+
} = require('../../lib/commonOpts');
|
|
17
|
+
const { getAccountName } = require('../../lib/sandboxes');
|
|
18
|
+
const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
19
|
+
const { getTableContents } = require('@hubspot/cli-lib/lib/table');
|
|
20
|
+
const SpinniesManager = require('../../lib/SpinniesManager');
|
|
21
|
+
const { deleteAccount } = require('@hubspot/cli-lib/lib/config');
|
|
22
|
+
const {
|
|
23
|
+
isSpecifiedHubSpotAuthError,
|
|
24
|
+
} = require('@hubspot/cli-lib/errorHandlers/apiErrors');
|
|
25
|
+
|
|
26
|
+
const i18nKey = 'cli.commands.accounts.subcommands.clean';
|
|
27
|
+
|
|
28
|
+
exports.command = 'clean';
|
|
29
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
30
|
+
|
|
31
|
+
exports.handler = async options => {
|
|
32
|
+
const { qa } = options;
|
|
33
|
+
await loadAndValidateOptions(options, false);
|
|
34
|
+
|
|
35
|
+
const config = getConfig();
|
|
36
|
+
|
|
37
|
+
trackCommandUsage('accounts-clean', null);
|
|
38
|
+
|
|
39
|
+
const filteredTestAccounts = config.portals.filter(p =>
|
|
40
|
+
qa ? p.env === 'qa' : p.env !== 'qa'
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (filteredTestAccounts && filteredTestAccounts.length === 0) {
|
|
44
|
+
logger.log(i18n(`${i18nKey}.noResults`));
|
|
45
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const accountsToRemove = [];
|
|
49
|
+
SpinniesManager.init({
|
|
50
|
+
succeedColor: 'white',
|
|
51
|
+
});
|
|
52
|
+
SpinniesManager.add('accountsClean', {
|
|
53
|
+
text: i18n(`${i18nKey}.loading.add`),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
for (const account of filteredTestAccounts) {
|
|
57
|
+
try {
|
|
58
|
+
await accessTokenForPersonalAccessKey(account.portalId);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (
|
|
61
|
+
isSpecifiedHubSpotAuthError(error, {
|
|
62
|
+
statusCode: 401,
|
|
63
|
+
category: 'INVALID_AUTHENTICATION',
|
|
64
|
+
subCategory: 'LocalDevAuthErrorType.PORTAL_NOT_ACTIVE',
|
|
65
|
+
}) ||
|
|
66
|
+
isSpecifiedHubSpotAuthError(error, {
|
|
67
|
+
statusCode: 404,
|
|
68
|
+
category: 'INVALID_AUTHENTICATION',
|
|
69
|
+
subCategory: 'LocalDevAuthErrorType.INVALID_PORTAL_ID',
|
|
70
|
+
})
|
|
71
|
+
) {
|
|
72
|
+
accountsToRemove.push(account);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (accountsToRemove.length > 0) {
|
|
78
|
+
const oneAccountFound = accountsToRemove.length === 1;
|
|
79
|
+
SpinniesManager.succeed('accountsClean', {
|
|
80
|
+
text: i18n(
|
|
81
|
+
oneAccountFound
|
|
82
|
+
? `${i18nKey}.inactiveAccountsFound.one`
|
|
83
|
+
: `${i18nKey}.inactiveAccountsFound.other`,
|
|
84
|
+
{
|
|
85
|
+
count: accountsToRemove.length,
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
});
|
|
89
|
+
logger.log(
|
|
90
|
+
getTableContents(
|
|
91
|
+
accountsToRemove.map(p => [getAccountName(p)]),
|
|
92
|
+
{ border: { bodyLeft: ' ' } }
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
const { accountsCleanPrompt } = await promptUser([
|
|
96
|
+
{
|
|
97
|
+
name: 'accountsCleanPrompt',
|
|
98
|
+
type: 'confirm',
|
|
99
|
+
message: i18n(
|
|
100
|
+
oneAccountFound
|
|
101
|
+
? `${i18nKey}.confirm.one`
|
|
102
|
+
: `${i18nKey}.confirm.other`,
|
|
103
|
+
{
|
|
104
|
+
count: accountsToRemove.length,
|
|
105
|
+
}
|
|
106
|
+
),
|
|
107
|
+
},
|
|
108
|
+
]);
|
|
109
|
+
if (accountsCleanPrompt) {
|
|
110
|
+
logger.log('');
|
|
111
|
+
for (const accountToRemove of accountsToRemove) {
|
|
112
|
+
await deleteAccount(accountToRemove.name);
|
|
113
|
+
logger.log(
|
|
114
|
+
i18n(`${i18nKey}.removeSuccess`, {
|
|
115
|
+
accountName: getAccountName(accountToRemove),
|
|
116
|
+
})
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
SpinniesManager.succeed('accountsClean', {
|
|
122
|
+
text: i18n(`${i18nKey}.noResults`),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
logger.log('');
|
|
127
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
exports.builder = yargs => {
|
|
131
|
+
addConfigOptions(yargs, true);
|
|
132
|
+
addAccountOptions(yargs, true);
|
|
133
|
+
addUseEnvironmentOptions(yargs, true);
|
|
134
|
+
addTestingOptions(yargs, true);
|
|
135
|
+
|
|
136
|
+
yargs.example([['$0 accounts clean']]);
|
|
137
|
+
|
|
138
|
+
return yargs;
|
|
139
|
+
};
|
package/commands/accounts.js
CHANGED
|
@@ -5,6 +5,7 @@ const rename = require('./accounts/rename');
|
|
|
5
5
|
const use = require('./accounts/use');
|
|
6
6
|
const info = require('./accounts/info');
|
|
7
7
|
const remove = require('./accounts/remove');
|
|
8
|
+
const clean = require('./accounts/clean');
|
|
8
9
|
|
|
9
10
|
const i18nKey = 'cli.commands.accounts';
|
|
10
11
|
|
|
@@ -24,6 +25,7 @@ exports.builder = yargs => {
|
|
|
24
25
|
.command(use)
|
|
25
26
|
.command(info)
|
|
26
27
|
.command(remove)
|
|
28
|
+
.command(clean)
|
|
27
29
|
.demandCommand(1, '');
|
|
28
30
|
|
|
29
31
|
return yargs;
|
package/commands/project/add.js
CHANGED
|
@@ -11,7 +11,7 @@ const { loadAndValidateOptions } = require('../../lib/validation');
|
|
|
11
11
|
const i18nKey = 'cli.commands.project.subcommands.add';
|
|
12
12
|
|
|
13
13
|
exports.command = 'add';
|
|
14
|
-
exports.describe =
|
|
14
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
15
15
|
|
|
16
16
|
exports.handler = async options => {
|
|
17
17
|
await loadAndValidateOptions(options);
|
package/commands/project/dev.js
CHANGED
|
@@ -5,7 +5,10 @@ const {
|
|
|
5
5
|
addUseEnvironmentOptions,
|
|
6
6
|
addTestingOptions,
|
|
7
7
|
} = require('../../lib/commonOpts');
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
trackCommandUsage,
|
|
10
|
+
trackCommandMetadataUsage,
|
|
11
|
+
} = require('../../lib/usageTracking');
|
|
9
12
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
10
13
|
const { i18n } = require('../../lib/lang');
|
|
11
14
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
@@ -17,19 +20,22 @@ const {
|
|
|
17
20
|
ensureProjectExists,
|
|
18
21
|
handleProjectUpload,
|
|
19
22
|
pollProjectBuildAndDeploy,
|
|
23
|
+
showPlatformVersionWarning,
|
|
20
24
|
} = require('../../lib/projects');
|
|
21
25
|
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
|
|
22
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
uiAccountDescription,
|
|
28
|
+
uiBetaMessage,
|
|
29
|
+
uiCommandReference,
|
|
30
|
+
uiLine,
|
|
31
|
+
} = require('../../lib/ui');
|
|
23
32
|
const { confirmPrompt } = require('../../lib/prompts/promptUtils');
|
|
24
33
|
const {
|
|
25
34
|
selectTargetAccountPrompt,
|
|
35
|
+
confirmDefaultSandboxAccountPrompt,
|
|
26
36
|
} = require('../../lib/prompts/projectDevTargetAccountPrompt');
|
|
27
37
|
const SpinniesManager = require('../../lib/SpinniesManager');
|
|
28
|
-
const
|
|
29
|
-
LocalDevManager,
|
|
30
|
-
UPLOAD_PERMISSIONS,
|
|
31
|
-
} = require('../../lib/LocalDevManager');
|
|
32
|
-
const LocalDevManagerV2 = require('../../lib/LocalDevManagerV2');
|
|
38
|
+
const LocalDevManager = require('../../lib/LocalDevManager');
|
|
33
39
|
const { isSandbox } = require('../../lib/sandboxes');
|
|
34
40
|
const { getAccountConfig, getEnv } = require('@hubspot/cli-lib');
|
|
35
41
|
const { sandboxNamePrompt } = require('../../lib/prompts/sandboxesPrompt');
|
|
@@ -60,7 +66,7 @@ const {
|
|
|
60
66
|
const i18nKey = 'cli.commands.project.subcommands.dev';
|
|
61
67
|
|
|
62
68
|
exports.command = 'dev [--account]';
|
|
63
|
-
exports.describe =
|
|
69
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
64
70
|
|
|
65
71
|
exports.handler = async options => {
|
|
66
72
|
await loadAndValidateOptions(options);
|
|
@@ -72,6 +78,9 @@ exports.handler = async options => {
|
|
|
72
78
|
|
|
73
79
|
const { projectConfig, projectDir } = await getProjectConfig();
|
|
74
80
|
|
|
81
|
+
if (!options.debug) {
|
|
82
|
+
console.clear();
|
|
83
|
+
}
|
|
75
84
|
uiBetaMessage(i18n(`${i18nKey}.logs.betaMessage`));
|
|
76
85
|
|
|
77
86
|
if (!projectConfig) {
|
|
@@ -85,7 +94,23 @@ exports.handler = async options => {
|
|
|
85
94
|
const defaultAccountIsSandbox = isSandbox(accountConfig);
|
|
86
95
|
|
|
87
96
|
if (!targetAccountId && defaultAccountIsSandbox) {
|
|
88
|
-
|
|
97
|
+
logger.log();
|
|
98
|
+
const useDefaultSandboxAccount = await confirmDefaultSandboxAccountPrompt(
|
|
99
|
+
accountConfig.name,
|
|
100
|
+
accountConfig.sandboxAccountType
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
if (useDefaultSandboxAccount) {
|
|
104
|
+
targetAccountId = accountId;
|
|
105
|
+
} else {
|
|
106
|
+
logger.log(
|
|
107
|
+
i18n(`${i18nKey}.logs.declineDefaultSandboxExplanation`, {
|
|
108
|
+
useCommand: uiCommandReference('hs accounts use'),
|
|
109
|
+
devCommand: uiCommandReference('hs project dev'),
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
113
|
+
}
|
|
89
114
|
}
|
|
90
115
|
|
|
91
116
|
if (!targetAccountId) {
|
|
@@ -129,6 +154,13 @@ exports.handler = async options => {
|
|
|
129
154
|
}
|
|
130
155
|
try {
|
|
131
156
|
const { name } = await sandboxNamePrompt(DEVELOPER_SANDBOX);
|
|
157
|
+
|
|
158
|
+
trackCommandMetadataUsage(
|
|
159
|
+
'sandbox-create',
|
|
160
|
+
{ step: 'project-dev' },
|
|
161
|
+
accountId
|
|
162
|
+
);
|
|
163
|
+
|
|
132
164
|
const { result } = await buildSandbox({
|
|
133
165
|
name,
|
|
134
166
|
type: DEVELOPER_SANDBOX,
|
|
@@ -159,40 +191,37 @@ exports.handler = async options => {
|
|
|
159
191
|
}
|
|
160
192
|
}
|
|
161
193
|
|
|
194
|
+
logger.log();
|
|
162
195
|
const projectExists = await ensureProjectExists(
|
|
163
196
|
targetAccountId,
|
|
164
197
|
projectConfig.name,
|
|
165
198
|
{
|
|
166
199
|
allowCreate: false,
|
|
167
200
|
noLogs: true,
|
|
168
|
-
withPolling:
|
|
201
|
+
withPolling: createNewSandbox,
|
|
169
202
|
}
|
|
170
203
|
);
|
|
171
204
|
|
|
172
|
-
|
|
173
|
-
!defaultAccountIsSandbox && targetAccountId === accountId;
|
|
174
|
-
|
|
175
|
-
let uploadPermission = isNonSandboxAccount
|
|
176
|
-
? UPLOAD_PERMISSIONS.manual
|
|
177
|
-
: UPLOAD_PERMISSIONS.always;
|
|
205
|
+
let deployedBuild;
|
|
178
206
|
|
|
179
207
|
if (projectExists) {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
projectConfig.name
|
|
183
|
-
);
|
|
184
|
-
if (options.extension || sourceIntegration) {
|
|
185
|
-
uploadPermission = UPLOAD_PERMISSIONS.never;
|
|
186
|
-
}
|
|
208
|
+
const project = await fetchProject(targetAccountId, projectConfig.name);
|
|
209
|
+
deployedBuild = project.deployedBuild;
|
|
187
210
|
}
|
|
188
211
|
|
|
189
212
|
SpinniesManager.init();
|
|
190
213
|
|
|
214
|
+
if (!options.debug) {
|
|
215
|
+
console.clear();
|
|
216
|
+
}
|
|
217
|
+
uiBetaMessage(i18n(`${i18nKey}.logs.betaMessage`));
|
|
218
|
+
|
|
191
219
|
if (!projectExists) {
|
|
192
220
|
// Create the project without prompting if this is a newly created sandbox
|
|
193
221
|
let shouldCreateProject = createNewSandbox;
|
|
194
222
|
|
|
195
223
|
if (!shouldCreateProject) {
|
|
224
|
+
logger.log();
|
|
196
225
|
uiLine();
|
|
197
226
|
logger.warn(
|
|
198
227
|
i18n(`${i18nKey}.logs.projectMustExistExplanation`, {
|
|
@@ -211,6 +240,8 @@ exports.handler = async options => {
|
|
|
211
240
|
}
|
|
212
241
|
|
|
213
242
|
if (shouldCreateProject) {
|
|
243
|
+
await showPlatformVersionWarning(accountId, projectConfig);
|
|
244
|
+
|
|
214
245
|
try {
|
|
215
246
|
SpinniesManager.add('createProject', {
|
|
216
247
|
text: i18n(`${i18nKey}.status.creatingProject`, {
|
|
@@ -232,23 +263,16 @@ exports.handler = async options => {
|
|
|
232
263
|
}
|
|
233
264
|
} else {
|
|
234
265
|
// We cannot continue if the project does not exist in the target account
|
|
266
|
+
logger.log();
|
|
235
267
|
logger.log(i18n(`${i18nKey}.logs.choseNotToCreateProject`));
|
|
236
268
|
process.exit(EXIT_CODES.SUCCESS);
|
|
237
269
|
}
|
|
238
270
|
}
|
|
239
271
|
|
|
240
|
-
SpinniesManager.add('devModeSetup', {
|
|
241
|
-
text: i18n(`${i18nKey}.status.startupMessage`, {
|
|
242
|
-
projectName: projectConfig.name,
|
|
243
|
-
}),
|
|
244
|
-
isParent: true,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
272
|
let initialUploadResult;
|
|
248
273
|
|
|
249
|
-
// Create an initial build if the project was newly created in the account
|
|
250
|
-
|
|
251
|
-
if (!projectExists || uploadPermission === UPLOAD_PERMISSIONS.always) {
|
|
274
|
+
// Create an initial build if the project was newly created in the account
|
|
275
|
+
if (!projectExists) {
|
|
252
276
|
initialUploadResult = await handleProjectUpload(
|
|
253
277
|
targetAccountId,
|
|
254
278
|
projectConfig,
|
|
@@ -258,8 +282,6 @@ exports.handler = async options => {
|
|
|
258
282
|
);
|
|
259
283
|
|
|
260
284
|
if (initialUploadResult.uploadError) {
|
|
261
|
-
SpinniesManager.fail('devModeSetup');
|
|
262
|
-
|
|
263
285
|
if (
|
|
264
286
|
isSpecifiedError(initialUploadResult.uploadError, {
|
|
265
287
|
subCategory: ERROR_TYPES.PROJECT_LOCKED,
|
|
@@ -279,72 +301,42 @@ exports.handler = async options => {
|
|
|
279
301
|
}
|
|
280
302
|
process.exit(EXIT_CODES.ERROR);
|
|
281
303
|
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Let the user know when the initial build or deploy fails
|
|
285
|
-
// Do this before starting the dev server for v2 behavior because we cannot
|
|
286
|
-
// run a server on a broken project
|
|
287
|
-
if (
|
|
288
|
-
options.extension &&
|
|
289
|
-
initialUploadResult &&
|
|
290
|
-
!initialUploadResult.succeeded
|
|
291
|
-
) {
|
|
292
|
-
SpinniesManager.fail('devModeSetup');
|
|
293
|
-
|
|
294
|
-
let subTasks = [];
|
|
295
|
-
|
|
296
|
-
if (initialUploadResult.buildResult.status === 'FAILURE') {
|
|
297
|
-
subTasks =
|
|
298
|
-
initialUploadResult.buildResult[PROJECT_BUILD_TEXT.SUBTASK_KEY];
|
|
299
|
-
} else if (initialUploadResult.deployResult.status === 'FAILURE') {
|
|
300
|
-
subTasks =
|
|
301
|
-
initialUploadResult.deployResult[PROJECT_DEPLOY_TEXT.SUBTASK_KEY];
|
|
302
|
-
}
|
|
303
304
|
|
|
304
|
-
|
|
305
|
+
if (!initialUploadResult.succeeded) {
|
|
306
|
+
let subTasks = [];
|
|
305
307
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
308
|
+
if (initialUploadResult.buildResult.status === 'FAILURE') {
|
|
309
|
+
subTasks =
|
|
310
|
+
initialUploadResult.buildResult[PROJECT_BUILD_TEXT.SUBTASK_KEY];
|
|
311
|
+
} else if (initialUploadResult.deployResult.status === 'FAILURE') {
|
|
312
|
+
subTasks =
|
|
313
|
+
initialUploadResult.deployResult[PROJECT_DEPLOY_TEXT.SUBTASK_KEY];
|
|
314
|
+
}
|
|
311
315
|
|
|
312
|
-
|
|
313
|
-
}
|
|
316
|
+
const failedSubTasks = subTasks.filter(task => task.status === 'FAILURE');
|
|
314
317
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
? new LocalDevManagerV2({
|
|
319
|
-
debug: options.debug,
|
|
320
|
-
extension: options.extension,
|
|
321
|
-
projectConfig,
|
|
322
|
-
projectDir,
|
|
323
|
-
targetAccountId,
|
|
324
|
-
})
|
|
325
|
-
: new LocalDevManager({
|
|
326
|
-
debug: options.debug,
|
|
327
|
-
projectConfig,
|
|
328
|
-
projectDir,
|
|
329
|
-
targetAccountId,
|
|
330
|
-
uploadPermission,
|
|
318
|
+
logger.log();
|
|
319
|
+
failedSubTasks.forEach(failedSubTask => {
|
|
320
|
+
console.log(failedSubTask.errorMessage);
|
|
331
321
|
});
|
|
322
|
+
logger.log();
|
|
332
323
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// Let the user know when the initial build or deploy fails
|
|
336
|
-
if (
|
|
337
|
-
!options.extension &&
|
|
338
|
-
initialUploadResult &&
|
|
339
|
-
!initialUploadResult.succeeded
|
|
340
|
-
) {
|
|
341
|
-
if (initialUploadResult.buildResult.status === 'FAILURE') {
|
|
342
|
-
LocalDev.logBuildError(initialUploadResult.buildResult);
|
|
343
|
-
} else if (initialUploadResult.deployResult.status === 'FAILURE') {
|
|
344
|
-
LocalDev.logDeployError(initialUploadResult.deployResult);
|
|
324
|
+
process.exit(EXIT_CODES.ERROR);
|
|
345
325
|
}
|
|
326
|
+
|
|
327
|
+
deployedBuild = initialUploadResult.buildResult;
|
|
346
328
|
}
|
|
347
329
|
|
|
330
|
+
const LocalDev = new LocalDevManager({
|
|
331
|
+
debug: options.debug,
|
|
332
|
+
deployedBuild,
|
|
333
|
+
projectConfig,
|
|
334
|
+
projectDir,
|
|
335
|
+
targetAccountId,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
await LocalDev.start();
|
|
339
|
+
|
|
348
340
|
handleExit(LocalDev.stop);
|
|
349
341
|
};
|
|
350
342
|
|
|
@@ -354,12 +346,6 @@ exports.builder = yargs => {
|
|
|
354
346
|
addUseEnvironmentOptions(yargs, true);
|
|
355
347
|
addTestingOptions(yargs, true);
|
|
356
348
|
|
|
357
|
-
yargs.option('extension', {
|
|
358
|
-
describe: i18n(`${i18nKey}.options.extension.describe`),
|
|
359
|
-
type: 'string',
|
|
360
|
-
hidden: true,
|
|
361
|
-
});
|
|
362
|
-
|
|
363
349
|
yargs.example([['$0 project dev', i18n(`${i18nKey}.examples.default`)]]);
|
|
364
350
|
|
|
365
351
|
return yargs;
|
|
@@ -17,10 +17,7 @@ const {
|
|
|
17
17
|
downloadProject,
|
|
18
18
|
fetchProjectBuilds,
|
|
19
19
|
} = require('@hubspot/cli-lib/api/dfs');
|
|
20
|
-
const {
|
|
21
|
-
createProjectConfig,
|
|
22
|
-
ensureProjectExists,
|
|
23
|
-
} = require('../../lib/projects');
|
|
20
|
+
const { ensureProjectExists, getProjectConfig } = require('../../lib/projects');
|
|
24
21
|
const { loadAndValidateOptions } = require('../../lib/validation');
|
|
25
22
|
const {
|
|
26
23
|
downloadProjectPrompt,
|
|
@@ -36,6 +33,13 @@ exports.describe = i18n(`${i18nKey}.describe`);
|
|
|
36
33
|
exports.handler = async options => {
|
|
37
34
|
await loadAndValidateOptions(options);
|
|
38
35
|
|
|
36
|
+
const { projectConfig } = await getProjectConfig();
|
|
37
|
+
|
|
38
|
+
if (projectConfig) {
|
|
39
|
+
logger.error(i18n(`${i18nKey}.warnings.cannotDownloadWithinProject`));
|
|
40
|
+
process.exit(EXIT_CODES.ERROR);
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
const { project, dest, buildNumber } = options;
|
|
40
44
|
let { project: promptedProjectName } = await downloadProjectPrompt(options);
|
|
41
45
|
let projectName = promptedProjectName || project;
|
|
@@ -63,17 +67,6 @@ exports.handler = async options => {
|
|
|
63
67
|
|
|
64
68
|
const absoluteDestPath = dest ? path.resolve(getCwd(), dest) : getCwd();
|
|
65
69
|
|
|
66
|
-
const projectConfigCreated = await createProjectConfig(
|
|
67
|
-
absoluteDestPath,
|
|
68
|
-
projectName,
|
|
69
|
-
{ name: 'no-template' }
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
if (!projectConfigCreated) {
|
|
73
|
-
logger.log(i18n(`${i18nKey}.logs.downloadCancelled`));
|
|
74
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
70
|
let buildNumberToDownload = buildNumber;
|
|
78
71
|
|
|
79
72
|
if (!buildNumberToDownload) {
|
|
@@ -98,10 +91,8 @@ exports.handler = async options => {
|
|
|
98
91
|
await extractZipArchive(
|
|
99
92
|
zippedProject,
|
|
100
93
|
projectName,
|
|
101
|
-
path.resolve(absoluteDestPath
|
|
102
|
-
{
|
|
103
|
-
includesRootDir: false,
|
|
104
|
-
}
|
|
94
|
+
path.resolve(absoluteDestPath),
|
|
95
|
+
{ includesRootDir: false }
|
|
105
96
|
);
|
|
106
97
|
|
|
107
98
|
logger.log(
|
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
addUseEnvironmentOptions,
|
|
8
8
|
} = require('../../lib/commonOpts');
|
|
9
9
|
const { trackCommandUsage } = require('../../lib/usageTracking');
|
|
10
|
+
const { i18n } = require('../../lib/lang');
|
|
10
11
|
const {
|
|
11
12
|
logApiErrorInstance,
|
|
12
13
|
ApiErrorContext,
|
|
@@ -31,8 +32,10 @@ const {
|
|
|
31
32
|
const moment = require('moment');
|
|
32
33
|
const { promptUser } = require('../../lib/prompts/promptUtils');
|
|
33
34
|
|
|
35
|
+
const i18nKey = 'cli.commands.project.subcommands.listBuilds';
|
|
36
|
+
|
|
34
37
|
exports.command = 'list-builds [path]';
|
|
35
|
-
exports.describe =
|
|
38
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
36
39
|
|
|
37
40
|
exports.handler = async options => {
|
|
38
41
|
await loadAndValidateOptions(options);
|
|
@@ -16,6 +16,7 @@ const {
|
|
|
16
16
|
logFeedbackMessage,
|
|
17
17
|
validateProjectConfig,
|
|
18
18
|
pollProjectBuildAndDeploy,
|
|
19
|
+
showPlatformVersionWarning,
|
|
19
20
|
} = require('../../lib/projects');
|
|
20
21
|
const { i18n } = require('../../lib/lang');
|
|
21
22
|
const { getAccountConfig } = require('@hubspot/cli-lib');
|
|
@@ -48,6 +49,8 @@ exports.handler = async options => {
|
|
|
48
49
|
|
|
49
50
|
validateProjectConfig(projectConfig, projectDir);
|
|
50
51
|
|
|
52
|
+
await showPlatformVersionWarning(accountId, projectConfig);
|
|
53
|
+
|
|
51
54
|
await ensureProjectExists(accountId, projectConfig.name, { forceCreate });
|
|
52
55
|
|
|
53
56
|
try {
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
pollDeployStatus,
|
|
22
22
|
validateProjectConfig,
|
|
23
23
|
logFeedbackMessage,
|
|
24
|
+
showPlatformVersionWarning,
|
|
24
25
|
} = require('../../lib/projects');
|
|
25
26
|
const {
|
|
26
27
|
cancelStagedBuild,
|
|
@@ -97,6 +98,8 @@ exports.handler = async options => {
|
|
|
97
98
|
|
|
98
99
|
validateProjectConfig(projectConfig, projectDir);
|
|
99
100
|
|
|
101
|
+
await showPlatformVersionWarning(accountId, projectConfig);
|
|
102
|
+
|
|
100
103
|
await ensureProjectExists(accountId, projectConfig.name);
|
|
101
104
|
|
|
102
105
|
try {
|
package/commands/project.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { addConfigOptions, addAccountOptions } = require('../lib/commonOpts');
|
|
2
|
+
const { i18n } = require('../lib/lang');
|
|
2
3
|
const deploy = require('./project/deploy');
|
|
3
4
|
const create = require('./project/create');
|
|
4
5
|
const upload = require('./project/upload');
|
|
@@ -10,24 +11,26 @@ const open = require('./project/open');
|
|
|
10
11
|
const dev = require('./project/dev');
|
|
11
12
|
const add = require('./project/add');
|
|
12
13
|
|
|
14
|
+
const i18nKey = 'cli.commands.project';
|
|
15
|
+
|
|
13
16
|
exports.command = 'project';
|
|
14
|
-
exports.describe =
|
|
17
|
+
exports.describe = i18n(`${i18nKey}.describe`);
|
|
15
18
|
|
|
16
19
|
exports.builder = yargs => {
|
|
17
20
|
addConfigOptions(yargs, true);
|
|
18
21
|
addAccountOptions(yargs, true);
|
|
19
22
|
|
|
20
23
|
// TODO: deploy must be updated
|
|
21
|
-
yargs.command(deploy).demandCommand(1, '');
|
|
22
24
|
yargs.command(create).demandCommand(0, '');
|
|
23
|
-
yargs.command(
|
|
25
|
+
yargs.command(add).demandCommand(0, '');
|
|
24
26
|
yargs.command(watch).demandCommand(0, '');
|
|
25
|
-
yargs.command(
|
|
27
|
+
yargs.command(dev).demandCommand(0, '');
|
|
28
|
+
yargs.command(upload).demandCommand(0, '');
|
|
29
|
+
yargs.command(deploy).demandCommand(1, '');
|
|
26
30
|
yargs.command(logs).demandCommand(1, '');
|
|
31
|
+
yargs.command(listBuilds).demandCommand(0, '');
|
|
27
32
|
yargs.command(download).demandCommand(0, '');
|
|
28
33
|
yargs.command(open).demandCommand(0, '');
|
|
29
|
-
yargs.command(dev).demandCommand(0, '');
|
|
30
|
-
yargs.command(add).demandCommand(0, '');
|
|
31
34
|
|
|
32
35
|
return yargs;
|
|
33
36
|
};
|
|
@@ -22,7 +22,10 @@ const {
|
|
|
22
22
|
} = require('../../lib/sandboxes');
|
|
23
23
|
const { getValidEnv } = require('@hubspot/cli-lib/lib/environment');
|
|
24
24
|
const { logger } = require('@hubspot/cli-lib/logger');
|
|
25
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
trackCommandUsage,
|
|
27
|
+
trackCommandMetadataUsage,
|
|
28
|
+
} = require('../../lib/usageTracking');
|
|
26
29
|
const {
|
|
27
30
|
sandboxTypePrompt,
|
|
28
31
|
sandboxNamePrompt,
|
|
@@ -153,6 +156,12 @@ exports.handler = async options => {
|
|
|
153
156
|
// Prompt user to sync assets after sandbox creation
|
|
154
157
|
const sandboxAccountConfig = getAccountConfig(result.sandbox.sandboxHubId);
|
|
155
158
|
const handleSyncSandbox = async syncTasks => {
|
|
159
|
+
// Send tracking event for secondary action, in this case a sandbox sync within the sandbox create flow
|
|
160
|
+
trackCommandMetadataUsage(
|
|
161
|
+
'sandbox-sync',
|
|
162
|
+
{ step: 'sandbox-create' },
|
|
163
|
+
result.sandbox.sandboxHubId
|
|
164
|
+
);
|
|
156
165
|
await syncSandbox({
|
|
157
166
|
accountConfig: sandboxAccountConfig,
|
|
158
167
|
parentAccountConfig: accountConfig,
|