renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
122 lines • 5.59 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractPackageFile = extractPackageFile;
const logger_1 = require("../../../logger");
const fs_1 = require("../../../util/fs");
const regex_1 = require("../../../util/regex");
const git_refs_1 = require("../../datasource/git-refs");
const nixpkgs_1 = require("../../versioning/nixpkgs");
const schema_1 = require("./schema");
const nixpkgsRegex = (0, regex_1.regEx)(/"github:nixos\/nixpkgs(\/(?<ref>[a-z0-9-.]+))?"/i);
// as documented upstream
// https://github.com/NixOS/nix/blob/master/doc/manual/source/protocols/tarball-fetcher.md#gitea-and-forgejo-support
const lockableHTTPTarballProtocol = (0, regex_1.regEx)('^https://(?<domain>[^/]+)/(?<owner>[^/]+)/(?<repo>[^/]+)/archive/(?<rev>.+).tar.gz$');
async function extractPackageFile(content, packageFile) {
const packageLockFile = (0, fs_1.getSiblingFileName)(packageFile, 'flake.lock');
const lockContents = await (0, fs_1.readLocalFile)(packageLockFile, 'utf8');
logger_1.logger.trace(`nix.extractPackageFile(${packageLockFile})`);
const deps = [];
const match = nixpkgsRegex.exec(content);
if (match?.groups) {
const { ref } = match.groups;
deps.push({
depName: 'nixpkgs',
currentValue: ref,
datasource: git_refs_1.GitRefsDatasource.id,
packageName: 'https://github.com/NixOS/nixpkgs',
versioning: nixpkgs_1.id,
});
}
const flakeLockParsed = schema_1.NixFlakeLock.safeParse(lockContents);
if (!flakeLockParsed.success) {
logger_1.logger.debug({ packageLockFile, error: flakeLockParsed.error }, `invalid flake.lock file`);
return null;
}
const flakeLock = flakeLockParsed.data;
const rootInputs = flakeLock.nodes.root.inputs;
if (!rootInputs) {
logger_1.logger.debug({ packageLockFile, error: flakeLockParsed.error }, `flake.lock is missing "root" node`);
if (deps.length) {
return { deps };
}
return null;
}
for (const [depName, flakeInput] of Object.entries(flakeLock.nodes)) {
// the root input is a magic string for the entrypoint and only references other flake inputs
if (depName === 'root') {
continue;
}
// skip all locked and transitivie nodes as they cannot be updated by regular means
if (!(depName in rootInputs)) {
continue;
}
const flakeLocked = flakeInput.locked;
const flakeOriginal = flakeInput.original;
// istanbul ignore if: if we are not in a root node then original and locked always exist which cannot be easily expressed in the type
if (flakeLocked === undefined || flakeOriginal === undefined) {
logger_1.logger.debug({ packageLockFile, flakeInput }, `Found empty flake input, skipping`);
continue;
}
// indirect inputs cannot be reliable updated because they depend on the flake registry
if (flakeOriginal.type === 'indirect') {
continue;
}
switch (flakeLocked.type) {
case 'github':
deps.push({
depName,
currentValue: flakeOriginal.ref,
currentDigest: flakeLocked.rev,
datasource: git_refs_1.GitRefsDatasource.id,
packageName: `https://${flakeOriginal.host ?? 'github.com'}/${flakeOriginal.owner}/${flakeOriginal.repo}`,
});
break;
case 'gitlab':
deps.push({
depName,
currentValue: flakeOriginal.ref,
currentDigest: flakeLocked.rev,
datasource: git_refs_1.GitRefsDatasource.id,
packageName: `https://${flakeOriginal.host ?? 'gitlab.com'}/${decodeURIComponent(flakeOriginal.owner)}/${flakeOriginal.repo}`,
});
break;
case 'git':
deps.push({
depName,
currentValue: flakeOriginal.ref,
currentDigest: flakeLocked.rev,
datasource: git_refs_1.GitRefsDatasource.id,
packageName: flakeOriginal.url,
});
break;
case 'sourcehut':
deps.push({
depName,
currentValue: flakeOriginal.ref,
currentDigest: flakeLocked.rev,
datasource: git_refs_1.GitRefsDatasource.id,
packageName: `https://${flakeOriginal.host ?? 'git.sr.ht'}/${flakeOriginal.owner}/${flakeOriginal.repo}`,
});
break;
case 'tarball':
deps.push({
depName,
currentValue: flakeLocked.ref,
currentDigest: flakeLocked.rev,
datasource: git_refs_1.GitRefsDatasource.id,
// type tarball always contains this link
packageName: flakeOriginal.url.replace(lockableHTTPTarballProtocol, 'https://$<domain>/$<owner>/$<repo>'),
});
break;
// istanbul ignore next: just a safeguard
default:
logger_1.logger.debug({ packageLockFile }, `Unknown flake.lock type "${flakeLocked.type}", skipping`);
break;
}
}
if (deps.length) {
return { deps };
}
return null;
}
//# sourceMappingURL=extract.js.map