Skip to content

Commit

Permalink
Add force flag to reload (#103)
Browse files Browse the repository at this point in the history
* Since builder will not necessarily be triggered when a `.code.hash` file is present therefore force
  the reload by removing the file
  • Loading branch information
JoelClemence authored Sep 9, 2024
1 parent 5763f7a commit 5af3719
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 4 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ $ npm install -g chs-dev
$ chs-dev COMMAND
running command...
$ chs-dev (--version)
chs-dev/1.3.0 darwin-arm64 node-v20.10.0
chs-dev/1.3.0 darwin-arm64 node-v20.12.2
$ chs-dev --help [COMMAND]
USAGE
$ chs-dev COMMAND
Expand Down Expand Up @@ -506,11 +506,14 @@ Rebuilds and restarts the supplied service running in development mode to load i

```
USAGE
$ chs-dev reload SERVICE
$ chs-dev reload SERVICE [-f]
ARGUMENTS
SERVICE Name of the service
FLAGS
-f, --force Forcefully reload service and force a rebuild
DESCRIPTION
Rebuilds and restarts the supplied service running in development mode to load in any changes to source code
```
Expand Down
27 changes: 25 additions & 2 deletions src/commands/reload.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Args, Command, Config } from "@oclif/core";
import { Args, Command, Config, Flags } from "@oclif/core";
import { Inventory } from "../state/inventory.js";
import { join } from "path";
import fsExtra from "fs-extra";
import { DependencyCache } from "../run/dependency-cache.js";
import ChsDevConfig from "../model/Config.js";
import loadConfig from "../helpers/config-loader.js";
import { existsSync, unlinkSync } from "fs";

export default class Reload extends Command {

Expand All @@ -18,6 +19,18 @@ export default class Reload extends Command {
})
};

static flags = {
force: Flags.boolean({
required: false,
allowNo: false,
default: false,
description: "Forcefully reload service and force a rebuild",
name: "force",
char: "f",
aliases: ["force"]
})
};

private readonly inventory: Inventory;
private readonly dependencyCache: DependencyCache;
private readonly chsDevConfig: ChsDevConfig;
Expand All @@ -32,9 +45,19 @@ export default class Reload extends Command {
}

async run (): Promise<any> {
const { args } = await this.parse(Reload);
const { args, flags } = await this.parse(Reload);

const serviceName: string = args.service;
const codeHashFile = join(
this.chsDevConfig.projectPath,
"local",
serviceName,
"out/.code.hash"
);

if (flags.force && existsSync(codeHashFile)) {
unlinkSync(codeHashFile);
}

if (this.isServiceValid(serviceName)) {
const touchFile = join(this.chsDevConfig.projectPath, "local", serviceName, ".touch");
Expand Down
84 changes: 84 additions & 0 deletions test/commands/reload.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Service } from "../../src/model/Service";
import { join } from "path";
import { Config } from "@oclif/core";
import Reload from "../../src/commands/reload";
import fs from "fs";

const ensureFileMock = jest.fn();
const utimesMock = jest.fn();
Expand Down Expand Up @@ -69,6 +70,8 @@ describe("reload spec", () => {
const parseMock = jest.fn();
const logMock = jest.fn();
const errorMock = jest.fn();
const unlinkSyncSpy = jest.spyOn(fs, "unlinkSync");
const existsSyncSpy = jest.spyOn(fs, "existsSync");

const testDateTime = new Date(2023, 1, 1, 0, 0, 0);

Expand All @@ -93,13 +96,19 @@ describe("reload spec", () => {
reload.log = logMock;
// @ts-expect-error
reload.error = errorMock;

unlinkSyncSpy.mockImplementation((_) => {});
existsSyncSpy.mockReturnValue(true);
});

it("should not reload an invalid service", async () => {
// @ts-expect-error
parseMock.mockResolvedValue({
args: {
service: "not-found"
},
flags: {
force: false
}
});

Expand All @@ -115,6 +124,9 @@ describe("reload spec", () => {
parseMock.mockResolvedValue({
args: {
service: "service-one"
},
flags: {
force: false
}
});

Expand All @@ -134,6 +146,9 @@ describe("reload spec", () => {
parseMock.mockResolvedValue({
args: {
service: "service-one"
},
flags: {
force: false
}
});

Expand All @@ -143,4 +158,73 @@ describe("reload spec", () => {
expect(utimesMock).toHaveBeenCalledWith(join(projectDir, "local/service-one/.touch"), testDateTime, testDateTime);
});

it("does not remove code hash when force flag not supplied", async () => {
// @ts-expect-error
ensureFileMock.mockResolvedValue(undefined);

// @ts-expect-error
utimesMock.mockResolvedValue(undefined);

// @ts-expect-error
parseMock.mockResolvedValue({
args: {
service: "service-one"
},
flags: {
force: false
}
});

await reload.run();

expect(unlinkSyncSpy).not.toHaveBeenCalled();
});

it("removes code hash when force flag supplied", async () => {
// @ts-expect-error
ensureFileMock.mockResolvedValue(undefined);

// @ts-expect-error
utimesMock.mockResolvedValue(undefined);

// @ts-expect-error
parseMock.mockResolvedValue({
args: {
service: "service-one"
},
flags: {
force: true
}
});

await reload.run();

expect(unlinkSyncSpy).toHaveBeenCalledWith(
join(projectDir, "local/service-one/out/.code.hash")
);
});

it("does not remove code hash when force flag supplied and code hash does not exist", async () => {
existsSyncSpy.mockReturnValue(false);

// @ts-expect-error
ensureFileMock.mockResolvedValue(undefined);

// @ts-expect-error
utimesMock.mockResolvedValue(undefined);

// @ts-expect-error
parseMock.mockResolvedValue({
args: {
service: "service-one"
},
flags: {
force: true
}
});

await reload.run();

expect(unlinkSyncSpy).not.toHaveBeenCalled();
});
});

0 comments on commit 5af3719

Please sign in to comment.