Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions cmd/lab/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ const (
exitCannot = 2
)

// The three documents the last paragraph of the usage text names. They are
// named rather than restated, because a paraphrase printed by a binary somebody
// downloaded months ago is a copy of a document that has since moved on, and the
// reader has no way to tell which of the two they are holding.
//
// TWO LIMITS THAT BELONG HERE RATHER THAN ONLY IN THE ISSUE. A notice is not a
// control. Printing it stops nothing, and it should not be counted as a thing
// that prevents misuse when somebody later asks what does. And a notice an
// operator has to run a verb to see is weaker than one sitting in the download
// beside the binary, because the operator who most needs it is the one who runs
// the thing without asking it for help first. Both routes exist for that
// reason rather than either alone; the download half is issue #36 and has no
// archive to be carried in yet.
//
// Nothing outside this package holds these strings to the tree. The paths leg
// of the invariants scan reads this repository's own documents, which is the
// files at the root and everything under docs/, and a path named inside the
// runner is outside that subject by the leg's own reckoning. So the guard is
// the test beside this declaration and there is no second one.
var documentsAnOperatorIsOwed = []string{
"NOTICE.md",
"LICENSE",
"docs/privacy.md",
}

const usage = `lab reads this repository and reports what it examined.

lab check [path] walk the tree at path, default ".", and report
Expand All @@ -58,6 +83,10 @@ const usage = `lab reads this repository and reports what it examined.
lab help print this text

lab writes nothing to the tree it reads.

NOTICE.md says what this program is for, LICENSE carries the terms it is under,
and docs/privacy.md says what stays on the host. Reading them is on you; this
text only says where they are.
`

// THIS IS WHERE THE RUNNER READS THE TIME, and it is read once. Everything
Expand Down
32 changes: 32 additions & 0 deletions cmd/lab/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main
import (
"bytes"
"errors"
"os"
"path/filepath"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -215,3 +217,33 @@ func TestTheDocumentedCodesAreTheNumbersTheRecordFixes(t *testing.T) {
}
}
}

// TestHelpNamesTheDocumentsAnOperatorIsOwed holds the last paragraph of the
// usage text to the three files it points at. An operator who reads that
// paragraph and then looks for one of the files is the reader this asserts for,
// and both halves of the walk they make are here: that the text names the file,
// and that the file is in the tree to be found.
//
// The second half is the one that earns its place. A pointer in the runner is
// outside the subject of the invariants paths leg, which reads the files at the
// root and everything under docs/ and holds those to the paths they name. So a
// document deleted or moved under this paragraph reddens nothing anywhere else,
// and a binary would go on telling operators to read a file that is not there.
//
// What it does not judge is whether any of the three says what it should. That
// is a reading of prose and no test here makes it.
func TestHelpNamesTheDocumentsAnOperatorIsOwed(t *testing.T) {
var out, errOut bytes.Buffer
if got := run([]string{"help"}, &out, &errOut, ordinary(realWalk)); got != exitClean {
t.Fatalf("exit code %d, want %d", got, exitClean)
}

for _, document := range documentsAnOperatorIsOwed {
if !strings.Contains(out.String(), document) {
t.Errorf("the help output does not name %s:\n%s", document, out.String())
}
if _, err := os.Stat(filepath.Join("..", "..", filepath.FromSlash(document))); err != nil {
t.Errorf("the help output names %s and it is not in this tree: %v", document, err)
}
}
}
Loading