From be181c33fcb2de4c6e9444ab785f690c7dcdc466 Mon Sep 17 00:00:00 2001 From: Lyrkan Date: Sun, 7 Oct 2018 03:29:47 +0200 Subject: [PATCH] Add new Travis jobs to test lowest/highest versions of all the dependencies --- .travis.yml | 15 ++++ scripts/force-lowest-dependencies.js | 123 +++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100755 scripts/force-lowest-dependencies.js diff --git a/.travis.yml b/.travis.yml index 4c3b9ba1..4077ac49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,21 @@ cache: matrix: include: + - name: 'Lowest versions of the dependencies' + os: linux + node_js: "10" + env: JOB_PART=test + install: + - rm yarn.lock + - node ./scripts/force-lowest-dependencies + - yarn + - name: 'Highest versions of the dependencies' + os: linux + node_js: "10" + env: JOB_PART=test + install: + - rm yarn.lock + - yarn - os: linux node_js: "10" env: JOB_PART=travis:lint diff --git a/scripts/force-lowest-dependencies.js b/scripts/force-lowest-dependencies.js new file mode 100755 index 00000000..1a232175 --- /dev/null +++ b/scripts/force-lowest-dependencies.js @@ -0,0 +1,123 @@ +/* + * This file is part of the Symfony Webpack Encore package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const fs = require('fs'); +const childProcess = require('child_process'); + +function getLowestVersion(dependency, range) { + return new Promise((resolve, reject) => { + childProcess.exec( + `npm view "${dependency}@${range}" version`, + { encoding: 'utf-8' }, + (error, stdout) => { + if (error) { + reject(`Could not retrieve versions list for "${dependency}@${range}"`); + } + + const versions = stdout + .split('\n') + .filter(line => line); + + if (versions.length === 0) { + reject(`Could not find a lowest version for "${dependency}@${range}"`); + } + + const parts = versions[0].split(' '); + + // If there is only one version available that version + // is directly printed as the output of npm view. + if (parts.length === 1) { + resolve([dependency, parts[0]]); + } + + // If multiple versions are available then it outputs + // multiple lines matching the following format: + // @ '' + if (parts.length === 2) { + resolve([dependency, parts[1].replace(/'/g, '')]); + } + + reject(`Unexpected response for "${dependency}@${range}": ${versions[0]}`); + } + ); + }); +} + +fs.readFile('package.json', (error, data) => { + if (error) { + throw error; + } + + const packageInfo = JSON.parse(data); + + const dependencyPromises = []; + if (packageInfo.dependencies) { + for (const dependency in packageInfo.dependencies) { + dependencyPromises.push(getLowestVersion( + dependency, + packageInfo.dependencies[dependency] + )); + } + } + + const devDependencyPromises = []; + if (packageInfo.devDependencies) { + for (const devDependency in packageInfo.devDependencies) { + devDependencyPromises.push(getLowestVersion( + devDependency, + packageInfo.devDependencies[devDependency] + )); + } + } + + const dependenciesUpdate = Promise.all(dependencyPromises).then(versions => { + versions.forEach(version => { + packageInfo.dependencies[version[0]] = version[1]; + }); + }); + + const devDependenciesUpdate = Promise.all(devDependencyPromises).then(versions => { + versions.forEach(version => { + packageInfo.devDependencies[version[0]] = version[1]; + }); + }); + + // Once all the lowest versions have been resolved, update the + // package.json file accordingly. + Promise + .all([dependenciesUpdate, devDependenciesUpdate]) + .then(() => new Promise((resolve, reject) => { + fs.writeFile('package.json', JSON.stringify(packageInfo, null, 2), (error) => { + if (error) { + reject(error); + } + + resolve(); + }); + })) + .then(() => { + console.log('Updated package.json file with lowest dependency versions: '); + + console.log('Dependencies:'); + for (const dependency in packageInfo.dependencies) { + console.log(` - ${dependency}: ${packageInfo.dependencies[dependency]}`); + } + + console.log('Dev dependencies:'); + for (const dependency in packageInfo.devDependencies) { + console.log(` - ${dependency}: ${packageInfo.devDependencies[dependency]}`); + } + }) + .catch(error => { + console.error(error); + process.exit(1); // eslint-disable-line + }); +});