diff --git a/README.md b/README.md index 109ee1a..f203258 100644 --- a/README.md +++ b/README.md @@ -28,15 +28,19 @@ USAGE: url-parser [global options] command [command options] [arguments...] VERSION: - 0.1.0 + devel COMMANDS: - all, a print out all parts from url - scheme, s print out scheme from url - user, u print out username from url - password, pw print out password from url - path, p print out the path from url - help, h Shows a list of commands or help for one command + all, a Get all parts from url + scheme, s Get scheme from url + user, u Get username from url + password, pw Get password from url + path, pt Get path from url + host, h Get hostname from url + port, p Get port from url + query, q Get query from url + fragment, f Get fragment from url + help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --url value source url to parse [$URL_PARSER_URL] diff --git a/cmd/url-parser/config.go b/cmd/url-parser/config.go index 66a543d..076aba1 100644 --- a/cmd/url-parser/config.go +++ b/cmd/url-parser/config.go @@ -20,37 +20,65 @@ func configCommands() []*cli.Command { { Name: "all", Aliases: []string{"a"}, - Usage: "print out all parts from url", + Usage: "Get all parts from url", Action: commands.Run, Flags: globalFlags(), }, { Name: "scheme", Aliases: []string{"s"}, - Usage: "print out scheme from url", + Usage: "Get scheme from url", Action: commands.Scheme, Flags: globalFlags(), }, { Name: "user", Aliases: []string{"u"}, - Usage: "print out username from url", + Usage: "Get username from url", Action: commands.User, Flags: globalFlags(), }, { Name: "password", - Aliases: []string{"p"}, - Usage: "print out password from url", + Aliases: []string{"pw"}, + Usage: "Get password from url", Action: commands.Password, Flags: globalFlags(), }, { Name: "path", Aliases: []string{"pt"}, - Usage: "print out the path from url", + Usage: "Get path from url", Action: commands.Path, Flags: append(globalFlags(), commands.PathFlags()...), }, + { + Name: "host", + Aliases: []string{"h"}, + Usage: "Get hostname from url", + Action: commands.Host, + Flags: globalFlags(), + }, + { + Name: "port", + Aliases: []string{"p"}, + Usage: "Get port from url", + Action: commands.Port, + Flags: globalFlags(), + }, + { + Name: "query", + Aliases: []string{"q"}, + Usage: "Get query from url", + Action: commands.Query, + Flags: append(globalFlags(), commands.QueryFlags()...), + }, + { + Name: "fragment", + Aliases: []string{"f"}, + Usage: "Get fragment from url", + Action: commands.Fragment, + Flags: globalFlags(), + }, } } diff --git a/commands/fragment.go b/commands/fragment.go new file mode 100644 index 0000000..6cb4954 --- /dev/null +++ b/commands/fragment.go @@ -0,0 +1,17 @@ +package commands + +import ( + "fmt" + + "github.com/urfave/cli/v2" +) + +// Fragment prints out the fragment part from the url +func Fragment(ctx *cli.Context) error { + parts := parseURL(ctx.String("url")) + + if len(parts.Scheme) > 0 { + fmt.Println(parts.Fragment) + } + return nil +} diff --git a/commands/fragment_test.go b/commands/fragment_test.go new file mode 100644 index 0000000..f376b30 --- /dev/null +++ b/commands/fragment_test.go @@ -0,0 +1,39 @@ +package commands + +import ( + "flag" + "strings" + "testing" + + "github.com/kami-zh/go-capturer" + "github.com/urfave/cli/v2" +) + +type TestFragmentData struct { + urlString string + expected string +} + +func TestFragment(t *testing.T) { + urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment" + + tables := []TestFragmentData{ + { + urlString: urlString, + expected: "some-fragment", + }, + } + + for _, table := range tables { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + set.String("url", table.urlString, "test url") + + c := cli.NewContext(app, set, nil) + result := strings.TrimSpace(capturer.CaptureStdout(func() { Fragment(c) })) + + if result != table.expected { + t.Fatalf("URL fragment `%v`, should be `%v`", result, table.expected) + } + } +} diff --git a/commands/host.go b/commands/host.go new file mode 100644 index 0000000..1373776 --- /dev/null +++ b/commands/host.go @@ -0,0 +1,17 @@ +package commands + +import ( + "fmt" + + "github.com/urfave/cli/v2" +) + +// Host prints out the host part from the url +func Host(ctx *cli.Context) error { + parts := parseURL(ctx.String("url")) + + if len(parts.Scheme) > 0 { + fmt.Println(parts.Hostname()) + } + return nil +} diff --git a/commands/host_test.go b/commands/host_test.go new file mode 100644 index 0000000..5e8bb83 --- /dev/null +++ b/commands/host_test.go @@ -0,0 +1,39 @@ +package commands + +import ( + "flag" + "strings" + "testing" + + "github.com/kami-zh/go-capturer" + "github.com/urfave/cli/v2" +) + +type TestHostnameData struct { + urlString string + expected string +} + +func TestHost(t *testing.T) { + urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment" + + tables := []TestHostnameData{ + { + urlString: urlString, + expected: "host.com", + }, + } + + for _, table := range tables { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + set.String("url", table.urlString, "test url") + + c := cli.NewContext(app, set, nil) + result := strings.TrimSpace(capturer.CaptureStdout(func() { Host(c) })) + + if result != table.expected { + t.Fatalf("URL host `%v`, should be `%v`", result, table.expected) + } + } +} diff --git a/commands/port.go b/commands/port.go new file mode 100644 index 0000000..83fda61 --- /dev/null +++ b/commands/port.go @@ -0,0 +1,17 @@ +package commands + +import ( + "fmt" + + "github.com/urfave/cli/v2" +) + +// Port prints out the port from the url +func Port(ctx *cli.Context) error { + parts := parseURL(ctx.String("url")) + + if len(parts.Scheme) > 0 { + fmt.Println(parts.Port()) + } + return nil +} diff --git a/commands/port_test.go b/commands/port_test.go new file mode 100644 index 0000000..efb1c5b --- /dev/null +++ b/commands/port_test.go @@ -0,0 +1,39 @@ +package commands + +import ( + "flag" + "strings" + "testing" + + "github.com/kami-zh/go-capturer" + "github.com/urfave/cli/v2" +) + +type TestPortData struct { + urlString string + expected string +} + +func TestPort(t *testing.T) { + urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment" + + tables := []TestPortData{ + { + urlString: urlString, + expected: "5432", + }, + } + + for _, table := range tables { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + set.String("url", table.urlString, "test url") + + c := cli.NewContext(app, set, nil) + result := strings.TrimSpace(capturer.CaptureStdout(func() { Port(c) })) + + if result != table.expected { + t.Fatalf("URL port `%v`, should be `%v`", result, table.expected) + } + } +} diff --git a/commands/query.go b/commands/query.go new file mode 100644 index 0000000..ae51e35 --- /dev/null +++ b/commands/query.go @@ -0,0 +1,36 @@ +package commands + +import ( + "fmt" + + "github.com/urfave/cli/v2" +) + +// QueryFlags defines flags for query subcommand +func QueryFlags() []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: "query-field", + Usage: "filter parsed query string by field name", + EnvVars: []string{"URL_PARSER_QUERY_FIELD"}, + }, + } +} + +// Query prints out the query part from url +func Query(ctx *cli.Context) error { + parts := parseURL(ctx.String("url")) + f := ctx.String("query-field") + + if len(parts.RawQuery) > 0 { + if f != "" { + if result := parts.Query().Get(f); result != "" { + fmt.Println(result) + } + } else { + fmt.Println(parts.RawQuery) + } + } + + return nil +}