A CLI-first git forge.

cli forge git self-hosted

https://gitbay.org

Commit 794796910f

794796910f5fdc942f064f5e9e28a93b722586f5

parent: 439734b5d0

Verified · cmc

cmc <hello@cleberg.net> · 2026-08-25T15:33:14Z

Recognize 0BSD; stop mislabeling it as ISC

ISC is the 0BSD grant plus the notice-retention clause, so the old
permission-sentence marker matched both. ISC now matches on the clause,
0BSD on the title or the bare grant. License text is whitespace-collapsed
before matching so markers survive line wraps.
e2e/design_test.go +3 −2
@@ -55,12 +55,13 @@ func TestReadmeRelativeLinks(t *testing.T) {
5555 }
5656 // Explore rows carry topics, license, and updated date.
5757 inst.ssh(t, aliceKey, "", "repo", "topics", "add", "alice/site", "web")
58 os.WriteFile(filepath.Join(dir, "LICENSE"), []byte("Permission to use, copy, modify, and/or distribute this software...\n"), 0o644)
58 // Bare 0BSD grant (no notice-retention clause), wrapped mid-sentence.
59 os.WriteFile(filepath.Join(dir, "LICENSE"), []byte("Permission to use, copy, modify,\nand/or distribute this software for any\npurpose with or without fee is hereby granted.\n"), 0o644)
5960 mustGit(t, dir, env, "add", ".")
6061 mustGit(t, dir, env, "commit", "-q", "-m", "license")
6162 mustGit(t, dir, env, "push", "-q", "origin", "main")
6263 _, body = inst.get(t, "/explore")
63 for _, want := range []string{`href="/explore?q=web"`, "ISC", "updated 20"} {
64 for _, want := range []string{`href="/explore?q=web"`, "0BSD", "updated 20"} {
6465 if !strings.Contains(body, want) {
6566 t.Errorf("explore row missing %q", want)
6667 }
internal/httpd/readme.go +8 −2
@@ -23,7 +23,12 @@ var licenseChecks = []struct{ marker, name string }{
2323 {"BSD 3-Clause", "BSD-3-Clause"},
2424 {"BSD 2-Clause", "BSD-2-Clause"},
2525 {"Redistribution and use in source and binary forms", "BSD"},
26 {"Permission to use, copy, modify, and/or distribute", "ISC"},
26 {"BSD Zero Clause License", "0BSD"},
27 {"Zero Clause BSD", "0BSD"},
28 // ISC is the 0BSD grant plus the notice-retention clause; match on the
29 // clause so title-less 0BSD files don't read as ISC.
30 {"hereby granted, provided that the above copyright notice", "ISC"},
31 {"Permission to use, copy, modify, and/or distribute", "0BSD"},
2732 {"This is free and unencumbered software", "Unlicense"},
2833 {"CC0", "CC0"},
2934 }
@@ -36,7 +41,8 @@ func detectLicense(dir, ref string) string {
3641 if err != nil {
3742 continue
3843 }
39 text := string(raw)
44 // Collapse whitespace so markers match across line wraps.
45 text := strings.Join(strings.Fields(string(raw)), " ")
4046 for _, c := range licenseChecks {
4147 if strings.Contains(text, c.marker) {
4248 return c.name