Skip to content

Commit

Permalink
Implement #90 - Download failure message enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
bjuric committed Jan 23, 2025
1 parent 0be4bdc commit a50c48c
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 36 deletions.
27 changes: 21 additions & 6 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@

import { promises as fs } from "fs";

export type Repo = {
url: string;
custom: boolean;
};

export interface Config {
mavenRepo: string;
mavenSnapshotRepo: string;
mavenRepo: Repo;
mavenSnapshotRepo: Repo;
version: string;
}

Expand All @@ -29,12 +34,22 @@ export async function getConfig(
(await fs.readFile(packageJsonPath)).toString(),
);
const userSettings = packageJson.gwenWeb ?? {};
const defaultMavenRepo = "https://repo1.maven.org/maven2/";
const defaultMavenSnapshotRepo =
"https://s01.oss.sonatype.org/content/repositories/snapshots/";

return {
mavenRepo: userSettings.mavenRepo ?? "https://repo1.maven.org/maven2/",
mavenSnapshotRepo:
userSettings.mavenSnapshotRepo ??
"https://s01.oss.sonatype.org/content/repositories/snapshots/",
mavenRepo: {
url: userSettings.mavenRepo ?? defaultMavenRepo,
custom:
!!userSettings.mavenRepo && userSettings.mavenRepo != defaultMavenRepo,
},
mavenSnapshotRepo: {
url: userSettings.mavenSnapshotRepo ?? defaultMavenSnapshotRepo,
custom:
!!userSettings.mavenSnapshotRepo &&
userSettings.mavenSnapshotRepo != defaultMavenSnapshotRepo,
},
version: userSettings.version ?? "latest",
};
}
9 changes: 5 additions & 4 deletions lib/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import type { ReadableStream } from "node:stream/web";
import type { Repo } from "./config";
import fs, { promises as fsP } from "fs";
import path from "path";
import os from "os";
Expand All @@ -41,7 +42,7 @@ type Result = DoneResult | DownloadedResult | ErrorResult;

async function startDownload(
version: string,
mavenRepo: string,
mavenRepo: Repo,
): Promise<Result> {
if (await fileExists(path.join(storedVersionPath, `gwen-web-${version}`))) {
return {
Expand All @@ -58,7 +59,7 @@ async function startDownload(
);
const downloadRes = await fetch(
urljoin(
mavenRepo,
mavenRepo.url,
`/org/gweninterpreter/gwen-web/${version}/gwen-web-${version}.zip`,
),
);
Expand Down Expand Up @@ -113,7 +114,7 @@ async function startDownload(
if (e instanceof TypeError) {
return {
status: "error",
message: `Failed downloading Gwen-Web v${version}. Check your internet connection and try again.`,
message: `Failed downloading Gwen-Web v${version}. Check your internet${mavenRepo.custom ? " or maven repo" : ""} connection and try again.`,
};
} else {
return {
Expand Down Expand Up @@ -151,7 +152,7 @@ function handleError(result: Result): void {

export default async function download(
version: string,
mavenRepo: string,
mavenRepo: Repo,
): Promise<void> {
const dlResult = await startDownload(version, mavenRepo);
handleError(dlResult);
Expand Down
4 changes: 2 additions & 2 deletions lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function getVersionInfo(config: Config): Promise<VersionInfo> {
try {
const metaXmlRes = await fetch(
urljoin(
config.mavenRepo,
config.mavenRepo.url,
"/org/gweninterpreter/gwen-web/maven-metadata.xml",
),
);
Expand Down Expand Up @@ -74,7 +74,7 @@ async function getVersionInfo(config: Config): Promise<VersionInfo> {
};
} catch (e) {
throw new Error(
"Failed to get Gwen-Web versions. Check your internet connection and try again.",
`Failed to get Gwen-Web versions. Check your internet${config.mavenRepo.custom ? " or maven repo" : ""} connection and try again.`,
);
}
}
Expand Down
19 changes: 13 additions & 6 deletions test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,24 @@ describe("getConfig", () => {
const config = await getConfig("./test/fixtures/package.json");

expect(config.version).toBe("2.0.0");
expect(config.mavenRepo).toBe("testRepo");
expect(config.mavenSnapshotRepo).toBe("testSnapshotRepo");
expect(config.mavenRepo).toStrictEqual({ url: "testRepo", custom: true });
expect(config.mavenSnapshotRepo).toStrictEqual({
url: "testSnapshotRepo",
custom: true,
});
});

it("should pick the correct defaults when none are specified", async () => {
const config = await getConfig("./test/fixtures/blank-package.json");

expect(config.version).toBe("latest");
expect(config.mavenRepo).toBe("https://repo1.maven.org/maven2/");
expect(config.mavenSnapshotRepo).toBe(
"https://s01.oss.sonatype.org/content/repositories/snapshots/",
);
expect(config.mavenRepo).toStrictEqual({
url: "https://repo1.maven.org/maven2/",
custom: false,
});
expect(config.mavenSnapshotRepo).toStrictEqual({
url: "https://s01.oss.sonatype.org/content/repositories/snapshots/",
custom: false,
});
});
});
2 changes: 1 addition & 1 deletion test/files.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const testFile = "./test/fixtures/maven-metadata.xml";
describe("getFileSha1", () => {
it("should return the correct SHA1 hash for files", async () => {
await expect(getFileSha1(testFile)).resolves.toBe(
"b964a11afac8518ace639fb97de21aff58b8d457",
"f9abbe687aab74b9cc130ace1ee07cc81a8c4db5",
);
});

Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/maven-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@
<version>2.51.0</version>
<version>2.51.1</version>
<version>2.52.0</version>
<version>3.77.3</version>
<version>4.0.0</version>
<version>4.0.1</version>
<version>4.0.2</version>
<version>4.0.3</version>
<version>4.1.0</version>
<version>4.1.1</version>
<version>4.1.2</version>
<version>4.2.0</version>
<version>4.2.1</version>
<version>4.2.2</version>
<version>4.2.3</version>
<version>4.2.4</version>
<version>4.2.5</version>
<version>4.2.6</version>
<version>4.2.7</version>
</versions>
<lastUpdated>20210622093813</lastUpdated>
</versioning>
Expand Down
100 changes: 83 additions & 17 deletions test/version.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ import getDesiredVersion from "../lib/version";
const mockFetch = jest.spyOn(global, "fetch");
const metadataFixture = "./test/fixtures/maven-metadata.xml";

const config = {
mavenRepo: "test repo",
mavenSnapshotRepo: "test repo",
const configDefaultRepo = {
mavenRepo: { url: "test repo", custom: false },
mavenSnapshotRepo: { url: "test repo", custom: false },
version: "latest",
};

const configCustomRepo = {
mavenRepo: { url: "test repo", custom: true },
mavenSnapshotRepo: { url: "test repo", custom: true },
version: "latest",
};

Expand All @@ -45,63 +51,123 @@ describe("getDesiredVersion", () => {
process.env = origEnv;
});

it("should return the version specified in package.json", async () => {
it("should return the version specified in package.json (default repo)", async () => {
await expect(
getDesiredVersion({
...config,
...configDefaultRepo,
version: "2.0.0",
}),
).resolves.toBe("2.0.0");
});

it("should return the SNAPSHOT version specified in package.json", async () => {
it("should return the version specified in package.json (custom repo)", async () => {
await expect(
getDesiredVersion({
...configCustomRepo,
version: "2.1.0",
}),
).resolves.toBe("2.1.0");
});

it("should return the SNAPSHOT version specified in package.json (default repo)", async () => {
await expect(
getDesiredVersion({
...config,
...configDefaultRepo,
version: "2.0.0-1-SNAPSHOT",
}),
).resolves.toBe("2.0.0-1-SNAPSHOT");
});

it("should return the latest version matching specified semver range", async () => {
it("should return the SNAPSHOT version specified in package.json (custom repo)", async () => {
await expect(
getDesiredVersion({
...config,
...configCustomRepo,
version: "2.1.0-1-SNAPSHOT",
}),
).resolves.toBe("2.1.0-1-SNAPSHOT");
});

it("should return the latest version matching specified semver range (default repo)", async () => {
await expect(
getDesiredVersion({
...configDefaultRepo,
version: "^2.0.0",
}),
).resolves.toBe("2.52.0");
});

it("should return the version specified in environment variables", async () => {
it("should return the latest version matching specified semver range (custom repo)", async () => {
await expect(
getDesiredVersion({
...configCustomRepo,
version: "^3.0.0",
}),
).resolves.toBe("3.77.3");
});

it("should return the version specified in environment variables (default repo)", async () => {
process.env.GWEN_WEB_VERSION = "2.10.0";

await expect(
getDesiredVersion({
...config,
...configDefaultRepo,
version: "2.0.0",
}),
).resolves.toBe("2.10.0");
});

it("should return the latest version from the network", async () => {
await expect(getDesiredVersion(config)).resolves.toBe("2.52.0");
it("should return the version specified in environment variables (custom repo)", async () => {
process.env.GWEN_WEB_VERSION = "4.2.7";

await expect(
getDesiredVersion({
...configCustomRepo,
version: "4.2.7",
}),
).resolves.toBe("4.2.7");
});

it("should return the latest version from the network (default repo)", async () => {
await expect(getDesiredVersion(configDefaultRepo)).resolves.toBe("2.52.0");
});

it("should reject if the metadata is invalid", async () => {
it("should return the latest version from the network (custom repo)", async () => {
await expect(getDesiredVersion(configCustomRepo)).resolves.toBe("2.52.0");
});

it("should reject if the metadata is invalid (default repo)", async () => {
mockFetch.mockImplementationOnce(async () => new Response("bad response"));

await expect(getDesiredVersion(config)).rejects.toThrow(
await expect(getDesiredVersion(configDefaultRepo)).rejects.toThrow(
"Failed to get Gwen-Web versions. Check your internet connection and try again.",
);
});

it("should reject if the metadata could not be fetched", async () => {
it("should reject if the metadata is invalid (custom repo)", async () => {
mockFetch.mockImplementationOnce(async () => new Response("bad response"));

await expect(getDesiredVersion(configCustomRepo)).rejects.toThrow(
"Failed to get Gwen-Web versions. Check your internet or maven repo connection and try again.",
);
});

it("should reject if the metadata could not be fetched (default repo)", async () => {
mockFetch.mockImplementationOnce(
async () => new Response("not found", { status: 404 }),
);

await expect(getDesiredVersion(config)).rejects.toThrow(
await expect(getDesiredVersion(configDefaultRepo)).rejects.toThrow(
"Failed to get Gwen-Web versions. Check your internet connection and try again.",
);
});

it("should reject if the metadata could not be fetched (custom repo)", async () => {
mockFetch.mockImplementationOnce(
async () => new Response("not found", { status: 404 }),
);

await expect(getDesiredVersion(configCustomRepo)).rejects.toThrow(
"Failed to get Gwen-Web versions. Check your internet or maven repo connection and try again.",
);
});
});

0 comments on commit a50c48c

Please sign in to comment.