├── .all-contributorsrc ├── .dockerignore ├── .editorconfig ├── .gitpod.yml ├── .golangci.yml ├── .goreleaser.yml ├── .pre-commit-config.yaml ├── AUTHORS ├── COPYRIGHT ├── Dockerfile ├── LICENSE-APACHE ├── LICENSE-MIT ├── Makefile ├── README.md ├── SECURITY.md ├── depaware.txt ├── doc.go ├── go.mod ├── go.sum ├── internal └── tools │ └── tools_test.go ├── main.go ├── main_test.go ├── package.json └── rules.mk /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "badgeTemplate": "[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg)](#contributors)", 8 | "contributors": [ 9 | { 10 | "login": "moul", 11 | "name": "Manfred Touron", 12 | "avatar_url": "https://avatars1.githubusercontent.com/u/94029?v=4", 13 | "profile": "http://manfred.life", 14 | "contributions": [ 15 | "maintenance", 16 | "doc", 17 | "test", 18 | "code" 19 | ] 20 | }, 21 | { 22 | "login": "moul-bot", 23 | "name": "moul-bot", 24 | "avatar_url": "https://avatars1.githubusercontent.com/u/41326314?v=4", 25 | "profile": "https://manfred.life/moul-bot", 26 | "contributions": [ 27 | "maintenance" 28 | ] 29 | } 30 | ], 31 | "contributorsPerLine": 7, 32 | "projectName": "golang-repo-template", 33 | "projectOwner": "moul", 34 | "repoType": "github", 35 | "repoHost": "https://github.com", 36 | "skipCi": true 37 | } 38 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | ## 2 | ## Specific to .dockerignore 3 | ## 4 | 5 | .git/ 6 | Dockerfile 7 | contrib/ 8 | 9 | ## 10 | ## Common with .gitignore 11 | ## 12 | 13 | # Temporary files 14 | *~ 15 | *# 16 | .#* 17 | 18 | # Vendors 19 | node_modules/ 20 | vendor/ 21 | 22 | # Binaries for programs and plugins 23 | dist/ 24 | gin-bin 25 | *.exe 26 | *.exe~ 27 | *.dll 28 | *.so 29 | *.dylib 30 | 31 | # Test binary, build with `go test -c` 32 | *.test 33 | 34 | # Output of the go coverage tool, specifically when used with LiteIDE 35 | *.out 36 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | indent_style = space 11 | indent_size = 4 12 | 13 | [*.mod] 14 | indent_style = tab 15 | 16 | [{Makefile,**.mk}] 17 | indent_style = tab 18 | 19 | [*.go] 20 | indent_style = tab 21 | 22 | [*.css] 23 | indent_size = 2 24 | 25 | [*.proto] 26 | indent_size = 2 27 | 28 | [*.ftl] 29 | indent_size = 2 30 | 31 | [*.toml] 32 | indent_size = 2 33 | 34 | [*.swift] 35 | indent_size = 4 36 | 37 | [*.tmpl] 38 | indent_size = 2 39 | 40 | [*.js] 41 | indent_size = 2 42 | block_comment_start = /* 43 | block_comment_end = */ 44 | 45 | [*.{html,htm}] 46 | indent_size = 2 47 | 48 | [*.bat] 49 | end_of_line = crlf 50 | 51 | [*.{yml,yaml}] 52 | indent_size = 2 53 | 54 | [*.json] 55 | indent_size = 2 56 | 57 | [.{babelrc,eslintrc,prettierrc}] 58 | indent_size = 2 59 | 60 | [{Fastfile,.buckconfig,BUCK}] 61 | indent_size = 2 62 | 63 | [*.diff] 64 | indent_size = 1 65 | 66 | [*.m] 67 | indent_size = 1 68 | indent_style = space 69 | block_comment_start = /** 70 | block_comment = * 71 | block_comment_end = */ 72 | 73 | [*.java] 74 | indent_size = 4 75 | indent_style = space 76 | block_comment_start = /** 77 | block_comment = * 78 | block_comment_end = */ 79 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: go get && go build ./... && go test ./... 3 | command: go run 4 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | deadline: 1m 3 | tests: false 4 | skip-files: 5 | - "testing.go" 6 | - ".*\\.pb\\.go" 7 | - ".*\\.gen\\.go" 8 | 9 | linters-settings: 10 | golint: 11 | min-confidence: 0 12 | goconst: 13 | min-len: 5 14 | min-occurrences: 4 15 | misspell: 16 | locale: US 17 | 18 | linters: 19 | disable-all: true 20 | enable: 21 | - asciicheck 22 | - bodyclose 23 | #- depguard 24 | - dogsled 25 | - dupl 26 | - errcheck 27 | - exhaustive 28 | - exportloopref 29 | - gci 30 | - gochecknoinits 31 | - gocognit 32 | - goconst 33 | - gocritic 34 | - gocyclo 35 | - godot 36 | - goerr113 37 | - gofmt 38 | - gofumpt 39 | - goimports 40 | - revive 41 | - gomnd 42 | - gomodguard 43 | - gosec 44 | - gosimple 45 | - govet 46 | - ineffassign 47 | - misspell 48 | - nakedret 49 | - nestif 50 | - noctx 51 | - nolintlint 52 | - prealloc 53 | - exportloopref 54 | - staticcheck 55 | - unused 56 | - stylecheck 57 | - typecheck 58 | - unconvert 59 | - unparam 60 | - unused 61 | - whitespace 62 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | env: 2 | - GO111MODULE=on 3 | - GOPROXY=https://proxy.golang.org 4 | before: 5 | hooks: 6 | - go mod download 7 | builds: 8 | - 9 | env: 10 | - CGO_ENABLED=0 11 | goos: 12 | - linux 13 | - darwin 14 | - windows 15 | goarch: 16 | - 386 17 | - amd64 18 | - arm 19 | - arm64 20 | ignore: 21 | - 22 | goos: darwin 23 | goarch: 386 24 | flags: 25 | - "-a" 26 | ldflags: 27 | - '-extldflags "-static"' 28 | main: ./ 29 | checksum: 30 | name_template: '{{.ProjectName}}_checksums.txt' 31 | changelog: 32 | sort: asc 33 | filters: 34 | exclude: 35 | - '^docs:' 36 | - '^test:' 37 | - Merge pull request 38 | - Merge branch 39 | archives: 40 | - 41 | name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' 42 | #replacements: 43 | # darwin: Darwin 44 | # linux: Linux 45 | # windows: Windows 46 | # 386: i386 47 | # amd64: x86_64 48 | format_overrides: 49 | - 50 | goos: windows 51 | format: zip 52 | wrap_in_directory: true 53 | brews: 54 | - 55 | name: golang-repo-template 56 | # github: 57 | # owner: moul 58 | # name: homebrew-moul 59 | commit_author: 60 | name: moul-bot 61 | email: "bot@moul.io" 62 | homepage: https://github.com/moul/golang-repo-template 63 | description: "golang-repo-template" 64 | nfpms: 65 | - 66 | file_name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' 67 | homepage: https://github.com/moul/golang-repo-template 68 | description: "golang-repo-template" 69 | maintainer: "Manfred Touron " 70 | license: "Apache-2.0 OR MIT" 71 | vendor: moul 72 | formats: 73 | - deb 74 | - rpm 75 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | - repo: git://github.com/dnephin/pre-commit-golang 2 | rev: master 3 | hooks: 4 | - id: go-fmt 5 | - id: go-vet 6 | - id: go-lint 7 | - id: go-imports 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This file lists all individuals having contributed content to the repository. 2 | # For how it is generated, see 'https://github.com/moul/rules.mk' 3 | 4 | allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> 5 | Darko Djalevski 6 | Darko Djalevski 7 | dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> 8 | dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9 | Isma <71719097+Doozers@users.noreply.github.com> 10 | Manfred Touron <94029+moul@users.noreply.github.com> 11 | Manfred Touron 12 | moul <94029+moul@users.noreply.github.com> 13 | moul-bot 14 | Renovate Bot 15 | renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> 16 | semgrep.dev on behalf of @moul 17 | Stavros Panakakis <53979866+Stavrospanakakis@users.noreply.github.com> 18 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2021 Manfred Touron and other golang-repo-template Developers. 2 | 3 | Intellectual Property Notice 4 | ---------------------------- 5 | 6 | golang-repo-template is licensed under the Apache License, Version 2.0 7 | (see LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or 8 | the MIT license (see LICENSE-MIT or http://opensource.org/licenses/MIT), 9 | at your option. 10 | 11 | Copyrights and patents in the golang-repo-templates project are retained 12 | by contributors. 13 | No copyright assignment is required to contribute to golang-repo-template. 14 | 15 | SPDX-License-Identifier: (Apache-2.0 OR MIT) 16 | 17 | SPDX usage 18 | ---------- 19 | 20 | Individual files may contain SPDX tags instead of the full license text. 21 | This enables machine processing of license information based on the SPDX 22 | License Identifiers that are available here: https://spdx.org/licenses/ 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # dynamic config 2 | ARG BUILD_DATE 3 | ARG VCS_REF 4 | ARG VERSION 5 | 6 | # build 7 | FROM golang:1.20-alpine as builder 8 | RUN apk add --no-cache git gcc musl-dev make 9 | ENV GO111MODULE=on 10 | WORKDIR /go/src/moul.io/golang-repo-template 11 | COPY go.* ./ 12 | RUN go mod download 13 | COPY . ./ 14 | RUN make install 15 | 16 | # minimalist runtime 17 | FROM alpine:3.18.0 18 | LABEL org.label-schema.build-date=$BUILD_DATE \ 19 | org.label-schema.name="golang-repo-template" \ 20 | org.label-schema.description="" \ 21 | org.label-schema.url="https://moul.io/golang-repo-template/" \ 22 | org.label-schema.vcs-ref=$VCS_REF \ 23 | org.label-schema.vcs-url="https://github.com/moul/golang-repo-template" \ 24 | org.label-schema.vendor="Manfred Touron" \ 25 | org.label-schema.version=$VERSION \ 26 | org.label-schema.schema-version="1.0" \ 27 | org.label-schema.cmd="docker run -i -t --rm moul/golang-repo-template" \ 28 | org.label-schema.help="docker exec -it $CONTAINER golang-repo-template --help" 29 | COPY --from=builder /go/bin/golang-repo-template /bin/ 30 | ENTRYPOINT ["/bin/golang-repo-template"] 31 | #CMD [] 32 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2021 Manfred Touron (manfred.life) 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Manfred Touron (manfred.life) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GOPKG ?= moul.io/golang-repo-template 2 | DOCKER_IMAGE ?= moul/golang-repo-template 3 | GOBINS ?= . 4 | NPM_PACKAGES ?= . 5 | 6 | include rules.mk 7 | 8 | generate: install 9 | GO111MODULE=off go get github.com/campoy/embedmd 10 | mkdir -p .tmp 11 | echo 'foo@bar:~$$ golang-repo-template' > .tmp/usage.txt 12 | golang-repo-template 2>&1 >> .tmp/usage.txt 13 | embedmd -w README.md 14 | rm -rf .tmp 15 | .PHONY: generate 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golang-repo-template 2 | 3 | :smile: golang-repo-template 4 | 5 | [![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) 6 | [![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) 7 | [![GitHub release](https://img.shields.io/github/release/moul/golang-repo-template.svg)](https://github.com/moul/golang-repo-template/releases) 8 | [![Docker Metrics](https://images.microbadger.com/badges/image/moul/golang-repo-template.svg)](https://microbadger.com/images/moul/golang-repo-template) 9 | [![Made by Manfred Touron](https://img.shields.io/badge/made%20by-Manfred%20Touron-blue.svg?style=flat)](https://manfred.life/) 10 | 11 | [![Go](https://github.com/moul/golang-repo-template/workflows/Go/badge.svg)](https://github.com/moul/golang-repo-template/actions?query=workflow%3AGo) 12 | [![Release](https://github.com/moul/golang-repo-template/workflows/Release/badge.svg)](https://github.com/moul/golang-repo-template/actions?query=workflow%3ARelease) 13 | [![PR](https://github.com/moul/golang-repo-template/workflows/PR/badge.svg)](https://github.com/moul/golang-repo-template/actions?query=workflow%3APR) 14 | [![GolangCI](https://golangci.com/badges/github.com/moul/golang-repo-template.svg)](https://golangci.com/r/github.com/moul/golang-repo-template) 15 | [![codecov](https://codecov.io/gh/moul/golang-repo-template/branch/main/graph/badge.svg)](https://codecov.io/gh/moul/golang-repo-template) 16 | [![Go Report Card](https://goreportcard.com/badge/moul.io/golang-repo-template)](https://goreportcard.com/report/moul.io/golang-repo-template) 17 | [![CodeFactor](https://www.codefactor.io/repository/github/moul/golang-repo-template/badge)](https://www.codefactor.io/repository/github/moul/golang-repo-template) 18 | 19 | [![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) 20 | 21 | ## Usage 22 | 23 | [embedmd]:# (.tmp/usage.txt console) 24 | ```console 25 | foo@bar:~$ golang-repo-template 26 | _ _ _ _ 27 | __ _ ___ | | __ _ _ _ __ _ ___ _ _ ___ _ __ ___ ___ | |_ ___ _ __ _ __ | | __ _ | |_ ___ 28 | / _` |/ _ \| |/ _` || ' \ / _` ||___|| '_|/ -_)| '_ \/ _ \|___|| _|/ -_)| ' \ | '_ \| |/ _` || _|/ -_) 29 | \__, |\___/|_|\__,_||_||_|\__, | |_| \___|| .__/\___/ \__|\___||_|_|_|| .__/|_|\__,_| \__|\___| 30 | |___/ |___/ |_| |_| 31 | 12 CPUs, /home/moul/.local/bin/golang-repo-template, fwrz, go1.16.5 32 | [] 33 | ``` 34 | 35 | ## Install 36 | 37 | ### Using go 38 | 39 | ```sh 40 | go get moul.io/golang-repo-template 41 | ``` 42 | 43 | ### Releases 44 | 45 | See https://github.com/moul/golang-repo-template/releases 46 | 47 | ## Contribute 48 | 49 | ![Contribute <3](https://raw.githubusercontent.com/moul/moul/main/contribute.gif) 50 | 51 | I really welcome contributions. 52 | Your input is the most precious material. 53 | I'm well aware of that and I thank you in advance. 54 | Everyone is encouraged to look at what they can do on their own scale; 55 | no effort is too small. 56 | 57 | Everything on contribution is sum up here: [CONTRIBUTING.md](./.github/CONTRIBUTING.md) 58 | 59 | ### Dev helpers 60 | 61 | Pre-commit script for install: https://pre-commit.com 62 | 63 | ### Contributors ✨ 64 | 65 | 66 | [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg)](#contributors) 67 | 68 | 69 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |

Manfred Touron

🚧 📖 ⚠️ 💻

moul-bot

🚧
80 | 81 | 82 | 83 | 84 | 85 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) 86 | specification. Contributions of any kind welcome! 87 | 88 | ### Stargazers over time 89 | 90 | [![Stargazers over time](https://starchart.cc/moul/golang-repo-template.svg)](https://starchart.cc/moul/golang-repo-template) 91 | 92 | ## License 93 | 94 | © 2021 [Manfred Touron](https://manfred.life) 95 | 96 | Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) 97 | ([`LICENSE-APACHE`](LICENSE-APACHE)) or the [MIT license](https://opensource.org/licenses/MIT) 98 | ([`LICENSE-MIT`](LICENSE-MIT)), at your option. 99 | See the [`COPYRIGHT`](COPYRIGHT) file for more details. 100 | 101 | `SPDX-License-Identifier: (Apache-2.0 OR MIT)` 102 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security issues 2 | 3 | I take security seriously. If you discover a security issue, 4 | please bring it to my attention right away! 5 | 6 | ## Reporting a Vulnerability 7 | 8 | Please **DO NOT** file a public issue, 9 | instead send your report privately to security@moul.io. 10 | 11 | Security reports are greatly appreciated and I will publicly thank you for it, 12 | although I keep your name confidential if you request it. 13 | -------------------------------------------------------------------------------- /depaware.txt: -------------------------------------------------------------------------------- 1 | moul.io/golang-repo-template dependencies: (generated by github.com/tailscale/depaware) 2 | 3 | github.com/peterbourgon/ff/v3 from moul.io/climan+ 4 | github.com/peterbourgon/ff/v3/internal from github.com/peterbourgon/ff/v3 5 | 💣 go.uber.org/atomic from go.uber.org/zap+ 6 | go.uber.org/multierr from go.uber.org/zap+ 7 | go.uber.org/zap from moul.io/zapconfig+ 8 | go.uber.org/zap/buffer from go.uber.org/zap/internal/bufferpool+ 9 | go.uber.org/zap/internal from go.uber.org/zap 10 | go.uber.org/zap/internal/bufferpool from go.uber.org/zap+ 11 | go.uber.org/zap/internal/color from go.uber.org/zap/zapcore 12 | go.uber.org/zap/internal/exit from go.uber.org/zap/zapcore 13 | go.uber.org/zap/zapcore from go.uber.org/zap+ 14 | moul.io/banner from moul.io/motd 15 | moul.io/climan from moul.io/golang-repo-template 16 | moul.io/motd from moul.io/golang-repo-template 17 | moul.io/srand from moul.io/golang-repo-template 18 | moul.io/u from moul.io/golang-repo-template 19 | moul.io/zapconfig from moul.io/golang-repo-template 20 | golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305 21 | golang.org/x/crypto/chacha20poly1305 from crypto/tls 22 | golang.org/x/crypto/cryptobyte from crypto/ecdsa+ 23 | golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+ 24 | golang.org/x/crypto/hkdf from crypto/tls 25 | golang.org/x/net/dns/dnsmessage from net 26 | golang.org/x/net/http/httpguts from net/http 27 | golang.org/x/net/http/httpproxy from net/http 28 | golang.org/x/net/http2/hpack from net/http 29 | golang.org/x/net/idna from golang.org/x/net/http/httpguts+ 30 | D golang.org/x/net/route from net 31 | golang.org/x/sys/cpu from golang.org/x/crypto/chacha20poly1305 32 | golang.org/x/text/secure/bidirule from golang.org/x/net/idna 33 | golang.org/x/text/transform from golang.org/x/text/secure/bidirule+ 34 | golang.org/x/text/unicode/bidi from golang.org/x/net/idna+ 35 | golang.org/x/text/unicode/norm from golang.org/x/net/idna 36 | archive/zip from moul.io/u 37 | bufio from archive/zip+ 38 | bytes from bufio+ 39 | compress/flate from archive/zip+ 40 | compress/gzip from net/http 41 | container/list from crypto/tls+ 42 | context from crypto/tls+ 43 | crypto from crypto/ecdsa+ 44 | crypto/aes from crypto/ecdsa+ 45 | crypto/cipher from crypto/aes+ 46 | crypto/des from crypto/tls+ 47 | crypto/dsa from crypto/x509 48 | crypto/ecdh from crypto/ecdsa+ 49 | crypto/ecdsa from crypto/tls+ 50 | crypto/ed25519 from crypto/tls+ 51 | crypto/elliptic from crypto/ecdsa+ 52 | crypto/hmac from crypto/tls+ 53 | crypto/md5 from crypto/tls+ 54 | crypto/rand from crypto/ed25519+ 55 | crypto/rc4 from crypto/tls 56 | crypto/rsa from crypto/tls+ 57 | crypto/sha1 from crypto/tls+ 58 | crypto/sha256 from crypto/tls+ 59 | crypto/sha512 from crypto/ecdsa+ 60 | crypto/subtle from crypto/aes+ 61 | crypto/tls from net/http+ 62 | crypto/x509 from crypto/tls 63 | crypto/x509/pkix from crypto/x509 64 | embed from crypto/internal/nistec+ 65 | encoding from encoding/json+ 66 | encoding/asn1 from crypto/x509+ 67 | encoding/base64 from encoding/json+ 68 | encoding/binary from archive/zip+ 69 | encoding/hex from crypto/x509+ 70 | encoding/json from go.uber.org/atomic+ 71 | encoding/pem from crypto/tls+ 72 | errors from archive/zip+ 73 | flag from go.uber.org/zap+ 74 | fmt from compress/flate+ 75 | hash from archive/zip+ 76 | hash/crc32 from archive/zip+ 77 | io from archive/zip+ 78 | io/fs from archive/zip+ 79 | io/ioutil from golang.org/x/sys/cpu+ 80 | log from go.uber.org/zap+ 81 | math from compress/flate+ 82 | math/big from crypto/dsa+ 83 | math/bits from compress/flate+ 84 | math/rand from math/big+ 85 | mime from mime/multipart+ 86 | mime/multipart from net/http 87 | mime/quotedprintable from mime/multipart 88 | net from crypto/tls+ 89 | net/http from go.uber.org/zap 90 | net/http/httptrace from net/http 91 | net/http/internal from net/http 92 | net/netip from net 93 | net/textproto from golang.org/x/net/http/httpguts+ 94 | net/url from crypto/x509+ 95 | os from archive/zip+ 96 | os/exec from moul.io/u 97 | os/signal from moul.io/u 98 | os/user from moul.io/u 99 | path from archive/zip+ 100 | path/filepath from crypto/x509+ 101 | reflect from crypto/x509+ 102 | sort from compress/flate+ 103 | strconv from compress/flate+ 104 | strings from archive/zip+ 105 | sync from archive/zip+ 106 | sync/atomic from context+ 107 | syscall from crypto/rand+ 108 | text/tabwriter from moul.io/climan 109 | time from archive/zip+ 110 | unicode from bytes+ 111 | unicode/utf16 from encoding/asn1+ 112 | unicode/utf8 from archive/zip+ 113 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Copyright © 2021 Manfred Touron 2 | // SPDX-License-Identifier: Apache-2.0 OR MIT 3 | 4 | // message from the author: 5 | // 6 | // +--------------------------------------------------------------+ 7 | // | * * * ░░░░░░░░░░░░░░░░░░░░ Hello ░░░░░░░░░░░░░░░░░░░░░░░░░░| 8 | // +--------------------------------------------------------------+ 9 | // | | 10 | // | ++ ______________________________________ | 11 | // | ++++ / \ | 12 | // | ++++ | | | 13 | // | ++++++++++ | Feel free to contribute to this | | 14 | // | +++ | | project or contact me on | | 15 | // | ++ | | manfred.life if you like this | | 16 | // | + -== ==| | project! | | 17 | // | ( <*> <*> | | | 18 | // | | | /| :) | | 19 | // | | _) / | | | 20 | // | | +++ / \______________________________________/ | 21 | // | \ =+ / | 22 | // | \ + | 23 | // | |\++++++ | 24 | // | | ++++ ||// | 25 | // | ___| |___ _||/__ __| 26 | // | / --- \ \| ||| __ _ ___ __ __/ /| 27 | // |/ | | \ \ / / ' \/ _ \/ // / / | 28 | // || | | | | | /_/_/_/\___/\_,_/_/ | 29 | // +--------------------------------------------------------------+ 30 | package main // import "moul.io/golang-repo-template" 31 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module moul.io/golang-repo-template 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/peterbourgon/ff/v3 v3.4.0 7 | github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 8 | go.uber.org/goleak v1.2.1 9 | go.uber.org/zap v1.24.0 10 | moul.io/climan v1.0.0 11 | moul.io/motd v1.0.0 12 | moul.io/srand v1.6.1 13 | moul.io/u v1.27.0 14 | moul.io/zapconfig v1.4.0 15 | ) 16 | 17 | require ( 18 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect 19 | go.uber.org/atomic v1.11.0 // indirect 20 | go.uber.org/multierr v1.11.0 // indirect 21 | golang.org/x/mod v0.4.2 // indirect 22 | golang.org/x/sys v0.1.0 // indirect 23 | golang.org/x/tools v0.1.5 // indirect 24 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 25 | moul.io/banner v1.0.1 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 2 | github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= 3 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 6 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 8 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 9 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 10 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 11 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 12 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 13 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 14 | github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= 15 | github.com/peterbourgon/ff/v3 v3.0.0/go.mod h1:UILIFjRH5a/ar8TjXYLTkIvSvekZqPm5Eb/qbGk6CT0= 16 | github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc= 17 | github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= 18 | github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= 19 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= 20 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 21 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 22 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 23 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 24 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 25 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 26 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 27 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 28 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 29 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 30 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 31 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 32 | github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= 33 | github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HPjrSuJYEkdZ+0ItmGQAQ75cRHIiftIyE= 34 | github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= 35 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 36 | go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 37 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 38 | go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= 39 | go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= 40 | go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= 41 | go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= 42 | go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= 43 | go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= 44 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 45 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 46 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= 47 | go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= 48 | go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= 49 | go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= 50 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 51 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 52 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 53 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 54 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 55 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 56 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 57 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 58 | golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= 59 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 60 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 61 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 62 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 63 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 64 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 65 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 66 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 67 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 68 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 69 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 70 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 71 | golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= 72 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 73 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 74 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 75 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 76 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 77 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 78 | golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 79 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 80 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 81 | golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 82 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 83 | golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= 84 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 85 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 86 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 87 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 88 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 89 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 90 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 91 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 92 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 93 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 94 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 95 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 96 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 97 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 98 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 99 | moul.io/banner v1.0.1 h1:+WsemGLhj2pOajw2eR5VYjLhOIqs0XhIRYchzTyMLk0= 100 | moul.io/banner v1.0.1/go.mod h1:XwvIGKkhKRKyN1vIdmR5oaKQLIkMhkMqrsHpS94QzAU= 101 | moul.io/climan v1.0.0 h1:Xc9xnUrLVPK69lnCfVJnCvVtMm4v6Lt2743fnadvpWc= 102 | moul.io/climan v1.0.0/go.mod h1:iT29NKBU5U7cAYxmpt9XXfv3PV1OW+5OKvze553VTwc= 103 | moul.io/motd v1.0.0 h1:Trk4fPibDfPJf2iCBSQC8ws7Q02sMwivQdVEFAjCPto= 104 | moul.io/motd v1.0.0/go.mod h1:39rvZ0lC2oRhHDY2VoPyZ8r70VKqeJye3QAxjeLDJso= 105 | moul.io/srand v1.6.1 h1:SJ335F+54ivLdlH7wH52Rtyv0Ffos6DpsF5wu3ZVMXU= 106 | moul.io/srand v1.6.1/go.mod h1:P2uaZB+GFstFNo8sEj6/U8FRV1n25kD0LLckFpJ+qvc= 107 | moul.io/u v1.23.0/go.mod h1:ytlQ/zt+Sdk+PFGEx+fpTivoa0ieA5yMo6itRswIWNQ= 108 | moul.io/u v1.25.1/go.mod h1:ggYDXxUjoHpfDsMPD3STqkUZTyA741PZiQhSd+7kRnA= 109 | moul.io/u v1.27.0 h1:rF0p184mludn2DzL0unA8Gf/mFWMBerdqOh8cyuQYzQ= 110 | moul.io/u v1.27.0/go.mod h1:ggYDXxUjoHpfDsMPD3STqkUZTyA741PZiQhSd+7kRnA= 111 | moul.io/zapconfig v1.4.0 h1:J3ND5J3e/qQ++jlpqdSR1EtDNV+iujtvXgLsjy1uyq8= 112 | moul.io/zapconfig v1.4.0/go.mod h1:bYTa5j7r82yPmSR6i5CcrPSVoWEbdpN7o9IgndSVby8= 113 | -------------------------------------------------------------------------------- /internal/tools/tools_test.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | package tools 5 | 6 | import ( 7 | _ "github.com/tailscale/depaware" // required by rules.mk 8 | ) 9 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "flag" 7 | "fmt" 8 | "math/rand" 9 | "os" 10 | 11 | ff "github.com/peterbourgon/ff/v3" 12 | "go.uber.org/zap" 13 | "go.uber.org/zap/zapcore" 14 | "moul.io/climan" 15 | "moul.io/motd" 16 | "moul.io/srand" 17 | "moul.io/u" 18 | "moul.io/zapconfig" 19 | ) 20 | 21 | func main() { 22 | if err := run(os.Args[1:]); err != nil { 23 | if !errors.Is(err, flag.ErrHelp) { 24 | fmt.Fprintf(os.Stderr, "error: %+v\n", err) 25 | } 26 | os.Exit(1) 27 | } 28 | } 29 | 30 | var opts struct { 31 | Debug bool 32 | rootLogger *zap.Logger 33 | } 34 | 35 | func run(args []string) error { 36 | // parse CLI 37 | root := &climan.Command{ 38 | Name: "golang-repo-template", 39 | ShortUsage: "golang-repo-template [global flags] [flags] [args]", 40 | ShortHelp: "More info on https://moul.io/golang-repo-template.", 41 | FlagSetBuilder: func(fs *flag.FlagSet) { fs.BoolVar(&opts.Debug, "debug", opts.Debug, "debug mode") }, 42 | Exec: doRoot, 43 | FFOptions: []ff.Option{ff.WithEnvVarPrefix("golang-repo-template")}, 44 | // Subcommands: []*climan.Command{}, 45 | // LongHelp: "", 46 | } 47 | if err := root.Parse(args); err != nil { 48 | return fmt.Errorf("parse error: %w", err) 49 | } 50 | 51 | // init runtime 52 | { 53 | // prng 54 | rand.Seed(srand.Fast()) 55 | 56 | // concurrency 57 | // runtime.GOMAXPROCS(1) 58 | 59 | // logger 60 | config := zapconfig.New().SetPreset("light-console") 61 | if opts.Debug { 62 | config = config.SetLevel(zapcore.DebugLevel) 63 | } else { 64 | config = config.SetLevel(zapcore.InfoLevel) 65 | } 66 | var err error 67 | opts.rootLogger, err = config.Build() 68 | if err != nil { 69 | return fmt.Errorf("logger init: %w", err) 70 | } 71 | } 72 | 73 | // run 74 | if err := root.Run(context.Background()); err != nil { 75 | return fmt.Errorf("%w", err) 76 | } 77 | 78 | return nil 79 | } 80 | 81 | func doRoot(_ context.Context, args []string) error { 82 | if len(args) > 0 { 83 | return flag.ErrHelp 84 | } 85 | 86 | opts.rootLogger.Debug("init", zap.Strings("args", args), zap.Any("opts", opts)) 87 | fmt.Print(motd.Default()) 88 | fmt.Println(u.PrettyJSON(args)) 89 | return nil 90 | } 91 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "flag" 6 | "testing" 7 | 8 | "go.uber.org/goleak" 9 | ) 10 | 11 | func TestRun(t *testing.T) { 12 | err := run([]string{"-h"}) 13 | if !errors.Is(err, flag.ErrHelp) { 14 | t.Fatalf("err should be flag.ErrHelp, got %v", err) 15 | } 16 | } 17 | 18 | func TestMain(m *testing.M) { 19 | goleak.VerifyTestMain(m) 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment": "this project is not a node.js one, package.json is just used to define some metadata", 3 | "name": "@moul.io/golang-repo-template", 4 | "version": "0.0.1", 5 | "author": "Manfred Touron (https://manfred.life)", 6 | "contributors": [ 7 | "Manfred Touron (https://manfred.life)" 8 | ], 9 | "license": "(Apache-2.0 OR MIT)", 10 | "scripts": { 11 | "start": "golang-repo-template", 12 | "install": "make install", 13 | "test": "make test" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/moul/golang-repo-template.git" 18 | }, 19 | "bugs": "https://github.com/moul/golang-repo-template/issues", 20 | "homepage": "https://moul.io/golang-repo-template", 21 | "release": { 22 | "branches": ["master", "main"], 23 | "plugins": [ 24 | "@semantic-release/commit-analyzer", 25 | "@semantic-release/release-notes-generator", 26 | "@semantic-release/github" 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rules.mk: -------------------------------------------------------------------------------- 1 | # +--------------------------------------------------------------+ 2 | # | * * * moul.io/rules.mk | 3 | # +--------------------------------------------------------------+ 4 | # | | 5 | # | ++ ______________________________________ | 6 | # | ++++ / \ | 7 | # | ++++ | | | 8 | # | ++++++++++ | https://moul.io/rules.mk is a set | | 9 | # | +++ | | of common Makefile rules that can | | 10 | # | ++ | | be configured from the Makefile | | 11 | # | + -== ==| | or with environment variables. | | 12 | # | ( <*> <*> | | | 13 | # | | | /| Manfred Touron | | 14 | # | | _) / | manfred.life | | 15 | # | | +++ / \______________________________________/ | 16 | # | \ =+ / | 17 | # | \ + | 18 | # | |\++++++ | 19 | # | | ++++ ||// | 20 | # | ___| |___ _||/__ __| 21 | # | / --- \ \| ||| __ _ ___ __ __/ /| 22 | # |/ | | \ \ / / ' \/ _ \/ // / / | 23 | # || | | | | | /_/_/_/\___/\_,_/_/ | 24 | # +--------------------------------------------------------------+ 25 | 26 | .PHONY: _default_entrypoint 27 | _default_entrypoint: help 28 | 29 | ## 30 | ## Common helpers 31 | ## 32 | 33 | rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) 34 | check-program = $(foreach exec,$(1),$(if $(shell PATH="$(PATH)" which $(exec)),,$(error "No $(exec) in PATH"))) 35 | my-filter-out = $(foreach v,$(2),$(if $(findstring $(1),$(v)),,$(v))) 36 | novendor = $(call my-filter-out,vendor/,$(1)) 37 | 38 | ## 39 | ## rules.mk 40 | ## 41 | ifneq ($(wildcard rules.mk),) 42 | .PHONY: rulesmk.bumpdeps 43 | rulesmk.bumpdeps: 44 | wget -O rules.mk https://raw.githubusercontent.com/moul/rules.mk/master/rules.mk 45 | BUMPDEPS_STEPS += rulesmk.bumpdeps 46 | endif 47 | 48 | ## 49 | ## Maintainer 50 | ## 51 | 52 | ifneq ($(wildcard .git/HEAD),) 53 | .PHONY: generate.authors 54 | generate.authors: AUTHORS 55 | AUTHORS: .git/ 56 | echo "# This file lists all individuals having contributed content to the repository." > AUTHORS 57 | echo "# For how it is generated, see 'https://github.com/moul/rules.mk'" >> AUTHORS 58 | echo >> AUTHORS 59 | git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf >> AUTHORS 60 | GENERATE_STEPS += generate.authors 61 | endif 62 | 63 | ## 64 | ## Golang 65 | ## 66 | 67 | ifndef GOPKG 68 | ifneq ($(wildcard go.mod),) 69 | GOPKG = $(shell sed '/module/!d;s/^omdule\ //' go.mod) 70 | endif 71 | endif 72 | ifdef GOPKG 73 | GO ?= go 74 | GOPATH ?= $(HOME)/go 75 | GO_INSTALL_OPTS ?= 76 | GO_TEST_OPTS ?= -test.timeout=30s 77 | GOMOD_DIRS ?= $(sort $(call novendor,$(dir $(call rwildcard,*,*/go.mod go.mod)))) 78 | GOCOVERAGE_FILE ?= ./coverage.txt 79 | GOTESTJSON_FILE ?= ./go-test.json 80 | GOBUILDLOG_FILE ?= ./go-build.log 81 | GOINSTALLLOG_FILE ?= ./go-install.log 82 | 83 | ifdef GOBINS 84 | .PHONY: go.install 85 | go.install: 86 | ifeq ($(CI),true) 87 | @rm -f /tmp/goinstall.log 88 | @set -e; for dir in $(GOBINS); do ( set -xe; \ 89 | cd $$dir; \ 90 | $(GO) install -v $(GO_INSTALL_OPTS) .; \ 91 | ); done 2>&1 | tee $(GOINSTALLLOG_FILE) 92 | 93 | else 94 | @set -e; for dir in $(GOBINS); do ( set -xe; \ 95 | cd $$dir; \ 96 | $(GO) install $(GO_INSTALL_OPTS) .; \ 97 | ); done 98 | endif 99 | INSTALL_STEPS += go.install 100 | 101 | .PHONY: go.release 102 | go.release: 103 | $(call check-program, goreleaser) 104 | goreleaser --snapshot --skip-publish --rm-dist 105 | @echo -n "Do you want to release? [y/N] " && read ans && \ 106 | if [ $${ans:-N} = y ]; then set -xe; goreleaser --rm-dist; fi 107 | RELEASE_STEPS += go.release 108 | endif 109 | 110 | .PHONY: go.unittest 111 | go.unittest: 112 | ifeq ($(CI),true) 113 | @echo "mode: atomic" > /tmp/gocoverage 114 | @rm -f $(GOTESTJSON_FILE) 115 | @set -e; for dir in $(GOMOD_DIRS); do (set -e; (set -euf pipefail; \ 116 | cd $$dir; \ 117 | (($(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); \ 118 | ); \ 119 | rm $@.ok 2>/dev/null || exit 1; \ 120 | if [ -f /tmp/profile.out ]; then \ 121 | cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \ 122 | rm -f /tmp/profile.out; \ 123 | fi)); done 124 | @mv /tmp/gocoverage $(GOCOVERAGE_FILE) 125 | else 126 | @echo "mode: atomic" > /tmp/gocoverage 127 | @set -e; for dir in $(GOMOD_DIRS); do (set -e; (set -xe; \ 128 | cd $$dir; \ 129 | $(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race); \ 130 | if [ -f /tmp/profile.out ]; then \ 131 | cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \ 132 | rm -f /tmp/profile.out; \ 133 | fi); done 134 | @mv /tmp/gocoverage $(GOCOVERAGE_FILE) 135 | endif 136 | 137 | .PHONY: go.checkdoc 138 | go.checkdoc: 139 | go doc $(first $(GOMOD_DIRS)) 140 | 141 | .PHONY: go.coverfunc 142 | go.coverfunc: go.unittest 143 | go tool cover -func=$(GOCOVERAGE_FILE) | grep -v .pb.go: | grep -v .pb.gw.go: 144 | 145 | .PHONY: go.lint 146 | go.lint: 147 | @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ 148 | cd $$dir; \ 149 | golangci-lint run --verbose ./...; \ 150 | ); done 151 | 152 | .PHONY: go.tidy 153 | go.tidy: 154 | @# tidy dirs with go.mod files 155 | @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ 156 | cd $$dir; \ 157 | $(GO) mod tidy; \ 158 | ); done 159 | 160 | .PHONY: go.depaware-update 161 | go.depaware-update: go.tidy 162 | @# gen depaware for bins 163 | @set -e; for dir in $(GOBINS); do ( set -xe; \ 164 | cd $$dir; \ 165 | $(GO) run github.com/tailscale/depaware --update .; \ 166 | ); done 167 | @# tidy unused depaware deps if not in a tools_test.go file 168 | @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ 169 | cd $$dir; \ 170 | $(GO) mod tidy; \ 171 | ); done 172 | 173 | .PHONY: go.depaware-check 174 | go.depaware-check: go.tidy 175 | @# gen depaware for bins 176 | @set -e; for dir in $(GOBINS); do ( set -xe; \ 177 | cd $$dir; \ 178 | $(GO) run github.com/tailscale/depaware --check .; \ 179 | ); done 180 | 181 | 182 | .PHONY: go.build 183 | go.build: 184 | @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ 185 | cd $$dir; \ 186 | $(GO) build ./...; \ 187 | ); done 188 | 189 | .PHONY: go.bump-deps 190 | go.bumpdeps: 191 | @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ 192 | cd $$dir; \ 193 | $(GO) get -u ./...; \ 194 | ); done 195 | 196 | .PHONY: go.fmt 197 | go.fmt: 198 | @set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \ 199 | cd $$dir; \ 200 | $(GO) run golang.org/x/tools/cmd/goimports -w `go list -f '{{.Dir}}' ./...` \ 201 | ); done 202 | 203 | VERIFY_STEPS += go.depaware-check 204 | BUILD_STEPS += go.build 205 | BUMPDEPS_STEPS += go.bumpdeps go.depaware-update 206 | TIDY_STEPS += go.tidy 207 | LINT_STEPS += go.lint 208 | UNITTEST_STEPS += go.unittest 209 | FMT_STEPS += go.fmt 210 | 211 | # FIXME: disabled, because currently slow 212 | # new rule that is manually run sometimes, i.e. `make pre-release` or `make maintenance`. 213 | # alternative: run it each time the go.mod is changed 214 | #GENERATE_STEPS += go.depaware-update 215 | endif 216 | 217 | ## 218 | ## Tool 219 | ## 220 | 221 | ifneq ($(wildcard ./tool/lint/Makefile),) 222 | .PHONY: tool.lint 223 | tool.lint: 224 | cd tool/lint; make 225 | LINT_STEPS += tool.lint 226 | endif 227 | 228 | ## 229 | ## Gitattributes 230 | ## 231 | 232 | ifneq ($(wildcard .gitattributes),) 233 | .PHONY: _linguist-ignored 234 | _linguist-kept: 235 | @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 236 | 237 | .PHONY: _linguist-kept 238 | _linguist-ignored: 239 | @git check-attr linguist-vendored linguist-ignored `find . -not -path './.git/*' -type f` | grep '\ set$$' | cut -d: -f1 | sort -u 240 | endif 241 | 242 | ## 243 | ## Node 244 | ## 245 | 246 | ifndef NPM_PACKAGES 247 | ifneq ($(wildcard package.json),) 248 | NPM_PACKAGES = . 249 | endif 250 | endif 251 | ifdef NPM_PACKAGES 252 | .PHONY: npm.publish 253 | npm.publish: 254 | @echo -n "Do you want to npm publish? [y/N] " && read ans && \ 255 | @if [ $${ans:-N} = y ]; then \ 256 | set -e; for dir in $(NPM_PACKAGES); do ( set -xe; \ 257 | cd $$dir; \ 258 | npm publish --access=public; \ 259 | ); done; \ 260 | fi 261 | RELEASE_STEPS += npm.publish 262 | endif 263 | 264 | ## 265 | ## Docker 266 | ## 267 | 268 | docker_build = docker build \ 269 | --build-arg VCS_REF=`git rev-parse --short HEAD` \ 270 | --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ 271 | --build-arg VERSION=`git describe --tags --always` \ 272 | -t "$2" -f "$1" "$(dir $1)" 273 | 274 | ifndef DOCKERFILE_PATH 275 | DOCKERFILE_PATH = ./Dockerfile 276 | endif 277 | ifndef DOCKER_IMAGE 278 | ifneq ($(wildcard Dockerfile),) 279 | DOCKER_IMAGE = $(notdir $(PWD)) 280 | endif 281 | endif 282 | ifdef DOCKER_IMAGE 283 | ifneq ($(DOCKER_IMAGE),none) 284 | .PHONY: docker.build 285 | docker.build: 286 | $(call check-program, docker) 287 | $(call docker_build,$(DOCKERFILE_PATH),$(DOCKER_IMAGE)) 288 | 289 | BUILD_STEPS += docker.build 290 | endif 291 | endif 292 | 293 | ## 294 | ## Common 295 | ## 296 | 297 | TEST_STEPS += $(UNITTEST_STEPS) 298 | TEST_STEPS += $(LINT_STEPS) 299 | TEST_STEPS += $(TIDY_STEPS) 300 | 301 | ifneq ($(strip $(TEST_STEPS)),) 302 | .PHONY: test 303 | test: $(PRE_TEST_STEPS) $(TEST_STEPS) 304 | endif 305 | 306 | ifdef INSTALL_STEPS 307 | .PHONY: install 308 | install: $(PRE_INSTALL_STEPS) $(INSTALL_STEPS) 309 | endif 310 | 311 | ifdef UNITTEST_STEPS 312 | .PHONY: unittest 313 | unittest: $(PRE_UNITTEST_STEPS) $(UNITTEST_STEPS) 314 | endif 315 | 316 | ifdef LINT_STEPS 317 | .PHONY: lint 318 | lint: $(PRE_LINT_STEPS) $(FMT_STEPS) $(LINT_STEPS) 319 | endif 320 | 321 | ifdef TIDY_STEPS 322 | .PHONY: tidy 323 | tidy: $(PRE_TIDY_STEPS) $(TIDY_STEPS) 324 | endif 325 | 326 | ifdef BUILD_STEPS 327 | .PHONY: build 328 | build: $(PRE_BUILD_STEPS) $(BUILD_STEPS) 329 | endif 330 | 331 | ifdef VERIFY_STEPS 332 | .PHONY: verify 333 | verify: $(PRE_VERIFY_STEPS) $(VERIFY_STEPS) 334 | endif 335 | 336 | ifdef RELEASE_STEPS 337 | .PHONY: release 338 | release: $(PRE_RELEASE_STEPS) $(RELEASE_STEPS) 339 | endif 340 | 341 | ifdef BUMPDEPS_STEPS 342 | .PHONY: bumpdeps 343 | bumpdeps: $(PRE_BUMDEPS_STEPS) $(BUMPDEPS_STEPS) 344 | endif 345 | 346 | ifdef FMT_STEPS 347 | .PHONY: fmt 348 | fmt: $(PRE_FMT_STEPS) $(FMT_STEPS) 349 | endif 350 | 351 | ifdef GENERATE_STEPS 352 | .PHONY: generate 353 | generate: $(PRE_GENERATE_STEPS) $(GENERATE_STEPS) 354 | endif 355 | 356 | .PHONY: help 357 | help:: 358 | @echo "General commands:" 359 | @[ "$(BUILD_STEPS)" != "" ] && echo " build" || true 360 | @[ "$(BUMPDEPS_STEPS)" != "" ] && echo " bumpdeps" || true 361 | @[ "$(FMT_STEPS)" != "" ] && echo " fmt" || true 362 | @[ "$(GENERATE_STEPS)" != "" ] && echo " generate" || true 363 | @[ "$(INSTALL_STEPS)" != "" ] && echo " install" || true 364 | @[ "$(LINT_STEPS)" != "" ] && echo " lint" || true 365 | @[ "$(RELEASE_STEPS)" != "" ] && echo " release" || true 366 | @[ "$(TEST_STEPS)" != "" ] && echo " test" || true 367 | @[ "$(TIDY_STEPS)" != "" ] && echo " tidy" || true 368 | @[ "$(UNITTEST_STEPS)" != "" ] && echo " unittest" || true 369 | @[ "$(VERIFY_STEPS)" != "" ] && echo " verify" || true 370 | @# FIXME: list other commands 371 | 372 | print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true 373 | --------------------------------------------------------------------------------