misc refactors

This commit is contained in:
silverwind 2024-03-19 01:30:46 +01:00
parent 25fa123af6
commit 553a977d6b
Signed by: silverwind
GPG Key ID: 2E62B41C93869443

@ -87,9 +87,6 @@ const release = argSetToRegexes(parseMixedArg(args.release));
const patch = argSetToRegexes(parseMixedArg(args.patch)); const patch = argSetToRegexes(parseMixedArg(args.patch));
const minor = argSetToRegexes(parseMixedArg(args.minor)); const minor = argSetToRegexes(parseMixedArg(args.minor));
const allowDowngrade = parseMixedArg(args["allow-downgrade"]); const allowDowngrade = parseMixedArg(args["allow-downgrade"]);
const npmrc = rc("npm", {registry: "https://registry.npmjs.org"});
const authTokenOpts = {npmrc, recursive: true};
const githubApiUrl = args.githubapi ? normalizeUrl(args.githubapi) : "https://api.github.com"; const githubApiUrl = args.githubapi ? normalizeUrl(args.githubapi) : "https://api.github.com";
const pypiApiUrl = args.pypiapi ? normalizeUrl(args.pypiapi) : "https://pypi.org"; const pypiApiUrl = args.pypiapi ? normalizeUrl(args.pypiapi) : "https://pypi.org";
@ -112,7 +109,7 @@ function findUpSync(filename, dir) {
return parent === dir ? null : findUpSync(filename, parent); return parent === dir ? null : findUpSync(filename, parent);
} }
function getAuthAndRegistry(name, registry) { function getAuthAndRegistry(name, registry, authTokenOpts, npmrc) {
if (!name.startsWith("@")) { if (!name.startsWith("@")) {
return [registryAuthToken(registry, authTokenOpts), registry]; return [registryAuthToken(registry, authTokenOpts), registry];
} else { } else {
@ -145,9 +142,9 @@ async function doFetch(url, opts) {
return res; return res;
} }
async function fetchNpmInfo(name, type, originalRegistry, agentOpts) { async function fetchNpmInfo(name, type, originalRegistry, agentOpts, authTokenOpts, npmrc) {
const [auth, registry] = getAuthAndRegistry(name, originalRegistry); const [auth, registry] = getAuthAndRegistry(name, originalRegistry, authTokenOpts, npmrc);
const packageName = type === "resolutions" ? resolutionsBasePackage(name) : name; const packageName = type === "resolutions" ? basename(name) : name;
const urlName = packageName.replace(/\//g, "%2f"); const urlName = packageName.replace(/\//g, "%2f");
const url = `${registry}/${urlName}`; const url = `${registry}/${urlName}`;
@ -199,24 +196,17 @@ function getInfoUrl({repository, homepage, info}, registry, name) {
return `https://github.com/${name.replace(/^@/, "")}`; return `https://github.com/${name.replace(/^@/, "")}`;
} else if (repository) { } else if (repository) {
const url = typeof repository === "string" ? repository : repository.url; const url = typeof repository === "string" ? repository : repository.url;
const info = gitInfo(url); const info = gitInfo(url);
const browse = info?.browse?.(); const browse = info?.browse?.();
if (browse) { if (browse) {
infoUrl = browse; // https://github.com/babel/babel infoUrl = browse;
} }
if (infoUrl && repository.directory && info.treepath) { if (infoUrl && repository.directory && info.treepath) {
// https://github.com/babel/babel/tree/HEAD/packages/babel-cli
// HEAD seems to always go to the default branch on GitHub but ideally
// package.json should have a field for source branch
infoUrl = `${infoUrl}/${info.treepath}/HEAD/${repository.directory}`; infoUrl = `${infoUrl}/${info.treepath}/HEAD/${repository.directory}`;
} }
if (!infoUrl && repository?.url && /^https?:/.test(repository.url)) { if (!infoUrl && repository?.url && /^https?:/.test(repository.url)) {
infoUrl = repository.url; infoUrl = repository.url;
} }
if (!infoUrl && url) { if (!infoUrl && url) {
infoUrl = url; infoUrl = url;
} }
@ -226,22 +216,14 @@ function getInfoUrl({repository, homepage, info}, registry, name) {
} }
function finishWithMessage(message) { function finishWithMessage(message) {
if (args.json) { console.info(args.json ? JSON.stringify({message}) : message);
console.info(JSON.stringify({message}));
} else {
console.info(message);
}
doExit(); doExit();
} }
function doExit(err) { function doExit(err) {
if (err) { if (err) {
const error = err.stack || err.message; const error = err.stack ?? err.message;
if (args.json) { console.info(args.json ? JSON.stringify({error}) : red(error));
console.info(JSON.stringify({error}));
} else {
console.info(red(error));
}
} }
process.exit(err ? 1 : 0); process.exit(err ? 1 : 0);
} }
@ -553,7 +535,7 @@ async function checkUrlDep([key, dep], {useGreatest} = {}) {
if (!valid(oldRefBare)) return; if (!valid(oldRefBare)) return;
if (!useGreatest) { if (!useGreatest) {
const lastTag = tags[tags.length - 1]; const lastTag = tags.at(-1);
const lastTagBare = lastTag.replace(/^v/, ""); const lastTagBare = lastTag.replace(/^v/, "");
if (!valid(lastTagBare)) return; if (!valid(lastTagBare)) return;
@ -579,11 +561,6 @@ async function checkUrlDep([key, dep], {useGreatest} = {}) {
} }
} }
function resolutionsBasePackage(name) {
const packages = name.match(/(@[^/]+\/)?([^/]+)/g) || [];
return packages[packages.length - 1];
}
function normalizeRange(range) { function normalizeRange(range) {
const versionMatches = range.match(versionRe); const versionMatches = range.match(versionRe);
if (versionMatches?.length !== 1) return range; if (versionMatches?.length !== 1) return range;
@ -688,8 +665,7 @@ function resolveFiles(filesArg) {
} }
} else { // search for files } else { // search for files
for (const filename of ["package.json", "pyproject.toml"]) { for (const filename of ["package.json", "pyproject.toml"]) {
const pwd = cwd(); const file = findUpSync(filename, cwd());
const file = findUpSync(filename, pwd);
if (file) resolvedFiles.add(resolve(file)); if (file) resolvedFiles.add(resolve(file));
} }
} }
@ -757,12 +733,7 @@ async function main() {
const projectDir = dirname(resolve(file)); const projectDir = dirname(resolve(file));
const filename = basename(file); const filename = basename(file);
let mode; const mode = filename === "pyproject.toml" ? "pypi" : "npm";
if (filename === "pyproject.toml") {
mode = "pypi";
} else {
mode = "npm";
}
filePerMode[mode] = file; filePerMode[mode] = file;
if (!deps[mode]) deps[mode] = {}; if (!deps[mode]) deps[mode] = {};
@ -787,16 +758,17 @@ async function main() {
const exclude = matchersToRegexSet(excludeCli, config?.exclude); const exclude = matchersToRegexSet(excludeCli, config?.exclude);
const agentOpts = {}; const agentOpts = {};
const npmrc = rc("npm", {registry: "https://registry.npmjs.org"});
const authTokenOpts = {npmrc, recursive: true};
if (mode === "npm") { if (mode === "npm") {
if (npmrc["strict-ssl"] === false) { if (npmrc["strict-ssl"] === false) {
agentOpts.rejectUnauthorized = false; agentOpts.rejectUnauthorized = false;
} }
if ("cafile" in npmrc) { if (npmrc?.cafile) {
agentOpts.ca = getCerts(extractCerts(readFileSync(npmrc.cafile, "utf8"))); agentOpts.ca = getCerts(extractCerts(readFileSync(npmrc.cafile, "utf8")));
} }
if ("ca" in npmrc) { if (npmrc?.ca) {
const cas = Array.isArray(npmrc.ca) ? npmrc.ca : [npmrc.ca]; agentOpts.ca = getCerts(Array.isArray(npmrc.ca) ? npmrc.ca : [npmrc.ca].map(ca => extractCerts(ca)));
agentOpts.ca = getCerts(cas.map(ca => extractCerts(ca)));
} }
} }
@ -875,7 +847,7 @@ async function main() {
const entries = await pAll(Object.keys(deps[mode]).map(key => () => { const entries = await pAll(Object.keys(deps[mode]).map(key => () => {
const [type, name] = key.split(sep); const [type, name] = key.split(sep);
if (mode === "npm") { if (mode === "npm") {
return fetchNpmInfo(name, type, registry, agentOpts); return fetchNpmInfo(name, type, registry, agentOpts, authTokenOpts, npmrc);
} else { } else {
return fetchPypiInfo(name, type, agentOpts); return fetchPypiInfo(name, type, agentOpts);
} }