Run all linting in Docker via Dockerfile.lint (closes #30) #31

Open
clawbot wants to merge 20 commits from next into main
Showing only changes of commit 2fcb3e6ced - Show all commits
+28 -9
View File
@@ -39,11 +39,12 @@
// one pass over literals, so a value that itself names another variable, a
// value built by a make function (`$(shell ...)`, `$(addprefix ...)`), and the
// body of a `define`/`endef` block are not expanded and not followed. A
// `docker build` resolves to the file named by `-f`, `-f=`, `--file` or
// `--file=`, wherever in the invocation that flag sits, and to `Dockerfile`
// when it names none; a Dockerfile chosen some other way — a bundled short
// flag cluster (`-qf <file>`), a value this walk cannot expand to a literal —
// resolves to the default rather than to the real file. Within those edges, a
// `docker build` resolves to the file named by `-f`, `-f=`, `-f<file>` with
// the value attached to the flag, `--file` or `--file=`, wherever in the
// invocation that flag sits, and to `Dockerfile` when it names none; a
// Dockerfile chosen some other way — a bundled short flag cluster
// (`-qf <file>`), a value this walk cannot expand to a literal — resolves to
// the default rather than to the real file. Within those edges, a
// prettier call is caught wherever it is added.
//
// Two entrypoints are walked, because they cover different graphs: `make check`
@@ -437,16 +438,19 @@ const edgesOf = (line: string): string[] => {
// it the count would miss the one invocation that is supposed to survive.
//
// Every spelling of the file flag is read, not just `-f <file>`. Docker
// accepts `--file <file>`, `--file=<file>` and `-f=<file>` for the same
// thing, and matching `-f ` alone resolved all of them to the default
// accepts `--file <file>`, `--file=<file>`, `-f=<file>` and the value
// attached to the short flag as one token (`-f<file>`) for the same thing,
// and matching `-f ` alone resolved all of them to the default
// `Dockerfile` edge — so `docker build --file=Dockerfile.lint .` in a
// recipe was followed into the wrong file, counted nothing, and reported
// green. The flag is searched for anywhere in the invocation, as `-f`
// already was, because a real build line wraps it in `--build-arg` and
// other flags. A leading `\s` is required so that a longer flag ending in
// the same letters cannot supply the match.
// the same letters cannot supply the match, and the attached form is
// allowed only for the short flag, so that `--force-rm` — a long flag that
// merely starts with the same letters — still does not read as one.
if (/\bdocker\s+build\b/.test(line)) {
const file = /\s(?:-f|--file)[=\s]+(\S+)/.exec(line);
const file = /\s(?:--file[=\s]+|-f=?\s*)(\S+)/.exec(line);
edges.push(`docker:${file === null ? "Dockerfile" : file[1]}`);
}
@@ -1021,6 +1025,21 @@ describe("the resolver reads what the shell would run", () => {
]);
});
// The value may be attached to the short flag with no separator at all:
// `-fDockerfile.lint` is a single token, and the flag parser reads it as
// `-f` naming that file, exactly as `-f Dockerfile.lint` does. Requiring a
// separator sent it to the default `Dockerfile` edge instead — the same
// false green as the long spellings above, and one the header promised was
// followed: a second prettier pass added as `docker build
// -fDockerfile.lint .` was resolved into the wrong file, counted nothing,
// and left the build green. `-fFILE` is an ordinary thing for a human to
// write, so it is followed rather than merely documented as unfollowed.
it("follows a short file flag with its value attached", () => {
expect(edgesOf("docker build -fDockerfile.lint .")).toEqual([
"docker:Dockerfile.lint",
]);
});
// The flag is found anywhere in the invocation rather than at a fixed
// position, matching how `-f` was already read, since a real build line
// carries `--build-arg` and friends around it.