All extract tests pass.
All dep5 tests pass.
All TOML tests pass.
All covered file tests pass.
Now let me create the test fixtures and project tests.
All project tests pass (the reuse-example test is correctly skipped since we haven't added the submodule yet).
Now let me add the submodule, fake_repository testdata, CI workflows, and README.
Let me check what's in this repo to understand the structure for the conformance test.
Good, the reuse-example has headers in source files and .license sidecars for images. No REUSE.toml or dep5, just header-only. Let me now run the conformance test to see if it passes.
The conformance test passes against the real reuse-example repo. Now let me create the fake_repository testdata and infrastructure files.
Now add a test using the fake_repository.
Now let me create the CI workflow and README.
Now the README.
Now let's run the full test suite and go vet.
All 64 tests pass with the race detector. Let me also run go vet.
Clean. Let me also clean up the unused function flagged by the linter.
Now check if filepath is still needed in dep5.go after removing that function.
Let me start by exploring sibling modules for patterns and the REUSE spec.
64 tests pass, go vet clean.
Everything is done. Here's a summary of what was built:
Files created (all under /Users/andrew/code/git-pkgs/reuse/):
| File | Purpose |
|---|---|
reuse.go | Core types: ReuseInfo, SourceType, PrecedenceType |
glob.go + glob_test.go | REUSE.toml glob matching (*, **, escapes) |
extract.go + extract_test.go | SPDX tag extraction from file contents (license, copyright, contributor, ignore blocks, snippets) |
dep5.go + dep5_test.go | Minimal Debian copyright format parser for .reuse/dep5 |
toml.go + toml_test.go | REUSE.toml parsing with annotations, precedence, string-or-array fields |
covered.go + covered_test.go | Covered file logic (ignored dirs/files, symlinks, zero-byte) |
project.go + project_test.go | Project-level parsing tying everything together with precedence resolution |
go.mod / go.sum | Module github.com/git-pkgs/reuse, Go 1.25.6, dep on BurntSushi/toml |
LICENSE | MIT (from SPDX) |
README.md | Usage examples |
.gitignore | *.test, *.prof |
.gitmodules | testdata/reuse-example submodule |
.github/workflows/ci.yml | CI matching sibling modules (with submodules: true) |
.github/dependabot.yml | Weekly updates for gomod + github-actions |
testdata/reuse-example/ | fsfe/reuse-example submodule for conformance testing |
testdata/fake_repository/ | Edge case fixtures (dual licensing, ignore blocks, sidecars, no-header files) |
Test results: 64 tests pass with -race, go vet clean. The conformance test against the real fsfe/reuse-example repo confirms all covered files get both license and copyright extracted correctly.
Ready for you to review. Want me to commit?
Good idea. Let me look at what we have and figure out a sensible split.
Good, the sibling modules (manifests, registries) use internal/core for shared types with type aliases in root. That pattern avoids import cycles when subpackages need shared types.
Let me read the current files to map out the dependency graph precisely.
Now let me write the plan.
Now let me check the zizmor workflow pattern and set up the project.
No zizmor workflow in sibling repos. Let me check the plan context for that, but I'll skip it since it's not in the siblings. Let me now start building.
Good. Now let me initialize the project.
Now let me create all the foundational files. I'll work through the build order, creating multiple files in parallel where possible.
Good - go mod tidy removed the toml dep since no code imports it yet. It'll come back when we add toml.go. Let me now create the core files.
One failure: **/*.go should match foo.go (no directory prefix). The Python reference confirms this - ** can match an empty string. The ** translates to .* which handles this, but the / between ** and * is the issue. **/ should optionally match nothing. Let me fix the glob translation.
The issue is that **/*.go becomes ^.*/[^/]*\.go$, which requires at least one /. When ** is followed by /, the / should be optional (since ** can match empty). I need to consume the trailing / after ** and make it part of the pattern as (.*/)?.