adsa-cli 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/bin/adsa.mjs +28 -13
- package/lib/history.mjs +9 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,10 @@ the version checked out in front of them instead of reading files and guessing.
|
|
|
58
58
|
|
|
59
59
|
`npx adsa-cli rubric` prints what 1, 3 and 5 mean for each.
|
|
60
60
|
|
|
61
|
+
`--out <dir>` puts every artifact of a run together somewhere else — the report, the
|
|
62
|
+
score, the badge and the history — and reads the previous score from there too, so a
|
|
63
|
+
repository can be audited without writing anything into it.
|
|
64
|
+
|
|
61
65
|
## Commands
|
|
62
66
|
|
|
63
67
|
```
|
package/bin/adsa.mjs
CHANGED
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
* adsa badge the README badge for the committed score
|
|
12
12
|
*/
|
|
13
13
|
import { mkdirSync, realpathSync, writeFileSync } from "node:fs";
|
|
14
|
-
import { join, resolve } from "node:path";
|
|
14
|
+
import { join, relative, resolve } from "node:path";
|
|
15
15
|
import { pathToFileURL } from "node:url";
|
|
16
16
|
import { loadConfig, resolveTarget } from "../lib/config.mjs";
|
|
17
17
|
import { scan } from "../lib/scan.mjs";
|
|
18
18
|
import { RUBRIC, score, scoreFile } from "../lib/score.mjs";
|
|
19
19
|
import { buildTodo, html, markdown } from "../lib/report.mjs";
|
|
20
20
|
import { badgeEndpoint, badgeMarkdown } from "../lib/badge.mjs";
|
|
21
|
-
import { isDir } from "../lib/fsx.mjs";
|
|
21
|
+
import { exists, isDir } from "../lib/fsx.mjs";
|
|
22
22
|
import { DIR, appendHistory, compare, readHistory, write } from "../lib/history.mjs";
|
|
23
23
|
import { FIXES, applyFix } from "../lib/fix.mjs";
|
|
24
24
|
import { evaluate, taskFile } from "../lib/eval.mjs";
|
|
@@ -47,7 +47,7 @@ Usage
|
|
|
47
47
|
|
|
48
48
|
Options
|
|
49
49
|
--json Machine-readable output
|
|
50
|
-
--out <dir>
|
|
50
|
+
--out <dir> Write every artifact here instead of .adsa/
|
|
51
51
|
--gate Exit non-zero if the score dropped, or is below --min
|
|
52
52
|
--min <n> Minimum acceptable total for --gate
|
|
53
53
|
--dry-run fix: show what would change, write nothing
|
|
@@ -157,9 +157,13 @@ function cmdAudit(dir, flags, out, json) {
|
|
|
157
157
|
return 1;
|
|
158
158
|
}
|
|
159
159
|
const scored = score(facts, config);
|
|
160
|
-
|
|
160
|
+
// Everything one run writes lands together. --out is read from where the command
|
|
161
|
+
// was typed, so an absolute path is absolute and a relative one is relative to
|
|
162
|
+
// the reader, not to the repository being audited.
|
|
163
|
+
const artefacts = flags.out ? resolve(process.cwd(), flags.out) : join(root, DIR);
|
|
164
|
+
const fresh = !exists(join(artefacts, "score.json"));
|
|
161
165
|
const file = scoreFile(facts, scored);
|
|
162
|
-
const previous = readJson(join(
|
|
166
|
+
const previous = readJson(join(artefacts, "score.json"));
|
|
163
167
|
const delta = compare(previous, file);
|
|
164
168
|
|
|
165
169
|
if (flags.json) {
|
|
@@ -191,14 +195,25 @@ function cmdAudit(dir, flags, out, json) {
|
|
|
191
195
|
}
|
|
192
196
|
}
|
|
193
197
|
|
|
194
|
-
const history = appendHistory(
|
|
195
|
-
write(join(
|
|
196
|
-
write(join(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
writeFileSync(join(
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
const history = appendHistory(artefacts, { date: file.generatedAt, total: file.total, max: file.max, dimensions: file.dimensions });
|
|
199
|
+
write(join(artefacts, "score.json"), file);
|
|
200
|
+
write(join(artefacts, "badge.json"), badgeEndpoint(file.total, file.max));
|
|
201
|
+
mkdirSync(artefacts, { recursive: true });
|
|
202
|
+
writeFileSync(join(artefacts, "report.html"), html(facts, scored, history));
|
|
203
|
+
writeFileSync(join(artefacts, "report.md"), markdown(facts, scored));
|
|
204
|
+
// A path that climbs out of the current directory reads better absolute than as
|
|
205
|
+
// a ladder of "..".
|
|
206
|
+
const near = relative(process.cwd(), artefacts);
|
|
207
|
+
const shown = !near ? "." : near.startsWith("..") ? artefacts : near;
|
|
208
|
+
if (!flags.json && !flags.quiet) {
|
|
209
|
+
out(dim(`\nReport: ${join(shown, "report.html")} · score: ${join(shown, "score.json")}`));
|
|
210
|
+
// Say once what the directory is for, rather than leave someone to guess
|
|
211
|
+
// whether a new folder in their repository belongs in the commit.
|
|
212
|
+
if (fresh && !flags.out && exists(join(root, ".git"))) {
|
|
213
|
+
out(dim(" score.json, badge.json and history.json are meant to be committed — the badge and the gate read them."));
|
|
214
|
+
out(dim(" report.html and report.md are rewritten every run; ignore them if you would rather not carry them."));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
202
217
|
|
|
203
218
|
if (flags.gate) {
|
|
204
219
|
const floor = flags.min ?? config.minScore ?? (previous ? previous.total : null);
|
package/lib/history.mjs
CHANGED
|
@@ -5,22 +5,24 @@ import { readJson } from "./fsx.mjs";
|
|
|
5
5
|
|
|
6
6
|
export const DIR = ".adsa";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/** Takes the directory the run writes into, not the repository root: with --out
|
|
9
|
+
* that is somewhere else entirely, and the history has to travel with the score. */
|
|
10
|
+
export function historyPath(dir) {
|
|
11
|
+
return join(dir, "history.json");
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
export function readHistory(
|
|
13
|
-
const json = readJson(historyPath(
|
|
14
|
+
export function readHistory(dir) {
|
|
15
|
+
const json = readJson(historyPath(dir));
|
|
14
16
|
return Array.isArray(json) ? json : [];
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
/** Appends a run, collapsing same-day reruns so the file does not grow per invocation. */
|
|
18
|
-
export function appendHistory(
|
|
19
|
-
const history = readHistory(
|
|
20
|
+
export function appendHistory(dir, entry) {
|
|
21
|
+
const history = readHistory(dir);
|
|
20
22
|
const day = entry.date.slice(0, 10);
|
|
21
23
|
const filtered = history.filter((h) => h.date.slice(0, 10) !== day);
|
|
22
24
|
filtered.push(entry);
|
|
23
|
-
write(historyPath(
|
|
25
|
+
write(historyPath(dir), filtered);
|
|
24
26
|
return filtered;
|
|
25
27
|
}
|
|
26
28
|
|