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

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

@ -8,16 +8,28 @@ module.exports = {
init: function(verbose = false) {
config.verbose = verbose;
},
getDependency(depName) {
if (config.verbose) {
console.log(`Looking up npm for ${depName}`);
}
// supports scoped packages, e.g. @user/package
return got(`https://registry.npmjs.org/${depName.replace('/', '%2F')}`, { json: true });
getDependencies: function(packageContents) {
const allDependencies = [];
const dependencyTypes = ['dependencies', 'devDependencies'];
dependencyTypes.forEach(function(depType) {
Object.keys(packageContents[depType]).forEach(function(depName) {
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 = {};
if (!res.body['versions']) {
console.log(depName + ' versions is null');
}
Object.keys(res.body['versions']).forEach(function(version) {
if (stable.is(currentVersion) && !stable.is(version)) {
// Ignore unstable versions, unless the current version is unstable
@ -34,4 +46,47 @@ module.exports = {
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 });
}