diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..ade6197 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,24 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: "[BUG] " +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. ... +2. ... +3. ... +4. ... + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..f1fb96f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[FEATURE REQUEST] " +labels: enhancement +assignees: '' + +--- + +**What is your use case?** +What real problem are you trying to solve? + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..cd88554 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "gomod" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0c07787 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,60 @@ +--- +name: release + +on: + push: + tags: + - 'v*' + +jobs: + markdownlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: articulate/actions-markdownlint@v1 + + unittests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22.x' + - name: Install dependencies + run: go mod download + - name: Test with the Go CLI + run: go test ./... + - name: Build + run: go build -v ./... + + build: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + needs: + - markdownlint + - unittests + steps: + - name: Define build timestamp + id: timestamp + run: echo "::set-output name=now::$(date -u +'%Y%m%d%H%M%S')" + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22.x' + - name: Install dependencies + run: go mod download + - name: Build & Publish release release + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser + version: '~> v2' + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 0000000..4ff1d10 --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,52 @@ +--- +name: verify + +on: + push: + branches: + - master + pull_request: + types: + - opened + - reopened + - edited + - synchronize + +jobs: + markdownlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: articulate/actions-markdownlint@v1 + + unittests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22.x' + - name: Install dependencies + run: go mod download + - name: Test with the Go CLI + run: go test ./... + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: '1.22.x' + - name: Install dependencies + run: go mod download + - name: Build project against .goreleaser.yaml + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser + version: '~> v2' + args: build --snapshot + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..ea17190 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,44 @@ +--- +version: 2 +builds: + - id: checksum + main: ./ + binary: checksum + ldflags: + - -s -w -X main.appVersion={{.Version}} -X main.buildTimestamp={{.Date}} + env: + - CGO_ENABLED=0 + goos: + - darwin + - dragonfly + - freebsd + - linux + - netbsd + - openbsd + - solaris + - windows + goarch: + # x86 + - amd64 + - "386" + + # ARM + - arm64 + - arm + + # MIPS + - mips64 + - mips64le + - mips + - mipsle + goamd64: ["v1", "v2", "v3"] + goarm: ["6", "7"] + gomips: ["hardfloat", "softfloat"] + mod_timestamp: "{{ .CommitTimestamp }}" +archives: + - format: binary +checksum: + name_template: "checksums.txt" + algorithm: sha256 + split: false + disable: false diff --git a/.goreleaser.yml b/.goreleaser.yml deleted file mode 100644 index e0c22ec..0000000 --- a/.goreleaser.yml +++ /dev/null @@ -1,75 +0,0 @@ -brews: - - name: checksum - github: - owner: teran - name: homebrew-tap - ids: - - default - commit_author: - name: "Igor Shishkin" - email: me@teran.ru - url_template: "https://github.com/teran/checksum/releases/download/{{ .Tag }}/{{ .ArtifactName }}" - folder: Formula - homepage: "https://github.com/teran/checksum" - description: "SHA256 file verification for consistency check purposes" - test: | - system "#{bin}/checksum --version" - install: | - bin.install "checksum" -builds: -- env: - - CGO_ENABLED=0 - goos: - - darwin - - dragonfly - - freebsd - - linux - - netbsd - - openbsd - - solaris - - windows - goarch: - # x86 - - amd64 - - 386 - - # ARM - - arm64 - - arm - - # MIPS - - mips64 - - mips64le - - mips - - mipsle - goarm: - - 6 - - 7 - gomips: - - hardfloat - - softfloat - ignore: - # Upstrem issue: - # vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go:400:12: undefined: uint128 - - goos: freebsd - goarch: arm64 -archives: - - id: default - format_overrides: - - goos: windows - format: zip - replacements: - 386: i386 - darwin: macOS -checksum: - name_template: 'checksums.txt' -snapshot: - name_template: "{{ .Tag }}-next" -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' -signs: - - artifacts: checksum diff --git a/Makefile b/Makefile deleted file mode 100644 index 5228b09..0000000 --- a/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -export PACKAGES := $(shell env GOPATH=$(GOPATH) go list ./...) -export VERSION := $(shell git describe --exact-match --tags $(git log -n1 --pretty='%h') || git rev-parse --verify --short HEAD || echo ${VERSION}) -export COMMIT := $(shell git rev-parse --verify --short HEAD) -export DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") - -all: clean build - -clean: - rm -vf bin/* - -build: build-macos build-linux build-windows - -build-macos: build-macos-amd64 - -build-linux: build-linux-amd64 - -build-windows: build-windows-amd64 - -build-macos-amd64: - GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}" -o bin/checksum-darwin-amd64 . - -build-linux-amd64: - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}" -o bin/checksum-linux-amd64 . - -build-windows-amd64: - GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}" -o bin/checksum-windows-amd64.exe . - -sign: - gpg --detach-sign --digest-algo SHA512 --no-tty --batch --output bin/checksum-darwin-amd64.sig bin/checksum-darwin-amd64 - gpg --detach-sign --digest-algo SHA512 --no-tty --batch --output bin/checksum-darwin-i386.sig bin/checksum-darwin-i386 - gpg --detach-sign --digest-algo SHA512 --no-tty --batch --output bin/checksum-linux-amd64.sig bin/checksum-linux-amd64 - gpg --detach-sign --digest-algo SHA512 --no-tty --batch --output bin/checksum-linux-i386.sig bin/checksum-linux-i386 - gpg --detach-sign --digest-algo SHA512 --no-tty --batch --output bin/checksum-windows-amd64.exe.sig bin/checksum-windows-amd64.exe - gpg --detach-sign --digest-algo SHA512 --no-tty --batch --output bin/checksum-windows-i386.exe.sig bin/checksum-windows-i386.exe - -test: - go test ./... - -verify: - gpg --verify bin/checksum-darwin-amd64.sig bin/checksum-darwin-amd64 - gpg --verify bin/checksum-darwin-i386.sig bin/checksum-darwin-i386 - gpg --verify bin/checksum-linux-amd64.sig bin/checksum-linux-amd64 - gpg --verify bin/checksum-linux-i386.sig bin/checksum-linux-i386 - gpg --verify bin/checksum-windows-amd64.exe.sig bin/checksum-windows-amd64.exe - gpg --verify bin/checksum-windows-i386.exe.sig bin/checksum-windows-i386.exe diff --git a/README.md b/README.md index db69b02..771bcde 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,75 @@ -checksum -======== +# checksum -Utility to store length, sha1, sha256 hashes of files in dedicated "database"(actually just a JSON file) to -verify it later as a part of consistency check with automatic new file indexing. +[![Verify](https://github.com/teran/checksum/actions/workflows/verify.yml/badge.svg?branch=master)](https://github.com/teran/checksum/actions/workflows/verify.yml) +[![Go Report Card](https://goreportcard.com/badge/github.com/teran/checksum)](https://goreportcard.com/report/github.com/teran/checksum) +[![Go Reference](https://pkg.go.dev/badge/github.com/teran/checksum.svg)](https://pkg.go.dev/github.com/teran/checksum) -Usage ------ +Utility to store length, sha1, sha256 hashes of files in dedicated "database" +(actually just a JSON file) to verify it later as a part of consistency check +with automatic new file indexing. +## Usage + + ```man Utility to verify files consistency with length, SHA1 and SHA256 -Usage: - checksum [FLAG]... +Usage: checksum [FLAG]... Version: - version: 7d4c766 - commit: 7d4c766 - built with: go1.12.5 - built at: 2019-05-14T23:51:55Z + version: 0.8.6-SNAPSHOT-641103d + built with: go1.22.4 + built at: 2024-06-30T06:41:18Z Description: checksum creates database (actually just a JSON file) to store file length, SHA1, SHA256 to verify file consistency and report if something goes wrong. Flags: - --concurrency, -c Amount of routines to spawn at the same time for checksum verification (type: int) - Default value is 8 for your system - --complete Completion for shell (type: bool) - --datadir, -d Data directory path to run new files scan (type: string) - --database, -D Database file path (required) (type: string) - --delete-missed Delete missed files from database (type: bool) - --generate-checksums-only Skip verification step and add new files only (type: bool) - --pattern, -p Pattern to match filenames which checking for new files (type: string) - Default is `.(3fr|ari|arw|bay|crw|cr2|cr3|cap|data|dcs|dcr|drf|eip|erf|fff|gpr|iiq|k25|kdc|mdc|mef|mos|mrw|nef|nrw|obm|orf|pef|ptx|pxn|r3d|raf|raw|rwl|rw2|rwz|sr2|srf|srw|x3f)$` - --skip-failed, --sf Skip FAIL verification results from output (type: bool) - --skip-missed, --sm Skip MISS verification results from output (type: bool) - --skip-ok, --so Skip OK verification results from output (type: bool) - --progressbar Show progress bar instead of printing handled files (type: bool) - --version, -V Print application and Golang versions (type: bool) - -h, --help show help (type: bool) + --concurrency, -c Amount of routines to spawn at the same time for checksum verification (type: int) + Default value is 20 for your system + --complete Completion for shell (type: bool) + --datadir, -d Data directory path to run new files scan (type: string) + --database, -D Database file path (required) (type: string) + --delete-missed Delete missed files from database (type: bool) + --generate-checksums-only Skip verification step and add new files only (type: bool) + --pattern, -p Pattern to match filenames which checking for new files (type: string) + Default is `.(3fr|ari|arw|bay|crw|cr2|cr3|cap|data|dcs|dcr|drf|eip|erf|fff|gpr|iiq|k25|kdc|mdc|mef|mos|mrw|nef|nrw|obm|orf|pef|ptx|pxn|r3d|raf|raw|rwl|rw2|rwz|sr2|srf|srw|x3f)$` + --skip-failed, --sf Skip FAIL verification results from output (type: bool) + --skip-missed, --sm Skip MISS verification results from output (type: bool) + --skip-ok, --so Skip OK verification results from output (type: bool) + --progressbar Show progress bar instead of printing handled files (type: bool) + --version, -V Print application and Golang versions (type: bool) + -h, --help show help (type: bool) ``` + - -Why not shasum/md5sum/etc.? ---------------------------- +## Why to use checksum but md5sum, shasum and other checksum provides straight workflow for verification and adding new files processes -to avoid remembering someting like `find $dir | xargs md5sum >> /tmp/database.txt`. +to avoid remembering something like `find $dir | xargs md5sum >> /tmp/database.txt`. -checkum automatically: +checksum automatically: * verifies files * adds new * report about fails and misses -How to install --------------- +## How to install -Just refer to [releases page](https://github.com/teran/checksum/releases) and download appropriate binary for your platform or build your own one right from master. +Just refer to [releases page](https://github.com/teran/checksum/releases) and +download appropriate binary for your platform or build your own one right from +master. -Build ------ +## Build System-wide requirements: * Go +* goreleaser Build: ```bash -make predependencies build +goreleaser build --snapshot --clean ``` diff --git a/config.go b/config.go index 3924bd4..3a92949 100644 --- a/config.go +++ b/config.go @@ -39,7 +39,7 @@ func newConfig() *config { } if c.DbPath == "" { - set.Help(true) + set.Help() os.Exit(1) } @@ -60,10 +60,9 @@ func (c *config) Metadata() map[string]flag.Flag { version = fmt.Sprintf(` version: %s - commit: %s built with: %s built at: %s - `, version, commit, runtime.Version(), date) + `, appVersion, runtime.Version(), buildTimestamp) desc = ` checksum creates database (actually just a JSON file) to store file length, SHA1, SHA256 diff --git a/go.mod b/go.mod index 25ee2d7..bae2449 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,11 @@ module github.com/teran/checksum go 1.14 + +require ( + github.com/cosiner/flag v0.5.2 + github.com/fatih/color v1.17.0 + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/stretchr/testify v1.9.0 + gopkg.in/cheggaaa/pb.v1 v1.0.28 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1ce5094 --- /dev/null +++ b/go.sum @@ -0,0 +1,40 @@ +github.com/cosiner/argv v0.0.1 h1:2iAFN+sWPktbZ4tvxm33Ei8VY66FPCxdOxpncUGpAXE= +github.com/cosiner/argv v0.0.1/go.mod h1:p/NrK5tF6ICIly4qwEDsf6VDirFiWWz0FenfYBwJaKQ= +github.com/cosiner/flag v0.5.2 h1:dcI3ExLwrYt/wgg1RXZBn7FFFn3Mi5Lyremoa7Tt5ts= +github.com/cosiner/flag v0.5.2/go.mod h1:+zDQNSDNnkR7CGUlSrw2d/5S26bL91amx0FVUbnmLrU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index b378413..98238e5 100644 --- a/main.go +++ b/main.go @@ -22,9 +22,8 @@ import ( var ( wg sync.WaitGroup - version = "No version specified(probably trunk build)" - commit = "master" - date = "0000-00-00T00:00:00Z" + appVersion = "No version specified(probably trunk build)" + buildTimestamp = "0000-00-00T00:00:00Z" db *database.Database filePattern *regexp.Regexp diff --git a/operations.go b/operations.go index ec08968..a5e1d5f 100644 --- a/operations.go +++ b/operations.go @@ -92,7 +92,7 @@ func verify(path string, length int64, sha1, sha256 string) bool { } func printVersion() { - fmt.Printf("checksum version: %s\n", version) + fmt.Printf("checksum version: %s\n", appVersion) fmt.Printf("Built wih Go version: %s\n", runtime.Version()) }