diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a3e8a8..e7f1789 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -163,7 +163,7 @@ jobs: - name: deadcode run: | go install golang.org/x/tools/cmd/deadcode@latest - deadcode ./... 2>&1 | head -50 + deadcode ./... # ------------------------------------------------------------------------- # Duplication detection — jscpd. @@ -172,13 +172,13 @@ jobs: name: duplication runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: '20' - name: jscpd run: | - npx jscpd --min-lines 5 --min-tokens 50 --reporters console --blame . 2>&1 | head -50 + npx --yes jscpd@5.0.12 --min-lines 5 --min-tokens 50 --reporters console --blame . # ------------------------------------------------------------------------- # Fuzz the diff parser, which consumes untrusted/adversarial unified-diff @@ -196,9 +196,9 @@ jobs: cache: true - name: Run fuzz targets run: | - go test -fuzz=FuzzParseDiff -fuzztime=60s ./internal/diff - go test -fuzz=FuzzParseHunkHeader -fuzztime=60s ./internal/diff - go test -fuzz=FuzzParseUnifiedDiff -fuzztime=60s ./internal/diff + go test -fuzz=FuzzParseDiff -fuzztime=55s ./internal/diff + go test -fuzz=FuzzParseHunkHeader -fuzztime=55s ./internal/diff + go test -fuzz=FuzzParseUnifiedDiff -fuzztime=55s ./internal/diff # ------------------------------------------------------------------------- # Cross-platform build matrix — only for repos that produce a binary. diff --git a/internal/diff/diff.go b/internal/diff/diff.go index e3f5a72..e355822 100644 --- a/internal/diff/diff.go +++ b/internal/diff/diff.go @@ -131,10 +131,12 @@ func parseFileChunk(chunk string) File { file.OldPath = strings.TrimPrefix(line, "--- a/") case strings.HasPrefix(line, "--- /dev/null"): file.Added = true + file.Deleted = false case strings.HasPrefix(line, "+++ b/"): file.Path = strings.TrimPrefix(line, "+++ b/") case strings.HasPrefix(line, "+++ /dev/null"): file.Deleted = true + file.Added = false case strings.HasPrefix(line, "rename from "): file.OldPath = strings.TrimPrefix(line, "rename from ") file.Renamed = true diff --git a/internal/diff/diff_test.go b/internal/diff/diff_test.go index 15c1ce2..448e150 100644 --- a/internal/diff/diff_test.go +++ b/internal/diff/diff_test.go @@ -167,6 +167,19 @@ index abc..def 100644 } } +func TestParse_NotBothAddedAndDeleted(t *testing.T) { + diff := `diff --git a/devnull b/devnull +--- /dev/null ++++ /dev/null +` + files := Parse(diff) + for _, f := range files { + if f.Added && f.Deleted { + t.Errorf("file %q should not be both added and deleted", f.Path) + } + } +} + func TestParse_Empty(t *testing.T) { files := Parse("") if len(files) != 0 {