diff --git a/SPECIFICATION.md b/SPECIFICATION.md index 7108ba2..042ef9c 100644 --- a/SPECIFICATION.md +++ b/SPECIFICATION.md @@ -38,11 +38,14 @@ by another process leading to an inconsistent state). If the file lock is obtained, the process shall first read it and parse it completely to extract the sumfile version. If this fails the process shall exit immediately unless the `-force` flag is used (see details below). Else it shall -recompute checksums for all actions used in the repository (see [Computing -Checksums]) using the best available hashing algorithm. It shall then store them -in a sumfile (see [Storing Checksums]) using the same sumfile version as before -and releases the lock. As a consequence, this adds missing and removes redundant -checksums from the sumfile. +compute checksums for all new actions used in the repository (see [Computing +Checksums]) using the best available hashing algorithm. Here, a new action also +includes a new version of a previously used action. Additionally, it should +remove any entry which is no longer in use. No existing checksum for a used +action shall be updated unless the `-force` flag is used. It shall then store +them in a sumfile (see [Storing Checksums]) using the same sumfile version as +before and releases the lock. In short, updating will only add new and remove +old checksums from an existing sumfile. With the `-force` flag the process will ignore errors in the sumfile and fix those while updating. If the sumfile version can still be determined from diff --git a/internal/ghasum/operations.go b/internal/ghasum/operations.go index 26aa66c..5ebe6a6 100644 --- a/internal/ghasum/operations.go +++ b/internal/ghasum/operations.go @@ -18,6 +18,7 @@ import ( "errors" "io" "io/fs" + "slices" "github.com/ericcornelissen/ghasum/internal/cache" "github.com/ericcornelissen/ghasum/internal/checksum" @@ -123,6 +124,7 @@ func Update(cfg *Config, force bool) error { } version, err := version(raw) + oldChecksums, _ := decode(raw) if err != nil { if !force { return errors.Join(ErrSumfileRead, err) @@ -143,6 +145,15 @@ func Update(cfg *Config, force bool) error { return err } + for i, entry := range checksums { + for _, oldEntry := range oldChecksums { + if slices.Equal(entry.ID, oldEntry.ID) { + checksums[i] = oldEntry + break + } + } + } + encoded, err := encode(version, checksums) if err != nil { return err diff --git a/testdata/update/success.txtar b/testdata/update/success.txtar index 01a3421..feb8962 100644 --- a/testdata/update/success.txtar +++ b/testdata/update/success.txtar @@ -14,12 +14,34 @@ stdout 'Ok' ! stderr . cmp changed/.github/workflows/gha.sum want/gha.sum +# Removal necessary +! cmp remove/.github/workflows/gha.sum want/gha.sum + +exec ghasum update -cache .cache/ remove/ +stdout 'Ok' +! stderr . +cmp remove/.github/workflows/gha.sum want/gha.sum + +# Preserve existing values +! cmp preserve/.github/workflows/gha.sum want/gha-preserve.sum + +exec ghasum update -cache .cache/ preserve/ +stdout 'Ok' +! stderr . +cmp preserve/.github/workflows/gha.sum want/gha-preserve.sum + -- want/gha.sum -- version 1 actions/checkout@v4.1.1 KsR9XQGH7ydTl01vlD8pIZrXhkzXyjcnzhmP+/KaJZI= actions/setup-go@v5.0.0 7lPZupz84sSI3T+PiaMr/ML3XPqJaEo7dMaPsQUnM6c= golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI= +-- want/gha-preserve.sum -- +version 1 + +actions/checkout@v4.1.1 this-is-invalid-but-should-not-be-updated +actions/setup-go@v5.0.0 7lPZupz84sSI3T+PiaMr/ML3XPqJaEo7dMaPsQUnM6c= +golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI= -- unchanged/.github/workflows/gha.sum -- version 1 @@ -55,6 +77,57 @@ golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlC name: Example workflow on: [push] +jobs: + example: + name: example + runs-on: ubuntu-22.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.1 + - name: Install Go + uses: actions/setup-go@v5.0.0 + with: + go-version-file: go.mod + - name: golangci-lint + uses: golangci/golangci-lint-action@3a91952 + - name: This step does not use an action + run: Echo 'hello world!' +-- remove/.github/workflows/gha.sum -- +version 1 + +actions/checkout@main PKruFKnotZi8RQ196H3R7c5bgw9+mfI7BN/h0A7XiV8= +actions/checkout@v4.1.1 KsR9XQGH7ydTl01vlD8pIZrXhkzXyjcnzhmP+/KaJZI= +actions/setup-go@v5.0.0 7lPZupz84sSI3T+PiaMr/ML3XPqJaEo7dMaPsQUnM6c= +golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI= +-- remove/.github/workflows/workflow.yml -- +name: Example workflow +on: [push] + +jobs: + example: + name: example + runs-on: ubuntu-22.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.1 + - name: Install Go + uses: actions/setup-go@v5.0.0 + with: + go-version-file: go.mod + - name: golangci-lint + uses: golangci/golangci-lint-action@3a91952 + - name: This step does not use an action + run: Echo 'hello world!' +-- preserve/.github/workflows/gha.sum -- +version 1 + +actions/checkout@v4.1.1 this-is-invalid-but-should-not-be-updated +actions/setup-go@v4.1.0 RQ197c5MRKiujfm0VpQ19p7BN/07XFW9H3R7GH36RXi= +golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI= +-- preserve/.github/workflows/workflow.yml -- +name: Example workflow +on: [push] + jobs: example: name: example