Skip to content

Commit

Permalink
refactor: richly model metadata file
Browse files Browse the repository at this point in the history
  • Loading branch information
kormide committed Nov 6, 2023
1 parent c65fbad commit e03d8b9
Show file tree
Hide file tree
Showing 6 changed files with 588 additions and 85 deletions.
64 changes: 64 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
declare global {
namespace jest {
interface Matchers<R> {
toThrowErrorContaining<T extends Error>(
errorType: new (...args: any[]) => T,
message: string
): R;
}
}
}

expect.extend({
toThrowErrorContaining<T extends Error>(
func: Function,
errorType: new (...args: any[]) => T,
message: string
) {
try {
func();
} catch (e) {
if (!(e instanceof errorType)) {
return {
pass: false,
message: () => `\
Expected error to throw:
${errorType}
But instead it threw:
${e.constructor}
`,
};
}

if (!e.message.includes(message)) {
return {
pass: false,
message: () => `\
Expected error message to contain:
${message}
But instead it was:
${e.message}
`,
};
}

return {
pass: true,
message: () => "",
};
}

return {
pass: false,
message: () => "Expected function to throw but it did not",
};
},
});

export default undefined;
28 changes: 26 additions & 2 deletions src/domain/create-entry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import {
import { expectThrownError } from "../test/util";
import {
CreateEntryService,
MetadataParseError,
VersionAlreadyPublishedError,
} from "./create-entry";
import { CANONICAL_BCR } from "./find-registry-fork";
import { computeIntegrityHash } from "./integrity-hash";
import { MetadataFileError } from "./metadata-file";
import { ModuleFile } from "./module-file";
import { ReleaseArchive } from "./release-archive";
import { Repository } from "./repository";
Expand Down Expand Up @@ -303,6 +303,30 @@ describe("createEntryFiles", () => {
).toEqual(JSON.parse(writtenMetadataContent));
});

test("does not include versions in the template metadata file", async () => {
// ...because the canonical released versions comes from the BCR
mockRulesetFiles({ metadataVersions: ["0.0.1"] });

const tag = "v1.2.3";
const rulesetRepo = await RulesetRepository.create("repo", "owner", tag);
const bcrRepo = CANONICAL_BCR;

mockBcrMetadataExists(rulesetRepo, bcrRepo, "fake_ruleset", true);
mockBcrMetadataFile(rulesetRepo, bcrRepo, "fake_ruleset", {
versions: ["1.0.0"],
});

await createEntryService.createEntryFiles(rulesetRepo, bcrRepo, tag, ".");

const writeMetadataCall = mocked(fs.writeFileSync).mock.calls.find(
(call) => (call[0] as string).includes("metadata.json")
);
const writtenMetadataContent = writeMetadataCall[1] as string;
expect(
JSON.parse(fakeMetadataFile({ versions: ["1.0.0", "1.2.3"] })) // doesn't have 0.0.1
).toEqual(JSON.parse(writtenMetadataContent));
});

test("updates bcr metadata file if there were changes to the template", async () => {
mockRulesetFiles({ metadataHomepage: "foo.bar.com" });

Expand Down Expand Up @@ -361,7 +385,7 @@ describe("createEntryFiles", () => {
await expectThrownError(
() =>
createEntryService.createEntryFiles(rulesetRepo, bcrRepo, tag, "."),
MetadataParseError
MetadataFileError
);
});

Expand Down
59 changes: 22 additions & 37 deletions src/domain/create-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { GitClient } from "../infrastructure/git.js";
import { GitHubClient } from "../infrastructure/github.js";
import { UserFacingError } from "./error.js";
import { computeIntegrityHash } from "./integrity-hash.js";
import { MetadataFile } from "./metadata-file.js";
import { ModuleFile } from "./module-file.js";
import { ReleaseArchive } from "./release-archive.js";
import { Repository } from "./repository.js";
Expand All @@ -19,14 +20,6 @@ export class VersionAlreadyPublishedError extends UserFacingError {
}
}

export class MetadataParseError extends UserFacingError {
public constructor(repository: Repository, path: string) {
super(
`Could not parse metadata file ${path} from repository ${repository.canonicalName}.`
);
}
}

export class CreateEntryService {
constructor(
private readonly gitClient: GitClient,
Expand Down Expand Up @@ -71,12 +64,9 @@ export class CreateEntryService {
fs.mkdirSync(bcrEntryPath);
}

updateMetadataFile(
rulesetRepo.metadataTemplatePath(moduleRoot),
bcrRepo,
path.join(bcrEntryPath, "metadata.json"),
version
);
const metadataTemplate = rulesetRepo.metadataTemplate(moduleRoot);

updateMetadataFile(metadataTemplate, bcrEntryPath, version);

fs.mkdirSync(bcrVersionEntryPath);

Expand Down Expand Up @@ -235,34 +225,29 @@ export class CreateEntryService {
}

function updateMetadataFile(
sourcePath: string,
bcrRepo: Repository,
destPath: string,
metadataTemplate: MetadataFile,
bcrEntryPath: string,
version: string
) {
let publishedVersions = [];
let yankedVersions = {};
// Ignore any versions in the template metadata file since the
// canonical source for released and yanked versions exists in
// the metadata file stored in the Bazel Central Registry.
metadataTemplate.clearVersions();
metadataTemplate.clearYankedVersions();

const destPath = path.join(bcrEntryPath, "metadata.json");
if (fs.existsSync(destPath)) {
try {
const existingMetadata = JSON.parse(fs.readFileSync(destPath, "utf8"));
publishedVersions = existingMetadata.versions;
yankedVersions = existingMetadata.yanked_versions;
} catch (error) {
throw new MetadataParseError(bcrRepo, destPath);
const bcrMetadata = new MetadataFile(destPath);

if (bcrMetadata.hasVersion(version)) {
throw new VersionAlreadyPublishedError(version);
}
}

if (publishedVersions.includes(version)) {
throw new VersionAlreadyPublishedError(version);
// Add all versions from the BCR metadata
metadataTemplate.addVersions(...bcrMetadata.versions);
metadataTemplate.addYankedVersions(bcrMetadata.yankedVersions);
}

const metadata = JSON.parse(
fs.readFileSync(sourcePath, {
encoding: "utf-8",
})
);
metadata.versions = [...publishedVersions, version];
metadata.yanked_versions = { ...metadata.yanked_versions, ...yankedVersions };

fs.writeFileSync(destPath, JSON.stringify(metadata, null, 4) + "\n");
metadataTemplate.addVersions(version);
metadataTemplate.save(destPath);
}
Loading

0 comments on commit e03d8b9

Please sign in to comment.