Skip to content

Commit ef2932d

Browse files
authored
Merge pull request #44 from coderoad/fixes
Add "clean" = false option
2 parents 36fd3f1 + ea6756f commit ef2932d

File tree

5 files changed

+146
-23
lines changed

5 files changed

+146
-23
lines changed

Diff for: src/help.ts

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Usage: coderoad validate [path] [options]
4747
4848
Options:
4949
--help (-h) display these help docs
50+
--clean (-c) set to false to preserve .tmp folder. Helpful for debugging
5051
5152
More docs at https://github.com/coderoad/coderoad-cli`);
5253
}

Diff for: src/utils/args.ts

+50-18
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,64 @@
1-
type ArgValueParams = { name: string; alias?: string; param?: boolean };
1+
type ArgValueParams = {
2+
name: string;
3+
alias?: string;
4+
type?: "string" | "bool" | "number";
5+
};
26

3-
const checkValue = (
7+
function checkValue<T>(
48
args: string[],
59
string: string,
6-
options: ArgValueParams
7-
) => {
10+
isBool: boolean
11+
): string | null {
812
const nameIndex = args.indexOf(string);
9-
if (nameIndex > -1) {
10-
if (options.param) {
11-
const value = args[nameIndex + 1];
12-
if (!value) {
13-
throw new Error(`Argument ${string} is missing a parameter value`);
13+
if (nameIndex >= 0) {
14+
const nextArg = args[nameIndex + 1];
15+
16+
if (nextArg !== undefined) {
17+
const nextIsCommand = !!nextArg.match(/^\-/);
18+
if (nextIsCommand) {
19+
return isBool ? "true" : null;
1420
}
15-
return value;
21+
return nextArg;
22+
} else {
23+
// no secondary set value
24+
return isBool ? "true" : null;
1625
}
1726
}
1827
return null;
19-
};
28+
}
2029

21-
export function getArg(args: string[], options: ArgValueParams): string | null {
22-
let value: null | string = null;
30+
export function getArg<T>(
31+
args: string[],
32+
options: ArgValueParams
33+
): string | boolean | number | null {
34+
let stringValue: null | string = null;
35+
const isBool = options.type === "bool";
2336

24-
const aliasString = `-${options.alias}`;
25-
value = checkValue(args, aliasString, options);
26-
if (!value) {
37+
if (options.alias) {
38+
const aliasString = `-${options.alias}`;
39+
stringValue = checkValue(args, aliasString, isBool);
40+
}
41+
if (!stringValue) {
2742
const nameString = `--${options.name}`;
28-
value = checkValue(args, nameString, options);
43+
stringValue = checkValue(args, nameString, isBool);
44+
}
45+
46+
if (stringValue === null) {
47+
return null;
2948
}
3049

31-
return value;
50+
if (!options.type) {
51+
options.type = "string";
52+
}
53+
54+
// coerce type
55+
switch (options.type) {
56+
case "bool":
57+
return (stringValue || "").toLowerCase() !== "false";
58+
case "number":
59+
return Number(stringValue);
60+
case "string":
61+
default:
62+
return stringValue;
63+
}
3264
}

Diff for: src/utils/exec.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ export function createCherryPick(cwd: string) {
2222
return async function cherryPick(commits: string[]): Promise<void> {
2323
for (const commit of commits) {
2424
try {
25-
const { stdout } = await createExec(cwd)(
25+
const { stdout, stderr } = await createExec(cwd)(
2626
`git cherry-pick -X theirs ${commit}`
2727
);
28+
if (stderr) {
29+
console.warn(stderr);
30+
}
2831
if (!stdout) {
2932
console.warn(`No cherry-pick output for ${commit}`);
3033
}
3134
} catch (e) {
3235
console.warn(`Cherry-pick failed for ${commit}`);
36+
console.error(e.message);
3337
}
3438
}
3539
};
@@ -50,6 +54,7 @@ export function createCommandRunner(cwd: string) {
5054
}
5155
const { stdout, stderr } = await createExec(cwdDir)(command);
5256

57+
console.log(stdout);
5358
console.warn(stderr);
5459
} catch (e) {
5560
console.error(`Command failed: "${command}"`);

Diff for: src/validate.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,30 @@ import {
1010
} from "./utils/exec";
1111
import { getCommits, CommitLogObject } from "./utils/commits";
1212

13+
interface Options {
14+
yaml: string;
15+
clean: boolean;
16+
}
17+
1318
async function validate(args: string[]) {
1419
// dir - default .
1520
const dir = !args.length || args[0].match(/^-/) ? "." : args[0];
1621
const localDir = path.join(process.cwd(), dir);
1722

1823
// -y --yaml - default coderoad-config.yml
19-
const options = {
20-
yaml: getArg(args, { name: "yaml", alias: "y" }) || "coderoad.yaml",
24+
const options: Options = {
25+
// @ts-ignore
26+
yaml:
27+
getArg(args, { name: "yaml", alias: "y", type: "string" }) ||
28+
"coderoad.yaml",
29+
// @ts-ignore
30+
clean: getArg(args, { name: "clean", alias: "c", type: "bool" }),
2131
};
2232

23-
const _yaml = await fs.readFile(path.join(localDir, options.yaml), "utf8");
33+
const _yaml: string = await fs.readFile(
34+
path.join(localDir, options.yaml),
35+
"utf8"
36+
);
2437

2538
// parse yaml config
2639
let skeleton;
@@ -158,7 +171,10 @@ async function validate(args: string[]) {
158171
console.error(e.message);
159172
} finally {
160173
// cleanup
161-
await fs.emptyDir(tmpDir);
174+
console.log("options.clean", options.clean);
175+
if (options.clean) {
176+
await fs.emptyDir(tmpDir);
177+
}
162178
}
163179
}
164180

Diff for: tests/args.test.ts

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { getArg } from "../src/utils/args";
2+
3+
describe("args", () => {
4+
it("should capture an arg name from text", () => {
5+
const args = ["--name", "value"];
6+
const result = getArg(args, { name: "name" });
7+
expect(result).toBe("value");
8+
});
9+
it("should capture an arg alias from text", () => {
10+
const args = ["-n", "value"];
11+
const result = getArg(args, { name: "name", alias: "n" });
12+
expect(result).toBe("value");
13+
});
14+
it("should capture an arg name from text when starting values", () => {
15+
const args = ["dir", "--name", "value"];
16+
const result = getArg(args, { name: "name" });
17+
expect(result).toBe("value");
18+
});
19+
it("should capture an arg alias from text", () => {
20+
const args = ["dir", "-n", "value"];
21+
const result = getArg(args, { name: "name", alias: "n" });
22+
expect(result).toBe("value");
23+
});
24+
it("should convert bool string to true", () => {
25+
const args = ["--someBool", "true"];
26+
const result = getArg(args, {
27+
name: "someBool",
28+
alias: "sb",
29+
type: "bool",
30+
});
31+
expect(result).toBe(true);
32+
});
33+
it("should convert bool string to false", () => {
34+
const args = ["--someBool", "false"];
35+
const result = getArg(args, {
36+
name: "someBool",
37+
alias: "sb",
38+
type: "bool",
39+
});
40+
expect(result).toBe(false);
41+
});
42+
it("should default value to true if no next value", () => {
43+
const args = ["--someBool"];
44+
const result = getArg(args, {
45+
name: "someBool",
46+
alias: "sb",
47+
type: "bool",
48+
});
49+
expect(result).toBe(true);
50+
});
51+
it("should default value to true if next value is --name", () => {
52+
const args = ["--someBool", "--someOtherBool"];
53+
const result = getArg(args, {
54+
name: "someBool",
55+
alias: "sb",
56+
type: "bool",
57+
});
58+
expect(result).toBe(true);
59+
});
60+
it("should default value to true if next value is -alias", () => {
61+
const args = ["--someBool", "-a"];
62+
const result = getArg(args, {
63+
name: "someBool",
64+
alias: "sb",
65+
type: "bool",
66+
});
67+
expect(result).toBe(true);
68+
});
69+
});

0 commit comments

Comments
 (0)