Skip to content

Commit

Permalink
Update after UX feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
joe-yeager committed Aug 21, 2024
1 parent d6dba4d commit 3130b26
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 176 deletions.
4 changes: 3 additions & 1 deletion packages/cli/commands/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const dev = require('./project/dev');
const add = require('./project/add');
const migrateApp = require('./project/migrateApp');
const cloneApp = require('./project/cloneApp');
const installDeps = require('./project/install');
const installDeps = require('./project/installDeps');
const addDeps = require('./project/addDep');

const i18nKey = 'commands.project';

Expand All @@ -38,6 +39,7 @@ exports.builder = yargs => {
.command(migrateApp)
.command(cloneApp)
.command(installDeps)
.command(addDeps)
.demandCommand(1, '');

return yargs;
Expand Down
51 changes: 51 additions & 0 deletions packages/cli/commands/project/addDep.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const { getProjectConfig } = require('../../lib/projects');
const path = require('node:path');
const { promptUser } = require('../../lib/prompts/promptUtils');
const {
installDeps,
getProjectPackageJsonFiles,
} = require('../../lib/dependencyManagement');
const { EXIT_CODES } = require('../../lib/enums/exitCodes');
const { logger } = require('@hubspot/local-dev-lib/logger');

exports.command = 'add-dep [packages..]';
exports.describe = 'Install your deps';
exports.builder = yargs => yargs;

exports.handler = async ({ packages }) => {
try {
const projectConfig = await getProjectConfig();

if (!projectConfig || !projectConfig.projectDir) {
logger.error('Must be ran within a project');
process.exit(EXIT_CODES.ERROR);
}

const { projectDir } = projectConfig;

const packageParentDirs = await getProjectPackageJsonFiles();
const { installLocations } = await promptUser([
{
name: 'installLocations',
type: 'checkbox',
when: () => packages && packages.length > 0,
message: `Which location would you like to add the dependencies to?`,
choices: packageParentDirs.map(dir => ({
name: path.relative(projectDir, dir),
value: dir,
})),
validate: choices => {
if (choices === undefined || choices.length === 0) {
return 'You must choose at least one location';
}
return true;
},
},
]);

await installDeps({ packages, installLocations });
} catch (e) {
logger.error(e.message);
process.exit(EXIT_CODES.ERROR);
}
};
3 changes: 3 additions & 0 deletions packages/cli/commands/project/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const {
createInitialBuildForNewProject,
useExistingDevTestAccount,
} = require('../../lib/localDev');
const { installDeps } = require('../../lib/dependencyManagement');

const i18nKey = 'commands.project.subcommands.dev';

Expand Down Expand Up @@ -234,6 +235,8 @@ exports.handler = async options => {
env,
});

// TODO: Add prompt if we decide to go that route
await installDeps({ silent: true });
await LocalDev.start();

handleExit(({ isSIGHUP }) => LocalDev.stop(!isSIGHUP));
Expand Down
175 changes: 0 additions & 175 deletions packages/cli/commands/project/install.js

This file was deleted.

16 changes: 16 additions & 0 deletions packages/cli/commands/project/installDeps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const { installDeps } = require('../../lib/dependencyManagement');
const { logger } = require('@hubspot/local-dev-lib/logger');
const { EXIT_CODES } = require('../../lib/enums/exitCodes');

exports.command = 'install-deps';
exports.describe = 'Install your deps';
exports.builder = yargs => yargs;

exports.handler = async () => {
try {
await installDeps({});
} catch (e) {
logger.error(e.message());
process.exit(EXIT_CODES.ERROR);
}
};
99 changes: 99 additions & 0 deletions packages/cli/lib/dependencyManagement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const { logger } = require('@hubspot/local-dev-lib/logger');
const { getProjectConfig } = require('./projects');
const DEFAULT_PACKAGE_MANAGER = 'npm';
const { execSync } = require('child_process');
const { EXIT_CODES } = require('./enums/exitCodes');
const { walk } = require('@hubspot/local-dev-lib/fs');
const path = require('node:path');
const { uiLink } = require('./ui');

function isGloballyInstalled(command) {
try {
execSync(`${command} --version`);
return true;
} catch (e) {
return false;
}
}

async function installDeps({ packages, installLocations, silent = false }) {
const installDirs = installLocations || (await getProjectPackageJsonFiles());
installDirs.forEach(directory => {
installInDirectory(packages, directory, silent);
});
}

function installInDirectory(packages, directory, silent) {
logger.info(
`Installing dependencies ${
packages ? `[${packages.join(', ')}] ` : ''
}in ${directory}`
);
let installCommand = `${DEFAULT_PACKAGE_MANAGER} --prefix=${directory} install`;

if (packages) {
installCommand = `${installCommand} ${packages.join(' ')}`;
}

logger.debug(`Running ${installCommand}`);
try {
execSync(installCommand, {
stdio: silent ? 'ignore' : 'inherit',
});
} catch (e) {
logger.error(`Installing dependencies for ${directory} failed`);
process.exit(EXIT_CODES.ERROR);
}
}

async function getProjectPackageJsonFiles() {
const projectConfig = await getProjectConfig();

if (
!projectConfig ||
!projectConfig.projectDir ||
!projectConfig.projectConfig
) {
throw new Error('Must be ran within a project');
}

const {
projectDir,
projectConfig: { srcDir },
} = projectConfig;

if (!isGloballyInstalled(DEFAULT_PACKAGE_MANAGER)) {
throw new Error(
`This command depends on ${DEFAULT_PACKAGE_MANAGER}, install ${uiLink(
DEFAULT_PACKAGE_MANAGER,
'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm'
)}`
);
}

const packageJsonFiles = (await walk(path.join(projectDir, srcDir))).filter(
file =>
file.includes('package.json') &&
!file.includes('node_modules') &&
!file.includes('.vite') &&
!file.includes('dist')
);

if (packageJsonFiles.length === 0) {
throw new Error('Could not find any package.json files in the project');
}

const packageParentDirs = [];
packageJsonFiles.forEach(packageJsonFile => {
const parentDir = path.dirname(packageJsonFile);
packageParentDirs.push(parentDir);
});

return packageParentDirs;
}

module.exports = {
installDeps,
DEFAULT_PACKAGE_MANAGER,
getProjectPackageJsonFiles,
};

0 comments on commit 3130b26

Please sign in to comment.