Compare commits

..

1 Commits

Author SHA1 Message Date
609a36c128 docs: add usage info to readme 2019-04-04 17:08:24 -07:00
7 changed files with 18 additions and 78 deletions

View File

@@ -6,17 +6,6 @@ Node package compare and change runner.
[![npm](https://img.shields.io/npm/v/pkgcomp.svg)](https://www.npmjs.com/package/pkgcomp)
[![Project Status](https://img.shields.io/badge/status-experimental-orange.svg)](https://nodejs.org/api/documentation.html#documentation_stability_index)
This tool will execute a command if the dependencies or lock files of your module have changed since the last time it was run. Any of the following will be considered a change:
- If the `dependencies` or `devDependencies` in `package.json` change
- If the `dependencies` or `devDependencies` in any of your workspaces change
- Uses `workspaces` property in root `package.json`, works with Yarn workspaces
- If one of the files in your `checkFiles` config's md5 hash changes
If the command exits with a non-zero exit code, `pkgcomp` will exit with the same exit code.
**NOTE:** Out of the box the script will do nothing, you have to provide a command to run, via the `cmd` config. See [Configuration](#configuration) below.
## Usage
Simply install the package and run it from the command line in your project. You can install it globally and run it that way, but installing locally is generally better.
@@ -26,7 +15,9 @@ yarn add -D pkgcomp
npx pkgcomp
```
**NOTE:** Out of the box the script will do nothing, you have to provide a command to run, via the `cmd` config. See [Configuration](#configuration) below.
If the `dependencies` or `devDependencies` in `package.json` change, or if one of the files in your `checkFiles` config's md5 hash changes, your command will run. If the command exits with a non-zero exit code, `pkgcomp` will exit with the same exit code.
Out of the box the script will do nothing, you have to provide a command to run, via the `cmd` config. See [Configuration](#configuration) below.
You can also set the command, and control how the script works, via the available [command line arguments](#cli-arguments)
@@ -63,7 +54,7 @@ Configuration is provided as JSON, and can be defined in any of the following (l
### Config options
Name | Default | Description
---- | ------- | -----------
-- | -- | --
`checkFiles` | `['package-lock.json', 'yarn.lock']` | Additional files to checksum and compare, files that are not included will be skipped
`rootDir` | `process.cwd()` | The root path to your project
`dataDir` | `<Home>/.local/share` | Directory where this module's data should be written to
@@ -97,7 +88,7 @@ As a property in `package.json`:
## CLI Arguments
Argument | Default | Description
-------- | ------- | -----------
-- | -- | --
`--verbose` | `false` | Shows more verbose output, like if the command is being skipped or a file in `checkFiles` does not exist
`--force` | `false` | Runs your command regardless of whether or not there were changes in the package
`--cmd` | | Specify the command to run when changes are found (ex. `--cmd="yarn install"`)

View File

@@ -9,12 +9,11 @@
"scripts": {
"lint": "eslint 'src/**/*.{js,mjs}'",
"version": "npm-auto-version",
"start": "node .",
"test": "npm run lint"
"start": "node ."
},
"repository": {
"type": "git",
"url": "git+https://git.w33ble.com/w33ble/pkgcomp.git"
"url": "git+https://github.com/w33ble/pkgcomp.git"
},
"keywords": [
"spawn",
@@ -64,7 +63,7 @@
"trailingComma": "es5"
},
"dependencies": {
"glob-parent": "^5.0.0",
"fast-deep-equal": "^2.0.1",
"joycon": "^2.2.4",
"md5-file": "^4.0.0",
"mkdirp": "^0.5.1",

View File

@@ -36,9 +36,7 @@ function buildConfig(args) {
// parse args from CLI
const args = parseArgs();
const { name } = utils.getPackageInfo();
pkgcomp(buildConfig(args), name, args).catch(err => {
pkgcomp(buildConfig(args), utils.getIdent(), args).catch(err => {
// eslint-disable-next-line no-console
console.error(err);
process.exit(err.exitCode);

View File

@@ -18,7 +18,7 @@ exports.read = (fileRoot, ident) => {
try {
const data = JSON.parse(fs.readFileSync(filePath));
return JSON.stringify(data[ident] || {});
return data[ident] || {};
} catch (err) {
if (err.code === 'ENOENT') {
fs.writeFileSync(filePath, JSON.stringify({}));

View File

@@ -1,5 +1,6 @@
const path = require('path');
const md5File = require('md5-file');
const deepEqual = require('fast-deep-equal');
const shellExec = require('shell-exec');
const data = require('./data');
const utils = require('./utils');
@@ -42,25 +43,14 @@ module.exports = async function pkgcomp(config, ident, opts = defaultOptions) {
// read dependencies from package.json
const pkg = utils.getFileContents(path.join(config.rootDir, 'package.json'), { format: 'json' });
// read dependencies from workspace packages
const workspaces = utils.getPackageWorkspaces().map(({ name, package }) => {
const wpkg = utils.getFileContents(path.join(config.rootDir, package), { format: 'json' });
return {
name,
dependencies: wpkg.dependencies,
devDependencies: wpkg.devDependencies,
};
});
const payload = {
hashes,
dependencies: pkg.dependencies,
devDependencies: pkg.devDependencies,
workspaces,
};
// check if the command should be run
const runCmd = Boolean(opts.force || (doExec && packageHistory !== JSON.stringify(payload)));
const runCmd = Boolean(opts.force || (doExec && !deepEqual(packageHistory, payload)));
if (runCmd) {
const res = await execCommand(config.cmd);
@@ -70,9 +60,6 @@ module.exports = async function pkgcomp(config, ident, opts = defaultOptions) {
err.cmd = res.cmd;
throw err;
}
} else if (opts.verbose) {
// eslint-disable-next-line no-console
console.log('No changes, command skipped');
}
data.write(config.dataDir, ident, payload);

View File

@@ -2,7 +2,6 @@ const path = require('path');
const fs = require('fs');
const os = require('os');
const JoyCon = require('joycon');
const globParent = require('glob-parent');
exports.getRootPath = () => process.cwd();
@@ -28,40 +27,13 @@ exports.getFileContents = (filePath, opts = {}) => {
return content;
};
exports.getPackageInfo = () => {
const { name, workspaces } = exports.getFileContents(
path.join(exports.getRootPath(), 'package.json'),
{
format: 'json',
}
);
if (!name) throw new Error('Unable to read project name from package.json');
// handle nohoist config: https://yarnpkg.com/blog/2018/02/15/nohoist/
const realWorkspaces = workspaces.packages ? workspaces.packages : workspaces;
return { name, workspaces: realWorkspaces };
exports.getRootFileContents = (filename, opts = {}) => {
return exports.getFileContents(path.join(exports.getRootPath(), filename), opts);
};
exports.getPackageWorkspaces = () => {
const { workspaces } = exports.getPackageInfo();
if (!workspaces) return [];
return workspaces.reduce((acc, glob) => {
const parent = globParent(glob);
const packages = fs
.readdirSync(parent)
.map(package => {
const packageJson = path.join(parent, package, 'package.json');
if (!exports.canAccessFile(packageJson)) return false;
return {
name: package,
package: packageJson,
};
})
.filter(Boolean);
return acc.concat(packages);
}, []);
exports.getIdent = () => {
const { name } = exports.getRootFileContents('package.json', { format: 'json' });
return name;
};
exports.getConfig = (overrides = {}) => {

View File

@@ -1027,13 +1027,6 @@ getopts@^2.0.6:
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.4.tgz#3137fe8a5fddf304904059a851bdc1c22f0f54fb"
integrity sha512-Rz7DGyomZjrenu9Jx4qmzdlvJgvrEFHXHvjK0FcZtcTC1U5FmES7OdZHUwMuSnEE6QvBvwse1JODKj7TgbSEjQ==
glob-parent@^5.0.0:
version "5.0.0"
resolved "https://npm.w33ble.com:443/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954"
integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==
dependencies:
is-glob "^4.0.1"
glob@^7.0.3, glob@^7.1.2, glob@^7.1.3:
version "7.1.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
@@ -1331,7 +1324,7 @@ is-fullwidth-code-point@^2.0.0:
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
is-glob@^4.0.0, is-glob@^4.0.1:
is-glob@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==