Merge pull request #25330 from backstage/blam/fix-cli-bump

This commit is contained in:
Ben Lambert
2024-06-19 19:38:42 +02:00
committed by GitHub
2 changed files with 18 additions and 67 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Fix issue with CLI that was preventing upgrading from 1.28
+13 -67
View File
@@ -98,24 +98,6 @@ export class Lockfile {
return Lockfile.parse(lockfileContents);
}
static #getRangesFromDataKey(key: string): string[] {
const [, name, ranges] = key.match(ENTRY_PATTERN) ?? [];
if (!name) {
throw new Error(`Failed to parse yarn.lock entry '${key}'`);
}
return ranges.split(/\s*,\s*/).map(rangePart => {
let range = rangePart;
if (range.startsWith(`${name}@`)) {
range = range.slice(`${name}@`.length);
}
if (range.startsWith('npm:')) {
range = range.slice('npm:'.length);
}
return range;
});
}
static parse(content: string) {
const legacy = LEGACY_REGEX.test(content);
@@ -131,7 +113,7 @@ export class Lockfile {
for (const [key, value] of Object.entries(data)) {
if (SPECIAL_OBJECT_KEYS.includes(key)) continue;
const [, name] = ENTRY_PATTERN.exec(key) ?? [];
const [, name, ranges] = ENTRY_PATTERN.exec(key) ?? [];
if (!name) {
throw new Error(`Failed to parse yarn.lock entry '${key}'`);
}
@@ -141,8 +123,13 @@ export class Lockfile {
queries = [];
packages.set(name, queries);
}
const ranges = Lockfile.#getRangesFromDataKey(key);
for (const range of ranges) {
for (let range of ranges.split(/\s*,\s*/)) {
if (range.startsWith(`${name}@`)) {
range = range.slice(`${name}@`.length);
}
if (range.startsWith('npm:')) {
range = range.slice('npm:'.length);
}
queries.push({ range, version: value.version, dataKey: key });
}
}
@@ -289,34 +276,9 @@ export class Lockfile {
}
remove(name: string, range: string): boolean {
const simpleQuery = `${name}@${range}`;
const query = this.getEntryOf(name, range);
const query = `${name}@${range}`;
const existed = Boolean(this.data[query]);
if (simpleQuery === query) {
// Single-versioned entry, just delete
delete this.data[query];
} else {
// Remove this version from the entry key. This modifies the key, so the
// package queries' <dataKey> needs to be updated too.
const newRanges = Lockfile.#getRangesFromDataKey(query).filter(
q => q !== simpleQuery,
);
const newQuery = newRanges.join(', ');
// Replace the entry with a new one without this particular range
const entry = this.data[query];
delete this.data[query];
this.data[newQuery] = entry;
// Fix all package queries pointing to the old query
this.packages.get(name)?.forEach(q => {
if (q.dataKey === query) {
q.dataKey = newQuery;
}
});
}
delete this.data[query];
const newEntries = this.packages.get(name)?.filter(e => e.range !== range);
if (newEntries) {
@@ -326,35 +288,19 @@ export class Lockfile {
return existed;
}
getEntryOf(name: string, range: string) {
const query = this.packages.get(name)?.find(q => q.range === range);
if (!query) {
throw new Error(`No entry data for ${name}@${range}`);
}
return query.dataKey;
}
/** Modifies the lockfile by bumping packages to the suggested versions */
replaceVersions(results: AnalyzeResultNewVersion[]) {
// When replacing versions, we might replace the same version multiple times,
// as a query may contain multiple versions. This keeps the original version,
// to ensure we don't make mistakes.
const oldVersions = Object.fromEntries(
Object.entries(this.data).map(([key, val]) => [key, val.version]),
);
for (const { name, range, oldVersion, newVersion } of results) {
const query = this.getEntryOf(name, range);
const query = `${name}@${range}`;
// Update the backing data
const entryData = this.data[query];
if (!entryData) {
throw new Error(`No entry data for ${query}`);
}
if (oldVersions[query] !== oldVersion) {
if (entryData.version !== oldVersion) {
throw new Error(
`Expected existing version data for ${query} to be ${oldVersion}, was ${oldVersions[query]}`,
`Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`,
);
}