current commit
261024.31 · Forge links and pasted URLs lead to online repos
package main

import (
	"go/scanner"
	"go/token"
	"os"
	"os/exec"
	"path"
	"strings"
	"testing"
)

// The name lives in WORKING_NAME alone. Go code takes it from progName, the Makefile
// and the package files from WORKING_NAME, so a tracked file names the program
// only in prose: comments, README.md, doc/ and go.mod, which Go needs as
// a literal. A name such as www also occurs inside words that belong to
// others, which foreign strips first.
func TestNameHasOneSource(t *testing.T) {
	needGit(t)
	out, err := exec.Command("git", "ls-files").Output()
	if err != nil {
		t.Fatalf("git ls-files: %v", err)
	}
	lower := strings.ToLower(progName)
	for _, f := range strings.Fields(string(out)) {
		if f == "WORKING_NAME" || f == "go.mod" || f == "README.md" || strings.HasPrefix(f, "doc/") || strings.HasPrefix(f, "assets/fonts/") {
			continue
		}
		src, err := os.ReadFile(f)
		if err != nil {
			t.Fatal(err)
		}
		if path.Ext(f) == ".go" {
			var s scanner.Scanner
			fset := token.NewFileSet()
			s.Init(fset.AddFile(f, -1, len(src)), src, nil, 0)
			for {
				pos, tok, lit := s.Scan()
				if tok == token.EOF {
					break
				}
				if (tok == token.STRING || tok == token.CHAR) && strings.Contains(foreign.Replace(strings.ToLower(lit)), lower) {
					t.Errorf("%s: %s", fset.Position(pos), lit)
				}
			}
			continue
		}
		for i, line := range strings.Split(string(src), "\n") {
			if !strings.HasPrefix(strings.TrimSpace(line), "#") && strings.Contains(foreign.Replace(strings.ToLower(line)), lower) {
				t.Errorf("%s:%d: %s", f, i+1, line)
			}
		}
	}
}

// foreign removes the words that hold www without naming the program: web
// hosts, the host prefix a forge link may carry and the form media type.
var foreign = strings.NewReplacer("://www.", "://", `"www."`, "", "x-www-form-urlencoded", "")