KDOC 13: make2helpを読む
makefileはMakeの設定ファイルである。make2helpはそのMakefileのヘルプを表示するGoパッケージである。Makefileのコメントから自動生成してくれる。ミニマルな機能で読みやすい。
流れ
- コマンドライン処理
- ファイルをパース
- 固定のキーワードは無視
- タスクとコメントを抽出
- いい感じに表示
ファイル分け
rules
表示を扱うmap構造とメソッド集。
make2help
ファイルのスキャンしてrulesを生成する。
cli
コマンドライン引数を処理する。
cmd/main
cli構造体のメソッドを実行する。
一般的に使えそうなmemo
cliが呼び出す部分
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/cli.go#L43-L53
r := rules{}
for _, f := range argv {
tmpRule, err := scan(f)
if err != nil {
fmt.Fprintln(cli.ErrStream, err)
return exitCodeErr
}
r = r.merge(tmpRule)
}
fmt.Fprint(cli.OutStream, r.string(all, colorful))
return exitCodeOK
- CLIがiotaでOKや各種Errorを返す。すべて正常実行の扱いで、panicを使わない
- ruleを作成して、それぞれバッファに書き込む
引数をparseする
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/cli.go#L61-L74
func parseFlags(argv []string) (restArgv []string, isHelp, isAll bool) {
for _, v := range argv {
if helpReg.MatchString(v) {
isHelp = true
return
}
if allReg.MatchString(v) {
isAll = true
continue
}
restArgv = append(restArgv, v)
}
return
}
直に受け取ったargvをパースする。
正規表現 MustCompile を使う
動的ではなく、コンパイル前に実行する。
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/cli.go#L56-L59
var (
helpReg = regexp.MustCompile(`^--?h(?:elp)?$`)
allReg = regexp.MustCompile(`^--?all$`)
)
定数で扱う
文字列が、キーワードに含まれるどうかを判定する。
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/make2help.go#L12-L14
const (
builtInTargetPhony = ".PHONY"
builtInTargetSuffixes = ".SUFFIXES"
それをmapにする。
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/make2help.go#L29-L34
var (
ruleReg = regexp.MustCompile(`^([^\s]+)\s*:`)
isBuiltInTargets = map[string]bool{
builtInTargetPhony: true,
builtInTargetSuffixes: true,
使用例。targetにキーワードが含まれていれば、trueを返す。
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/make2help.go#L69
if isBuiltInTargets[target] {
cmd/main.goでは構造体の初期化と1メソッドを呼び出すだけ
1行だけでシンプル。
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/cmd/make2help/main.go#L10
os.Exit((&make2help.CLI{ErrStream: os.Stderr, OutStream: os.Stdout}).Run(os.Args[1:]))
同じことを検証する
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/make2help_test.go#L25-L27
if !reflect.DeepEqual(r, expect) {
t.Errorf("somthing went wrong\n got: %#v\nexpect: %#v", r, expect)
}
rulesのメソッド
https://github.com/Songmu/make2help/blob/7d76187a6c490467f3e0ca879ae6eb1c1ec0d30b/rules.go#L11
type rules map[string][]string
rulesに定義されているメソッドはmerge, string, indentAndRules。シンプルな定義と、一般的な操作として定義されている。