renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
206 lines • 8.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractPackageFile = extractPackageFile;
exports.extractAllPackageFiles = extractAllPackageFiles;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const global_1 = require("../../../../config/global");
const logger_1 = require("../../../../logger");
const fs_1 = require("../../../../util/fs");
const regex_1 = require("../../../../util/regex");
const npm_1 = require("../../../datasource/npm");
const dependency_1 = require("./common/dependency");
const package_file_1 = require("./common/package-file");
const pnpm_1 = require("./pnpm");
const post_1 = require("./post");
const yarn_1 = require("./yarn");
const yarnrc_1 = require("./yarnrc");
function hasMultipleLockFiles(lockFiles) {
return Object.values(lockFiles).filter(is_1.default.string).length > 1;
}
async function extractPackageFile(content, packageFile, config) {
logger_1.logger.trace(`npm.extractPackageFile(${packageFile})`);
logger_1.logger.trace({ content });
let packageJson;
try {
packageJson = JSON.parse(content);
}
catch {
logger_1.logger.debug({ packageFile }, `Invalid JSON`);
return null;
}
const res = (0, package_file_1.extractPackageJson)(packageJson, packageFile);
if (!res) {
return null;
}
let workspacesPackages;
if (is_1.default.array(packageJson.workspaces)) {
workspacesPackages = packageJson.workspaces;
}
else {
workspacesPackages = packageJson.workspaces?.packages;
}
const lockFiles = {
yarnLock: 'yarn.lock',
packageLock: 'package-lock.json',
shrinkwrapJson: 'npm-shrinkwrap.json',
pnpmShrinkwrap: 'pnpm-lock.yaml',
};
for (const [key, val] of Object.entries(lockFiles)) {
const filePath = (0, fs_1.getSiblingFileName)(packageFile, val);
if (await (0, fs_1.readLocalFile)(filePath, 'utf8')) {
lockFiles[key] = filePath;
}
else {
lockFiles[key] = undefined;
}
}
lockFiles.npmLock = lockFiles.packageLock ?? lockFiles.shrinkwrapJson;
delete lockFiles.packageLock;
delete lockFiles.shrinkwrapJson;
if (hasMultipleLockFiles(lockFiles)) {
logger_1.logger.warn('Updating multiple npm lock files is deprecated and support will be removed in future versions.');
}
let npmrc;
const npmrcFileName = await (0, fs_1.findLocalSiblingOrParent)(packageFile, '.npmrc');
if (npmrcFileName) {
let repoNpmrc = await (0, fs_1.readLocalFile)(npmrcFileName, 'utf8');
if (is_1.default.string(repoNpmrc)) {
if (is_1.default.string(config.npmrc) && !config.npmrcMerge) {
logger_1.logger.debug({ npmrcFileName }, 'Repo .npmrc file is ignored due to config.npmrc with config.npmrcMerge=false');
npmrc = config.npmrc;
}
else {
npmrc = config.npmrc ?? '';
if (npmrc.length) {
if (!npmrc.endsWith('\n')) {
npmrc += '\n';
}
}
if (repoNpmrc?.includes('package-lock')) {
logger_1.logger.debug('Stripping package-lock setting from .npmrc');
repoNpmrc = repoNpmrc.replace((0, regex_1.regEx)(/(^|\n)package-lock.*?(\n|$)/g), '\n');
}
if (repoNpmrc.includes('=${') && !global_1.GlobalConfig.get('exposeAllEnv')) {
logger_1.logger.debug({ npmrcFileName }, 'Stripping .npmrc file of lines with variables');
repoNpmrc = repoNpmrc
.split(regex_1.newlineRegex)
.filter((line) => !line.includes('=${'))
.join('\n');
}
npmrc += repoNpmrc;
}
}
}
else if (is_1.default.string(config.npmrc)) {
npmrc = config.npmrc;
}
const yarnrcYmlFileName = await (0, fs_1.findLocalSiblingOrParent)(packageFile, '.yarnrc.yml');
const yarnZeroInstall = yarnrcYmlFileName
? await (0, yarn_1.isZeroInstall)(yarnrcYmlFileName)
: false;
let yarnConfig = null;
const repoYarnrcYml = yarnrcYmlFileName
? await (0, fs_1.readLocalFile)(yarnrcYmlFileName, 'utf8')
: null;
if (is_1.default.string(repoYarnrcYml) && repoYarnrcYml.trim().length > 0) {
yarnConfig = (0, yarnrc_1.loadConfigFromYarnrcYml)(repoYarnrcYml);
}
const legacyYarnrcFileName = await (0, fs_1.findLocalSiblingOrParent)(packageFile, '.yarnrc');
const repoLegacyYarnrc = legacyYarnrcFileName
? await (0, fs_1.readLocalFile)(legacyYarnrcFileName, 'utf8')
: null;
if (is_1.default.string(repoLegacyYarnrc) && repoLegacyYarnrc.trim().length > 0) {
yarnConfig = (0, yarnrc_1.loadConfigFromLegacyYarnrc)(repoLegacyYarnrc);
}
if (res.deps.length === 0) {
logger_1.logger.debug('Package file has no deps');
if (!(!!res.managerData?.packageJsonName ||
!!res.packageFileVersion ||
!!npmrc ||
workspacesPackages)) {
logger_1.logger.debug('Skipping file');
return null;
}
}
let skipInstalls = config.skipInstalls;
if (skipInstalls === null) {
const hasFancyRefs = !!res.deps.some((dep) => !!dep.currentValue?.startsWith('file:') ||
!!dep.currentValue?.startsWith('npm:'));
if ((hasFancyRefs && !!lockFiles.npmLock) || yarnZeroInstall) {
// https://github.com/npm/cli/issues/1432
// Explanation:
// - npm install --package-lock-only is buggy for transitive deps in file: and npm: references
// - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already
// - Also, do not skip install if Yarn zero-install is used
logger_1.logger.debug('Automatically setting skipInstalls to false');
skipInstalls = false;
}
else {
skipInstalls = true;
}
}
const extractedConstraints = (0, dependency_1.getExtractedConstraints)(res.deps);
if (yarnConfig) {
for (const dep of res.deps) {
if (dep.depName) {
const registryUrlFromYarnConfig = (0, yarnrc_1.resolveRegistryUrl)(dep.packageName ?? dep.depName, yarnConfig);
if (registryUrlFromYarnConfig && dep.datasource === npm_1.NpmDatasource.id) {
dep.registryUrls = [registryUrlFromYarnConfig];
}
}
}
}
return {
...res,
npmrc,
managerData: {
...res.managerData,
...lockFiles,
yarnZeroInstall,
hasPackageManager: is_1.default.nonEmptyStringAndNotWhitespace(packageJson.packageManager),
workspacesPackages,
npmrcFileName, // store npmrc file name so we can later tell if it came from the workspace or not
},
skipInstalls,
extractedConstraints,
};
}
async function extractAllPackageFiles(config, packageFiles) {
const npmFiles = [];
for (const packageFile of packageFiles) {
const content = await (0, fs_1.readLocalFile)(packageFile, 'utf8');
// istanbul ignore else
if (content) {
// pnpm workspace files are their own package file, defined via managerFilePatterns.
// We duck-type the content here, to allow users to rename the file itself.
const parsedPnpmWorkspaceYaml = (0, pnpm_1.tryParsePnpmWorkspaceYaml)(content);
if (parsedPnpmWorkspaceYaml.success) {
logger_1.logger.trace({ packageFile }, `Extracting file as a pnpm workspace YAML file`);
const deps = await (0, pnpm_1.extractPnpmWorkspaceFile)(parsedPnpmWorkspaceYaml.data, packageFile);
if (deps) {
npmFiles.push({
...deps,
packageFile,
});
}
}
else {
logger_1.logger.trace({ packageFile }, `Extracting as a package.json file`);
const deps = await extractPackageFile(content, packageFile, config);
if (deps) {
npmFiles.push({
...deps,
packageFile,
});
}
}
}
else {
logger_1.logger.debug({ packageFile }, `No content found`);
}
}
await (0, post_1.postExtract)(npmFiles);
return npmFiles;
}
//# sourceMappingURL=index.js.map