Skip to content

Commit 3115854

Browse files
committed
fix: mend cli errors
1 parent 4a67182 commit 3115854

File tree

6 files changed

+73
-64
lines changed

6 files changed

+73
-64
lines changed

src/cli/create.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { ensureDirSync, exists } from "https://deno.land/std/fs/mod.ts";
2-
import { dirname, join } from "https://deno.land/std/path/mod.ts";
1+
import { ensureDirSync } from "https://deno.land/std@0.166.0/fs/mod.ts";
2+
import { dirname, join } from "https://deno.land/std@0.166.0/path/mod.ts";
33
import { renderFileToString } from "https://deno.land/x/dejs@0.9.3/mod.ts";
44
import { listDays, SOLUTIONS_MODULE, SOLUTIONS_PATH } from "./load.ts";
55

66
const __dirname = dirname(new URL(import.meta.url).pathname);
77

8-
export async function createDay(day: number) {
8+
export async function createDay(day: number | undefined) {
99
if (day == null) {
1010
const days = await listDays();
1111
day = 1;
@@ -16,13 +16,15 @@ export async function createDay(day: number) {
1616

1717
const mainFolder = join(SOLUTIONS_PATH, `day${day}`);
1818

19-
if (await exists(mainFolder)) {
20-
console.error(`Error - Day ${day} already exists`);
21-
Deno.exit(1);
19+
try {
20+
Deno.mkdirSync(mainFolder);
21+
} catch (error) {
22+
if (error instanceof Deno.errors.AlreadyExists) {
23+
throw new Error(`Error - Day ${day} already exists`, error);
24+
}
25+
throw error;
2226
}
2327

24-
ensureDirSync(mainFolder);
25-
2628
Deno.writeTextFileSync(
2729
join(mainFolder, "mod.ts"),
2830
await renderFileToString(

src/cli/load.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { existsSync } from "https://deno.land/std/fs/mod.ts";
2-
import { dirname, join } from "https://deno.land/std/path/mod.ts";
1+
import { dirname, join } from "https://deno.land/std@0.166.0/path/mod.ts";
32
import { Solution, Solutions } from "./types.d.ts";
43
import { dayKey, extractDayNumber } from "./utils.ts";
54

@@ -18,33 +17,42 @@ export async function listDays() {
1817
export function readDaySampleInput(day: number) {
1918
const dayName = dayKey(day);
2019
const daySampleInput = join(SOLUTIONS_PATH, dayName, "sample.txt");
21-
if (!existsSync(daySampleInput)) {
22-
console.error(`Day ${day} sample input not found`);
23-
Deno.exit(1);
20+
try {
21+
return Deno.readTextFileSync(daySampleInput);
22+
} catch (error) {
23+
if (error instanceof Deno.errors.NotFound) {
24+
throw new Error(`Day ${day} sample input not found`, error);
25+
}
26+
throw error;
2427
}
25-
return Deno.readTextFileSync(daySampleInput);
2628
}
2729

28-
export function readDayInput(day: number) {
30+
export function readDayInput(day: number): string {
2931
const dayName = dayKey(day);
3032
const daySampleInput = join(SOLUTIONS_PATH, dayName, "input.txt");
31-
if (!existsSync(daySampleInput)) {
32-
console.error(`Day ${day} input not found`);
33-
Deno.exit(1);
33+
try {
34+
return Deno.readTextFileSync(daySampleInput);
35+
} catch (error) {
36+
if (error instanceof Deno.errors.NotFound) {
37+
throw Error(`Day ${day} input not found`, error);
38+
}
39+
throw error;
3440
}
35-
return Deno.readTextFileSync(daySampleInput);
3641
}
3742

38-
export async function loadSolutionsModules(): Promise<Solutions> {
43+
export function loadSolutionsModules(): Promise<Solutions> {
3944
return import(SOLUTIONS_MODULE);
4045
}
4146

4247
export async function loadModule(day: number): Promise<Solution> {
4348
const dayName = dayKey(day);
4449
const dayModule = join(SOLUTIONS_PATH, dayName, "mod.ts");
45-
if (!existsSync(dayModule)) {
46-
console.error(`Day ${day} module not found`);
47-
Deno.exit(1);
50+
try {
51+
return await import(dayModule);
52+
} catch (error) {
53+
if (error instanceof TypeError) {
54+
throw new Error(`Day ${day} module not found`, error);
55+
}
56+
throw error;
4857
}
49-
return await import(dayModule);
5058
}

src/cli/mod.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
import { Command } from "https://deno.land/x/cliffy/command/mod.ts";
1+
import { Command } from "https://deno.land/x/cliffy@v0.25.4/command/mod.ts";
22
import { createDay } from "./create.ts";
33
import { runAllDays, runDay } from "./run.ts";
4+
import { Format } from "./types.d.ts";
5+
import { isFormat } from "./utils.ts";
46

57
try {
68
await new Command()
79
.name("aoc")
8-
.version("<version>")
10+
.version("0.1.1")
911
.description("Solutions for Advent of Code. https://adventofcode.com/")
1012
.throwErrors()
1113
.command(
1214
"run",
1315
new Command()
1416
.description("Run day solution")
15-
.option("-d, --day <day:number>", "Day to run")
17+
.option("-d, --day <day:number>", "Day to run", { required: true })
1618
.option(
1719
"-p, --part <part:number>",
1820
"Part of the day solution to run.",
19-
{ default: 1 },
21+
{ required: true },
2022
)
2123
.option(
2224
"-a, --all-parts",
2325
"Execute both parts. If present part option will be ignore.",
26+
{ conflicts: ["part"] },
2427
)
2528
.option("-t, --time", "Show spent time")
2629
.option(
@@ -37,8 +40,8 @@ try {
3740
"Output format.",
3841
{
3942
default: "plain",
40-
value(value: string) {
41-
if (!["plain", "json", "csv"].includes(value)) {
43+
value(value: string): Format {
44+
if (!isFormat(value)) {
4245
throw new Error(
4346
`Format must be one of plain, json or csv but got: ${value}`,
4447
);
@@ -48,7 +51,11 @@ try {
4851
},
4952
)
5053
.action(({ day, part, allParts, time, sample, format, file }) =>
51-
runDay(day, file, { part, allParts, time, sample, format })
54+
runDay(
55+
day,
56+
file,
57+
{ part, allParts, time, sample, format },
58+
)
5259
),
5360
)
5461
.command(
@@ -62,7 +69,8 @@ try {
6269
)
6370
.option(
6471
"-a, --all-parts",
65-
"Execute both parts. If present part option will be ignore.",
72+
"Execute both parts. If present 'part' option will be ignore.",
73+
{ conflicts: ["part"] },
6674
)
6775
.option("-t, --time", "Show spent time")
6876
.option(
@@ -74,13 +82,13 @@ try {
7482
"Output format.",
7583
{
7684
default: "plain",
77-
value(value: string) {
78-
if (!["plain", "json", "csv"].includes(value)) {
79-
throw new Error(
80-
`Format must be one of plain, json or csv but got: ${value}`,
81-
);
85+
value(value: string): Format {
86+
if (isFormat(value)) {
87+
return value;
8288
}
83-
return value;
89+
throw new Error(
90+
`Format must be one of plain, json or csv but got: ${value}`,
91+
);
8492
},
8593
},
8694
)
@@ -92,7 +100,7 @@ try {
92100
.description("Create new day solution folder skeleton")
93101
.option(
94102
"-d, --day <day:number>",
95-
"Day of the solution. By default the corresponding next day will be created.",
103+
"Day of the solution. If omit the corresponding next day will be created.",
96104
)
97105
.action(({ day }) => createDay(day)),
98106
)

src/cli/run.ts

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@ import {
55
readDaySampleInput,
66
} from "./load.ts";
77
import { log } from "./log.ts";
8-
import {
9-
Result,
10-
ResultDay,
11-
RunOptions,
12-
Solution,
13-
SolutionPart,
14-
} from "./types.d.ts";
8+
import { Result, ResultDay, RunOptions, Solution } from "./types.d.ts";
159
import { dayKey, extractDayNumber } from "./utils.ts";
1610

1711
function runWithTime<T>(fn: () => Result<T>): Result<T> {
@@ -21,16 +15,6 @@ function runWithTime<T>(fn: () => Result<T>): Result<T> {
2115
return { ...result, time };
2216
}
2317

24-
function runPart<Input, Output>(
25-
part: SolutionPart<Input, Output>,
26-
input: Input,
27-
{ time: time = false }: Pick<RunOptions, "time">,
28-
): Result<Output> {
29-
return !time
30-
? { result: part(input) }
31-
: runWithTime(() => ({ result: part(input) }));
32-
}
33-
3418
function runModule(
3519
module: Solution,
3620
text: string,
@@ -42,7 +26,7 @@ function runModule(
4226
const moduleFn = sampleExtraArgs
4327
? () => module.main(text, part === 2, sampleExtraArgs)
4428
: () => module.main(text, part === 2);
45-
return !time
29+
return time !== true
4630
? { result: moduleFn() }
4731
: runWithTime(() => ({ result: moduleFn() }));
4832
}
@@ -59,13 +43,13 @@ function runAllParts(
5943

6044
export async function runDay(
6145
day: number,
62-
file: string,
46+
file: string | undefined,
6347
{ part, allParts, time, sample, format }: RunOptions,
6448
) {
6549
const module: Solution = await loadModule(day);
66-
const text = file
50+
const text = file != null
6751
? Deno.readTextFileSync(file)
68-
: sample
52+
: sample === true
6953
? readDaySampleInput(day)
7054
: readDayInput(day);
7155
const result = allParts

src/cli/types.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ declare enum Format {
66

77
export interface RunOptions {
88
part: number;
9-
allParts: boolean;
10-
time: boolean;
11-
sample: boolean;
9+
allParts?: boolean;
10+
time?: boolean;
11+
sample?: boolean;
1212
format: Format;
1313
}
1414

src/cli/utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Result, ResultDay, ResultsDays } from "./types.d.ts";
1+
import { Format, Result, ResultDay, ResultsDays } from "./types.d.ts";
22

33
export function isResult(obj: Result | ResultDay | ResultsDays): obj is Result {
44
return typeof obj === "object" && "result" in obj;
@@ -24,3 +24,10 @@ export function extractDayNumber(day: string) {
2424
export function dayKey(day: number) {
2525
return `day${day}`;
2626
}
27+
28+
export function isFormat(value: string | null): value is Format {
29+
if (value == null) {
30+
return false;
31+
}
32+
return ["plain", "json", "csv"].includes(value);
33+
}

0 commit comments

Comments
 (0)