diff --git a/dist/index.js b/dist/index.js index 59cc085..450f2d7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -47949,22 +47949,29 @@ class DockerComposeInstallerService { this.manualInstallerAdapter = manualInstallerAdapter; } async install({ composeVersion, cwd, githubToken }) { - const currentVersion = await this.version({ cwd }); - if (!composeVersion) { + const currentVersion = await this.getInstalledVersion(cwd); + const needsInstall = !currentVersion || (composeVersion && composeVersion !== currentVersion); + if (!needsInstall) { return currentVersion; } - if (currentVersion === composeVersion) { - return currentVersion; - } - if (composeVersion === COMPOSE_VERSION_LATEST) { + let targetVersion = composeVersion || COMPOSE_VERSION_LATEST; + if (targetVersion === COMPOSE_VERSION_LATEST) { if (!githubToken) { throw new Error("GitHub token is required to install the latest version"); } - composeVersion = await this.getLatestVersion(githubToken); + targetVersion = await this.getLatestVersion(githubToken); } - await this.installVersion(composeVersion); + await this.installVersion(targetVersion); return this.version({ cwd }); } + async getInstalledVersion(cwd) { + try { + return await this.version({ cwd }); + } + catch { + return null; + } + } async version({ cwd }) { const result = await (0,dist.version)({ cwd, diff --git a/src/services/docker-compose-installer.service.test.ts b/src/services/docker-compose-installer.service.test.ts index 5e66b54..d6c680b 100644 --- a/src/services/docker-compose-installer.service.test.ts +++ b/src/services/docker-compose-installer.service.test.ts @@ -30,7 +30,7 @@ describe("DockerComposeInstallerService", () => { }); afterEach(() => { - jest.clearAllMocks(); + jest.resetAllMocks(); }); describe("install", () => { @@ -234,5 +234,139 @@ describe("DockerComposeInstallerService", () => { expect(manualInstallerAdapterMock.install).not.toHaveBeenCalled(); }); + + it("should install when version check fails", async () => { + // Arrange: first call to version() doesn't find + versionMock.mockRejectedValueOnce(new Error("version not installed")); + + const installedVersion = "2.0.0"; + + // After installation, version() returns the new version + versionMock.mockResolvedValueOnce({ + exitCode: 0, + out: "", + err: "", + data: { + version: installedVersion, + }, + }); + + Object.defineProperty(process, "platform", { + value: "linux", + }); + + // Act + const result = await service.install({ + composeVersion: installedVersion, + cwd: "/path/to/cwd", + githubToken: "token", + }); + + // Assert + expect(result).toBe(installedVersion); + expect(manualInstallerAdapterMock.install).toHaveBeenCalledWith(installedVersion); + }); + + it("should install latest version when missing or unspecified", async () => { + // Arrange: first call to version() doesn't find + versionMock.mockRejectedValueOnce(new Error("version check failed")); + // second call finds newly installed version + versionMock.mockResolvedValueOnce({ + exitCode: 0, + out: "", + err: "", + data: { + version: "v1.4.0", + }, + }); + + const latestVersion = "v1.4.0"; + + const mockClient = mockAgent.get("https://api.github.com"); + mockClient + .intercept({ + path: "/repos/docker/compose/releases/latest", + method: "GET", + }) + .reply( + 200, + { + tag_name: latestVersion, + }, + { + headers: { + "content-type": "application/json", + }, + } + ); + setGlobalDispatcher(mockClient); + + versionMock.mockResolvedValueOnce({ + exitCode: 0, + out: "", + err: "", + data: { + version: latestVersion, + }, + }); + + Object.defineProperty(process, "platform", { + value: "linux", + }); + Object.defineProperty(globalThis, "fetch", { + value: jest.fn(), + }); + + // Act + const result = await service.install({ + composeVersion: "latest", + cwd: "/path/to/cwd", + githubToken: "token", + }); + + // Assert + expect(result).toBe(latestVersion); + expect(manualInstallerAdapterMock.install).toHaveBeenCalledWith(latestVersion); + }); + + it("should throw if Compose is missing and no GitHub token is provided", async () => { + // Arrange: first call to version() doesn't find + versionMock.mockRejectedValueOnce(new Error("version check failed")); + + Object.defineProperty(process, "platform", { + value: "linux", + }); + + await expect( + service.install({ + composeVersion: "latest", + cwd: "/path/to/cwd", + githubToken: null, + }) + ).rejects.toThrow("GitHub token is required to install the latest version"); + }); + + it("should not install when the version is already installed and no version is specified", async () => { + // Arrange + versionMock.mockResolvedValue({ + exitCode: 0, + out: "", + err: "", + data: { + version: "1.2.3", + }, + }); + + // Act + const result = await service.install({ + composeVersion: "", + cwd: "/path/to/cwd", + githubToken: null, + }); + + // Assert + expect(result).toBe("1.2.3"); + expect(manualInstallerAdapterMock.install).not.toHaveBeenCalled(); + }); }); }); diff --git a/src/services/docker-compose-installer.service.ts b/src/services/docker-compose-installer.service.ts index dba3fa7..78c22ee 100644 --- a/src/services/docker-compose-installer.service.ts +++ b/src/services/docker-compose-installer.service.ts @@ -17,28 +17,35 @@ export class DockerComposeInstallerService { constructor(private readonly manualInstallerAdapter: ManualInstallerAdapter) {} async install({ composeVersion, cwd, githubToken }: InstallInputs): Promise { - const currentVersion = await this.version({ cwd }); + const currentVersion = await this.getInstalledVersion(cwd); - if (!composeVersion) { + const needsInstall = !currentVersion || (composeVersion && composeVersion !== currentVersion); + if (!needsInstall) { return currentVersion; } - if (currentVersion === composeVersion) { - return currentVersion; - } + let targetVersion = composeVersion || COMPOSE_VERSION_LATEST; - if (composeVersion === COMPOSE_VERSION_LATEST) { + if (targetVersion === COMPOSE_VERSION_LATEST) { if (!githubToken) { throw new Error("GitHub token is required to install the latest version"); } - composeVersion = await this.getLatestVersion(githubToken); + targetVersion = await this.getLatestVersion(githubToken); } - await this.installVersion(composeVersion); + await this.installVersion(targetVersion); return this.version({ cwd }); } + private async getInstalledVersion(cwd: string): Promise { + try { + return await this.version({ cwd }); + } catch { + return null; + } + } + private async version({ cwd }: VersionInputs): Promise { const result = await version({ cwd,