@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
165 lines • 5.47 kB
JavaScript
import fs from 'fs';
import path from 'path';
import inquirer from 'inquirer';
import { omit, pick } from 'es-toolkit/object';
import { logger } from '../../utils/logger.js';
import { installComposerDependencies, updateComposerDependencies } from '../../utils/composer.js';
import { cleanInstallNodeDependencies, installNodeDependencies } from '../../utils/npm.js';
import { LOCKFILE_INSTALL_SOURCE, MANIFEST_INSTALL_SOURCE, confirmDependencyInstall, formatInstallTargetLabel, outputInstallSummary, selectInstallSource } from './utils.js';
const installNpmDependencies = async ({
appDir,
options = {},
rootDir
}, dependencies = {}) => {
const {
cleanInstallNodeDependenciesImpl = cleanInstallNodeDependencies,
existsSyncImpl = fs.existsSync,
installNodeDependenciesImpl = installNodeDependencies,
loggerImpl = logger,
promptImpl = inquirer.prompt
} = dependencies;
const targetLabel = formatInstallTargetLabel(rootDir, appDir);
const shouldInstall = await confirmDependencyInstall({
allYes: options.allYes === true,
dependencyLabel: 'NPM',
promptImpl,
subjectLabel: 'Atlas application',
targetLabel
});
if (!shouldInstall) {
loggerImpl.info(`Skipped NPM dependency installation for ${targetLabel}.`);
return null;
}
const lockfilePath = path.join(appDir, 'package-lock.json');
const hasLockfile = existsSyncImpl(lockfilePath);
const npmOptions = omit(options, ['allYes']);
let installSource = MANIFEST_INSTALL_SOURCE;
if (hasLockfile) {
loggerImpl.info('package-lock.json detected.');
installSource = await selectInstallSource({
allYes: options.allYes === true,
dependencyLabel: 'NPM',
lockfileChoiceLabel: 'Use package-lock.json (recommended)',
manifestChoiceLabel: 'Install from package.json',
promptImpl,
targetLabel
});
} else {
loggerImpl.warning('No package-lock.json detected. Installing from package.json.');
}
outputInstallSummary({
dependencyLabel: 'NPM',
loggerImpl,
sourceLabel: installSource === LOCKFILE_INSTALL_SOURCE ? 'package-lock.json' : 'package.json',
targetLabel
});
if (installSource === LOCKFILE_INSTALL_SOURCE) {
return cleanInstallNodeDependenciesImpl(appDir, npmOptions);
}
return installNodeDependenciesImpl(appDir, npmOptions);
};
const installAppComposerDependencies = async ({
rootDir,
options = {}
}, dependencies = {}) => {
const {
existsSyncImpl = fs.existsSync,
installComposerDependenciesImpl = installComposerDependencies,
loggerImpl = logger,
promptImpl = inquirer.prompt,
updateComposerDependenciesImpl = updateComposerDependencies
} = dependencies;
const targetLabel = formatInstallTargetLabel(rootDir, rootDir);
const shouldInstall = await confirmDependencyInstall({
allYes: options.allYes === true,
dependencyLabel: 'Composer',
promptImpl,
subjectLabel: 'Atlas application',
targetLabel
});
if (!shouldInstall) {
loggerImpl.info(`Skipped Composer dependency installation for ${targetLabel}.`);
return null;
}
const lockfilePath = path.join(rootDir, 'composer.lock');
const hasLockfile = existsSyncImpl(lockfilePath);
const composerOptions = {
...pick(options, ['force']),
allYes: true,
cwd: rootDir
};
let installSource = MANIFEST_INSTALL_SOURCE;
if (hasLockfile) {
loggerImpl.info('composer.lock detected.');
installSource = await selectInstallSource({
allYes: options.allYes === true,
dependencyLabel: 'Composer',
lockfileChoiceLabel: 'Use composer.lock (recommended)',
manifestChoiceLabel: 'Update from composer.json',
promptImpl,
targetLabel
});
} else {
loggerImpl.warning('No composer.lock detected. Installing from composer.json.');
}
outputInstallSummary({
dependencyLabel: 'Composer',
loggerImpl,
sourceLabel: installSource === LOCKFILE_INSTALL_SOURCE ? 'composer.lock' : 'composer.json',
targetLabel
});
if (installSource === LOCKFILE_INSTALL_SOURCE) {
return installComposerDependenciesImpl(composerOptions);
}
return updateComposerDependenciesImpl(composerOptions);
};
export default async ({
npm = false,
composer = false,
...options
} = {}, dependencies = {}) => {
const {
cleanInstallNodeDependenciesImpl = cleanInstallNodeDependencies,
cwd = process.cwd(),
existsSyncImpl = fs.existsSync,
installComposerDependenciesImpl = installComposerDependencies,
installNodeDependenciesImpl = installNodeDependencies,
loggerImpl = logger,
promptImpl = inquirer.prompt,
updateComposerDependenciesImpl = updateComposerDependencies
} = dependencies;
const rootDir = cwd;
const appDir = path.join(rootDir, 'app');
if (!existsSyncImpl(appDir)) {
loggerImpl.error('The /app directory does not exist. Make sure you are in the root directory of your project.', {
exit: true,
exitCode: 1
});
return;
}
if (npm || !composer) {
await installNpmDependencies({
appDir,
options,
rootDir
}, {
cleanInstallNodeDependenciesImpl,
existsSyncImpl,
installNodeDependenciesImpl,
loggerImpl,
promptImpl
});
}
if (composer || !npm) {
await installAppComposerDependencies({
options,
rootDir
}, {
existsSyncImpl,
installComposerDependenciesImpl,
loggerImpl,
promptImpl,
updateComposerDependenciesImpl
});
}
};