-
Notifications
You must be signed in to change notification settings - Fork 6
/
main.ts
executable file
·130 lines (109 loc) · 3.16 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env deno --allow-run
// Copyright 2019 Yoshiya Hinosawa. All rights reserved. MIT license.
import writeFile = Deno.writeFile;
const { exit, args, readFile } = Deno;
import { parse } from "https://deno.land/std@v0.3.1/flags/mod.ts";
import { red, green, blue } from "https://deno.land/std@v0.3.1/colors/mod.ts";
import { globrex } from "https://deno.land/std@v0.3.1/fs/globrex.ts";
import { encode } from "https://deno.land/std@v0.3.1/strings/strings.ts";
import { xrun, decode } from "./util.ts";
function match(filename, glob) {
return globrex(glob, { globstar: true }).regex.test(filename);
}
async function readConfig(config = ".licenserc.json") {
let data;
let configObj;
try {
data = await readFile(config);
} catch (e) {
console.log(`Error: config file "${config}" not found.`);
exit(1);
}
try {
configObj = JSON.parse(decode(data));
} catch (e) {
console.log(`Error: Failed to parse "${config}" as JSON.`);
console.log(e);
exit(1);
}
const ignore: string[] = configObj.ignore || [];
delete configObj.ignore;
const entries: Array<[string, string | string[]]> = Object.entries(configObj);
return { ignore, config: entries };
}
const checkFile = async (
filename: string,
copyright: string | string[],
quiet: boolean,
inject: boolean
) => {
const sourceCode = decode(await readFile(filename));
const copyrightLines: string[] = Array.isArray(copyright)
? copyright
: [String(copyright)];
if (copyrightLines.every(line => sourceCode.includes(line))) {
if (!quiet) {
console.log(filename, "...", green("ok"));
}
return true;
}
if (inject) {
console.log(`${filename} ${blue("missing copyright. injecting ... done")}`);
await writeFile(
filename,
encode(copyrightLines.join("\n") + "\n" + sourceCode)
);
return true;
} else {
console.log(filename, red("missing copyright!"));
}
return false;
};
const main = async opts => {
if (opts.help) {
console.log(`
Usage: license_checker.ts [options]
Options:
-H, --help Show this help message and exit.
-V, --version Show the version number and exit.
-q, --quiet Don't print messages except errors.
-i, --inject Inject license into head if missing.
-c, --config <filename> Specify config filename. Default is '.licenserc.json'.
`);
exit(0);
}
if (opts.version) {
console.log("1.5.0");
exit(0);
}
const { config, ignore } = await readConfig();
const filenames = (await xrun(["git", "ls-files"])).trim().split("\n");
const tasks = [];
for (const filename of filenames) {
for (const [glob, copyright] of config) {
if (ignore.some(pattern => filename.includes(pattern))) {
continue;
}
if (match(filename, glob)) {
tasks.push(checkFile(filename, copyright, opts.quiet, opts.inject));
}
}
}
const results = await Promise.all(tasks);
if (results.includes(false)) {
exit(1);
return;
}
exit(0);
};
main(
parse(args.slice(1), {
boolean: ["quiet", "help", "version", "inject"],
alias: {
q: "quiet",
i: "inject",
H: "help",
V: "version"
}
})
);