├── bin └── .gitignore ├── codecov.yml ├── .gitignore ├── cmd └── make2help │ └── main.go ├── go.mod ├── .github └── workflows │ ├── reviewdog.yml │ ├── release.yaml │ └── test.yaml ├── testdata └── Makefile ├── rules_test.go ├── LICENSE ├── go.sum ├── Makefile ├── make2help_test.go ├── rules.go ├── cli.go ├── CHANGELOG.md ├── README.md ├── make2help.go └── CREDITS /bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.gitignore 3 | !.github 4 | dist/ 5 | -------------------------------------------------------------------------------- /cmd/make2help/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/Songmu/make2help" 7 | ) 8 | 9 | func main() { 10 | os.Exit((&make2help.CLI{ErrStream: os.Stderr, OutStream: os.Stdout}).Run(os.Args[1:])) 11 | } 12 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Songmu/make2help 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/mattn/go-colorable v0.1.12 7 | github.com/mattn/go-isatty v0.0.14 8 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d 9 | golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f 10 | ) 11 | 12 | require golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect 13 | -------------------------------------------------------------------------------- /.github/workflows/reviewdog.yml: -------------------------------------------------------------------------------- 1 | name: reviewdog 2 | on: [pull_request] 3 | jobs: 4 | staticcheck: 5 | name: staticcheck 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: reviewdog/action-staticcheck@v1 10 | with: 11 | github_token: ${{ secrets.github_token }} 12 | reporter: github-pr-review 13 | fail_on_error: true 14 | -------------------------------------------------------------------------------- /testdata/Makefile: -------------------------------------------------------------------------------- 1 | task2: 2 | @echo task2 3 | 4 | ## task3 desu 5 | ## multi line 6 | task3: 7 | @echo task3 8 | 9 | ## task1 desu 10 | task1: 11 | @echo task1 12 | 13 | ## task4 desuyo 14 | .PHONY: task4 15 | task4: 16 | @echo task4 17 | 18 | ## task5 no phony 19 | .DEFAULT: task5 20 | task5: 21 | @echo task5 22 | 23 | ## task6 suffix whitespace 24 | task6 : 25 | @echo task6 26 | 27 | ## task7 pattern rule 28 | task7%: 29 | @echo task7 30 | -------------------------------------------------------------------------------- /rules_test.go: -------------------------------------------------------------------------------- 1 | package make2help 2 | 3 | import "testing" 4 | 5 | func TestString(t *testing.T) { 6 | 7 | r := rules{ 8 | "task1": []string{"task1 desu"}, 9 | "task2": []string{}, 10 | "task3": []string{"task3 desu", "multi line"}, 11 | } 12 | 13 | result := r.string(false, false) 14 | expect := `task1: task1 desu 15 | task3: task3 desu 16 | multi line 17 | ` 18 | 19 | if result != expect { 20 | t.Errorf("result is not expected one: %s", result) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: release 2 | on: 3 | push: 4 | tags: 5 | - "v[0-9]+.[0-9]+.[0-9]+" 6 | jobs: 7 | release: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: setup go 11 | uses: actions/setup-go@v3 12 | with: 13 | go-version: 1.x 14 | - name: checkout 15 | uses: actions/checkout@v3 16 | with: 17 | fetch-depth: 0 18 | - name: release 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | run: | 22 | make crossbuild upload 23 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: [push] 3 | jobs: 4 | test: 5 | runs-on: ${{ matrix.os }} 6 | strategy: 7 | fail-fast: false 8 | matrix: 9 | os: 10 | - ubuntu-latest 11 | - macOS-latest 12 | - windows-latest 13 | steps: 14 | - name: setup go 15 | uses: actions/setup-go@v3 16 | with: 17 | go-version: 1.x 18 | - name: checkout 19 | uses: actions/checkout@v3 20 | - name: Set git to use LF 21 | run: | 22 | git config --global core.autocrlf false 23 | git config --global core.eol lf 24 | if: "matrix.os == 'windows-latest'" 25 | - name: test 26 | run: go test -coverprofile coverage.out -covermode atomic ./... 27 | - name: Upload coverage to Codecov 28 | uses: codecov/codecov-action@v3 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Songmu 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 2 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 3 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 4 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 5 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= 6 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 7 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 8 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 9 | golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew= 10 | golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 11 | golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= 12 | golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION = $(shell godzil show-version) 2 | CURRENT_VERSION = $(shell git rev-parse --short HEAD) 3 | BUILD_LDFLAGS = "-s -w -X github.com/Songmu/make2help.revision=$(CURRENT_REVISION)" 4 | u := $(if $(update),-u) 5 | 6 | .DEFAULT_GOAL := help 7 | export GO111MODULE=on 8 | 9 | ## Install dependencies 10 | .PHONY: deps 11 | deps: 12 | go get ${u} -d -v 13 | go mod tidy 14 | 15 | ## Run tests 16 | .PHONY: test 17 | test: 18 | go test 19 | 20 | ## Install dependencies 21 | .PHONY: devel-deps 22 | devel-deps: 23 | go install github.com/Songmu/godzil/cmd/godzil@latest 24 | go install github.com/tcnksm/ghr@latest 25 | 26 | bin/%: cmd/%/main.go 27 | go build -ldflags "$(LDFLAGS)" -o $@ $< 28 | 29 | ## Bump version 30 | .PHONY: release 31 | release: devel-deps 32 | godzil release 33 | 34 | CREDITS: deps devel-deps go.sum 35 | godzil credits -w 36 | 37 | ## Cross build 38 | .PHONY: crossbuild 39 | crossbuild: CREDITS 40 | godzil crossbuild -pv=v$(VERSION) -build-ldflags=$(BUILD_LDFLAGS) \ 41 | -os=linux,darwin,freebsd,windows -d=./dist/v$(VERSION) ./cmd/* 42 | 43 | ## Upload 44 | .PHONY: upload 45 | upload: 46 | ghr -body="$$(godzil changelog --latest -F markdown)" v$(VERSION) dist/v$(VERSION) 47 | 48 | ## Show help 49 | .PHONY: help 50 | help: 51 | @make2help $(MAKEFILE_LIST) 52 | -------------------------------------------------------------------------------- /make2help_test.go: -------------------------------------------------------------------------------- 1 | package make2help 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestScan(t *testing.T) { 9 | r, err := scan("testdata/Makefile") 10 | 11 | if err != nil { 12 | t.Errorf("err should nil but: %s", err) 13 | } 14 | 15 | expect := rules{ 16 | "task1": []string{"task1 desu"}, 17 | "task2": []string{}, 18 | "task3": []string{"task3 desu", "multi line"}, 19 | "task4": []string{"task4 desuyo"}, 20 | "task5": []string{"task5 no phony"}, 21 | "task6": []string{"task6 suffix whitespace"}, 22 | "task7%": []string{"task7 pattern rule"}, 23 | } 24 | 25 | if !reflect.DeepEqual(r, expect) { 26 | t.Errorf("somthing went wrong\n got: %#v\nexpect: %#v", r, expect) 27 | } 28 | } 29 | 30 | func TestMerge(t *testing.T) { 31 | r1 := rules{ 32 | "task1": []string{"task1 desu"}, 33 | "task2": []string{}, 34 | "task3": []string{"task3 desu", "multi line"}, 35 | } 36 | 37 | r2 := rules{ 38 | "task2": []string{"task2 desu"}, 39 | "task4": []string{}, 40 | } 41 | 42 | r3 := r1.merge(r2) 43 | 44 | expect := rules{ 45 | "task1": []string{"task1 desu"}, 46 | "task2": []string{"task2 desu"}, 47 | "task3": []string{"task3 desu", "multi line"}, 48 | "task4": []string{}, 49 | } 50 | 51 | if !reflect.DeepEqual(r3, expect) { 52 | t.Errorf("somthing went wrong: %#v", r3) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rules.go: -------------------------------------------------------------------------------- 1 | package make2help 2 | 3 | import ( 4 | "bytes" 5 | "sort" 6 | "strings" 7 | 8 | "github.com/mgutz/ansi" 9 | ) 10 | 11 | type rules map[string][]string 12 | 13 | func (r rules) merge(r2 rules) rules { 14 | for k, v := range r2 { 15 | r[k] = v 16 | } 17 | return r 18 | } 19 | 20 | func (r rules) string(all, colorful bool) string { 21 | var buf bytes.Buffer 22 | indent, tasks := r.indentAndRules(all) 23 | colorfunc := ansi.ColorFunc("cyan") 24 | for _, task := range tasks { 25 | helplines := r[task] 26 | msg := task 27 | if colorful { 28 | msg = colorfunc(msg) 29 | } 30 | buf.WriteString(msg) 31 | buf.WriteString(":") 32 | restIndent := indent - len(task) - 1 33 | if len(helplines) < 1 { 34 | buf.WriteString("\n") 35 | } 36 | for _, helpline := range helplines { 37 | buf.WriteString(strings.Repeat(" ", restIndent)) 38 | buf.WriteString(helpline) 39 | buf.WriteString("\n") 40 | restIndent = indent 41 | } 42 | } 43 | return buf.String() 44 | } 45 | 46 | func (r rules) indentAndRules(all bool) (int, []string) { 47 | indent := 19 48 | var tasks []string 49 | for k, v := range r { 50 | if all || len(v) > 0 { 51 | // delimiter(Kolon) and space = 2 width 52 | if len(k)+2 > indent { 53 | indent = len(k) + 2 54 | } 55 | tasks = append(tasks, k) 56 | } 57 | } 58 | sort.Slice(tasks, func(i, j int) bool { 59 | return strings.ToLower(tasks[i]) < strings.ToLower(tasks[j]) 60 | }) 61 | return indent, tasks 62 | } 63 | -------------------------------------------------------------------------------- /cli.go: -------------------------------------------------------------------------------- 1 | package make2help 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "regexp" 8 | 9 | "github.com/mattn/go-colorable" 10 | "github.com/mattn/go-isatty" 11 | ) 12 | 13 | const version = "0.2.1" 14 | 15 | var revision = "HEAD" 16 | 17 | const ( 18 | exitCodeOK = iota 19 | exitCodeParseFlagError 20 | exitCodeErr 21 | ) 22 | 23 | // CLI is struct for command line tool 24 | type CLI struct { 25 | OutStream, ErrStream io.Writer 26 | } 27 | 28 | // Run the make2help 29 | func (cli *CLI) Run(argv []string) int { 30 | argv, isHelp, all := parseFlags(argv) 31 | if isHelp { 32 | fmt.Fprintln(cli.ErrStream, help()) 33 | return exitCodeOK 34 | } 35 | if len(argv) < 1 { 36 | argv = []string{"Makefile"} 37 | } 38 | colorful := false 39 | if w, ok := cli.OutStream.(*os.File); ok { 40 | colorful = isatty.IsTerminal(w.Fd()) 41 | cli.OutStream = colorable.NewColorable(w) 42 | } 43 | r := rules{} 44 | for _, f := range argv { 45 | tmpRule, err := scan(f) 46 | if err != nil { 47 | fmt.Fprintln(cli.ErrStream, err) 48 | return exitCodeErr 49 | } 50 | r = r.merge(tmpRule) 51 | } 52 | fmt.Fprint(cli.OutStream, r.string(all, colorful)) 53 | return exitCodeOK 54 | } 55 | 56 | var ( 57 | helpReg = regexp.MustCompile(`^--?h(?:elp)?$`) 58 | allReg = regexp.MustCompile(`^--?all$`) 59 | ) 60 | 61 | func parseFlags(argv []string) (restArgv []string, isHelp, isAll bool) { 62 | for _, v := range argv { 63 | if helpReg.MatchString(v) { 64 | isHelp = true 65 | return 66 | } 67 | if allReg.MatchString(v) { 68 | isAll = true 69 | continue 70 | } 71 | restArgv = append(restArgv, v) 72 | } 73 | return 74 | } 75 | 76 | func help() string { 77 | return fmt.Sprintf(`Usage: 78 | $ make2help [Makefiles] 79 | 80 | Utility for self-documented Makefile 81 | 82 | It shows rules in Makefiles with documents. 83 | 84 | Options: 85 | -all display all rules in the Makefiles 86 | 87 | Version: %s`, version) 88 | } 89 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v0.2.1](https://github.com/Songmu/make2help/compare/v0.2.0...v0.2.1) (2022-07-13) 4 | 5 | * maintenance [#15](https://github.com/Songmu/make2help/pull/15) ([Songmu](https://github.com/Songmu)) 6 | * Capture targets with % [#14](https://github.com/Songmu/make2help/pull/14) ([shackra](https://github.com/shackra)) 7 | 8 | ## [v0.2.0](https://github.com/Songmu/make2help/compare/v0.1.1...v0.2.0) (2019-10-27) 9 | 10 | * introduce GitHub Action and update deps [#10](https://github.com/Songmu/make2help/pull/10) ([Songmu](https://github.com/Songmu)) 11 | * Eliminate pattern rules [#9](https://github.com/Songmu/make2help/pull/9) ([shumon84](https://github.com/shumon84)) 12 | * Support targets have whitespace suffix [#8](https://github.com/Songmu/make2help/pull/8) ([shumon84](https://github.com/shumon84)) 13 | 14 | ## [v0.1.1](https://github.com/Songmu/make2help/compare/v0.1.0...v0.1.1) (2019-08-19) 15 | 16 | * update deps [#7](https://github.com/Songmu/make2help/pull/7) ([Songmu](https://github.com/Songmu)) 17 | * fix built in target validation logic [#6](https://github.com/Songmu/make2help/pull/6) ([shumon84](https://github.com/shumon84)) 18 | 19 | ## [v0.1.0](https://github.com/Songmu/make2help/compare/v0.0.2...v0.1.0) (2019-02-21) 20 | 21 | * Introduce go modules and update releng tools [#5](https://github.com/Songmu/make2help/pull/5) ([Songmu](https://github.com/Songmu)) 22 | * use standard sort package and drop patrickmn/sortutil [#4](https://github.com/Songmu/make2help/pull/4) ([Songmu](https://github.com/Songmu)) 23 | * introduce xerrors [#3](https://github.com/Songmu/make2help/pull/3) ([Songmu](https://github.com/Songmu)) 24 | * support each phony style [#2](https://github.com/Songmu/make2help/pull/2) ([Songmu](https://github.com/Songmu)) 25 | 26 | ## [v0.0.2](https://github.com/Songmu/make2help/compare/v0.0.1...v0.0.2) (2016-06-12) 27 | 28 | * adjust output [#1](https://github.com/Songmu/make2help/pull/1) ([Songmu](https://github.com/Songmu)) 29 | 30 | ## v0.0.1 (2016-06-12) 31 | 32 | * Initial release 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | make2help 2 | ======= 3 | 4 | [![Test Status](https://github.com/Songmu/make2help/workflows/test/badge.svg?branch=main)][actions] 5 | [![MIT License](https://img.shields.io/github/license/Songmu/make2help)][license] 6 | [![PkgGoDev](https://pkg.go.dev/badge/github.com/Songmu/make2help)][PkgGoDev] 7 | 8 | [actions]: https://github.com/Songmu/make2help/actions?workflow=test 9 | [license]: https://github.com/Songmu/make2help/blob/master/LICENSE 10 | [PkgGoDev]: https://pkg.go.dev/github.com/Songmu/make2help 11 | 12 | ## Description 13 | 14 | Utility for self-documented Makefile 15 | 16 | It scans Makefiles and shows rules with documents. It considers the comment line started with 17 | double hash (`## `) just before a rule is written as document of the rule. 18 | 19 | ## Installation 20 | 21 | Binaries are available. 22 | 23 | https://github.com/Songmu/make2help/releases 24 | 25 | You can also `go install`. 26 | 27 | % go install github.com/Songmu/make2help/cmd/make2help@latest 28 | 29 | ## Synopsis 30 | 31 | % make2help 32 | cover: Take coverage 33 | deps: Install dependencies 34 | dev-deps: Install dependencies 35 | help: Show help 36 | lint: Lint 37 | release: Release the binaries 38 | test: Run tests 39 | 40 | ## Options 41 | 42 | ``` 43 | -all display all rules in the Makefiles 44 | ``` 45 | 46 | ## Example 47 | 48 | With defining `help` target in Makefile and setting it to `.DEFAULT_GOAL`, you can see 49 | help messages just type `make`. 50 | 51 | ```Makefile 52 | .DEFAULT_GOAL := help 53 | 54 | ## Run tests 55 | test: deps 56 | go test ./... 57 | 58 | ## Install dependencies 59 | deps: 60 | go get -d -v ./... 61 | 62 | ## Show help 63 | help: 64 | @make2help $(MAKEFILE_LIST) 65 | 66 | .PHONY: test deps help 67 | ``` 68 | 69 | ```Shell 70 | % make 71 | deps: Install dependencies 72 | help: Show help 73 | test: Run tests 74 | ``` 75 | 76 | ## Author 77 | 78 | [Songmu](https://github.com/Songmu) 79 | -------------------------------------------------------------------------------- /make2help.go: -------------------------------------------------------------------------------- 1 | package make2help 2 | 3 | import ( 4 | "bufio" 5 | "os" 6 | "regexp" 7 | "strings" 8 | 9 | "golang.org/x/xerrors" 10 | ) 11 | 12 | const ( 13 | builtInTargetPhony = ".PHONY" 14 | builtInTargetSuffixes = ".SUFFIXES" 15 | builtInTargetDefault = ".DEFAULT" 16 | builtInTargetPrecious = ".PRECIOUS" 17 | builtInTargetIntermediate = ".INTERMEDIATE" 18 | builtInTargetSecondary = ".SECONDARY" 19 | builtInTargetSecondExpansion = ".SECONDEXPANSION" 20 | builtInTargetDeleteOnError = ".DELETE_ON_ERROR" 21 | builtInTargetIgnore = ".IGNORE" 22 | builtInTargetLowResolutionTime = ".LOW_RESOLUTION_TIME" 23 | builtInTargetSilent = ".SILENT" 24 | builtInTargetExportAllVariables = ".EXPORT_ALL_VARIABLES" 25 | builtInTargetNotParallel = ".NOTPARALLEL" 26 | builtInTargetOneShell = ".ONESHELL" 27 | builtInTargetPosix = ".POSIX" 28 | ) 29 | 30 | var ( 31 | ruleReg = regexp.MustCompile(`^([^\s]+)\s*:`) 32 | isBuiltInTargets = map[string]bool{ 33 | builtInTargetPhony: true, 34 | builtInTargetSuffixes: true, 35 | builtInTargetDefault: true, 36 | builtInTargetPrecious: true, 37 | builtInTargetIntermediate: true, 38 | builtInTargetSecondary: true, 39 | builtInTargetSecondExpansion: true, 40 | builtInTargetDeleteOnError: true, 41 | builtInTargetIgnore: true, 42 | builtInTargetLowResolutionTime: true, 43 | builtInTargetSilent: true, 44 | builtInTargetExportAllVariables: true, 45 | builtInTargetNotParallel: true, 46 | builtInTargetOneShell: true, 47 | builtInTargetPosix: true, 48 | } 49 | ) 50 | 51 | func scan(filepath string) (rules, error) { 52 | f, err := os.Open(filepath) 53 | if err != nil { 54 | return nil, xerrors.Errorf("failed to open file: %w", err) 55 | } 56 | r := rules{} 57 | buf := []string{} 58 | sc := bufio.NewScanner(f) 59 | for sc.Scan() { 60 | line := sc.Text() 61 | 62 | if strings.HasPrefix(line, "## ") { 63 | buf = append(buf, line[3:]) 64 | continue 65 | } 66 | 67 | if matches := ruleReg.FindStringSubmatch(line); len(matches) > 1 { 68 | target := matches[1] 69 | if isBuiltInTargets[target] { 70 | continue 71 | } 72 | r[target] = buf 73 | } 74 | if len(buf) > 0 { 75 | buf = []string{} 76 | } 77 | } 78 | if err = sc.Err(); err != nil { 79 | return nil, xerrors.Errorf("scan failed: %w", err) 80 | } 81 | return r, nil 82 | } 83 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Go (the standard library) 2 | https://golang.org/ 3 | ---------------------------------------------------------------- 4 | Copyright (c) 2009 The Go Authors. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following disclaimer 14 | in the documentation and/or other materials provided with the 15 | distribution. 16 | * Neither the name of Google Inc. nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | ================================================================ 33 | 34 | github.com/mattn/go-colorable 35 | https://github.com/mattn/go-colorable 36 | ---------------------------------------------------------------- 37 | The MIT License (MIT) 38 | 39 | Copyright (c) 2016 Yasuhiro Matsumoto 40 | 41 | Permission is hereby granted, free of charge, to any person obtaining a copy 42 | of this software and associated documentation files (the "Software"), to deal 43 | in the Software without restriction, including without limitation the rights 44 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 45 | copies of the Software, and to permit persons to whom the Software is 46 | furnished to do so, subject to the following conditions: 47 | 48 | The above copyright notice and this permission notice shall be included in all 49 | copies or substantial portions of the Software. 50 | 51 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 52 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 53 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 54 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 55 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 56 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 57 | SOFTWARE. 58 | 59 | ================================================================ 60 | 61 | github.com/mattn/go-isatty 62 | https://github.com/mattn/go-isatty 63 | ---------------------------------------------------------------- 64 | Copyright (c) Yasuhiro MATSUMOTO 65 | 66 | MIT License (Expat) 67 | 68 | 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: 69 | 70 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 71 | 72 | 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. 73 | 74 | ================================================================ 75 | 76 | github.com/mgutz/ansi 77 | https://github.com/mgutz/ansi 78 | ---------------------------------------------------------------- 79 | The MIT License (MIT) 80 | Copyright (c) 2013 Mario L. Gutierrez 81 | 82 | 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: 83 | 84 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 85 | 86 | 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. 87 | 88 | 89 | ================================================================ 90 | 91 | golang.org/x/sys 92 | https://golang.org/x/sys 93 | ---------------------------------------------------------------- 94 | Copyright (c) 2009 The Go Authors. All rights reserved. 95 | 96 | Redistribution and use in source and binary forms, with or without 97 | modification, are permitted provided that the following conditions are 98 | met: 99 | 100 | * Redistributions of source code must retain the above copyright 101 | notice, this list of conditions and the following disclaimer. 102 | * Redistributions in binary form must reproduce the above 103 | copyright notice, this list of conditions and the following disclaimer 104 | in the documentation and/or other materials provided with the 105 | distribution. 106 | * Neither the name of Google Inc. nor the names of its 107 | contributors may be used to endorse or promote products derived from 108 | this software without specific prior written permission. 109 | 110 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 111 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 112 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 113 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 114 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 115 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 116 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 117 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 118 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 119 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 120 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 121 | 122 | ================================================================ 123 | 124 | golang.org/x/xerrors 125 | https://golang.org/x/xerrors 126 | ---------------------------------------------------------------- 127 | Copyright (c) 2019 The Go Authors. All rights reserved. 128 | 129 | Redistribution and use in source and binary forms, with or without 130 | modification, are permitted provided that the following conditions are 131 | met: 132 | 133 | * Redistributions of source code must retain the above copyright 134 | notice, this list of conditions and the following disclaimer. 135 | * Redistributions in binary form must reproduce the above 136 | copyright notice, this list of conditions and the following disclaimer 137 | in the documentation and/or other materials provided with the 138 | distribution. 139 | * Neither the name of Google Inc. nor the names of its 140 | contributors may be used to endorse or promote products derived from 141 | this software without specific prior written permission. 142 | 143 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 144 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 145 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 146 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 147 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 148 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 149 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 150 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 151 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 152 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 153 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 154 | 155 | ================================================================ 156 | 157 | --------------------------------------------------------------------------------