Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func main() {
| `flagrun.Version(version string)` | バージョン表示に使用する文字列を指定します。 |
| `flagrun.Commit(commit string)` | コミットハッシュなどを指定します(デフォルト: `dev`)。 |
| `flagrun.ArgsRequired()` | コマンドライン引数を必須にします。引数がない場合は UNKNOWN で終了します。 |
| `flagrun.AlwaysStdout()` | `Run` の戻り値を、終了コードに関係なく標準出力へ出力します。 |

## 終了コード

Expand Down
49 changes: 39 additions & 10 deletions flagrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"reflect"
"runtime"
"runtime/debug"
"strings"

"github.com/jessevdk/go-flags"
Expand All @@ -27,6 +28,7 @@ type Flagrun struct {
ArgsRequired bool
Version string
Commit string
AlwaysStdout bool
}

type FlagrunOptions func(*Flagrun)
Expand All @@ -53,6 +55,12 @@ func ArgsRequired() FlagrunOptions {
}
}

func AlwaysStdout() FlagrunOptions {
return func(f *Flagrun) {
f.AlwaysStdout = true
}
}

func printLine(w io.Writer, s string) error {
if w == nil {
return nil
Expand All @@ -65,9 +73,9 @@ func printLine(w io.Writer, s string) error {
}

func Go(opt Runner, options ...FlagrunOptions) int {
msg, code := internalGo(os.Args[1:], os.Stdout, os.Stderr, opt, options...)
f, msg, code := internalGo(os.Args[1:], os.Stdout, os.Stderr, opt, options...)
if msg != "" {
if code == OK {
if code == OK || f.AlwaysStdout {
_ = printLine(os.Stdout, msg)
} else {
_ = printLine(os.Stderr, msg)
Expand Down Expand Up @@ -105,15 +113,36 @@ func hasBooleanVersionField(opt Runner) bool {
return ok && field.Type.Kind() == reflect.Bool && v.FieldByName("Version").Bool()
}

func buildCommitHash() string {
commit := "0000000"
Comment thread
kazeburo marked this conversation as resolved.
Outdated
dirty := false
if info, ok := debug.ReadBuildInfo(); ok {
for _, setting := range info.Settings {
if setting.Key == "vcs.revision" && setting.Value != "" {
commit = setting.Value
} else if setting.Key == "vcs.modified" && setting.Value == "true" {
dirty = true
}
}
Comment thread
kazeburo marked this conversation as resolved.
}
if len(commit) > 7 {
commit = commit[:7]
}
if dirty {
commit += "-dirty"
}
return commit
}

func internalGo(
argv []string,
stdout io.Writer,
stderr io.Writer,
opt Runner,
options ...FlagrunOptions,
) (string, int) {
) (*Flagrun, string, int) {
f := &Flagrun{
Commit: "dev",
Commit: buildCommitHash(),
Version: "unknown",
}
for _, option := range options {
Expand All @@ -136,18 +165,18 @@ func internalGo(
runtime.GOARCH,
runtime.Version(),
f.Commit)
return "", OK
return f, "", OK
} else if flags.WroteHelp(err) {
fmt.Fprintf(stdout, "%v\n", err)
return "", OK
return f, "", OK
} else if err != nil {
fmt.Fprintf(stderr, "%v\n", err)
return "", UNKNOWN
return f, "", UNKNOWN
} else if f.ArgsRequired && len(args) == 0 {
fmt.Fprintf(stderr, "command is required\n")
psr.WriteHelp(stderr)
return "", UNKNOWN
return f, "", UNKNOWN
}

return opt.Run(args)
msg, code := opt.Run(args)
return f, msg, code
}
8 changes: 5 additions & 3 deletions flagrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type testRunner struct {
Expand Down Expand Up @@ -84,10 +85,10 @@ func TestInternalGo(t *testing.T) {
}
var stdout bytes.Buffer
var stderr bytes.Buffer
msg, code := internalGo(tt.args, &stdout, &stderr, o, options...)
f, msg, code := internalGo(tt.args, &stdout, &stderr, o, options...)
stdoutStr := stdout.String()
stderrStr := stderr.String()

require.NotNil(t, f, "%s Flagrun instance should not be nil", tt.name)
assert.Equal(t, tt.wantMsg, msg, "%s msg", tt.name)
assert.Contains(t, stdoutStr, tt.wantStdout, "%s stdout", tt.name)
assert.Contains(t, stderrStr, tt.wantStderr, "%s stderr", tt.name)
Expand All @@ -112,10 +113,11 @@ func TestInternalGoWithRequiredParameters(t *testing.T) {
o := &requiredRunner{}
var stdout bytes.Buffer
var stderr bytes.Buffer
msg, code := internalGo([]string{}, &stdout, &stderr, o)
f, msg, code := internalGo([]string{}, &stdout, &stderr, o)
stdoutStr := stdout.String()
stderrStr := stderr.String()

assert.NotNil(t, f, "Flagrun instance should not be nil")
assert.Equal(t, "", msg)
assert.Contains(t, stdoutStr, "")
assert.Contains(t, stderrStr, "the required flag `-r, --required")
Expand Down