Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions scripts/registry-lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export interface IndexMetadata {
license?: string;
source?: string;
fetched_at?: string;
repository_source?: string;
}

export interface IndexPlugin {
Expand Down Expand Up @@ -1659,9 +1660,19 @@ export function buildIndex(
previousById.set(plugin.id, plugin);
}
const plugins = entries
.map(({ entry, official }) =>
toIndexPlugin(entry, official, previousById.get(entry.id)?.metadata),
)
.map(({ entry, official }) => {
const previousPlugin = previousById.get(entry.id);
let metadata = previousPlugin?.metadata;
// Invalidate metadata if repository has changed
if (
metadata?.repository_source !== undefined &&
normalizeRepositoryUrl(metadata.repository_source) !==
normalizeRepositoryUrl(entry.repository)
) {
metadata = undefined;
}
return toIndexPlugin(entry, official, metadata);
})
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));

const generatedAt =
Expand Down
7 changes: 5 additions & 2 deletions scripts/sync-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export function manifestMetadata(
text: string,
source: string,
expectedId: string,
repositoryUrl: string,
previous: IndexMetadata | undefined,
fetchedAt: string,
): ManifestMetadataResult {
Expand All @@ -193,7 +194,7 @@ export function manifestMetadata(
};
}

const metadata: IndexMetadata = { source };
const metadata: IndexMetadata = { source, repository_source: repositoryUrl };
if (typeof plugin.version === "string") metadata.version = plugin.version;
if (typeof plugin.description === "string") {
metadata.description = plugin.description;
Expand All @@ -207,7 +208,8 @@ export function manifestMetadata(
previous.version === metadata.version &&
previous.description === metadata.description &&
previous.license === metadata.license &&
previous.source === metadata.source;
previous.source === metadata.source &&
previous.repository_source === metadata.repository_source;
metadata.fetched_at =
unchanged && previous.fetched_at ? previous.fetched_at : fetchedAt;
return { metadata };
Expand Down Expand Up @@ -281,6 +283,7 @@ async function main(): Promise<number> {
text,
source,
entry.id,
entry.repository,
existing,
nowUtcSeconds(),
);
Expand Down
12 changes: 7 additions & 5 deletions scripts/validate-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,13 @@ function checkSubmoduleMapping(entries: LoadedEntry[]): Diagnostic[] {
}

/**
* Read recorded submodule pins (`plugins/<name>` to commit SHA) from
* `git submodule status`, which works without initialized submodules.
* Returns null when git cannot report the pins.
* Read recorded submodule gitlinks (`plugins/<name>` to commit SHA) from
* `git ls-tree HEAD`, which reads the gitlinks recorded in the parent commit
* rather than checkout status. Returns null when git cannot report the pins.
*/
function readSubmodulePins(): Map<string, string> | null {
const result = Bun.spawnSync({
cmd: ["git", "submodule", "status"],
cmd: ["git", "ls-tree", "HEAD", "plugins"],
cwd: REPO_ROOT,
stdout: "pipe",
stderr: "pipe",
Expand All @@ -410,7 +410,9 @@ function readSubmodulePins(): Map<string, string> | null {
if (result.exitCode !== 0) return null;
const pins = new Map<string, string>();
for (const line of result.stdout.toString().split("\n")) {
const match = line.match(/^[ +\-U]([0-9a-f]{40}) (\S+)/);
// Format: <mode> <type> <sha> <path>
// Example: 160000 commit abc123... plugins/activity
const match = line.match(/^160000 commit ([0-9a-f]{40})\t(.+)$/);
const sha = match?.[1];
const path = match?.[2];
if (sha !== undefined && path !== undefined) pins.set(path, sha);
Expand Down
72 changes: 72 additions & 0 deletions tests/registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1547,12 +1547,14 @@ license = "MIT"
text,
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
"sample.plugin",
"https://github.com/example/sample-plugin",
undefined,
"2024-01-01T00:00:00Z",
);
expect(result.metadata).toEqual({
source:
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
repository_source: "https://github.com/example/sample-plugin",
version: "1.0.0",
description: "A sample plugin",
license: "MIT",
Expand All @@ -1571,6 +1573,7 @@ version = "1.0.0"
text,
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
"sample.plugin",
"https://github.com/example/sample-plugin",
undefined,
"2024-01-01T00:00:00Z",
);
Expand All @@ -1587,6 +1590,7 @@ version = "1.0.0"
text,
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
"sample.plugin",
"https://github.com/example/sample-plugin",
undefined,
"2024-01-01T00:00:00Z",
);
Expand All @@ -1600,6 +1604,7 @@ version = "1.0.0"
text,
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
"sample.plugin",
"https://github.com/example/sample-plugin",
undefined,
"2024-01-01T00:00:00Z",
);
Expand All @@ -1618,6 +1623,7 @@ license = "MIT"
const previous = {
source:
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
repository_source: "https://github.com/example/sample-plugin",
version: "1.0.0",
description: "A sample plugin",
license: "MIT",
Expand All @@ -1627,6 +1633,7 @@ license = "MIT"
text,
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
"sample.plugin",
"https://github.com/example/sample-plugin",
previous,
"2024-01-02T00:00:00Z",
);
Expand All @@ -1644,6 +1651,7 @@ license = "MIT"
const previous = {
source:
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
repository_source: "https://github.com/example/sample-plugin",
version: "1.0.0",
description: "A sample plugin",
license: "MIT",
Expand All @@ -1653,11 +1661,75 @@ license = "MIT"
text,
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
"sample.plugin",
"https://github.com/example/sample-plugin",
previous,
"2024-01-02T00:00:00Z",
);
expect(result.metadata?.fetched_at).toBe("2024-01-02T00:00:00Z");
});

test("invalidates metadata when repository changes", () => {
const entries = [loaded(baseEntry)];
const previous: RegistryIndex = {
schema_version: 1,
generated_at: "2024-01-01T00:00:00Z",
plugins: [
{
id: "sample.plugin",
name: "Sample Plugin",
kind: "plugin",
repository: "https://github.com/example/sample-plugin",
official: false,
signature_status: "unsigned",
metadata: {
version: "1.0.0",
description: "A sample plugin",
source:
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
repository_source: "https://github.com/old-owner/sample-plugin",
fetched_at: "2024-01-01T00:00:00Z",
},
},
],
};
const index = buildIndex(entries, previous);
expect(index.plugins[0]?.metadata).toBeUndefined();
});

test("preserves metadata when repository URL has equivalent spelling", () => {
const entries = [loaded(baseEntry)];
const previous: RegistryIndex = {
schema_version: 1,
generated_at: "2024-01-01T00:00:00Z",
plugins: [
{
id: "sample.plugin",
name: "Sample Plugin",
kind: "plugin",
repository: "https://github.com/example/sample-plugin",
official: false,
signature_status: "unsigned",
metadata: {
version: "1.0.0",
description: "A sample plugin",
source:
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
repository_source: "https://github.com/example/sample-plugin.git",
fetched_at: "2024-01-01T00:00:00Z",
},
},
],
};
const index = buildIndex(entries, previous);
expect(index.plugins[0]?.metadata).toEqual({
version: "1.0.0",
description: "A sample plugin",
source:
"https://raw.githubusercontent.com/example/sample-plugin/HEAD/bitty-plugin.toml",
repository_source: "https://github.com/example/sample-plugin.git",
fetched_at: "2024-01-01T00:00:00Z",
});
});
});

describe("bounded response reading", () => {
Expand Down
Loading