diff --git a/.github/release.yml b/.github/release.yml
new file mode 100644
index 0000000..6ad1455
--- /dev/null
+++ b/.github/release.yml
@@ -0,0 +1,29 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+changelog:
+ exclude:
+ labels:
+ - ignore-for-release
+ authors:
+ - octocat
+ categories:
+ - title: Breaking Changes 🛠
+ labels:
+ - breaking
+ - title: Exciting New Features 🎉
+ labels:
+ - feature
+ - title: Fixes 🔧
+ labels:
+ - fix
+ - title: Other Changes
+ labels:
+ - "*"
diff --git a/.github/settings.yml b/.github/settings.yml
new file mode 100644
index 0000000..d5b309d
--- /dev/null
+++ b/.github/settings.yml
@@ -0,0 +1,20 @@
+_extends: .github
+
+repository:
+ # See https://developer.github.com/v3/repos/#edit for all available settings.
+
+ # A short description of the repository that will show up on GitHub
+ description: 📦 Template repository for AtomicGo repositories
+
+ # A comma-separated list of topics to set on the repository
+ topics: atomicgo, hacktoberfest, go, golang, golang-library
+
+ # Either `true` to enable issues for this repository, `false` to disable them.
+ has_issues: true
+
+ # Either `true` to enable projects for this repository, or `false` to disable them.
+ # If projects are disabled for the organization, passing `true` will cause an API error.
+ has_projects: false
+
+ # Either `true` to enable the wiki for this repository, `false` to disable it.
+ has_wiki: false
diff --git a/.github/workflows/atomicgo.yml b/.github/workflows/atomicgo.yml
new file mode 100644
index 0000000..ca79427
--- /dev/null
+++ b/.github/workflows/atomicgo.yml
@@ -0,0 +1,190 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+name: AtomicGo
+
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: write
+ packages: write
+
+jobs:
+ test:
+ name: Test Go Code
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ steps:
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: stable
+
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v3
+
+ - name: Get dependencies
+ run: go get -v -t -d ./...
+
+ - name: Build
+ run: go build -v .
+
+ - name: Test
+ run: go test -coverprofile="coverage.txt" -covermode=atomic -v -p 1 .
+
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v3
+
+ build:
+ name: Build AtomicGo Package
+ runs-on: ubuntu-latest
+ needs: test
+
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Download assets
+ run: |
+ mkdir -p .templates
+ wget https://raw.githubusercontent.com/atomicgo/atomicgo/main/templates/example.gotxt -O .templates/example.gotxt
+ wget https://raw.githubusercontent.com/atomicgo/atomicgo/main/templates/readme.md -O .templates/readme.md
+
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: stable
+
+ - name: Install Go tools
+ run: |
+ go install github.com/robertkrimen/godocdown/godocdown@latest
+ go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest
+ go install github.com/caarlos0/svu@latest
+
+ - name: Set up Git configuration
+ run: |
+ REPO_FULLNAME="${{ github.repository }}"
+ echo "::group::Setup git"
+ git config --global --add safe.directory /github/workspace
+
+ echo "::notice::Login into git"
+ git config --global user.email "git@marvinjwendt.com"
+ git config --global user.name "MarvinJWendt"
+
+ echo "::notice::Ignore workflow files (we may not touch them)"
+ git update-index --assume-unchanged .github/workflows/*
+
+ - name: Generate README.md
+ run: |
+ echo "::group::Generate README.md"
+ FILE=./.github/atomicgo/custom_readme
+ INCLUDE_UNEXPORTED=./.github/atomicgo/include_unexported
+ if test -f "$FILE"; then
+ echo "::notice::.github/custom_readme is present. Not generating a new readme."
+ else
+ echo "::notice::Running Godocdown"
+ $(go env GOPATH)/bin/godocdown -template ./.templates/readme.md >README.md
+ echo "::notice::Running gomarkdoc"
+ GOMARKDOC_FLAGS="--template-file example=./.templates/example.gotxt"
+ if test -f "$INCLUDE_UNEXPORTED"; then
+ GOMARKDOC_FLAGS+=" -u"
+ fi
+
+ $(go env GOPATH)/bin/gomarkdoc $GOMARKDOC_FLAGS --repository.url "https://github.com/${{ github.repository }}" --repository.default-branch main --repository.path / -e -o README.md .
+ fi
+ echo "::endgroup::"
+
+ - name: Run custom CI system
+ run: |
+ echo "::group::Run custom CI system"
+ echo "::notice::Counting unit tests"
+ unittest_count=$(go test -v -p 1 ./... | tee /dev/tty | grep -c "RUN")
+
+ echo "::notice::Replacing badge in README.md"
+ sed -i 's|> $GITHUB_ENV
+ echo "::notice::Current version is $(svu current)"
+
+ - name: Calculate next version
+ id: next_version
+ run: |
+ echo "next_version=$(svu next)" >> $GITHUB_ENV
+ echo "::notice::Next version is $(svu next)"
+
+ - name: Check if release is needed
+ id: check_release
+ run: |
+ echo "release_needed=$( [ '${{ env.current_version }}' != '${{ env.next_version }}' ] && echo true || echo false )" >> $GITHUB_ENV
+
+ - name: Create tag
+ if: env.release_needed == 'true'
+ run: |
+ git tag -a ${{ env.next_version }} -m "Release v${{ env.next_version }}"
+ git push origin ${{ env.next_version }}
+ sleep 5 # sleep for 5 seconds to allow GitHub to process the tag
+
+ - name: Release
+ if: env.release_needed == 'true'
+ uses: softprops/action-gh-release@v2
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ generate_release_notes: true
+ tag_name: ${{ env.next_version }}
+
+ - name: Tweet release
+ if: env.release_needed == 'true' && !github.event.repository.private
+ uses: Eomm/why-don-t-you-tweet@v1
+ with:
+ tweet-message:
+ "New ${{ github.event.repository.name }} release: ${{ env.next_version }} 🚀
+
+ Try it out: atomicgo.dev/${{ github.event.repository.name }}
+
+ #go #golang #opensource #library #release #atomicgo"
+ env:
+ TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
+ TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
+ TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
+ TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
new file mode 100644
index 0000000..64da3c1
--- /dev/null
+++ b/.github/workflows/go.yml
@@ -0,0 +1,42 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+name: Go
+
+on:
+ pull_request:
+
+jobs:
+ test:
+ name: Test Go code
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ steps:
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: stable
+
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v3
+
+ - name: Get dependencies
+ run: go get -v -t -d ./...
+
+ - name: Build
+ run: go build -v .
+
+ - name: Test
+ run: go test -coverprofile="coverage.txt" -covermode=atomic -v -p 1 .
+
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v1
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..5701467
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,30 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+name: Code Analysis
+
+on: [push, pull_request]
+
+jobs:
+ lint:
+ if: "!contains(github.event.head_commit.message, 'autoupdate')"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Go
+ uses: actions/setup-go@v4
+ with:
+ go-version: "stable"
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ version: latest
diff --git a/.github/workflows/tweet-release.yml b/.github/workflows/tweet-release.yml
new file mode 100644
index 0000000..3175850
--- /dev/null
+++ b/.github/workflows/tweet-release.yml
@@ -0,0 +1,36 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+name: Tweet release
+
+# Listen to the `release` event
+on:
+ release:
+ types: [published]
+
+jobs:
+ tweet:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: Eomm/why-don-t-you-tweet@v1
+ # We don't want to tweet if the repository is not a public one
+ if: ${{ !github.event.repository.private }}
+ with:
+ tweet-message:
+ "New ${{ github.event.repository.name }} release: ${{ github.event.release.tag_name }}! 🎉
+
+ Try it out: atomicgo.dev/${{ github.event.repository.name }}
+
+ #go #golang #opensource #library #release #atomicgo"
+ env:
+ TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
+ TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
+ TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
+ TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f81cc48
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,53 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+# Binaries
+*.exe
+*.exe~
+*.so
+
+# Go specifics
+
+## Test binary, built with `go test -c`
+*.test
+
+## Output of the go coverage tool
+*.out
+
+## Vendored dependencies
+vendor/
+
+# IDEs
+
+## IntelliJ
+.idea
+*.iml
+out
+gen
+
+## Visual Studio Code
+.vscode
+*.code-workspace
+
+# Operating System Files
+
+## macOS
+.DS_Store
+
+# Other
+
+## Experimenting folder
+experimenting
+
+## CI assets
+.templates
+
+## Taskfile
+.task
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..f2444da
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,195 @@
+# ┌───────────────────────────────────────────────────────────────────┐
+# │ │
+# │ IMPORTANT NOTE │
+# │ │
+# │ This file is synced with https://github.com/atomicgo/template │
+# │ │
+# │ Please apply all changes to the template repository │
+# │ │
+# └───────────────────────────────────────────────────────────────────┘
+
+run:
+ timeout: 3m
+
+linters:
+ enable:
+ - errcheck # check for unchecked errors
+ - gosimple # specializes in simplifying code
+ - govet # roughly the same as go vet
+ - ineffassign # detects when assignments to existing variables are not used
+ - staticcheck # staticcheck is a go vet on steroids, applying static analysis to your code
+ - unused # finds unused variables and constants
+ - asasalint # check `any` variadic funcs
+ - asciicheck # check for non-ASCII characters
+ - bidichk # check for dangerous unicode character sequences
+ - bodyclose # check that HTTP response body is closed
+ - canonicalheader # check that canonical headers are used
+ - containedctx # detects struct contained context.Context field
+ - contextcheck # check whether the function uses a non-inherited context
+ - decorder # check declaration order and count of types, constants, variables and functions
+ - dupl # finds duplicated code
+ - durationcheck # check for two durations multiplied together
+ - err113 # check the errors handling expressions
+ - errchkjson # checks types passed to the json encoding functions
+ - errname # check error names
+ - errorlint # check error wrapping
+ - exhaustive # check that all enum cases are handled
+ - exportloopref # checks for pointers to enclosing loop variables
+ - fatcontext # detects nested contexts in loops
+ - forcetypeassert # finds unchecked type assertions
+ - funlen # check for long functions
+ - gci # controls Go package import order and makes it always deterministic
+ - gocheckcompilerdirectives # checks that go compiler directive comments (//go:) are valid
+ - gochecksumtype # exhaustiveness checks on Go "sum types"
+ - gocognit # check for high cognitive complexity
+ - gocritic # Go source code linter that provides a ton of rules
+ - gocyclo # checks cyclomatic complexity
+ - gofmt # checks whether code was gofmt-ed
+ - gofumpt # checks whether code was gofumpt-ed
+ - goimports # check import statements are formatted according to the 'goimport' command
+ - goprintffuncname # checks that printf-like functions are named with f at the end
+ - gosec # inspects source code for security problems
+ - gosmopolitan # report certain i18n/l10n anti-patterns in your Go codebase
+ - inamedparam # reports interfaces with unnamed method parameters
+ - interfacebloat # check for large interfaces
+ - intrange # find places where for loops could make use of an integer range
+ - lll # check for long lines
+ - maintidx # measures the maintainability index of each function
+ - mirror # reports wrong mirror patterns of bytes/strings usage
+ - misspell # finds commonly misspelled English words
+ - musttag # enforce field tags in (un)marshaled structs
+ - nakedret # checks that functions with naked returns are not longer than a maximum size
+ - nestif # reports deeply nested if statements
+ - nilerr # finds code that returns nil even if it checks that the error is not nil
+ - nilnil # checks that there is no simultaneous return of nil error and an invalid value
+ - nlreturn # checks for a new line before return and branch statements to increase code clarity
+ - nolintlint # reports ill-formed or insufficient nolint directives
+ - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
+ - paralleltest # detects missing usage of t.Parallel() method in your Go test
+ - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative
+ - prealloc # finds slice declarations that could potentially be pre-allocated
+ - predeclared # finds code that shadows one of Go's predeclared identifiers
+ - promlinter # checks Prometheus metrics naming via promlint
+ - protogetter # reports direct reads from proto message fields when getters should be used
+ - reassign # checks that package variables are not reassigned
+ - revive # drop-in replacement of golint.
+ - rowserrcheck # checks whether Rows.Err of rows is checked successfully
+ - sloglint # ensures consistent code style when using log/slog
+ - spancheck # checks for mistakes with OpenTelemetry/Census spans
+ - sqlclosecheck # checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed
+ - stylecheck # replacement for golint
+ - tagalign # checks that struct tags are well aligned
+ - tagliatelle # checks the struct tags
+ - tenv # analyzer that detects using os.Setenv instead of t.Setenv
+ - thelper # detects tests helpers which is not start with t.Helper() method
+ - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes
+ - unconvert # unnecessary type conversions
+ - usestdlibvars # detects the possibility to use variables/constants from the Go standard library
+ - varnamelen # checks that the length of a variable's name matches its scope
+ - wastedassign # finds wasted assignment statements
+ - whitespace # checks for unnecessary newlines at the start and end of functions, if, for, etc
+ - wrapcheck # checks that errors returned from external packages are wrapped
+ - wsl # add or remove empty lines
+
+ disable:
+ - copyloopvar # fixed in go 1.22+
+ - depguard # no forbidden imports
+ - dogsled # blank identifiers are allowed
+ - dupword # duplicate words are allowed
+ - exhaustruct # many structs don't need to be exhaustive
+ - forbidigo # no forbidden identifiers
+ - ginkgolinter # not used
+ - gochecknoinits # init functions are fine, if used carefully
+ - goconst # many false positives
+ - godot # comments don't need to be complete sentences
+ - godox # todo comments are allowed
+ - goheader # no need for a header
+ - gomoddirectives # allow all directives
+ - gomodguard # no forbidden imports
+ - grouper # unused
+ - importas # some aliases are fine
+ - loggercheck # no slog support
+ - makezero # make with non-zero initial length is fine
+ - noctx # http request may be sent without context
+ - nonamedreturns # named returns are fine
+ - testableexamples # examples do not need to be testable (have declared output)
+ - testifylint # testify is not recommended
+ - testpackage # not a go best practice
+ - unparam # interfaces can enforce parameters
+ - zerologlint # slog should be used instead of zerlog
+ - execinquery # deprecated
+ - gomnd # deprecated
+ - mnd # too many detections
+ - cyclop # covered by gocyclo
+ - gochecknoglobals # there are many valid reasons for global variables, depending on the project
+ - ireturn # there are too many exceptions
+
+linters-settings:
+ wsl:
+ allow-cuddle-declarations: true
+ force-err-cuddling: true
+ force-case-trailing-whitespace: 3
+
+ funlen:
+ lines: 100
+ statements: 50
+ ignore-comments: true
+
+ lll:
+ line-length: 140
+ tab-width: 1
+
+ nlreturn:
+ block-size: 2
+
+ exhaustive:
+ check-generated: false
+ default-signifies-exhaustive: true
+
+ varnamelen:
+ ignore-type-assert-ok: true # ignore "ok" variables
+ ignore-map-index-ok: true
+ ignore-chan-recv-ok: true
+ ignore-decls:
+ - n int # generic number
+ - x int # generic number (e.g. coordinate)
+ - y int # generic number (e.g. coordinate)
+ - z int # generic number (e.g. coordinate)
+ - i int # generic number
+ - a int # generic number
+ - r int # generic number (e.g. red or radius)
+ - g int # generic number (e.g. green)
+ - b int # generic number (e.g. blue)
+ - r int64 # generic number (e.g. red or radius)
+ - g int64 # generic number (e.g. green)
+ - b int64 # generic number (e.g. blue)
+ - c int # generic number (e.g. count)
+ - j int # generic number (e.g. index)
+ - T any # generic type
+ - a any # generic any (e.g. data)
+ - b any # generic any (e.g. body)
+ - c any # generic any
+ - d any # generic any (e.g. data)
+ - data any # generic data
+ - n any # generic any
+ - ch chan T # common generic channel name
+ - ch chan int # common generic channel name
+ - ch chan any # common generic channel name
+ - wg sync.WaitGroup # common generic WaitGroup name
+ - t time.Time # often used as a variable name
+ - f func() # often used as a callback variable name
+ - f func(T) # often used as a generic callback variable name
+ - cb func() # often used as a callback variable name
+ - t testing.T # default testing.T variable name
+ - b testing.B # default testing.B variable name
+ - sb strings.Builder # often used as a variable name
+
+issues:
+ exclude-rules:
+ - path: "_test(_[^/]+)?\\.go"
+ linters:
+ - gochecknoglobals
+ - noctx
+ - funlen
+ - dupl
+ - errcheck
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..164477e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Marvin Wendt (aka. MarvinJWendt)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..90daed5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Documentation +| +Contributing +| +Code of Conduct +
+ +--- + +
+
+
+
go get atomicgo.dev/template
+