diff --git a/packages/cli/commands/project/deploy.js b/packages/cli/commands/project/deploy.js index 6b969ace9..5dc5c7089 100644 --- a/packages/cli/commands/project/deploy.js +++ b/packages/cli/commands/project/deploy.js @@ -87,11 +87,7 @@ exports.handler = async options => { if (e.statusCode === 400) { logger.error(e.error.message); } else { - logApiErrorInstance( - accountId, - e, - new ApiErrorContext({ accountId, projectPath }) - ); + logApiErrorInstance(e, new ApiErrorContext({ accountId, projectPath })); } } }; diff --git a/packages/cli/commands/project/upload.js b/packages/cli/commands/project/upload.js index 512ac0428..22220029d 100644 --- a/packages/cli/commands/project/upload.js +++ b/packages/cli/commands/project/upload.js @@ -31,6 +31,7 @@ const { getProjectConfig, validateProjectConfig, pollBuildStatus, + ensureProjectExists, } = require('../../lib/projects'); const loadAndValidateOptions = async options => { @@ -83,12 +84,13 @@ const uploadProjectFiles = async (accountId, projectName, filePath) => { )} project files to ${chalk.bold(accountId)}`, }); - logApiErrorInstance(err, { - context: new ApiErrorContext({ + logApiErrorInstance( + err, + new ApiErrorContext({ accountId, projectName, - }), - }); + }) + ); } }; @@ -100,10 +102,14 @@ exports.handler = async options => { trackCommandUsage('project-upload', { projectPath }, accountId); - const cwd = projectPath ? path.resolve(getCwd(), projectPath) : getCwd(); - const projectConfig = await getProjectConfig(cwd); + const projectDir = projectPath + ? path.resolve(getCwd(), projectPath) + : getCwd(); + const projectConfig = await getProjectConfig(projectDir); + + validateProjectConfig(projectConfig, projectDir); - validateProjectConfig(projectConfig); + await ensureProjectExists(accountId, projectConfig.name); const tempFile = tmp.fileSync({ postfix: '.zip' }); @@ -131,8 +137,10 @@ exports.handler = async options => { archive.pipe(output); - archive.directory(path.resolve(cwd, projectConfig.srcDir), false, file => - shouldIgnoreFile(file.name) ? false : file + archive.directory( + path.resolve(projectDir, projectConfig.srcDir), + false, + file => (shouldIgnoreFile(file.name) ? false : file) ); archive.finalize(); diff --git a/packages/cli/lib/projects.js b/packages/cli/lib/projects.js index 6d5fb84d7..40889b49a 100644 --- a/packages/cli/lib/projects.js +++ b/packages/cli/lib/projects.js @@ -16,7 +16,16 @@ const { PROJECT_DEPLOY_STATUS, PROJECT_DEPLOY_STATUS_TEXT, } = require('@hubspot/cli-lib/lib/constants'); -const { getBuildStatus, getDeployStatus } = require('@hubspot/cli-lib/api/dfs'); +const { + getBuildStatus, + getDeployStatus, + fetchProject, + createProject, +} = require('@hubspot/cli-lib/api/dfs'); +const { + logApiErrorInstance, + ApiErrorContext, +} = require('@hubspot/cli-lib/errorHandlers'); const isBuildComplete = build => { return ( @@ -88,7 +97,7 @@ const getOrCreateProjectConfig = async projectPath => { return projectConfig; }; -const validateProjectConfig = projectConfig => { +const validateProjectConfig = (projectConfig, projectDir) => { if (!projectConfig) { logger.error( `Project config not found. Try running 'hs project init' first.` @@ -103,7 +112,7 @@ const validateProjectConfig = projectConfig => { process.exit(1); } - if (!fs.existsSync(projectConfig.srcDir)) { + if (!fs.existsSync(path.resolve(projectDir, projectConfig.srcDir))) { logger.error( `Project source directory '${projectConfig.srcDir}' does not exist.` ); @@ -111,6 +120,37 @@ const validateProjectConfig = projectConfig => { } }; +const ensureProjectExists = async (accountId, projectName) => { + try { + await fetchProject(accountId, projectName); + } catch (err) { + if (err.statusCode === 404) { + const { shouldCreateProject } = await prompt([ + { + name: 'shouldCreateProject', + message: `The project ${projectName} does not exist in ${accountId}. Would you like to create it?`, + type: 'confirm', + }, + ]); + + if (shouldCreateProject) { + try { + return createProject(accountId, projectName); + } catch (err) { + return logApiErrorInstance(err, new ApiErrorContext({ accountId })); + } + } else { + return logger.log( + `Your project ${chalk.bold( + projectName + )} could not be found in ${chalk.bold(accountId)}.` + ); + } + } + logApiErrorInstance(err, new ApiErrorContext({ accountId })); + } +}; + const getProjectDetailUrl = (projectName, accountId) => { if (!projectName) return; @@ -335,4 +375,5 @@ module.exports = { showWelcomeMessage, pollBuildStatus, pollDeployStatus, + ensureProjectExists, };