Major refactor to ensure synchronous operation

This commit is contained in:
Rhys Arkins 2017-01-07 21:01:32 +01:00
Родитель 693fe47c97
Коммит 887ccfd2a3
2 изменённых файлов: 78 добавлений и 44 удалений

Просмотреть файл

@ -29,47 +29,26 @@ npm.init(config.verbose);
let basePackageJson; let basePackageJson;
github.init(token, repoName, config.baseBranch, config.verbose).then(() => { github.init(token, repoName, config.baseBranch, config.verbose).then(() => {
// Get the base package.json
return github.getFileContents(packageFile); return github.getFileContents(packageFile);
}).then((packageContents) => { }).then((packageContents) => {
basePackageJson = packageContents; // Get the list of possible upgrades
return iterateDependencies('dependencies'); return npm.getAllDependencyUpgrades(packageContents);
}).then(() => { }).then((upgrades) => {
iterateDependencies('devDependencies'); if (config.verbose) {
}).catch(err => { console.log('All upgrades: ' + JSON.stringify(upgrades));
console.log('Error: ' + err);
});
function iterateDependencies(depType) {
const deps = basePackageJson[depType];
if (!deps) {
return;
} }
console.log(`Checking ${Object.keys(deps).length} ${depType}`); // We are processing each upgrade sequentially for two major reasons:
return Object.keys(deps).reduce((total, depName) => { // 1. Reduce chances of GitHub API rate limiting
return total.then(() => { // 2. Edge case collision of branch name, e.g. dependency also listed as dev dependency
if (config.verbose) { return upgrades.reduce((promiseChain, upgrade) => {
console.log(' * ' + depName); return promiseChain.then(() => {
} return updateDependency(upgrade.depType, upgrade.depName, upgrade.currentVersion, upgrade.nextVersion);
const currentVersion = deps[depName].replace(/[^\d.]/g, '');
if (!semver.valid(currentVersion)) {
console.log(`${depName}: Invalid current version`);
return;
}
return npm.getDependencyUpgrades(depName, currentVersion)
.then(allUpgrades => {
if (config.verbose) {
console.log(`All upgrades for ${depName}: ${JSON.stringify(allUpgrades)}`);
}
return Object.keys(allUpgrades).reduce((promiseChain, upgrade) => {
return promiseChain.then(() => {
return updateDependency(depType, depName, currentVersion, allUpgrades[upgrade]);
});
}, Promise.resolve());
});
}); });
}, Promise.resolve()); }, Promise.resolve());
} }).catch(err => {
console.log('updateDependency error: ' + err);
});
function updateDependency(depType, depName, currentVersion, nextVersion) { function updateDependency(depType, depName, currentVersion, nextVersion) {
const nextVersionMajor = semver.major(nextVersion); const nextVersionMajor = semver.major(nextVersion);

Просмотреть файл

@ -8,16 +8,28 @@ module.exports = {
init: function(verbose = false) { init: function(verbose = false) {
config.verbose = verbose; config.verbose = verbose;
}, },
getDependency(depName) { getDependencies: function(packageContents) {
if (config.verbose) { const allDependencies = [];
console.log(`Looking up npm for ${depName}`); const dependencyTypes = ['dependencies', 'devDependencies'];
} dependencyTypes.forEach(function(depType) {
// supports scoped packages, e.g. @user/package Object.keys(packageContents[depType]).forEach(function(depName) {
return got(`https://registry.npmjs.org/${depName.replace('/', '%2F')}`, { json: true }); allDependencies.push({
depType: depType,
depName: depName,
currentVersion: packageContents[depType][depName],
});
});
});
return allDependencies;
}, },
getDependencyUpgrades(depName, currentVersion) {
return this.getDependency(depName).then(res => { getDependencyUpgrades: function(depName, currentVersion) {
return getDependency(depName)
.then(res => {
let allUpgrades = {}; let allUpgrades = {};
if (!res.body['versions']) {
console.log(depName + ' versions is null');
}
Object.keys(res.body['versions']).forEach(function(version) { Object.keys(res.body['versions']).forEach(function(version) {
if (stable.is(currentVersion) && !stable.is(version)) { if (stable.is(currentVersion) && !stable.is(version)) {
// Ignore unstable versions, unless the current version is unstable // Ignore unstable versions, unless the current version is unstable
@ -34,4 +46,47 @@ module.exports = {
return allUpgrades; return allUpgrades;
}); });
}, },
getAllDependencyUpgrades: function(packageContents) {
const allDependencyChecks = [];
const allDependencyUpgrades = [];
const dependencyTypes = ['dependencies', 'devDependencies'];
const getDependencyUpgrades = this.getDependencyUpgrades;
dependencyTypes.forEach(function(depType) {
if (!packageContents[depType]) {
return;
}
Object.keys(packageContents[depType]).forEach(function(depName) {
var currentVersion = packageContents[depType][depName];
if (!semver.valid(currentVersion)) {
if (config.verbose) {
console.log(`${depName}: Skipping invalid version ${currentVersion}`);
}
return;
}
allDependencyChecks.push(getDependencyUpgrades(depName, currentVersion)
.then(res => {
if (Object.keys(res).length > 0) {
console.log(`${depName} upgrades: ${JSON.stringify(res)}`);
Object.keys(res).forEach(function(majorVersion) {
allDependencyUpgrades.push({
depType: depType,
depName: depName,
currentVersion: currentVersion,
nextVersion: res[majorVersion],
});
});
}
}));
});
});
return Promise.all(allDependencyChecks).then(() => {
return allDependencyUpgrades;
});
},
}; };
function getDependency(depName) {
// supports scoped packages, e.g. @user/package
return got(`https://registry.npmjs.org/${depName.replace('/', '%2F')}`, { json: true });
}