2017-06-29 05:29:41 +00:00
|
|
|
const logger = require('../../logger');
|
2017-06-02 06:29:36 +00:00
|
|
|
const fs = require('fs');
|
|
|
|
const cp = require('child_process');
|
|
|
|
const tmp = require('tmp');
|
|
|
|
const path = require('path');
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
generateLockFile,
|
|
|
|
getLockFile,
|
|
|
|
maintainLockFile,
|
|
|
|
};
|
|
|
|
|
|
|
|
async function generateLockFile(newPackageJson, npmrcContent) {
|
|
|
|
logger.debug('Generating new package-lock.json file');
|
|
|
|
const tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
|
|
|
let packageLock;
|
|
|
|
try {
|
|
|
|
fs.writeFileSync(path.join(tmpDir.name, 'package.json'), newPackageJson);
|
|
|
|
if (npmrcContent) {
|
|
|
|
fs.writeFileSync(path.join(tmpDir.name, '.npmrc'), npmrcContent);
|
|
|
|
}
|
|
|
|
logger.debug('Spawning npm install');
|
|
|
|
const result = cp.spawnSync('npm', ['install'], {
|
|
|
|
cwd: tmpDir.name,
|
|
|
|
shell: true,
|
|
|
|
});
|
|
|
|
logger.debug(String(result.stdout));
|
|
|
|
logger.debug(String(result.stderr));
|
|
|
|
packageLock = fs.readFileSync(path.join(tmpDir.name, 'package-lock.json'));
|
2017-06-05 17:22:39 +00:00
|
|
|
} catch (error) /* istanbul ignore next */ {
|
|
|
|
try {
|
|
|
|
tmpDir.removeCallback();
|
|
|
|
} catch (err2) {
|
|
|
|
logger.warn(`Failed to remove tmpDir ${tmpDir.name}`);
|
|
|
|
}
|
2017-06-02 06:29:36 +00:00
|
|
|
throw error;
|
|
|
|
}
|
2017-06-05 17:22:39 +00:00
|
|
|
try {
|
|
|
|
tmpDir.removeCallback();
|
|
|
|
} catch (err2) {
|
|
|
|
logger.warn(`Failed to remove tmpDir ${tmpDir.name}`);
|
|
|
|
}
|
2017-06-02 06:29:36 +00:00
|
|
|
return packageLock;
|
|
|
|
}
|
|
|
|
|
2017-06-28 20:33:27 +00:00
|
|
|
async function getLockFile(packageFile, packageContent, api, npmVersion) {
|
2017-06-02 06:29:36 +00:00
|
|
|
// Detect if a package-lock.json file is in use
|
|
|
|
const packageLockFileName = path.join(
|
|
|
|
path.dirname(packageFile),
|
|
|
|
'package-lock.json'
|
|
|
|
);
|
|
|
|
if (!await api.getFileContent(packageLockFileName)) {
|
|
|
|
return null;
|
|
|
|
}
|
2017-06-28 20:33:27 +00:00
|
|
|
if (npmVersion === '') {
|
|
|
|
throw new Error(
|
|
|
|
'Need to generate package-lock.json but npm is not installed'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// TODO: have a more forwards-compatible check
|
|
|
|
if (npmVersion[0] !== '5') {
|
|
|
|
throw new Error(
|
|
|
|
`Need to generate package-lock.json but npm version is "${npmVersion}"`
|
|
|
|
);
|
|
|
|
}
|
2017-06-02 06:29:36 +00:00
|
|
|
// Copy over custom config commitFiles
|
|
|
|
const npmrcContent = await api.getFileContent('.npmrc');
|
|
|
|
// Generate package-lock.json using shell command
|
|
|
|
const newPackageLockContent = await module.exports.generateLockFile(
|
|
|
|
packageContent,
|
|
|
|
npmrcContent
|
|
|
|
);
|
|
|
|
// Return file object
|
|
|
|
return {
|
|
|
|
name: packageLockFileName,
|
|
|
|
contents: newPackageLockContent,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async function maintainLockFile(inputConfig) {
|
|
|
|
logger.debug(`maintainLockFile(${JSON.stringify(inputConfig)})`);
|
|
|
|
const packageContent = await inputConfig.api.getFileContent(
|
|
|
|
inputConfig.packageFile
|
|
|
|
);
|
|
|
|
const packageLockFileName = path.join(
|
|
|
|
path.dirname(inputConfig.packageFile),
|
|
|
|
'package-lock.json'
|
|
|
|
);
|
|
|
|
logger.debug(`Checking for ${packageLockFileName}`);
|
|
|
|
const existingPackageLock = await inputConfig.api.getFileContent(
|
|
|
|
packageLockFileName
|
|
|
|
);
|
2017-06-20 15:57:04 +00:00
|
|
|
logger.trace(`existingPackageLock:\n${existingPackageLock}`);
|
2017-06-02 06:29:36 +00:00
|
|
|
if (!existingPackageLock) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
logger.debug('Found existing package-lock.json file');
|
|
|
|
const newPackageLock = await module.exports.getLockFile(
|
|
|
|
inputConfig.packageFile,
|
|
|
|
packageContent,
|
|
|
|
inputConfig.api
|
|
|
|
);
|
2017-06-20 15:57:04 +00:00
|
|
|
logger.trace(`newPackageLock:\n${newPackageLock.contents}`);
|
2017-06-02 06:29:36 +00:00
|
|
|
if (existingPackageLock.toString() === newPackageLock.contents.toString()) {
|
|
|
|
logger.debug('npm lock file does not need updating');
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
logger.debug('npm lock needs updating');
|
|
|
|
return newPackageLock;
|
|
|
|
}
|