jazelle/commands/add.js (76 lines of code) (raw):

// @flow const {resolve} = require('path'); const {getPassThroughArgs} = require('../utils/parse-argv.js'); const {assertProjectDir} = require('../utils/assert-project-dir.js'); const {getManifest} = require('../utils/get-manifest.js'); const {getAllDependencies} = require('../utils/get-all-dependencies.js'); const {shouldSync, getVersion} = require('../utils/version-onboarding.js'); const {getLocalDependencies} = require('../utils/get-local-dependencies.js'); const {read, write} = require('../utils/node-helpers.js'); const {findLocalDependency} = require('../utils/find-local-dependency.js'); const {add: addDep} = require('../utils/lockfile.js'); const {install} = require('./install.js'); const sortPackageJson = require('../utils/sort-package-json'); /* adding local dep should: - add it to the project's package.json, pointing to the exact local version - update the BUILD.bazel file `deps` field - not add it to the project's yarn.lock */ /*:: export type AddArgs = { root: string, cwd: string, args: Array<string>, version?: string, dev?: boolean, }; export type Add = (AddArgs) => Promise<void>; */ const add /*: Add */ = async ({root, cwd, args, dev = false}) => { await assertProjectDir({dir: cwd}); const type = dev ? 'devDependencies' : 'dependencies'; // group by whether the dep is local (listed in manifest.json) or external (from registry) const locals = []; const externals = []; const params = getPassThroughArgs(args); for (const param of params) { let [, name, version] = param.match(/(@?[^@]*)@?(.*)/) || []; const local = await findLocalDependency({root, name}); if (local && (!version || local.meta.version === version)) { locals.push({local, name}); } else { externals.push({name, range: version, type}); } } // add local deps if (locals.length > 0) { const meta = JSON.parse(await read(`${cwd}/package.json`, 'utf8')); if (!meta[type]) meta[type] = {}; for (const {local, name} of locals) { // update existing entries const types = [ 'dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies', 'resolutions', ]; for (const t of types) { if (meta[t] && meta[t][name]) { meta[t][name] = local.meta.version; } } meta[type][name] = local.meta.version; } await write(`${cwd}/package.json`, sortPackageJson(meta), 'utf8'); } // add external deps if (externals.length > 0) { const {projects, versionPolicy, registry} = await getManifest({root}); const unversioned = externals.filter(({range}) => !range); if (unversioned.length > 0 && versionPolicy) { const deps = await getAllDependencies({root, projects}); for (const external of unversioned) { const {name} = external; if (shouldSync({versionPolicy, name})) { const version = getVersion({name, deps}); if (version !== '') external.range = version; } } } const deps = await getLocalDependencies({ dirs: projects.map(dir => `${root}/${dir}`), target: resolve(root, cwd), }); const tmp = `${root}/third_party/jazelle/temp/yarn-utilities-tmp`; await addDep({ registry, roots: [cwd], additions: externals, ignore: deps.map(d => d.meta.name), tmp, }); } await install({root, cwd, conservative: false}); }; module.exports = {add};