Skip to content

Instantly share code, notes, and snippets.

@jameswomack
Last active July 7, 2021 23:28
Show Gist options
  • Save jameswomack/72d52b164fd332cd787a634be878b8b9 to your computer and use it in GitHub Desktop.
Save jameswomack/72d52b164fd332cd787a634be878b8b9 to your computer and use it in GitHub Desktop.
A CLI script for syncing versions of all a scope's dependencies within a monorepo. Supports CLI args & environment variables
#!/usr/bin/env node
const argv = require('yargs-parser')(process.argv.slice(2));
function getEnvVarForScopeVConfigKey(keyName) {
const {env} = require('process');
return env[`MONOREPO_${keyName.toUpperCase()}`];
}
const ScopeVConfiguration = Object.create({
packageScope: (() => {
const envVar = getEnvVarForScopeVConfigKey('PACKAGE_SCOPE');
return argv.packageScope || envVar || '@babel';
})(),
packagesVersion: (() => {
const envVar = getEnvVarForScopeVConfigKey('PACKAGES_VERSION');
return argv.packagesVersion || envVar || '7.14.5';
})()
});
let foundDependenciesWithSpecifiedScope = false;
require('glob')
.sync('{,!(node_modules)/**/}package.json')
.map(path => {
if (path.includes('node_modules')) return;
let pkg;
try {
pkg = require(`./${path}`);
} catch (pkgRetrievalError) {
console.error(pkgRetrievalError); // eslint-disable-line
}
if (!pkg) return;
function setMonorepoPackagesVersionForDependenciesType(version, type) {
const dependencies = pkg[type];
if (!dependencies) return;
const dependenciesFound = Object.keys(dependencies).filter(k =>
k.startsWith(ScopeVConfiguration.packageScope)
);
if (dependenciesFound.length) foundDependenciesWithSpecifiedScope = true;
dependenciesFound.forEach(k => {
function logVersionSetMessageOfType(versionSetType) {
return console.log(`${path} ${type} ${k} ${versionSetType} to ${version}`); // eslint-disable-line
}
if (pkg[type][k] !== version) {
logVersionSetMessageOfType('changed');
pkg[type][k] = version;
} else {
logVersionSetMessageOfType('was already set');
}
});
}
// Partial application nation
const setConfiguredPackagesVersionDependenciesType = setMonorepoPackagesVersionForDependenciesType.bind(
null,
ScopeVConfiguration.packagesVersion
);
['dependencies', 'devDependencies'].forEach(
setConfiguredPackagesVersionDependenciesType
);
return require('fs').writeFileSync(
path,
`${JSON.stringify(pkg, null, '\t')}\n`
);
});
if (!foundDependenciesWithSpecifiedScope)
console.warn( // eslint-disable-line
`No dependencies w/ scope ${ScopeVConfiguration.packageScope} found`
);
> $ ./scopev.js # it'll tell ya if it couldn't find deps w/ the given scope [@babel is the default]
No dependencies w/ scope @babel found
> $ ./scopev.js --packages-version=21.0.0-foo.0 --package-scope=@examples # it'll tell ya if it's been changed
package.json dependencies @examples/sn-list-commons changed to 21.0.0-foo.0
> $ ./scopev.js --packages-version=21.1.2 --package-scope=@workflowit # it'll tell ya if it's already been set
package.json dependencies @workflowit/now-template-message was already set to 21.1.2
package.json dependencies @workflowit/sass-kit was already set to 21.1.2
package.json dependencies @workflowit/sass-utility was already set to 21.1.2
package.json dependencies @workflowit/ui-core was already set to 21.1.2
package.json dependencies @workflowit/ui-renderer-snabbdom was already set to 21.1.2
package.json devDependencies @workflowit/now-button was already set to 21.1.2
package.json devDependencies @workflowit/now-toggle was already set to 21.1.2
> $ ./scopev.js --packages-version=21.0.0-rtw.8 --package-scope=@foo # it'll tell ya if it's already been set [v2]
package.json devDependencies @foo/cli was already set to 21.0.0-rtw.8
package.json devDependencies @foo/test-api was already set to 21.0.0-rtw.8
> $ MONOREPO_PACKAGES_VERSION=21.0.0-alpha.19 MONOREPO_PACKAGE_SCOPE=@foo ./scopev.js # env vars work too! ⬡ 14.16.1 [±ci/esm ●●]
package.json devDependencies @foo/cli changed to 21.0.0-alpha.19
package.json devDependencies @foo/test-api changed to 21.0.0-alpha.19
@jameswomack
Copy link
Author

Note that you'll need to add executable permissions to scopev.js in order for it to operate sans the "node " prefix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment