Compare commits
1 Commits
master
...
609a36c128
| Author | SHA1 | Date | |
|---|---|---|---|
| 609a36c128 |
19
README.md
19
README.md
@@ -6,17 +6,6 @@ Node package compare and change runner.
|
|||||||
[](https://www.npmjs.com/package/pkgcomp)
|
[](https://www.npmjs.com/package/pkgcomp)
|
||||||
[](https://nodejs.org/api/documentation.html#documentation_stability_index)
|
[](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
|
## 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.
|
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
|
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)
|
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
|
### Config options
|
||||||
|
|
||||||
Name | Default | Description
|
Name | Default | Description
|
||||||
---- | ------- | -----------
|
-- | -- | --
|
||||||
`checkFiles` | `['package-lock.json', 'yarn.lock']` | Additional files to checksum and compare, files that are not included will be skipped
|
`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
|
`rootDir` | `process.cwd()` | The root path to your project
|
||||||
`dataDir` | `<Home>/.local/share` | Directory where this module's data should be written to
|
`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
|
## CLI Arguments
|
||||||
|
|
||||||
Argument | Default | Description
|
Argument | Default | Description
|
||||||
-------- | ------- | -----------
|
-- | -- | --
|
||||||
`--verbose` | `false` | Shows more verbose output, like if the command is being skipped or a file in `checkFiles` does not exist
|
`--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
|
`--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"`)
|
`--cmd` | | Specify the command to run when changes are found (ex. `--cmd="yarn install"`)
|
||||||
|
|||||||
@@ -9,12 +9,11 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint 'src/**/*.{js,mjs}'",
|
"lint": "eslint 'src/**/*.{js,mjs}'",
|
||||||
"version": "npm-auto-version",
|
"version": "npm-auto-version",
|
||||||
"start": "node .",
|
"start": "node ."
|
||||||
"test": "npm run lint"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://git.w33ble.com/w33ble/pkgcomp.git"
|
"url": "git+https://github.com/w33ble/pkgcomp.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"spawn",
|
"spawn",
|
||||||
@@ -64,7 +63,7 @@
|
|||||||
"trailingComma": "es5"
|
"trailingComma": "es5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob-parent": "^5.0.0",
|
"fast-deep-equal": "^2.0.1",
|
||||||
"joycon": "^2.2.4",
|
"joycon": "^2.2.4",
|
||||||
"md5-file": "^4.0.0",
|
"md5-file": "^4.0.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
|
|||||||
@@ -36,9 +36,7 @@ function buildConfig(args) {
|
|||||||
// parse args from CLI
|
// parse args from CLI
|
||||||
const args = parseArgs();
|
const args = parseArgs();
|
||||||
|
|
||||||
const { name } = utils.getPackageInfo();
|
pkgcomp(buildConfig(args), utils.getIdent(), args).catch(err => {
|
||||||
|
|
||||||
pkgcomp(buildConfig(args), name, args).catch(err => {
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(err);
|
console.error(err);
|
||||||
process.exit(err.exitCode);
|
process.exit(err.exitCode);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ exports.read = (fileRoot, ident) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(fs.readFileSync(filePath));
|
const data = JSON.parse(fs.readFileSync(filePath));
|
||||||
return JSON.stringify(data[ident] || {});
|
return data[ident] || {};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
fs.writeFileSync(filePath, JSON.stringify({}));
|
fs.writeFileSync(filePath, JSON.stringify({}));
|
||||||
|
|||||||
17
src/index.js
17
src/index.js
@@ -1,5 +1,6 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const md5File = require('md5-file');
|
const md5File = require('md5-file');
|
||||||
|
const deepEqual = require('fast-deep-equal');
|
||||||
const shellExec = require('shell-exec');
|
const shellExec = require('shell-exec');
|
||||||
const data = require('./data');
|
const data = require('./data');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
@@ -42,25 +43,14 @@ module.exports = async function pkgcomp(config, ident, opts = defaultOptions) {
|
|||||||
// read dependencies from package.json
|
// read dependencies from package.json
|
||||||
const pkg = utils.getFileContents(path.join(config.rootDir, 'package.json'), { format: '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 = {
|
const payload = {
|
||||||
hashes,
|
hashes,
|
||||||
dependencies: pkg.dependencies,
|
dependencies: pkg.dependencies,
|
||||||
devDependencies: pkg.devDependencies,
|
devDependencies: pkg.devDependencies,
|
||||||
workspaces,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// check if the command should be run
|
// 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) {
|
if (runCmd) {
|
||||||
const res = await execCommand(config.cmd);
|
const res = await execCommand(config.cmd);
|
||||||
@@ -70,9 +60,6 @@ module.exports = async function pkgcomp(config, ident, opts = defaultOptions) {
|
|||||||
err.cmd = res.cmd;
|
err.cmd = res.cmd;
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} else if (opts.verbose) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log('No changes, command skipped');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.write(config.dataDir, ident, payload);
|
data.write(config.dataDir, ident, payload);
|
||||||
|
|||||||
38
src/utils.js
38
src/utils.js
@@ -2,7 +2,6 @@ const path = require('path');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const JoyCon = require('joycon');
|
const JoyCon = require('joycon');
|
||||||
const globParent = require('glob-parent');
|
|
||||||
|
|
||||||
exports.getRootPath = () => process.cwd();
|
exports.getRootPath = () => process.cwd();
|
||||||
|
|
||||||
@@ -28,40 +27,13 @@ exports.getFileContents = (filePath, opts = {}) => {
|
|||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.getPackageInfo = () => {
|
exports.getRootFileContents = (filename, opts = {}) => {
|
||||||
const { name, workspaces } = exports.getFileContents(
|
return exports.getFileContents(path.join(exports.getRootPath(), filename), opts);
|
||||||
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.getPackageWorkspaces = () => {
|
exports.getIdent = () => {
|
||||||
const { workspaces } = exports.getPackageInfo();
|
const { name } = exports.getRootFileContents('package.json', { format: 'json' });
|
||||||
if (!workspaces) return [];
|
return name;
|
||||||
|
|
||||||
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.getConfig = (overrides = {}) => {
|
exports.getConfig = (overrides = {}) => {
|
||||||
|
|||||||
@@ -1027,13 +1027,6 @@ getopts@^2.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.4.tgz#3137fe8a5fddf304904059a851bdc1c22f0f54fb"
|
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.4.tgz#3137fe8a5fddf304904059a851bdc1c22f0f54fb"
|
||||||
integrity sha512-Rz7DGyomZjrenu9Jx4qmzdlvJgvrEFHXHvjK0FcZtcTC1U5FmES7OdZHUwMuSnEE6QvBvwse1JODKj7TgbSEjQ==
|
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:
|
glob@^7.0.3, glob@^7.1.2, glob@^7.1.3:
|
||||||
version "7.1.3"
|
version "7.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
|
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"
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||||
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||||
|
|
||||||
is-glob@^4.0.0, is-glob@^4.0.1:
|
is-glob@^4.0.0:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||||
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
|
integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
|
||||||
|
|||||||
Reference in New Issue
Block a user