Comparing version 0.1.0 to 0.2.0
@@ -0,3 +1,13 @@ | ||
<a name="0.2.0"></a> | ||
# [0.2.0](https://github.com/JamieMason/syncpack/compare/0.1.0...0.2.0) (2017-08-20) | ||
### Features | ||
* **sync:** synchronise versions across multiple package.json ([7d5848a](https://github.com/JamieMason/syncpack/commit/7d5848a)) | ||
<a name="0.1.0"></a> | ||
# 0.1.0 (2017-08-18) | ||
# [0.1.0](https://github.com/JamieMason/syncpack/compare/f6dada7...0.1.0) (2017-08-18) | ||
@@ -4,0 +14,0 @@ |
@@ -24,8 +24,15 @@ #!/usr/bin/env node | ||
_commander2.default.version(_package.version); | ||
var patternValue = void 0; | ||
_commander2.default.version(_package.version).arguments('[pattern]').action(function (pattern) { | ||
patternValue = pattern; | ||
}); | ||
_commander2.default.parse(process.argv); | ||
(0, _index2.default)({}).catch(function (err) { | ||
(0, _index2.default)({ | ||
pattern: patternValue | ||
}).catch(function (err) { | ||
log.bug('uncaught error in syncpack', err); | ||
process.exit(1); | ||
}); |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -7,4 +7,180 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.default = function () { | ||
return Promise.resolve(); | ||
var _nodentRuntime = require('nodent-runtime'); | ||
var _nodentRuntime2 = _interopRequireDefault(_nodentRuntime); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var _bluebird = require('bluebird'); | ||
var _bluebird2 = _interopRequireDefault(_bluebird); | ||
var _chalk = require('chalk'); | ||
var _chalk2 = _interopRequireDefault(_chalk); | ||
var _path = require('path'); | ||
var _path2 = _interopRequireDefault(_path); | ||
var _semver = require('semver'); | ||
var _semver2 = _interopRequireDefault(_semver); | ||
var _log = require('./lib/log'); | ||
var log = _interopRequireWildcard(_log); | ||
var _getFiles = require('./lib/get-files'); | ||
var _getFiles2 = _interopRequireDefault(_getFiles); | ||
var _writeJson = require('./lib/write-json'); | ||
var _writeJson2 = _interopRequireDefault(_writeJson); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var keys = function keys() { | ||
var object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return Object.keys(object); | ||
}; | ||
var clone = function clone(object) { | ||
return JSON.parse(JSON.stringify(object)); | ||
}; | ||
var concatAll = function concatAll(arrayOfArrays) { | ||
return [].concat.apply([], arrayOfArrays); | ||
}; | ||
var entries = function entries(object) { | ||
return keys(object).map(function (key) { | ||
return [key, object[key]]; | ||
}); | ||
}; | ||
var isEmptyObject = function isEmptyObject(object) { | ||
return keys(object).length === 0; | ||
}; | ||
var pluck = function pluck(key) { | ||
return function (object) { | ||
return object[key]; | ||
}; | ||
}; | ||
var stripWildCards = function stripWildCards(version) { | ||
return version.replace(/[*^=><]/g, ''); | ||
}; | ||
var getPackage = function getPackage(location) { | ||
return { location: location, json: require(location) }; | ||
}; | ||
var takeNewest = function takeNewest(max, next) { | ||
return !_semver2.default.valid(stripWildCards(next)) || _semver2.default.gt(stripWildCards(next), stripWildCards(max)) ? next : max; | ||
}; | ||
var indexEntries = function indexEntries(array) { | ||
return array.reduce(function (index, _ref) { | ||
var _ref2 = _slicedToArray(_ref, 2), | ||
key = _ref2[0], | ||
value = _ref2[1]; | ||
index[key] = index[key] || []; | ||
index[key] = index[key].indexOf(value) === -1 ? index[key].concat(value) : index[key]; | ||
return index; | ||
}, {}); | ||
}; | ||
var getNewestDeps = function getNewestDeps(key, packages) { | ||
var dependencies = concatAll(packages.map(pluck('json')).map(pluck(key)).map(entries)); | ||
var versionsByDependencyName = indexEntries(dependencies); | ||
return entries(versionsByDependencyName).map(function (_ref3) { | ||
var _ref4 = _slicedToArray(_ref3, 2), | ||
name = _ref4[0], | ||
versions = _ref4[1]; | ||
var newest = versions.reduce(takeNewest, '0.0.0'); | ||
return [name, newest]; | ||
}); | ||
}; | ||
var getChangedDeps = function getChangedDeps(key, packages) { | ||
return packages.map(function (pkg) { | ||
return getNewestDeps(key, packages).reduce(function (changes, _ref5) { | ||
var _ref6 = _slicedToArray(_ref5, 2), | ||
name = _ref6[0], | ||
version = _ref6[1]; | ||
if (pkg.json[key] && name in pkg.json[key] && pkg.json[key][name] !== version) { | ||
changes[name] = version; | ||
} | ||
return changes; | ||
}, {}); | ||
}); | ||
}; | ||
var reportChanges = function reportChanges(key, pkg, changes) { | ||
var changedEntries = entries(changes); | ||
if (changedEntries.length) { | ||
changedEntries.forEach(function (_ref7) { | ||
var _ref8 = _slicedToArray(_ref7, 2), | ||
name = _ref8[0], | ||
version = _ref8[1]; | ||
console.log(key + ' ' + name + ' ' + _chalk2.default.red(pkg.json[key][name]) + ' \u2192 ' + _chalk2.default.green(version)); | ||
}); | ||
} else { | ||
console.log(key + ' ' + _chalk2.default.green('✓ unchanged')); | ||
} | ||
}; | ||
exports.default = function (_ref9) { | ||
return new Promise(function ($return, $error) { | ||
var _ref9$pattern, pattern, packages, changedDeps, changedDevDeps, changedPeerDeps, nextPackages; | ||
_ref9$pattern = _ref9.pattern, pattern = _ref9$pattern === undefined ? './packages/*/package.json' : _ref9$pattern; | ||
return (0, _getFiles2.default)(pattern).then(function ($await_3) { | ||
packages = $await_3.map(getPackage); | ||
changedDeps = getChangedDeps('dependencies', packages); | ||
changedDevDeps = getChangedDeps('devDependencies', packages); | ||
changedPeerDeps = getChangedDeps('peerDependencies', packages); | ||
nextPackages = packages.map(function (_ref10, i) { | ||
var location = _ref10.location, | ||
json = _ref10.json; | ||
var nextPkg = { | ||
location: location, | ||
json: _extends({}, json, { | ||
dependencies: _extends({}, json.dependencies, changedDeps[i]), | ||
devDependencies: _extends({}, json.devDependencies, changedDevDeps[i]), | ||
peerDependencies: _extends({}, json.peerDependencies, changedPeerDeps[i]) | ||
}) | ||
}; | ||
if (isEmptyObject(nextPkg.json.dependencies)) { | ||
delete nextPkg.json.dependencies; | ||
} | ||
if (isEmptyObject(nextPkg.json.devDependencies)) { | ||
delete nextPkg.json.devDependencies; | ||
} | ||
if (isEmptyObject(nextPkg.json.peerDependencies)) { | ||
delete nextPkg.json.peerDependencies; | ||
} | ||
return nextPkg; | ||
}); | ||
packages.forEach(function (pkg, i) { | ||
console.log(_chalk2.default.grey.underline(_path2.default.relative(process.cwd(), pkg.location))); | ||
reportChanges('dependencies', pkg, changedDeps[i]); | ||
reportChanges('devDependencies', pkg, changedDevDeps[i]); | ||
reportChanges('peerDependencies', pkg, changedPeerDeps[i]); | ||
}); | ||
return _bluebird2.default.all(nextPackages.map(function (pkg) { | ||
return (0, _writeJson2.default)(pkg.location, pkg.json); | ||
})).then(function ($await_4) { | ||
return $return(); | ||
}.$asyncbind(this, $error), $error); | ||
}.$asyncbind(this, $error), $error); | ||
}.$asyncbind(this)); | ||
}; |
{ | ||
"name": "syncpack", | ||
"description": "Normalise differences in packages/*/package.json files in Lerna Monorepos", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"author": "Jamie Mason <jamie@foldleft.io> (https://github.com/JamieMason)", | ||
@@ -20,2 +20,3 @@ "bin": { | ||
"babel-cli": "6.24.1", | ||
"babel-plugin-transform-object-rest-spread": "6.26.0", | ||
"babel-preset-es2015": "6.22.0", | ||
@@ -22,0 +23,0 @@ "fast-async": "6.3.0", |
@@ -10,6 +10,43 @@ # syncpack | ||
Normalise differences across multiple `package.json` files, such as `packages/*/package.json` in [Lerna](https://lernajs.io) Monorepos. | ||
Synchronises the versions of dependencies used across multiple `package.json` files, such as | ||
`packages/*/package.json` in [Lerna](https://lernajs.io) Monorepos. | ||
## Status | ||
## Overview | ||
In Development, not yet ready for use. | ||
Imagine the packages `guybrush`, `herman`, and `elaine` all have `react` as a dependency, but | ||
versions `'15.4.0'`, `'15.5.4'`, and `'15.6.1'` respectively. | ||
``` | ||
/Users/foldleft/Dev/monorepo/packages/ | ||
├── guybrush | ||
│ └── package.json | ||
├── herman | ||
│ └── package.json | ||
└── elaine | ||
└── package.json | ||
``` | ||
Running `syncpack` will update each `package.json` to use version `'15.6.1'` of `react` in | ||
`dependencies`, `devDependencies`, and `peerDependencies` as needed. | ||
## Installation | ||
``` | ||
npm install --global syncpack | ||
``` | ||
## Usage | ||
### Command Line | ||
``` | ||
Usage: syncpack [options] [pattern] | ||
Options: | ||
-h, --help output usage information | ||
-V, --version output the version number | ||
``` | ||
The default pattern of `'./packages/*/package.json'` can be overridden as follows | ||
`syncpack './**/package.json'` |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
15863
9
235
52
6
4
1