make "garble command -h" give command-specific help

Before, "garble build -h" would print the same as "garble -h", which is
too much and confusing, as it doesn't tell us much about "build".

Now it's far better, and includes the output of "go build -h":

	$ garble build -h
	usage: garble [garble flags] build [arguments]

	This command wraps "go build". Below is its help:

	usage: go build [-o output] [build flags] [packages]
	Run 'go help build' for details.

We do the same for "garble reverse -h", since it doesn't wrap a Go tool
command.
pull/348/head
Daniel Martí 4 years ago
parent 750340db5b
commit 7fc424ca26

@ -8,7 +8,6 @@ import (
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"errors"
"flag" "flag"
"fmt" "fmt"
"go/ast" "go/ast"
@ -64,8 +63,6 @@ func usage() {
fmt.Fprintf(os.Stderr, ` fmt.Fprintf(os.Stderr, `
Garble obfuscates Go code by wrapping the Go toolchain. Garble obfuscates Go code by wrapping the Go toolchain.
Usage:
garble [garble flags] command [arguments] garble [garble flags] command [arguments]
For example, to build an obfuscated program: For example, to build an obfuscated program:
@ -78,7 +75,7 @@ The following commands are supported:
test [packages] wraps "go test" test [packages] wraps "go test"
reverse [files] de-obfuscates output such as stack traces reverse [files] de-obfuscates output such as stack traces
garble accepts the following flags: garble accepts the following flags before a command:
`[1:]) `[1:])
flagSet.PrintDefaults() flagSet.PrintDefaults()
@ -221,12 +218,9 @@ func main1() int {
return 2 return 2
} }
if err := mainErr(args); err != nil { if err := mainErr(args); err != nil {
switch err { if code, ok := err.(errJustExit); ok {
case flag.ErrHelp: os.Exit(int(code))
usage() }
return 2
case errJustExit:
default:
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
// If the build failed and a random seed was used, // If the build failed and a random seed was used,
@ -235,13 +229,14 @@ func main1() int {
if flagSeed == "random" { if flagSeed == "random" {
fmt.Fprintf(os.Stderr, "random seed: %s\n", base64.RawStdEncoding.EncodeToString(opts.Seed)) fmt.Fprintf(os.Stderr, "random seed: %s\n", base64.RawStdEncoding.EncodeToString(opts.Seed))
} }
}
return 1 return 1
} }
return 0 return 0
} }
var errJustExit = errors.New("") type errJustExit int
func (e errJustExit) Error() string { return fmt.Sprintf("exit: %d", e) }
func goVersionOK() bool { func goVersionOK() bool {
const ( const (
@ -309,7 +304,8 @@ func mainErr(args []string) error {
if len(args) > 0 { if len(args) > 0 {
return fmt.Errorf("the help command does not take arguments") return fmt.Errorf("the help command does not take arguments")
} }
return flag.ErrHelp usage()
return errJustExit(2)
case "version": case "version":
if len(args) > 0 { if len(args) > 0 {
return fmt.Errorf("the version command does not take arguments") return fmt.Errorf("the version command does not take arguments")
@ -400,6 +396,16 @@ func mainErr(args []string) error {
return nil return nil
} }
func hasHelpFlag(flags []string) bool {
for _, f := range flags {
switch f {
case "-h", "-help", "--help":
return true
}
}
return false
}
// toolexecCmd builds an *exec.Cmd which is set up for running "go <command>" // toolexecCmd builds an *exec.Cmd which is set up for running "go <command>"
// with -toolexec=garble and the supplied arguments. // with -toolexec=garble and the supplied arguments.
// //
@ -409,11 +415,15 @@ func toolexecCmd(command string, args []string) (*exec.Cmd, error) {
// Split the flags from the package arguments, since we'll need // Split the flags from the package arguments, since we'll need
// to run 'go list' on the same set of packages. // to run 'go list' on the same set of packages.
flags, args := splitFlagsFromArgs(args) flags, args := splitFlagsFromArgs(args)
for _, f := range flags { if hasHelpFlag(flags) {
switch f { out, _ := exec.Command("go", command, "-h").CombinedOutput()
case "-h", "-help", "--help": fmt.Fprintf(os.Stderr, `
return nil, flag.ErrHelp usage: garble [garble flags] %s [arguments]
}
This command wraps "go %s". Below is its help:
%s`[1:], command, command, out)
return nil, errJustExit(2)
} }
if err := setFlagOptions(); err != nil { if err := setFlagOptions(); err != nil {
@ -436,7 +446,7 @@ func toolexecCmd(command string, args []string) (*exec.Cmd, error) {
} }
if !goVersionOK() { if !goVersionOK() {
return nil, errJustExit return nil, errJustExit(1)
} }
var err error var err error
@ -1642,7 +1652,7 @@ This is likely due to go not being installed/setup correctly.
How to install Go: https://golang.org/doc/install How to install Go: https://golang.org/doc/install
`, err) `, err)
return errJustExit return errJustExit(1)
} }
if err := json.Unmarshal(out, &cache.GoEnv); err != nil { if err := json.Unmarshal(out, &cache.GoEnv); err != nil {
return err return err

@ -19,6 +19,11 @@ import (
// commandReverse implements "garble reverse". // commandReverse implements "garble reverse".
func commandReverse(args []string) error { func commandReverse(args []string) error {
flags, args := splitFlagsFromArgs(args) flags, args := splitFlagsFromArgs(args)
if hasHelpFlag(flags) {
fmt.Fprintf(os.Stderr, "usage: garble [garble flags] reverse [files]\n")
return errJustExit(2)
}
mainPkg := "." mainPkg := "."
if len(args) > 0 { if len(args) > 0 {
mainPkg = args[0] mainPkg = args[0]
@ -145,7 +150,7 @@ func commandReverse(args []string) error {
return err return err
} }
if !modified { if !modified {
return errJustExit return errJustExit(1)
} }
return nil return nil
} }
@ -165,7 +170,7 @@ func commandReverse(args []string) error {
f.Close() // since we're in a loop f.Close() // since we're in a loop
} }
if !anyModified { if !anyModified {
return errJustExit return errJustExit(1)
} }
return nil return nil
} }

@ -1,14 +1,16 @@
! garble ! garble
stderr -count=1 'Usage' stderr 'Garble obfuscates Go code'
stderr 'garble \[garble flags\] command' stderr 'garble \[garble flags\] command'
! stderr 'usage: go build' ! stderr 'usage: go build'
! stdout . ! stdout .
! garble -h ! garble -h
stderr 'Garble obfuscates Go code'
stderr 'garble \[garble flags\] command' stderr 'garble \[garble flags\] command'
! stdout . ! stdout .
! garble help ! garble help
stderr 'Garble obfuscates Go code'
stderr 'garble \[garble flags\] command' stderr 'garble \[garble flags\] command'
! stdout . ! stdout .
@ -17,8 +19,24 @@ stderr 'does not take arguments'
! stdout . ! stdout .
! garble build -h ! garble build -h
stderr 'garble \[garble flags\] command' stderr 'garble \[garble flags\] build'
! stderr 'usage: go build' stderr 'This command wraps "go build"'
stderr 'usage: go build'
stderr 'Run .go help build.'
! stderr 'Garble obfuscates Go code'
! stdout .
! garble test -h
stderr 'garble \[garble flags\] test'
stderr 'This command wraps "go test"'
stderr 'usage: go test'
stderr 'Run .go help test.'
! stderr 'Garble obfuscates Go code'
! stdout .
! garble reverse -h
stderr 'garble \[garble flags\] reverse \[files\]'
! stderr 'usage: go '
! stdout . ! stdout .
! garble -badflag ! garble -badflag

Loading…
Cancel
Save