diff --git a/Makefile b/Makefile index 63c19c4..3b31832 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,10 @@ VERSION := 0.1.16 NAME := urleap DIST := $(NAME)-$(VERSION) -urleap: coverage.out - go build -o urleap $(PACKAGE_LIST) +urleap: coverage.out cmd/urleap/main.go + go build -o urleap cmd/urleap/main.go -coverage.out: +coverage.out: cmd/urleap/main_test.go go test -covermode=count \ -coverprofile=coverage.out $(PACKAGE_LIST) diff --git a/cmd/urleap/main.go b/cmd/urleap/main.go index 5eea60b..f24b225 100644 --- a/cmd/urleap/main.go +++ b/cmd/urleap/main.go @@ -3,12 +3,102 @@ package main import ( "fmt" "os" + "path/filepath" + + flag "github.com/spf13/pflag" ) const VERSION = "0.1.16" -func goMain(args []string) int { +/* +helpMessage prints the help message. +This function is used in the small tests, so it may be called with a zero-length slice. +*/ +func helpMessage(args []string) string { + prog := "urleap" + if len(args) > 0 { + prog = filepath.Base(args[0]) + } + return fmt.Sprintf(`%s [OPTIONS] [URLs...] +OPTIONS + -t, --token specify the token for the service. This option is mandatory. + -q, --qrcode include QR-code of the URL in the output. + -c, --config specify the configuration file. + -h, --help print this mesasge and exit. + -v, --version print the version and exit. +ARGUMENT + URL specify the url for shortening. this arguments accept multiple values. + if no arguments were specified, urleap prints the list of available shorten urls.`, prog) +} + +type UrleapError struct { + statusCode int + message string +} + +func (e UrleapError) Error() string { + return e.message +} + +/* +This struct holds the values of the options. +*/ +type options struct { + token string + qrcode string + config string + help bool + version bool +} + +/* +Define the options and return the pointer to the options and the pointer to the flagset. +*/ +func buildOptions(args []string) (*options, *flag.FlagSet) { + opts := &options{} + flags := flag.NewFlagSet(args[0], flag.ContinueOnError) + flags.Usage = func() { fmt.Println(helpMessage(args)) } + flags.StringVarP(&opts.token, "token", "t", "", "specify the token for the service. This option is mandatory.") + flags.StringVarP(&opts.qrcode, "qrcode", "q", "", "include QR-code of the URL in the output.") + flags.StringVarP(&opts.config, "config", "c", "", "specify the configuration file.") + flags.BoolVarP(&opts.help, "help", "h", false, "print this mesasge and exit.") + flags.BoolVarP(&opts.version, "version", "v", false, "print the version and exit.") + return opts, flags +} + +/* +parseOptions parses options from the given command line arguments. +*/ +func parseOptions(args []string) (*options, []string, *UrleapError) { + opts, flags := buildOptions(args) + flags.Parse(args[1:]) + if opts.help { + fmt.Println(helpMessage(args)) + return nil, nil, &UrleapError{statusCode: 0, message: ""} + } + if opts.token == "" { + return nil, nil, &UrleapError{statusCode: 3, message: "no token was given"} + } + return opts, flags.Args(), nil +} + +func perform(opts *options, args []string) *UrleapError { fmt.Println("Hello World") + return nil +} + +func goMain(args []string) int { + opts, args, err := parseOptions(args) + if err != nil { + if err.statusCode != 0 { + fmt.Println(err.Error()) + } + return err.statusCode + } + if err := perform(opts, args); err != nil { + fmt.Println(err.Error()) + return err.statusCode + } return 0 } diff --git a/cmd/urleap/main_test.go b/cmd/urleap/main_test.go index 167256e..abaa517 100644 --- a/cmd/urleap/main_test.go +++ b/cmd/urleap/main_test.go @@ -3,13 +3,28 @@ package main import "testing" func Example_Main() { - goMain([]string{}) + goMain([]string{"./urleap", "-t", "token"}) // Output: // Hello World } +func Example_Help() { + goMain([]string{"./urleap", "--help"}) + // Output: + // urleap [OPTIONS] [URLs...] + // OPTIONS + // -t, --token specify the token for the service. This option is mandatory. + // -q, --qrcode include QR-code of the URL in the output. + // -c, --config specify the configuration file. + // -h, --help print this mesasge and exit. + // -v, --version print the version and exit. + // ARGUMENT + // URL specify the url for shortening. this arguments accept multiple values. + // if no arguments were specified, urleap prints the list of available shorten urls. +} + func Test_Main(t *testing.T) { - if status := goMain([]string{}); status != 0 { + if status := goMain([]string{"./urleap", "-t", "token"}); status != 0 { t.Error("Expected 0, got ", status) } } diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..a48cf0d --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +public diff --git a/go.mod b/go.mod index ae4ff28..12ed9a3 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/tamada/urleap go 1.20 + +require github.com/spf13/pflag v1.0.5 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..287f6fa --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=