diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 0000000..70a3520 --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,37 @@ +{ + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + "badgeTemplate": "[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg)](#contributors)", + "contributors": [ + { + "login": "moul", + "name": "Manfred Touron", + "avatar_url": "https://avatars1.githubusercontent.com/u/94029?v=4", + "profile": "http://manfred.life", + "contributions": [ + "maintenance", + "doc", + "test", + "code" + ] + }, + { + "login": "moul-bot", + "name": "moul-bot", + "avatar_url": "https://avatars1.githubusercontent.com/u/41326314?v=4", + "profile": "https://manfred.life/moul-bot", + "contributions": [ + "maintenance" + ] + } + ], + "contributorsPerLine": 7, + "projectName": "golang-repo-template", + "projectOwner": "moul", + "repoType": "github", + "repoHost": "https://github.com", + "skipCi": true +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e358cd7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,35 @@ +## +## Specific to .dockerignore +## + +.git/ +Dockerfile +contrib/ + +## +## Common with .gitignore +## + +# Temporary files +*~ +*# +.#* + +# Vendors +node_modules/ +vendor/ + +# Binaries for programs and plugins +dist/ +gin-bin +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d17f97d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,78 @@ +root = true + +[*] +charset = utf-8 + +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +indent_style = space +indent_size = 4 + +[*.mod] +indent_style = tab + +[{Makefile,**.mk}] +indent_style = tab + +[*.go] +indent_style = tab + +[*.css] +indent_size = 2 + +[*.proto] +indent_size = 2 + +[*.ftl] +indent_size = 2 + +[*.toml] +indent_size = 2 + +[*.swift] +indent_size = 4 + +[*.tmpl] +indent_size = 2 + +[*.js] +indent_size = 2 +block_comment_start = /* +block_comment_end = */ + +[*.{html,htm}] +indent_size = 2 + +[*.bat] +end_of_line = crlf + +[*.{yml,yaml}] +indent_size = 2 + +[*.json] +indent_size = 2 + +[.{babelrc,eslintrc,prettierrc}] +indent_size = 2 + +[{Fastfile,.buckconfig,BUCK}] +indent_size = 2 + +[*.diff] +indent_size = 1 + +[*.m] +indent_size = 1 +indent_style = space +block_comment_start = /** +block_comment = * +block_comment_end = */ + +[*.java] +indent_size = 4 +indent_style = space +block_comment_start = /** +block_comment = * +block_comment_end = */ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fe46d96 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,30 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Collapse generated and vendored files on GitHub +AUTHORS linguist-generated merge=union +*.gen.* linguist-generated merge=ours +*.pb.go linguist-generated merge=ours +*.pb.gw.go linguist-generated merge=ours +go.sum linguist-generated merge=ours +go.mod linguist-generated +gen.sum linguist-generated merge=ours +depaware.txt linguist-generated linguist-vendored merge=union +vendor/* linguist-vendored +rules.mk linguist-vendored +*/vendor/* linguist-vendored + +# doc +docs/* linguist-documentation +docs/Makefile linguist-documentation=false + +# Reduce conflicts on markdown files +*.md merge=union + +# A set of files you probably don't want in distribution +/.github export-ignore +/.githooks export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.gitmodules export-ignore +/tool/lint export-ignore diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..c54b51a --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,3 @@ +#!/bin/sh + +run-parts ./githooks/pre-commit.d/ -v --exit-on-error diff --git a/.githooks/pre-commit.d/generate b/.githooks/pre-commit.d/generate new file mode 100755 index 0000000..c017bff --- /dev/null +++ b/.githooks/pre-commit.d/generate @@ -0,0 +1,3 @@ +#!/bin/bash + +make generate diff --git a/.githooks/pre-commit.d/lint b/.githooks/pre-commit.d/lint new file mode 100755 index 0000000..fc44a69 --- /dev/null +++ b/.githooks/pre-commit.d/lint @@ -0,0 +1,53 @@ +#!/bin/bash + +STAGED_GO_FILES=$(git diff --cached --name-only | grep "\.go$") + +if [[ "$STAGED_GO_FILES" = "" ]]; then + exit 0 +fi + +GOLINT=$GOPATH/bin/golint +GOIMPORTS=$GOPATH/bin/goimports +PASS=true + +# Check for golint +if [[ ! -x "$GOLINT" ]]; then + printf "\t\033[41mPlease install golint\033[0m (go get -u golang.org/x/lint/golint)\n" + PASS=false +fi + +# Check for goimports +if [[ ! -x "$GOIMPORTS" ]]; then + printf "\t\033[41mPlease install goimports\033[0m (go get golang.org/x/tools/cmd/goimports)\n" + PASS=false +fi + +if ! $PASS; then + exit 1 +fi + +PASS=true + +for FILE in $STAGED_GO_FILES +do + # Run goimports on the staged file + $GOIMPORTS -w $FILE + + # Run golint on the staged file and check the exit status + $GOLINT "-set_exit_status" $FILE + if [[ $? == 1 ]]; then + printf "\t\033[31mgolint $FILE\033[0m \033[0;30m\033[41mFAILURE!\033[0m\n" + PASS=false + else + printf "\t\033[32mgolint $FILE\033[0m \033[0;30m\033[42mpass\033[0m\n" + fi +done + +if ! $PASS; then + printf "\033[0;30m\033[41mCOMMIT FAILED\033[0m\n" + exit 1 +else + printf "\033[0;30m\033[42mCOMMIT SUCCEEDED\033[0m\n" +fi + +exit 0 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2aa7027 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @moul diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..5ef0767 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at m+coc-report@42.am. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..2ae8c33 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,6 @@ +# Contributing + +When contributing to this repository, you can first discuss the change you wish to make via issue, +email, or any other method with the maintainers of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..058f7f2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,5 @@ +github: ["moul"] +patreon: moul +open_collective: moul +custom: +- "https://manfred.life/donate" diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..606d6d1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +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. Go to '...' +2. Type '....' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots / Logs** +If applicable, add screenshots or logs to help explain your problem. + +**Versions (please complete the following information, if relevant):** +- Software version: [e.g. v1.2.3, latest, building from sources] +- OS: [e.g. Ubuntu, Mac, iOS, ...] +- Golang version [e.g. 1.13] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..0086358 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3f27c3f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[IDEA] " +labels: enhancement +assignees: '' + +--- + +**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/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..5b1e9d3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ + diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..c9faab1 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,28 @@ +# Support + +> This project has a [code of conduct](./CODE_OF_CONDUCT.md). +> By interacting with this repository, organization, or community you agree to abide by its terms. + +Hi! :wave: We're excited that you're using this project and we’d love to help. To help us help you, please read through the following guidelines. + +Please understand that the people involved with this project often do so for fun, next to their day job; you are not entitled to free customer service. + +## Questions + +Help us help you! + +Spending time framing a question and adding support links or resources makes it much easier for us to help. It’s easy to fall into the trap of asking something too specific when you’re close to a problem. Then, those trying to help you out have to spend a lot of time asking additional questions to understand what you are hoping to achieve. + +Spending the extra time up front can help save everyone time in the long run. + +* Try to define what you need help with: + * Is there something in particular you want to do? + * What problem are you encountering and what steps have you taken to try and fix it? + * Is there a concept you’re not understanding? +* Have you tried checking out the documentation? +* Check out the tips on [requesting support](./CONTRIBUTING.md) in the contributing guide +* The more time you put into asking your question, the better we can help you + +## Contributions + +See [CONTRIBUTING.md](./CONTRIBUTING.md) on how to contribute. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..96d0d69 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 +updates: +- package-ecosystem: docker + directory: "/" + schedule: + interval: daily + time: "04:00" + open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + time: "04:00" + open-pull-requests-limit: 10 +- package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + time: "04:00" + open-pull-requests-limit: 10 diff --git a/.github/ghuser.io.json b/.github/ghuser.io.json new file mode 100644 index 0000000..9c6954f --- /dev/null +++ b/.github/ghuser.io.json @@ -0,0 +1,5 @@ +{ + "_comment": "Repo metadata for ghuser.io. See https://github.com/ghuser-io/ghuser.io/blob/master/docs/repo-settings.md", + "avatar_url": "https://avatars2.githubusercontent.com/u/94029", + "techs": ["Go"] +} diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..31ab500 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,7 @@ +{ + "extends": [ + "config:base" + ], + "groupName": "all", + "gomodTidy": true +} diff --git a/.github/workflows/bearer.yml b/.github/workflows/bearer.yml new file mode 100644 index 0000000..f468ed2 --- /dev/null +++ b/.github/workflows/bearer.yml @@ -0,0 +1,17 @@ +name: Bearer + +on: + schedule: + - cron: "0 9 * * *" # Runs every day at 9:00 am + +permissions: + contents: read # Minimal permissions + +jobs: + security: + runs-on: ubuntu-latest + steps: + - name: Run Bearer + uses: bearer/actions@main + env: + BEARER_TOKEN: ${{ secrets.BEARER_TOKEN }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..9a9ab73 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '33 8 * * 3' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml new file mode 100644 index 0000000..809ac77 --- /dev/null +++ b/.github/workflows/debug.yml @@ -0,0 +1,33 @@ +on: + push: + pull_request: + +jobs: + debug: + if: true + runs-on: ubuntu-latest + steps: + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + - name: Dump job context + env: + JOB_CONTEXT: ${{ toJson(job) }} + run: echo "$JOB_CONTEXT" + - name: Dump steps context + env: + STEPS_CONTEXT: ${{ toJson(steps) }} + run: echo "$STEPS_CONTEXT" + - name: Dump runner context + env: + RUNNER_CONTEXT: ${{ toJson(runner) }} + run: echo "$RUNNER_CONTEXT" + - name: Dump strategy context + env: + STRATEGY_CONTEXT: ${{ toJson(strategy) }} + run: echo "$STRATEGY_CONTEXT" + - name: Dump matrix context + env: + MATRIX_CONTEXT: ${{ toJson(matrix) }} + run: echo "$MATRIX_CONTEXT" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..d01b696 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,74 @@ +name: Docker +on: + push: + branch: ['master', 'main'] + tags: ['v*'] + pull_request: + release: + types: [published,released] + + +jobs: + repoman: + runs-on: ubuntu-latest + outputs: + has-docker: ${{ steps.info.outputs.has-docker }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: '0' + - uses: moul/repoman-action@v1 + id: info + + multi: + needs: repoman + if: needs.repoman.outputs.has-docker == 'true' + name: "build-and-push" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Build the container image + uses: docker/build-push-action@v3.0.0 + with: + repository: golang-repo-template + + - name: Push to GitHub Packages + uses: docker/build-push-action@v3.0.0 + if: github.event_name == 'release' || github.event_name == 'push' + with: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + registry: docker.pkg.github.com + repository: moul/golang-repo-template/golang-repo-template + tag_with_ref: true + + - name: Check Docker Hub Credentials + id: check_dockerhub_credentials + if: github.event_name == 'release' || github.event_name == 'push' + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + run: | + if [ "${DOCKER_USERNAME}" == "" ]; then + echo "Missing Username" + echo "##[set-output name=missingsecrets;]$(echo yes)" + elif [ "${DOCKER_PASSWORD}" == "" ]; then + echo "Missing Password" + echo "##[set-output name=missingsecrets;]$(echo yes)" + else + echo "All secrets present" + echo "##[set-output name=missingsecrets;]$(echo no)" + fi + + - name: Push to Docker Hub + if: | + (github.event_name == 'release' || github.event_name == 'push') && + contains(steps.check_dockerhub_credentials.outputs.missingsecrets, 'no') + uses: docker/build-push-action@v3.0.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + repository: moul/golang-repo-template + tag_with_ref: true diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..40dcc79 --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,179 @@ +name: Go +on: + push: + tags: + - v* + branches: + - master + - main + paths: + - '**.go' + - ".goreleaser.yml" + - ".golangci.yml" + - ".dockerignore" + - "Makefile" + - "rules.mk" + - "go.*" + - ".github/workflows/go.yml" + pull_request: + paths: + - '**.go' + - ".goreleaser.yml" + - ".golangci.yml" + - ".dockerignore" + - "Makefile" + - "rules.mk" + - "go.*" + - ".github/workflows/go.yml" + +jobs: + repoman: + runs-on: ubuntu-latest + outputs: + has-go-binary: ${{ steps.info.outputs.has-go-binary }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: '0' + - uses: moul/repoman-action@v1 + id: info + goreleaser-dryrun: + needs: repoman + if: needs.repoman.outputs.has-go-binary == 'true' + strategy: + matrix: + golang: [1.18.x] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.golang }} + - name: Cache Go modules + uses: actions/cache@v3.0.2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- + - name: Run GoReleaser (Dry Run) + uses: goreleaser/goreleaser-action@v2.9.1 + with: + version: latest + args: release --rm-dist --snapshot --skip-publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + golangci-lint: + runs-on: ubuntu-latest + strategy: + matrix: + golangci_lint: [v1.38] + steps: + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3.2.0 + with: + version: ${{ matrix.golangci_lint }} + #github-token: ${{ secrets.GITHUB_TOKEN }} + args: --timeout=2m + only-new-issues: false + working-directory: . + tests-on-windows: + needs: golangci-lint # run after golangci-lint action to not produce duplicated errors + runs-on: windows-latest + strategy: + matrix: + golang: [1.18.x] + steps: + - uses: actions/checkout@v3 + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.golang }} + - name: Run tests on Windows + run: make.exe unittest + continue-on-error: true + tests-on-mac: + needs: golangci-lint # run after golangci-lint action to not produce duplicated errors + runs-on: macos-latest + strategy: + matrix: + golang: [1.16.x] + env: + OS: macos-latest + GOLANG: ${{ matrix.golang }} + steps: + - uses: actions/checkout@v3 + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.golang }} + - uses: actions/cache@v3.0.2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- + - name: Compile the project + if: needs.repoman.outputs.has-go-binary == 'true' + run: make go.install + - name: Run tests on Unix-like operating systems + run: make unittest + - name: Check go.mod and go.sum + run: | + go mod tidy -v + git --no-pager diff go.mod go.sum + git --no-pager diff --quiet go.mod go.sum + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3.1.0 + with: + #token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.txt + flags: unittests + env_vars: OS,GOLANG + name: codecov-umbrella + fail_ci_if_error: false + tests-on-linux: + needs: golangci-lint # run after golangci-lint action to not produce duplicated errors + runs-on: ubuntu-latest + strategy: + matrix: + golang: + #- 1.14.x + #- 1.15.x + #- 1.16.x + - 1.17.x + - 1.18.x + env: + OS: ubuntu-latest + GOLANG: ${{ matrix.golang }} + steps: + - uses: actions/checkout@v3 + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.golang }} + - uses: actions/cache@v3.0.2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- + - name: Compile the project + if: needs.repoman.outputs.has-go-binary == 'true' + run: make go.install + - name: Check go.mod and go.sum + run: | + go mod tidy -v + git --no-pager diff go.mod go.sum + git --no-pager diff --quiet go.mod go.sum + - name: Run tests on Unix-like operating systems + run: make unittest + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3.1.0 + with: + #token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.txt + flags: unittests + env_vars: OS,GOLANG + name: codecov-umbrella + fail_ci_if_error: false diff --git a/.github/workflows/label-sponsors.yml b/.github/workflows/label-sponsors.yml new file mode 100644 index 0000000..b5c7479 --- /dev/null +++ b/.github/workflows/label-sponsors.yml @@ -0,0 +1,14 @@ +name: Label sponsors +on: + pull_request: + types: [opened] + issues: + types: [opened] +jobs: + build: + name: is-sponsor-label + runs-on: ubuntu-latest + steps: + - uses: JasonEtco/is-sponsor-label-action@v1.2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..57b79d7 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,42 @@ +name: PR + +on: + #pull_request_target: + pull_request: + branches: [ master, main ] + issue_comment: + types: [ edited ] + +jobs: + preview: + name: Release-Notes Preview + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: | + git fetch --prune --unshallow --tags + - uses: snyk/release-notes-preview@v1.6.2 + with: + releaseBranch: master + env: + GITHUB_PR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + doc: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + depth: 1 + - uses: nosborn/github-action-markdown-cli@master + with: + files: . + config_file: ./tool/lint/.markdownlint.json + - uses: K-Phoen/action-misspell@master + with: + github_token: ${{ github.token }} + reporter: github-pr-review + locale: "US" + - name: alexjs + uses: theashraf/alex-action@master diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5cda537 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,62 @@ +name: Release +on: + push: + branches: + - master + - main + +jobs: + release: + name: releaser + runs-on: ubuntu-latest + strategy: + matrix: + golang: [1.18.x] + steps: + - + name: Checkout + uses: actions/checkout@v3 + - + name: Unshallow + run: git fetch --prune --unshallow + - + uses: moul/repoman-action@v1 + id: repoman + - + name: Run Semantic Release + id: semantic + uses: docker://ghcr.io/codfish/semantic-release-action:v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - + name: Set up Go + if: steps.semantic.outputs.new-release-published == 'true' && steps.repoman.outputs.has-go-binary == 'true' + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.golang }} + - + name: Cache Go modules + if: steps.semantic.outputs.new-release-published == 'true' && steps.repoman.outputs.has-go-binary == 'true' + uses: actions/cache@v3.0.2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.golang }}-v1-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go-${{ matrix.golang }}-v1- + - + name: Run GoReleaser + if: steps.semantic.outputs.new-release-published == 'true' && steps.repoman.outputs.has-go-binary == 'true' + uses: goreleaser/goreleaser-action@v2.9.1 + with: + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - + name: Register version on pkg.go.dev + if: steps.semantic.outputs.new-release-published == 'true' + run: | + package=$(cat go.mod | grep ^module | awk '{print $2}') + version=v${{ steps.semantic.outputs.release-version }} + url=https://proxy.golang.org/${package}/@v/${version}.info + set -x +e + curl -i $url diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 0000000..cde3a60 --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,64 @@ +name: Scorecards supply-chain security +on: + # Only the default branch is supported. + branch_protection_rule: + schedule: + - cron: '35 9 * * 6' + push: + branches: [ main ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecards analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + actions: read + contents: read + + steps: + - name: "Checkout code" + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.0 + with: + persist-credentials: false + + - name: "Run analysis" + env: + SCORECARD_READ_TOKEN: ${{ secrets.SCORECARD_READ_TOKEN }} + if: env.SCORECARD_READ_TOKEN != null + uses: ossf/scorecard-action@f10ec7151e838890a3fbfa27875a33f80869977b # v1.0.4 + with: + results_file: results.sarif + results_format: sarif + # Read-only PAT token. To create it, + # follow the steps in https://github.com/ossf/scorecard-action#pat-token-creation. + repo_token: ${{ secrets.SCORECARD_READ_TOKEN }} + # Publish the results to enable scorecard badges. For more details, see + # https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories, `publish_results` will automatically be set to `false`, + # regardless of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). + - name: "Upload artifact" + env: + SCORECARD_READ_TOKEN: ${{ secrets.SCORECARD_READ_TOKEN }} + if: env.SCORECARD_READ_TOKEN != null + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.0.0 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + env: + SCORECARD_READ_TOKEN: ${{ secrets.SCORECARD_READ_TOKEN }} + if: env.SCORECARD_READ_TOKEN != null + uses: github/codeql-action/upload-sarif@v2 # v1.0.26 + with: + sarif_file: results.sarif diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 0000000..9677d30 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,21 @@ +on: + pull_request: {} + push: + branches: + - main + paths: + - .github/workflows/semgrep.yml + schedule: + - cron: '0 0 * * 0' +name: Semgrep +jobs: + semgrep: + name: Scan + runs-on: ubuntu-20.04 + env: + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} + container: + image: returntocorp/semgrep + steps: + - uses: actions/checkout@v3 + - run: semgrep ci diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b8f3991 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +go-test.json + +# Temporary files +*~ +*# +.#* +coverage.txt + +go-build.log +go-install.log +go-test.json + +# Vendors +package-lock.json +node_modules/ +vendor/ + +# Binaries for programs and plugins +dist/ +gin-bin +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# IDE settings +.idea +.vscode/ +.history/ diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..1bb1aff --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,3 @@ +tasks: + - init: go get && go build ./... && go test ./... + command: go run diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..157444f --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,68 @@ +run: + deadline: 1m + tests: false + skip-files: + - "testing.go" + - ".*\\.pb\\.go" + - ".*\\.gen\\.go" + +linters-settings: + golint: + min-confidence: 0 + maligned: + suggest-new: true + goconst: + min-len: 5 + min-occurrences: 4 + misspell: + locale: US + +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck + - exhaustive + - exportloopref + - gci + - gochecknoinits + - gocognit + - goconst + - gocritic + - gocyclo + - godot + - goerr113 + - gofmt + - gofumpt + - goimports + - golint + - gomnd + - gomodguard + - gosec + - gosimple + - govet + - ineffassign + - interfacer + - maligned + - misspell + - nakedret + - nestif + - noctx + - nolintlint + - prealloc + - scopelint + - sqlclosecheck + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..dd3c164 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,74 @@ +env: + - GO111MODULE=on + - GOPROXY=https://proxy.golang.org +before: + hooks: + - go mod download +builds: + - + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - 386 + - amd64 + - arm + - arm64 + ignore: + - + goos: darwin + goarch: 386 + flags: + - "-a" + ldflags: + - '-extldflags "-static"' + main: ./ +checksum: + name_template: '{{.ProjectName}}_checksums.txt' +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + - Merge pull request + - Merge branch +archives: + - + name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' + replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 + format_overrides: + - + goos: windows + format: zip + wrap_in_directory: true +brews: + - + name: golang-repo-template +# github: +# owner: moul +# name: homebrew-moul + commit_author: + name: moul-bot + email: "bot@moul.io" + homepage: https://github.com/moul/golang-repo-template + description: "golang-repo-template" +nfpms: + - + file_name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' + homepage: https://github.com/moul/golang-repo-template + description: "golang-repo-template" + maintainer: "Manfred Touron " + license: "Apache-2.0 OR MIT" + vendor: moul + formats: + - deb + - rpm diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f83c03c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +- repo: git://github.com/dnephin/pre-commit-golang + rev: master + hooks: + - id: go-fmt + - id: go-vet + - id: go-lint + - id: go-imports diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..35060c1 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,14 @@ +# This file lists all individuals having contributed content to the repository. +# For how it is generated, see 'https://github.com/moul/rules.mk' + +allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> +Darko Djalevski +Darko Djalevski +dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Manfred Touron <94029+moul@users.noreply.github.com> +Manfred Touron +moul-bot +Renovate Bot +renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> +Stavros Panakakis <53979866+Stavrospanakakis@users.noreply.github.com> diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..5b493a3 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,22 @@ +Copyright 2021 Manfred Touron and other golang-repo-template Developers. + +Intellectual Property Notice +---------------------------- + +golang-repo-template is licensed under the Apache License, Version 2.0 +(see LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or +the MIT license (see LICENSE-MIT or http://opensource.org/licenses/MIT), +at your option. + +Copyrights and patents in the golang-repo-templates project are retained +by contributors. +No copyright assignment is required to contribute to golang-repo-template. + + SPDX-License-Identifier: (Apache-2.0 OR MIT) + +SPDX usage +---------- + +Individual files may contain SPDX tags instead of the full license text. +This enables machine processing of license information based on the SPDX +License Identifiers that are available here: https://spdx.org/licenses/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..411382e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# dynamic config +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION + +# build +FROM golang:1.18.2-alpine as builder +RUN apk add --no-cache git gcc musl-dev make +ENV GO111MODULE=on +WORKDIR /go/src/moul.io/golang-repo-template +COPY go.* ./ +RUN go mod download +COPY . ./ +RUN make install + +# minimalist runtime +FROM alpine:3.15.4 +LABEL org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.name="golang-repo-template" \ + org.label-schema.description="" \ + org.label-schema.url="https://moul.io/golang-repo-template/" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/moul/golang-repo-template" \ + org.label-schema.vendor="Manfred Touron" \ + org.label-schema.version=$VERSION \ + org.label-schema.schema-version="1.0" \ + org.label-schema.cmd="docker run -i -t --rm moul/golang-repo-template" \ + org.label-schema.help="docker exec -it $CONTAINER golang-repo-template --help" +COPY --from=builder /go/bin/golang-repo-template /bin/ +ENTRYPOINT ["/bin/golang-repo-template"] +#CMD [] diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..a96ac23 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Manfred Touron (manfred.life) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..41a0a5c --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright (c) 2021 Manfred Touron (manfred.life) + +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/Makefile b/Makefile new file mode 100644 index 0000000..b0e6811 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +GOPKG ?= moul.io/golang-repo-template +DOCKER_IMAGE ?= moul/golang-repo-template +GOBINS ?= . +NPM_PACKAGES ?= . + +include rules.mk + +generate: install + GO111MODULE=off go get github.com/campoy/embedmd + mkdir -p .tmp + echo 'foo@bar:~$$ golang-repo-template' > .tmp/usage.txt + golang-repo-template 2>&1 >> .tmp/usage.txt + embedmd -w README.md + rm -rf .tmp +.PHONY: generate diff --git a/README.md b/README.md new file mode 100644 index 0000000..e6a19ea --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +# golang-repo-template + +:smile: golang-repo-template + +[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/moul.io/golang-repo-template) +[![License](https://img.shields.io/badge/license-Apache--2.0%20%2F%20MIT-%2397ca00.svg)](https://github.com/moul/golang-repo-template/blob/main/COPYRIGHT) +[![GitHub release](https://img.shields.io/github/release/moul/golang-repo-template.svg)](https://github.com/moul/golang-repo-template/releases) +[![Docker Metrics](https://images.microbadger.com/badges/image/moul/golang-repo-template.svg)](https://microbadger.com/images/moul/golang-repo-template) +[![Made by Manfred Touron](https://img.shields.io/badge/made%20by-Manfred%20Touron-blue.svg?style=flat)](https://manfred.life/) + +[![Go](https://github.com/moul/golang-repo-template/workflows/Go/badge.svg)](https://github.com/moul/golang-repo-template/actions?query=workflow%3AGo) +[![Release](https://github.com/moul/golang-repo-template/workflows/Release/badge.svg)](https://github.com/moul/golang-repo-template/actions?query=workflow%3ARelease) +[![PR](https://github.com/moul/golang-repo-template/workflows/PR/badge.svg)](https://github.com/moul/golang-repo-template/actions?query=workflow%3APR) +[![GolangCI](https://golangci.com/badges/github.com/moul/golang-repo-template.svg)](https://golangci.com/r/github.com/moul/golang-repo-template) +[![codecov](https://codecov.io/gh/moul/golang-repo-template/branch/main/graph/badge.svg)](https://codecov.io/gh/moul/golang-repo-template) +[![Go Report Card](https://goreportcard.com/badge/moul.io/golang-repo-template)](https://goreportcard.com/report/moul.io/golang-repo-template) +[![CodeFactor](https://www.codefactor.io/repository/github/moul/golang-repo-template/badge)](https://www.codefactor.io/repository/github/moul/golang-repo-template) + +[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/moul/golang-repo-template) + +## Usage + +[embedmd]:# (.tmp/usage.txt console) +```console +foo@bar:~$ golang-repo-template + _ _ _ _ + __ _ ___ | | __ _ _ _ __ _ ___ _ _ ___ _ __ ___ ___ | |_ ___ _ __ _ __ | | __ _ | |_ ___ +/ _` |/ _ \| |/ _` || ' \ / _` ||___|| '_|/ -_)| '_ \/ _ \|___|| _|/ -_)| ' \ | '_ \| |/ _` || _|/ -_) +\__, |\___/|_|\__,_||_||_|\__, | |_| \___|| .__/\___/ \__|\___||_|_|_|| .__/|_|\__,_| \__|\___| +|___/ |___/ |_| |_| +12 CPUs, /home/moul/.local/bin/golang-repo-template, fwrz, go1.16.5 +[] +``` + +## Install + +### Using go + +```sh +go get moul.io/golang-repo-template +``` + +### Releases + +See https://github.com/moul/golang-repo-template/releases + +## Contribute + +![Contribute <3](https://raw.githubusercontent.com/moul/moul/main/contribute.gif) + +I really welcome contributions. +Your input is the most precious material. +I'm well aware of that and I thank you in advance. +Everyone is encouraged to look at what they can do on their own scale; +no effort is too small. + +Everything on contribution is sum up here: [CONTRIBUTING.md](./.github/CONTRIBUTING.md) + +### Dev helpers + +Pre-commit script for install: https://pre-commit.com + +### Contributors ✨ + + +[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg)](#contributors) + + +Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + + +

Manfred Touron

🚧 📖 ⚠️ 💻

moul-bot

🚧
+ + + + + +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) +specification. Contributions of any kind welcome! + +### Stargazers over time + +[![Stargazers over time](https://starchart.cc/moul/golang-repo-template.svg)](https://starchart.cc/moul/golang-repo-template) + +## License + +© 2021 [Manfred Touron](https://manfred.life) + +Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) +([`LICENSE-APACHE`](LICENSE-APACHE)) or the [MIT license](https://opensource.org/licenses/MIT) +([`LICENSE-MIT`](LICENSE-MIT)), at your option. +See the [`COPYRIGHT`](COPYRIGHT) file for more details. + +`SPDX-License-Identifier: (Apache-2.0 OR MIT)` diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..4aec7dd --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,12 @@ +# Reporting security issues + +I take security seriously. If you discover a security issue, +please bring it to my attention right away! + +## Reporting a Vulnerability + +Please **DO NOT** file a public issue, +instead send your report privately to security@moul.io. + +Security reports are greatly appreciated and I will publicly thank you for it, +although I keep your name confidential if you request it. diff --git a/depaware.txt b/depaware.txt new file mode 100644 index 0000000..8e4595f --- /dev/null +++ b/depaware.txt @@ -0,0 +1,106 @@ +moul.io/golang-repo-template dependencies: (generated by github.com/tailscale/depaware) + + go.uber.org/atomic from go.uber.org/multierr+ + go.uber.org/multierr from go.uber.org/zap+ + go.uber.org/zap from moul.io/zapconfig + go.uber.org/zap/buffer from go.uber.org/zap/internal/bufferpool+ + go.uber.org/zap/internal/bufferpool from go.uber.org/zap+ + go.uber.org/zap/internal/color from go.uber.org/zap/zapcore + go.uber.org/zap/internal/exit from go.uber.org/zap/zapcore + go.uber.org/zap/zapcore from go.uber.org/zap+ + moul.io/banner from moul.io/motd + moul.io/motd from moul.io/golang-repo-template + moul.io/srand from moul.io/golang-repo-template + moul.io/u from moul.io/golang-repo-template + moul.io/zapconfig from moul.io/golang-repo-template + golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305 + golang.org/x/crypto/chacha20poly1305 from crypto/tls + golang.org/x/crypto/cryptobyte from crypto/ecdsa+ + golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+ + golang.org/x/crypto/curve25519 from crypto/tls + golang.org/x/crypto/hkdf from crypto/tls + golang.org/x/crypto/poly1305 from golang.org/x/crypto/chacha20poly1305 + golang.org/x/net/dns/dnsmessage from net + golang.org/x/net/http/httpguts from net/http + golang.org/x/net/http/httpproxy from net/http + golang.org/x/net/http2/hpack from net/http + golang.org/x/net/idna from golang.org/x/net/http/httpguts+ + D golang.org/x/net/route from net + golang.org/x/sys/cpu from golang.org/x/crypto/chacha20poly1305 + golang.org/x/text/secure/bidirule from golang.org/x/net/idna + golang.org/x/text/transform from golang.org/x/text/secure/bidirule+ + golang.org/x/text/unicode/bidi from golang.org/x/net/idna+ + golang.org/x/text/unicode/norm from golang.org/x/net/idna + archive/zip from moul.io/u + bufio from archive/zip+ + bytes from bufio+ + compress/flate from archive/zip+ + compress/gzip from net/http + container/list from crypto/tls+ + context from crypto/tls+ + crypto from crypto/ecdsa+ + crypto/aes from crypto/ecdsa+ + crypto/cipher from crypto/aes+ + crypto/des from crypto/tls+ + crypto/dsa from crypto/x509 + crypto/ecdsa from crypto/tls+ + crypto/ed25519 from crypto/tls+ + crypto/elliptic from crypto/ecdsa+ + crypto/hmac from crypto/tls+ + crypto/md5 from crypto/tls+ + crypto/rand from crypto/ed25519+ + crypto/rc4 from crypto/tls + crypto/rsa from crypto/tls+ + crypto/sha1 from crypto/tls+ + crypto/sha256 from crypto/tls+ + crypto/sha512 from crypto/ecdsa+ + crypto/subtle from crypto/aes+ + crypto/tls from net/http+ + crypto/x509 from crypto/tls + crypto/x509/pkix from crypto/x509 + encoding from encoding/json + encoding/asn1 from crypto/x509+ + encoding/base64 from encoding/json+ + encoding/binary from archive/zip+ + encoding/hex from crypto/x509+ + encoding/json from go.uber.org/atomic+ + encoding/pem from crypto/tls+ + errors from archive/zip+ + flag from go.uber.org/zap + fmt from compress/flate+ + hash from archive/zip+ + hash/crc32 from archive/zip+ + io from archive/zip+ + io/fs from archive/zip+ + io/ioutil from crypto/x509+ + log from go.uber.org/zap+ + math from compress/flate+ + math/big from crypto/dsa+ + math/bits from compress/flate+ + math/rand from math/big+ + mime from mime/multipart+ + mime/multipart from net/http + mime/quotedprintable from mime/multipart + net from crypto/tls+ + net/http from go.uber.org/zap + net/http/httptrace from net/http + net/http/internal from net/http + net/textproto from golang.org/x/net/http/httpguts+ + net/url from crypto/x509+ + os from archive/zip+ + os/exec from moul.io/u + os/signal from moul.io/u + os/user from moul.io/u + path from archive/zip+ + path/filepath from crypto/x509+ + reflect from crypto/x509+ + sort from compress/flate+ + strconv from compress/flate+ + strings from archive/zip+ + sync from archive/zip+ + sync/atomic from context+ + syscall from crypto/rand+ + time from archive/zip+ + unicode from bytes+ + unicode/utf16 from encoding/asn1+ + unicode/utf8 from archive/zip+ diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..504ea77 --- /dev/null +++ b/doc.go @@ -0,0 +1,29 @@ +// Copyright © 2021 Manfred Touron +// SPDX-License-Identifier: Apache-2.0 OR MIT + +// message from the author: +// +--------------------------------------------------------------+ +// | * * * ░░░░░░░░░░░░░░░░░░░░ Hello ░░░░░░░░░░░░░░░░░░░░░░░░░░| +// +--------------------------------------------------------------+ +// | | +// | ++ ______________________________________ | +// | ++++ / \ | +// | ++++ | | | +// | ++++++++++ | Feel free to contribute to this | | +// | +++ | | project or contact me on | | +// | ++ | | manfred.life if you like this | | +// | + -== ==| | project! | | +// | ( <*> <*> | | | +// | | | /| :) | | +// | | _) / | | | +// | | +++ / \______________________________________/ | +// | \ =+ / | +// | \ + | +// | |\++++++ | +// | | ++++ ||// | +// | ___| |___ _||/__ __| +// | / --- \ \| ||| __ _ ___ __ __/ /| +// |/ | | \ \ / / ' \/ _ \/ // / / | +// || | | | | | /_/_/_/\___/\_,_/_/ | +// +--------------------------------------------------------------+ +package main // import "moul.io/golang-repo-template" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b597089 --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module moul.io/golang-repo-template + +go 1.13 + +require ( + github.com/peterbourgon/ff/v3 v3.1.2 + github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 + go.uber.org/goleak v1.1.12 + go.uber.org/zap v1.21.0 + moul.io/climan v1.0.0 + moul.io/motd v1.0.0 + moul.io/srand v1.6.1 + moul.io/u v1.27.0 + moul.io/zapconfig v1.4.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..be51a69 --- /dev/null +++ b/go.sum @@ -0,0 +1,124 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +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/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= +github.com/peterbourgon/ff/v3 v3.1.2 h1:0GNhbRhO9yHA4CC27ymskOsuRpmX0YQxwxM9UPiP6JM= +github.com/peterbourgon/ff/v3 v3.1.2/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE= +github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= +github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HPjrSuJYEkdZ+0ItmGQAQ75cRHIiftIyE= +github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +moul.io/banner v1.0.1 h1:+WsemGLhj2pOajw2eR5VYjLhOIqs0XhIRYchzTyMLk0= +moul.io/banner v1.0.1/go.mod h1:XwvIGKkhKRKyN1vIdmR5oaKQLIkMhkMqrsHpS94QzAU= +moul.io/climan v1.0.0 h1:Xc9xnUrLVPK69lnCfVJnCvVtMm4v6Lt2743fnadvpWc= +moul.io/climan v1.0.0/go.mod h1:iT29NKBU5U7cAYxmpt9XXfv3PV1OW+5OKvze553VTwc= +moul.io/motd v1.0.0 h1:Trk4fPibDfPJf2iCBSQC8ws7Q02sMwivQdVEFAjCPto= +moul.io/motd v1.0.0/go.mod h1:39rvZ0lC2oRhHDY2VoPyZ8r70VKqeJye3QAxjeLDJso= +moul.io/srand v1.6.1 h1:SJ335F+54ivLdlH7wH52Rtyv0Ffos6DpsF5wu3ZVMXU= +moul.io/srand v1.6.1/go.mod h1:P2uaZB+GFstFNo8sEj6/U8FRV1n25kD0LLckFpJ+qvc= +moul.io/u v1.23.0/go.mod h1:ytlQ/zt+Sdk+PFGEx+fpTivoa0ieA5yMo6itRswIWNQ= +moul.io/u v1.25.1/go.mod h1:ggYDXxUjoHpfDsMPD3STqkUZTyA741PZiQhSd+7kRnA= +moul.io/u v1.27.0 h1:rF0p184mludn2DzL0unA8Gf/mFWMBerdqOh8cyuQYzQ= +moul.io/u v1.27.0/go.mod h1:ggYDXxUjoHpfDsMPD3STqkUZTyA741PZiQhSd+7kRnA= +moul.io/zapconfig v1.4.0 h1:J3ND5J3e/qQ++jlpqdSR1EtDNV+iujtvXgLsjy1uyq8= +moul.io/zapconfig v1.4.0/go.mod h1:bYTa5j7r82yPmSR6i5CcrPSVoWEbdpN7o9IgndSVby8= diff --git a/golang-repo-template b/golang-repo-template new file mode 100755 index 0000000..8cd0410 Binary files /dev/null and b/golang-repo-template differ diff --git a/internal/tools/tools_test.go b/internal/tools/tools_test.go new file mode 100644 index 0000000..17cc512 --- /dev/null +++ b/internal/tools/tools_test.go @@ -0,0 +1,7 @@ +// +build tools + +package tools + +import ( + _ "github.com/tailscale/depaware" // required by rules.mk +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..0c4e860 --- /dev/null +++ b/main.go @@ -0,0 +1,90 @@ +package main + +import ( + "context" + "errors" + "flag" + "fmt" + "math/rand" + "os" + + "github.com/peterbourgon/ff/v3" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "moul.io/climan" + "moul.io/motd" + "moul.io/srand" + "moul.io/u" + "moul.io/zapconfig" +) + +func main() { + if err := run(os.Args[1:]); err != nil { + if !errors.Is(err, flag.ErrHelp) { + fmt.Fprintf(os.Stderr, "error: %v+\n", err) + } + os.Exit(1) + } +} + +var opts struct { + Debug bool + rootLogger *zap.Logger +} + +func run(args []string) error { + // parse CLI + root := &climan.Command{ + Name: "golang-repo-template", + ShortUsage: "golang-repo-template [global flags] [flags] [args]", + ShortHelp: "More info on https://moul.io/golang-repo-template.", + FlagSetBuilder: func(fs *flag.FlagSet) { fs.BoolVar(&opts.Debug, "debug", opts.Debug, "debug mode") }, + Exec: doRoot, + FFOptions: []ff.Option{ff.WithEnvVarPrefix("golang-repo-template")}, + // Subcommands: []*climan.Command{}, + // LongHelp: "", + } + if err := root.Parse(args); err != nil { + return fmt.Errorf("parse error: %w", err) + } + + // init runtime + { + // prng + rand.Seed(srand.Fast()) + + // concurrency + // runtime.GOMAXPROCS(1) + + // logger + config := zapconfig.New().SetPreset("light-console") + if opts.Debug { + config = config.SetLevel(zapcore.DebugLevel) + } else { + config = config.SetLevel(zapcore.InfoLevel) + } + var err error + opts.rootLogger, err = config.Build() + if err != nil { + return fmt.Errorf("logger init: %w", err) + } + } + + // run + if err := root.Run(context.Background()); err != nil { + return fmt.Errorf("%w", err) + } + + return nil +} + +func doRoot(ctx context.Context, args []string) error { + if len(args) > 0 { + return flag.ErrHelp + } + + opts.rootLogger.Debug("init", zap.Strings("args", args), zap.Any("opts", opts)) + fmt.Print(motd.Default()) + fmt.Println(u.PrettyJSON(args)) + return nil +} diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..b519d9c --- /dev/null +++ b/main_test.go @@ -0,0 +1,20 @@ +package main + +import ( + "errors" + "flag" + "testing" + + "go.uber.org/goleak" +) + +func TestRun(t *testing.T) { + err := run([]string{"-h"}) + if !errors.Is(err, flag.ErrHelp) { + t.Fatalf("err should be flag.ErrHelp, got %v", err) + } +} + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e08aeb0 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "_comment": "this project is not a node.js one, package.json is just used to define some metadata", + "name": "@moul.io/golang-repo-template", + "version": "0.0.1", + "author": "Manfred Touron (https://manfred.life)", + "contributors": [ + "Manfred Touron (https://manfred.life)" + ], + "license": "(Apache-2.0 OR MIT)", + "scripts": { + "start": "golang-repo-template", + "install": "make install", + "test": "make test" + }, + "repository": { + "type": "git", + "url": "https://github.com/moul/golang-repo-template.git" + }, + "bugs": "https://github.com/moul/golang-repo-template/issues", + "homepage": "https://moul.io/golang-repo-template", + "release": { + "branches": ["master", "main"], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/github" + ] + } +} diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..2d1e60a --- /dev/null +++ b/rules.mk @@ -0,0 +1,372 @@ +# +--------------------------------------------------------------+ +# | * * * moul.io/rules.mk | +# +--------------------------------------------------------------+ +# | | +# | ++ ______________________________________ | +# | ++++ / \ | +# | ++++ | | | +# | ++++++++++ | https://moul.io/rules.mk is a set | | +# | +++ | | of common Makefile rules that can | | +# | ++ | | be configured from the Makefile | | +# | + -== ==| | or with environment variables. | | +# | ( <*> <*> | | | +# | | | /| Manfred Touron | | +# | | _) / | manfred.life | | +# | | +++ / \______________________________________/ | +# | \ =+ / | +# | \ + | +# | |\++++++ | +# | | ++++ ||// | +# | ___| |___ _||/__ __| +# | / --- \ \| ||| __ _ ___ __ __/ /| +# |/ | | \ \ / / ' \/ _ \/ // / / | +# || | | | | | /_/_/_/\___/\_,_/_/ | +# +--------------------------------------------------------------+ + +.PHONY: _default_entrypoint +_default_entrypoint: help + +## +## Common helpers +## + +rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) +check-program = $(foreach exec,$(1),$(if $(shell PATH="$(PATH)" which $(exec)),,$(error "No $(exec) in PATH"))) +my-filter-out = $(foreach v,$(2),$(if $(findstring $(1),$(v)),,$(v))) +novendor = $(call my-filter-out,vendor/,$(1)) + +## +## rules.mk +## +ifneq ($(wildcard rules.mk),) +.PHONY: rulesmk.bumpdeps +rulesmk.bumpdeps: + wget -O rules.mk https://raw.githubusercontent.com/moul/rules.mk/master/rules.mk +BUMPDEPS_STEPS += rulesmk.bumpdeps +endif + +## +## Maintainer +## + +ifneq ($(wildcard .git/HEAD),) +.PHONY: generate.authors +generate.authors: AUTHORS +AUTHORS: .git/ + echo "# This file lists all individuals having contributed content to the repository." > AUTHORS + echo "# For how it is generated, see 'https://github.com/moul/rules.mk'" >> AUTHORS + echo >> AUTHORS + git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf >> AUTHORS +GENERATE_STEPS += generate.authors +endif + +## +## Golang +## + +ifndef GOPKG +ifneq ($(wildcard go.mod),) +GOPKG = $(shell sed '/module/!d;s/^omdule\ //' go.mod) +endif +endif +ifdef GOPKG +GO ?= go +GOPATH ?= $(HOME)/go +GO_INSTALL_OPTS ?= +GO_TEST_OPTS ?= -test.timeout=30s +GOMOD_DIRS ?= $(sort $(call novendor,$(dir $(call rwildcard,*,*/go.mod go.mod)))) +GOCOVERAGE_FILE ?= ./coverage.txt +GOTESTJSON_FILE ?= ./go-test.json +GOBUILDLOG_FILE ?= ./go-build.log +GOINSTALLLOG_FILE ?= ./go-install.log + +ifdef GOBINS +.PHONY: go.install +go.install: +ifeq ($(CI),true) + @rm -f /tmp/goinstall.log + @set -e; for dir in $(GOBINS); do ( set -xe; \ + cd $$dir; \ + $(GO) install -v $(GO_INSTALL_OPTS) .; \ + ); done 2>&1 | tee $(GOINSTALLLOG_FILE) + +else + @set -e; for dir in $(GOBINS); do ( set -xe; \ + cd $$dir; \ + $(GO) install $(GO_INSTALL_OPTS) .; \ + ); done +endif +INSTALL_STEPS += go.install + +.PHONY: go.release +go.release: + $(call check-program, goreleaser) + goreleaser --snapshot --skip-publish --rm-dist + @echo -n "Do you want to release? [y/N] " && read ans && \ + if [ $${ans:-N} = y ]; then set -xe; goreleaser --rm-dist; fi +RELEASE_STEPS += go.release +endif + +.PHONY: go.unittest +go.unittest: +ifeq ($(CI),true) + @echo "mode: atomic" > /tmp/gocoverage + @rm -f $(GOTESTJSON_FILE) + @set -e; for dir in $(GOMOD_DIRS); do (set -e; (set -euf pipefail; \ + cd $$dir; \ + (($(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race -json && touch $@.ok) | tee -a $(GOTESTJSON_FILE) 3>&1 1>&2 2>&3 | tee -a $(GOBUILDLOG_FILE); \ + ); \ + rm $@.ok 2>/dev/null || exit 1; \ + if [ -f /tmp/profile.out ]; then \ + cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \ + rm -f /tmp/profile.out; \ + fi)); done + @mv /tmp/gocoverage $(GOCOVERAGE_FILE) +else + @echo "mode: atomic" > /tmp/gocoverage + @set -e; for dir in $(GOMOD_DIRS); do (set -e; (set -xe; \ + cd $$dir; \ + $(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race); \ + if [ -f /tmp/profile.out ]; then \ + cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \ + rm -f /tmp/profile.out; \ + fi); done + @mv /tmp/gocoverage $(GOCOVERAGE_FILE) +endif + +.PHONY: go.checkdoc +go.checkdoc: + go doc $(first $(GOMOD_DIRS)) + +.PHONY: go.coverfunc +go.coverfunc: go.unittest + go tool cover -func=$(GOCOVERAGE_FILE) | grep -v .pb.go: | grep -v .pb.gw.go: + +.PHONY: go.lint +go.lint: + @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ + cd $$dir; \ + golangci-lint run --verbose ./...; \ + ); done + +.PHONY: go.tidy +go.tidy: + @# tidy dirs with go.mod files + @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ + cd $$dir; \ + $(GO) mod tidy; \ + ); done + +.PHONY: go.depaware-update +go.depaware-update: go.tidy + @# gen depaware for bins + @set -e; for dir in $(GOBINS); do ( set -xe; \ + cd $$dir; \ + $(GO) run github.com/tailscale/depaware --update .; \ + ); done + @# tidy unused depaware deps if not in a tools_test.go file + @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ + cd $$dir; \ + $(GO) mod tidy; \ + ); done + +.PHONY: go.depaware-check +go.depaware-check: go.tidy + @# gen depaware for bins + @set -e; for dir in $(GOBINS); do ( set -xe; \ + cd $$dir; \ + $(GO) run github.com/tailscale/depaware --check .; \ + ); done + + +.PHONY: go.build +go.build: + @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ + cd $$dir; \ + $(GO) build ./...; \ + ); done + +.PHONY: go.bump-deps +go.bumpdeps: + @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ + cd $$dir; \ + $(GO) get -u ./...; \ + ); done + +.PHONY: go.fmt +go.fmt: + @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ + cd $$dir; \ + $(GO) run golang.org/x/tools/cmd/goimports -w `go list -f '{{.Dir}}' ./...` \ + ); done + +VERIFY_STEPS += go.depaware-check +BUILD_STEPS += go.build +BUMPDEPS_STEPS += go.bumpdeps go.depaware-update +TIDY_STEPS += go.tidy +LINT_STEPS += go.lint +UNITTEST_STEPS += go.unittest +FMT_STEPS += go.fmt + +# FIXME: disabled, because currently slow +# new rule that is manually run sometimes, i.e. `make pre-release` or `make maintenance`. +# alternative: run it each time the go.mod is changed +#GENERATE_STEPS += go.depaware-update +endif + +## +## Tool +## + +ifneq ($(wildcard ./tool/lint/Makefile),) +.PHONY: tool.lint +tool.lint: + cd tool/lint; make +LINT_STEPS += tool.lint +endif + +## +## Gitattributes +## + +ifneq ($(wildcard .gitattributes),) +.PHONY: _linguist-ignored +_linguist-kept: + @git check-attr linguist-vendored $(shell git check-attr linguist-generated $(shell find . -type f | grep -v .git/) | grep unspecified | cut -d: -f1) | grep unspecified | cut -d: -f1 | sort + +.PHONY: _linguist-kept +_linguist-ignored: + @git check-attr linguist-vendored linguist-ignored `find . -not -path './.git/*' -type f` | grep '\ set$$' | cut -d: -f1 | sort -u +endif + +## +## Node +## + +ifndef NPM_PACKAGES +ifneq ($(wildcard package.json),) +NPM_PACKAGES = . +endif +endif +ifdef NPM_PACKAGES +.PHONY: npm.publish +npm.publish: + @echo -n "Do you want to npm publish? [y/N] " && read ans && \ + @if [ $${ans:-N} = y ]; then \ + set -e; for dir in $(NPM_PACKAGES); do ( set -xe; \ + cd $$dir; \ + npm publish --access=public; \ + ); done; \ + fi +RELEASE_STEPS += npm.publish +endif + +## +## Docker +## + +docker_build = docker build \ + --build-arg VCS_REF=`git rev-parse --short HEAD` \ + --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg VERSION=`git describe --tags --always` \ + -t "$2" -f "$1" "$(dir $1)" + +ifndef DOCKERFILE_PATH +DOCKERFILE_PATH = ./Dockerfile +endif +ifndef DOCKER_IMAGE +ifneq ($(wildcard Dockerfile),) +DOCKER_IMAGE = $(notdir $(PWD)) +endif +endif +ifdef DOCKER_IMAGE +ifneq ($(DOCKER_IMAGE),none) +.PHONY: docker.build +docker.build: + $(call check-program, docker) + $(call docker_build,$(DOCKERFILE_PATH),$(DOCKER_IMAGE)) + +BUILD_STEPS += docker.build +endif +endif + +## +## Common +## + +TEST_STEPS += $(UNITTEST_STEPS) +TEST_STEPS += $(LINT_STEPS) +TEST_STEPS += $(TIDY_STEPS) + +ifneq ($(strip $(TEST_STEPS)),) +.PHONY: test +test: $(PRE_TEST_STEPS) $(TEST_STEPS) +endif + +ifdef INSTALL_STEPS +.PHONY: install +install: $(PRE_INSTALL_STEPS) $(INSTALL_STEPS) +endif + +ifdef UNITTEST_STEPS +.PHONY: unittest +unittest: $(PRE_UNITTEST_STEPS) $(UNITTEST_STEPS) +endif + +ifdef LINT_STEPS +.PHONY: lint +lint: $(PRE_LINT_STEPS) $(FMT_STEPS) $(LINT_STEPS) +endif + +ifdef TIDY_STEPS +.PHONY: tidy +tidy: $(PRE_TIDY_STEPS) $(TIDY_STEPS) +endif + +ifdef BUILD_STEPS +.PHONY: build +build: $(PRE_BUILD_STEPS) $(BUILD_STEPS) +endif + +ifdef VERIFY_STEPS +.PHONY: verify +verify: $(PRE_VERIFY_STEPS) $(VERIFY_STEPS) +endif + +ifdef RELEASE_STEPS +.PHONY: release +release: $(PRE_RELEASE_STEPS) $(RELEASE_STEPS) +endif + +ifdef BUMPDEPS_STEPS +.PHONY: bumpdeps +bumpdeps: $(PRE_BUMDEPS_STEPS) $(BUMPDEPS_STEPS) +endif + +ifdef FMT_STEPS +.PHONY: fmt +fmt: $(PRE_FMT_STEPS) $(FMT_STEPS) +endif + +ifdef GENERATE_STEPS +.PHONY: generate +generate: $(PRE_GENERATE_STEPS) $(GENERATE_STEPS) +endif + +.PHONY: help +help:: + @echo "General commands:" + @[ "$(BUILD_STEPS)" != "" ] && echo " build" || true + @[ "$(BUMPDEPS_STEPS)" != "" ] && echo " bumpdeps" || true + @[ "$(FMT_STEPS)" != "" ] && echo " fmt" || true + @[ "$(GENERATE_STEPS)" != "" ] && echo " generate" || true + @[ "$(INSTALL_STEPS)" != "" ] && echo " install" || true + @[ "$(LINT_STEPS)" != "" ] && echo " lint" || true + @[ "$(RELEASE_STEPS)" != "" ] && echo " release" || true + @[ "$(TEST_STEPS)" != "" ] && echo " test" || true + @[ "$(TIDY_STEPS)" != "" ] && echo " tidy" || true + @[ "$(UNITTEST_STEPS)" != "" ] && echo " unittest" || true + @[ "$(VERIFY_STEPS)" != "" ] && echo " verify" || true + @# FIXME: list other commands + +print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true diff --git a/tool/lint/.markdownlint.json b/tool/lint/.markdownlint.json new file mode 100644 index 0000000..7142e9e --- /dev/null +++ b/tool/lint/.markdownlint.json @@ -0,0 +1,9 @@ +{ + "default": true, + "no-inline-html": false, + "no-hard-tabs": false, + "no-trailing-punctuation": false, + "no-bare-urls": false, + "MD013": false, + "MD031": false +} diff --git a/tool/lint/.remarkignore b/tool/lint/.remarkignore new file mode 100644 index 0000000..7e5da87 --- /dev/null +++ b/tool/lint/.remarkignore @@ -0,0 +1,2 @@ +node_modules/ +vendor/ diff --git a/tool/lint/.remarkrc b/tool/lint/.remarkrc new file mode 100644 index 0000000..30efe3d --- /dev/null +++ b/tool/lint/.remarkrc @@ -0,0 +1,36 @@ +{ + "plugins": { + "lint": { + "blockquote-indentation": 2, + "emphasis-marker": "*", + "first-heading-level": false, + "link-title-style": "\"", + "list-item-indent": false, + "list-item-spacing": false, + "no-shell-dollars": false, + "maximum-heading-length": false, + "maximum-line-length": false, + "no-duplicate-headings": false, + "no-blockquote-without-caret": false, + "no-file-name-irregular-characters": true, + "no-file-name-outer-dashes": false, + "no-heading-punctuation": false, + "no-html": false, + "no-multiple-toplevel-headings": false, + "ordered-list-marker-style": ".", + "ordered-list-marker-value": "one", + "strong-marker": "*" + } + }, + "settings": { + "gfm": true, + "yaml": true, + "rule": "-", + "ruleSpaces": false, + "ruleRepetition": 70, + "emphasis": "*", + "listItemIndent": "1", + "incrementListMarker": false, + "spacedTable": false + } +} diff --git a/tool/lint/.spelling b/tool/lint/.spelling new file mode 100644 index 0000000..7854526 --- /dev/null +++ b/tool/lint/.spelling @@ -0,0 +1,7 @@ +manfred +touron +moul +golang-repo-template +contributing.md +pre-commit +dev diff --git a/tool/lint/Makefile b/tool/lint/Makefile new file mode 100644 index 0000000..2949587 --- /dev/null +++ b/tool/lint/Makefile @@ -0,0 +1,46 @@ +rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) +my-filter-out = $(foreach v,$(2),$(if $(findstring $(1),$(v)),,$(v))) +testfiles ?= $(sort $(call my-filter-out,node_modules/,$(call rwildcard,../..,*.md))) + +all: test + +test: info offensive-wording remark markdownlint spellcheck + @echo "" + @echo "--- OK. ---" +.PHONY: test + +info: deps + @echo "" + @echo "==> Files to check:" + @echo " $(testfiles:../.%=%)" +.PHONY: info + +offensive-wording: deps + @echo "" + @echo "==> Checking for inconsiderate/insensitive wording..." + @node_modules/.bin/alex --diff $(testfiles) || true +.PHONY: offensive-wording + +spellcheck: deps + @echo "" + @echo "==> Checking for spelling errors..." + @node_modules/.bin/mdspell --report --en-us --ignore-numbers --ignore-acronyms $(testfiles) +.PHONY: spellcheck + +remark: deps + @echo "" + @echo "==> Checking for messy formatting..." + @node_modules/.bin/remark --frail $(testfiles) +.PHONY: remark + +markdownlint: deps + @echo "" + @echo "==> Checking for good practices..." + @node_modules/.bin/markdownlint $(testfiles) +.PHONY: markdownlint + +deps: node_modules/ +node_modules/: package.json + npm install + touch $@ +.PHONY: deps diff --git a/tool/lint/package.json b/tool/lint/package.json new file mode 100644 index 0000000..f334595 --- /dev/null +++ b/tool/lint/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "alex": "10.0.0", + "markdown-spellcheck": "1.3.1", + "markdownlint-cli": "0.31.1", + "remark-cli": "10.0.1", + "remark-lint": "9.1.1" + } +}