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 @@ + + +

AtomicGo | template

+ +

+Downloads + + +Latest Release + + + +Tests + + + +Coverage + + + +Unit test count + + + +License: MIT + + + +Go report + + +

+ +--- + +

+Documentation +| +Contributing +| +Code of Conduct +

+ +--- + +

+ AtomicGo +

+ +

+ + + +
+

+

go get atomicgo.dev/template

+

+ + + +
+

+ + + + + +# template + +```go +import "atomicgo.dev/template" +``` + +Package template is used to generate new AtomicGo repositories. + +Write the description of the module here. You can use \*\*markdown\*\*\! This description should clearly explain what the package does. + +Example description: https://golang.org/src/encoding/gob/doc.go + + + + + +```go +package main + +import ( + "fmt" + + "atomicgo.dev/template" +) + +func main() { + fmt.Println(template.HelloWorld()) +} +``` + +#### Output + +``` +Hello, World! +``` + + + +## Index + +- [func HelloWorld\(\) string](<#HelloWorld>) + + + +## func [HelloWorld]() + +```go +func HelloWorld() string +``` + +HelloWorld returns \`Hello, World\!\`. + + + + + +```go +package main + +import ( + "fmt" + + "atomicgo.dev/template" +) + +func main() { + fmt.Println(template.HelloWorld()) +} +``` + +#### Output + +``` +Hello, World! +``` + + + +Generated by [gomarkdoc]() + + + + +--- + +> [AtomicGo.dev](https://atomicgo.dev)  ·  +> with ❤️ by [@MarvinJWendt](https://github.com/MarvinJWendt) | +> [MarvinJWendt.com](https://marvinjwendt.com) diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..f9e552e --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,38 @@ +# ┌───────────────────────────────────────────────────────────────────┐ +# │ │ +# │ IMPORTANT NOTE │ +# │ │ +# │ This file is synced with https://github.com/atomicgo/template │ +# │ │ +# │ Please apply all changes to the template repository │ +# │ │ +# └───────────────────────────────────────────────────────────────────┘ + +version: "3" + +tasks: + test: + desc: Run all tests + cmds: + - go test ./... + + benchmark: + desc: Run all benchmarks + aliases: [bench] + cmds: + - go test -bench=. ./... + + tdd: + desc: Test Driven Development - Watch tests + watch: true + sources: + - "**/*.go" + cmds: + - go test ./... + + lint: + desc: Run all linters + cmds: + - go mod tidy + - wsl --allow-cuddle-declarations --force-err-cuddling --force-case-trailing-whitespace 3 --fix ./... + - golangci-lint run diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..631eace --- /dev/null +++ b/codecov.yml @@ -0,0 +1,18 @@ +# ┌───────────────────────────────────────────────────────────────────┐ +# │ │ +# │ IMPORTANT NOTE │ +# │ │ +# │ This file is synced with https://github.com/atomicgo/template │ +# │ │ +# │ Please apply all changes to the template repository │ +# │ │ +# └───────────────────────────────────────────────────────────────────┘ + +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..0731a16 --- /dev/null +++ b/doc.go @@ -0,0 +1,9 @@ +/* +Package template is used to generate new AtomicGo repositories. + +Write the description of the module here. You can use **markdown**! +This description should clearly explain what the package does. + +Example description: https://golang.org/src/encoding/gob/doc.go +*/ +package template diff --git a/examples_test.go b/examples_test.go new file mode 100644 index 0000000..97a67cb --- /dev/null +++ b/examples_test.go @@ -0,0 +1,17 @@ +package template_test + +import ( + "fmt" + + "atomicgo.dev/template" +) + +func Example_demo() { + fmt.Println(template.HelloWorld()) + // Output: Hello, World! +} + +func ExampleHelloWorld() { + fmt.Println(template.HelloWorld()) + // Output: Hello, World! +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..da7f0e3 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module atomicgo.dev/template + +go 1.22 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/template.go b/template.go new file mode 100644 index 0000000..f74b2c0 --- /dev/null +++ b/template.go @@ -0,0 +1,6 @@ +package template + +// HelloWorld returns `Hello, World!`. +func HelloWorld() string { + return "Hello, World!" +} diff --git a/template_test.go b/template_test.go new file mode 100644 index 0000000..cc24f94 --- /dev/null +++ b/template_test.go @@ -0,0 +1,11 @@ +package template + +import "testing" + +func TestHelloWorld(t *testing.T) { + t.Parallel() + + if HelloWorld() != "Hello, World!" { + t.Fatal("Not equal") + } +}