mirror of
https://github.com/thegeeklab/url-parser.git
synced 2024-11-16 02:00:45 +00:00
feat: add option for json output (#109)
This commit is contained in:
parent
6507c1dfa4
commit
d79274f428
@ -34,7 +34,7 @@ NAME:
|
|||||||
url-parser - Parse URL and shows the part of it.
|
url-parser - Parse URL and shows the part of it.
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
url-parser [global options] command [command options] [arguments...]
|
url-parser [global options] command [command options]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
devel
|
devel
|
||||||
@ -45,7 +45,7 @@ COMMANDS:
|
|||||||
user, u Get username from url
|
user, u Get username from url
|
||||||
password, pw Get password from url
|
password, pw Get password from url
|
||||||
path, pt Get path from url
|
path, pt Get path from url
|
||||||
host, h Get hostname from url
|
host, ht Get hostname from url
|
||||||
port, p Get port from url
|
port, p Get port from url
|
||||||
query, q Get query from url
|
query, q Get query from url
|
||||||
fragment, f Get fragment from url
|
fragment, f Get fragment from url
|
||||||
@ -81,6 +81,10 @@ somevalue
|
|||||||
# It is also possible to read the URL from stdin
|
# It is also possible to read the URL from stdin
|
||||||
$ echo "https://somedomain.com" | url-parser host
|
$ echo "https://somedomain.com" | url-parser host
|
||||||
somedomain.com
|
somedomain.com
|
||||||
|
|
||||||
|
# Get json output or all parsed parts
|
||||||
|
$ url-parser --url https://somedomain.com/?some-key=somevalue all --json
|
||||||
|
{"scheme":"https","hostname":"somedomain.com","port":"","path":"/","fragment":"","rawQuery":"some-key=somevalue","queryParams":[{"key":"some-key","value":"somevalue"}],"username":"","password":""}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
@ -47,6 +47,7 @@ func main() {
|
|||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
Usage: "Get all parts from url",
|
Usage: "Get all parts from url",
|
||||||
Action: command.Run(cfg),
|
Action: command.Run(cfg),
|
||||||
|
Flags: command.AllFlags(cfg),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "scheme",
|
Name: "scheme",
|
||||||
|
@ -8,13 +8,102 @@ import (
|
|||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseURL(raw string) *url.URL {
|
type QueryParam struct {
|
||||||
urlString := strings.TrimSpace(raw)
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
url, err := url.Parse(urlString)
|
type URL struct {
|
||||||
|
url *url.URL
|
||||||
|
|
||||||
|
Scheme string `json:"scheme"`
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Fragment string `json:"fragment"`
|
||||||
|
RawQuery string `json:"rawQuery"`
|
||||||
|
Query string `json:"-"`
|
||||||
|
QueryParams []QueryParam `json:"queryParams"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URL) String() string {
|
||||||
|
return u.url.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Parser struct {
|
||||||
|
URL string
|
||||||
|
QueryField string
|
||||||
|
QuerySplit bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewURLParser(url, queryField string, querySplit bool) *Parser {
|
||||||
|
return &Parser{
|
||||||
|
URL: url,
|
||||||
|
QueryField: queryField,
|
||||||
|
QuerySplit: querySplit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parse() *URL {
|
||||||
|
urlString := strings.TrimSpace(p.URL)
|
||||||
|
|
||||||
|
parts, err := url.Parse(urlString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg(config.ErrParseURL.Error())
|
log.Fatal().Err(err).Msg(config.ErrParseURL.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return url
|
extURL := &URL{
|
||||||
|
url: parts,
|
||||||
|
Scheme: parts.Scheme,
|
||||||
|
Hostname: parts.Hostname(),
|
||||||
|
Path: parts.Path,
|
||||||
|
Fragment: parts.Fragment,
|
||||||
|
QueryParams: []QueryParam{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(parts.Scheme) > 0 {
|
||||||
|
extURL.Hostname = parts.Hostname()
|
||||||
|
extURL.Port = parts.Port()
|
||||||
|
}
|
||||||
|
|
||||||
|
if parts.User != nil {
|
||||||
|
if len(parts.User.Username()) > 0 {
|
||||||
|
extURL.Username = parts.User.Username()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if parts.User != nil {
|
||||||
|
pw, _ := parts.User.Password()
|
||||||
|
if len(pw) > 0 {
|
||||||
|
extURL.Password = pw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle query field extraction
|
||||||
|
if parts.RawQuery != "" {
|
||||||
|
extURL.RawQuery = parts.RawQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.QueryField != "" {
|
||||||
|
if result := parts.Query().Get(p.QueryField); result != "" {
|
||||||
|
extURL.Query = result
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
extURL.Query = parts.RawQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle query parameter splitting
|
||||||
|
values := parts.Query()
|
||||||
|
for k, v := range values {
|
||||||
|
if len(v) > 0 {
|
||||||
|
extURL.QueryParams = append(extURL.QueryParams, QueryParam{
|
||||||
|
Key: k,
|
||||||
|
Value: v[0],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extURL
|
||||||
}
|
}
|
||||||
|
@ -3,30 +3,62 @@ package command
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestParseData struct {
|
func TestParse(t *testing.T) {
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseURL(t *testing.T) {
|
|
||||||
//nolint:goconst
|
//nolint:goconst
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestParseData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected *URL
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
name: "parse url",
|
||||||
expected: urlString,
|
config: &config.Config{
|
||||||
|
URL: urlString,
|
||||||
|
QuerySplit: true,
|
||||||
|
},
|
||||||
|
expected: &URL{
|
||||||
|
Scheme: "postgres",
|
||||||
|
Username: "user",
|
||||||
|
Password: "pass",
|
||||||
|
Hostname: "host.com",
|
||||||
|
Port: "5432",
|
||||||
|
Path: "/path/to",
|
||||||
|
Query: "key=value&other=other%20value",
|
||||||
|
RawQuery: "key=value&other=other%20value",
|
||||||
|
QueryParams: []QueryParam{
|
||||||
|
{
|
||||||
|
Key: "key",
|
||||||
|
Value: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: "other",
|
||||||
|
Value: "other value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Fragment: "some-fragment",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
result := parseURL(urlString)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := NewURLParser(urlString, "", false).parse()
|
||||||
if result.String() != table.expected {
|
assert.Equal(t, tt.expected.Scheme, result.Scheme)
|
||||||
t.Fatalf("URL `%v`, should be `%v`", result, table.expected)
|
assert.Equal(t, tt.expected.Username, result.Username)
|
||||||
}
|
assert.Equal(t, tt.expected.Password, result.Password)
|
||||||
|
assert.Equal(t, tt.expected.Hostname, result.Hostname)
|
||||||
|
assert.Equal(t, tt.expected.Port, result.Port)
|
||||||
|
assert.Equal(t, tt.expected.Path, result.Path)
|
||||||
|
assert.Equal(t, tt.expected.Fragment, result.Fragment)
|
||||||
|
assert.Equal(t, tt.expected.RawQuery, result.RawQuery)
|
||||||
|
assert.Equal(t, tt.expected.Query, result.Query)
|
||||||
|
assert.ElementsMatch(t, tt.expected.QueryParams, result.QueryParams)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
// Fragment prints out the fragment part from the url.
|
// Fragment prints out the fragment part from the url.
|
||||||
func Fragment(cfg *config.Config) cli.ActionFunc {
|
func Fragment(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
if len(parts.Scheme) > 0 {
|
||||||
fmt.Println(parts.Fragment)
|
fmt.Println(parts.Fragment)
|
||||||
|
@ -4,34 +4,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestFragmentData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFragment(t *testing.T) {
|
func TestFragment(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestFragmentData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get fragment",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "some-fragment",
|
expected: "some-fragment",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Fragment(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Fragment(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL fragment `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import (
|
|||||||
// Host prints out the host part from the url.
|
// Host prints out the host part from the url.
|
||||||
func Host(cfg *config.Config) cli.ActionFunc {
|
func Host(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
if len(parts.Scheme) > 0 {
|
||||||
fmt.Println(parts.Hostname())
|
fmt.Println(parts.Hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -4,34 +4,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestHostnameData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHost(t *testing.T) {
|
func TestHost(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestHostnameData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get host",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "host.com",
|
expected: "host.com",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Host(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Host(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL host `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,10 @@ import (
|
|||||||
// Password prints out the password part from url.
|
// Password prints out the password part from url.
|
||||||
func Password(cfg *config.Config) cli.ActionFunc {
|
func Password(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if parts.User != nil {
|
if parts.Password != "" {
|
||||||
pw, _ := parts.User.Password()
|
fmt.Println(parts.Password)
|
||||||
if len(pw) > 0 {
|
|
||||||
fmt.Println(pw)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -4,34 +4,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestPasswordData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPassword(t *testing.T) {
|
func TestPassword(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestPasswordData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get password",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "pass",
|
expected: "pass",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Password(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Password(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL password `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ func PathFlags(cfg *config.Config) []cli.Flag {
|
|||||||
// Path prints out the path part from url.
|
// Path prints out the path part from url.
|
||||||
func Path(cfg *config.Config) cli.ActionFunc {
|
func Path(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
i := cfg.PathIndex
|
i := cfg.PathIndex
|
||||||
|
|
||||||
if len(parts.Path) > 0 {
|
if len(parts.Path) > 0 {
|
||||||
|
@ -4,38 +4,39 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestPathData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPath(t *testing.T) {
|
func TestPath(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestPathData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get path",
|
||||||
config: &config.Config{URL: urlString, PathIndex: -1},
|
config: &config.Config{URL: urlString, PathIndex: -1},
|
||||||
expected: "/path/to",
|
expected: "/path/to",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: "get path at index",
|
||||||
config: &config.Config{URL: urlString, PathIndex: 0},
|
config: &config.Config{URL: urlString, PathIndex: 0},
|
||||||
expected: "path",
|
expected: "path",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Path(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Path(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL path `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import (
|
|||||||
// Port prints out the port from the url.
|
// Port prints out the port from the url.
|
||||||
func Port(cfg *config.Config) cli.ActionFunc {
|
func Port(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
if len(parts.Scheme) > 0 {
|
||||||
fmt.Println(parts.Port())
|
fmt.Println(parts.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -4,34 +4,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestPortData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPort(t *testing.T) {
|
func TestPort(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestPortData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get port",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "5432",
|
expected: "5432",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Port(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Port(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL port `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,17 +22,10 @@ func QueryFlags(cfg *config.Config) []cli.Flag {
|
|||||||
// Query prints out the query part from url.
|
// Query prints out the query part from url.
|
||||||
func Query(cfg *config.Config) cli.ActionFunc {
|
func Query(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
f := cfg.QueryField
|
|
||||||
|
|
||||||
if len(parts.RawQuery) > 0 {
|
if parts.Query != "" {
|
||||||
if f != "" {
|
fmt.Println(parts.Query)
|
||||||
if result := parts.Query().Get(f); result != "" {
|
|
||||||
fmt.Println(result)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println(parts.RawQuery)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -4,40 +4,40 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestQueryData struct {
|
|
||||||
config *config.Config
|
|
||||||
QueryField string
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestQuery(t *testing.T) {
|
func TestQuery(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestQueryData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
QueryField string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get query",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "key=value&other=other%20value",
|
expected: "key=value&other=other%20value",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString, QueryField: "other"},
|
name: "get query field",
|
||||||
|
config: &config.Config{URL: urlString, QueryField: "other"},
|
||||||
expected: "other value",
|
expected: "other value",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Query(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Query(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL query `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
@ -10,12 +11,29 @@ import (
|
|||||||
// Run default command and print out full url.
|
// Run default command and print out full url.
|
||||||
func Run(cfg *config.Config) cli.ActionFunc {
|
func Run(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if len(parts.String()) > 0 {
|
if len(parts.String()) > 0 {
|
||||||
fmt.Println(parts)
|
if cfg.JSONOutput {
|
||||||
|
json, _ := json.Marshal(parts)
|
||||||
|
fmt.Println(string(json))
|
||||||
|
} else {
|
||||||
|
fmt.Println(parts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllFlags defines flags for all subcommand.
|
||||||
|
func AllFlags(cfg *config.Config) []cli.Flag {
|
||||||
|
return []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "json",
|
||||||
|
Usage: "output json",
|
||||||
|
EnvVars: []string{"URL_PARSER_JSON"},
|
||||||
|
Destination: &cfg.JSONOutput,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,37 +1,88 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestRunData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestRunData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get url",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: urlString,
|
expected: urlString,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "get url with query split",
|
||||||
|
config: &config.Config{
|
||||||
|
URL: urlString,
|
||||||
|
QuerySplit: true,
|
||||||
|
JSONOutput: true,
|
||||||
|
},
|
||||||
|
expected: `{
|
||||||
|
"scheme": "postgres",
|
||||||
|
"hostname": "host.com",
|
||||||
|
"port": "5432",
|
||||||
|
"path": "/path/to",
|
||||||
|
"fragment": "some-fragment",
|
||||||
|
"rawQuery": "key=value&other=other%20value",
|
||||||
|
"queryParams": [
|
||||||
|
{
|
||||||
|
"key": "key",
|
||||||
|
"value": "value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "other",
|
||||||
|
"value": "other value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"username": "user",
|
||||||
|
"password": "pass"
|
||||||
|
}`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Run(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Run(tt.config)(ctx) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if tt.config.JSONOutput {
|
||||||
t.Fatalf("URL `%v`, should be `%v`", result, table.expected)
|
got := &URL{}
|
||||||
}
|
expected := &URL{}
|
||||||
|
|
||||||
|
_ = json.Unmarshal([]byte(result), &got)
|
||||||
|
_ = json.Unmarshal([]byte(tt.expected), &expected)
|
||||||
|
|
||||||
|
assert.Equal(t, expected.Scheme, got.Scheme)
|
||||||
|
assert.Equal(t, expected.Username, got.Username)
|
||||||
|
assert.Equal(t, expected.Password, got.Password)
|
||||||
|
assert.Equal(t, expected.Hostname, got.Hostname)
|
||||||
|
assert.Equal(t, expected.Port, got.Port)
|
||||||
|
assert.Equal(t, expected.Path, got.Path)
|
||||||
|
assert.Equal(t, expected.Fragment, got.Fragment)
|
||||||
|
assert.Equal(t, expected.RawQuery, got.RawQuery)
|
||||||
|
assert.Equal(t, expected.Query, got.Query)
|
||||||
|
assert.ElementsMatch(t, expected.QueryParams, got.QueryParams)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
// Scheme prints out the scheme part from the url.
|
// Scheme prints out the scheme part from the url.
|
||||||
func Scheme(cfg *config.Config) cli.ActionFunc {
|
func Scheme(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
if len(parts.Scheme) > 0 {
|
||||||
fmt.Println(parts.Scheme)
|
fmt.Println(parts.Scheme)
|
||||||
|
@ -4,34 +4,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestSchemeData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestScheme(t *testing.T) {
|
func TestScheme(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestSchemeData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get scheme",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "postgres",
|
expected: "postgres",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Scheme(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Scheme(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL scheme `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,10 @@ import (
|
|||||||
// User prints out the user part from url.
|
// User prints out the user part from url.
|
||||||
func User(cfg *config.Config) cli.ActionFunc {
|
func User(cfg *config.Config) cli.ActionFunc {
|
||||||
return func(_ *cli.Context) error {
|
return func(_ *cli.Context) error {
|
||||||
parts := parseURL(cfg.URL)
|
parts := NewURLParser(cfg.URL, cfg.QueryField, cfg.QuerySplit).parse()
|
||||||
|
|
||||||
if parts.User != nil {
|
if parts.Username != "" {
|
||||||
if len(parts.User.Username()) > 0 {
|
fmt.Println(parts.Username)
|
||||||
fmt.Println(parts.User.Username())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -4,34 +4,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
"github.com/thegeeklab/url-parser/config"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/zenizh/go-capturer"
|
"github.com/zenizh/go-capturer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestUserData struct {
|
|
||||||
config *config.Config
|
|
||||||
expected string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUser(t *testing.T) {
|
func TestUser(t *testing.T) {
|
||||||
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
urlString := "postgres://user:pass@host.com:5432/path/to?key=value&other=other%20value#some-fragment"
|
||||||
|
|
||||||
tables := []TestUserData{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *config.Config
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
{
|
{
|
||||||
|
name: "get user",
|
||||||
config: &config.Config{URL: urlString},
|
config: &config.Config{URL: urlString},
|
||||||
expected: "user",
|
expected: "user",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, tt := range tests {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
ctx := cli.NewContext(app, nil, nil)
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = User(table.config)(ctx) }))
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = User(tt.config)(ctx) }))
|
||||||
if result != table.expected {
|
assert.Equal(t, tt.expected, result)
|
||||||
t.Fatalf("URL user `%v`, should be `%v`", result, table.expected)
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,7 @@ var (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
URL string
|
URL string
|
||||||
QueryField string
|
QueryField string
|
||||||
|
QuerySplit bool
|
||||||
PathIndex int
|
PathIndex int
|
||||||
|
JSONOutput bool
|
||||||
}
|
}
|
||||||
|
4
go.mod
4
go.mod
@ -4,15 +4,19 @@ go 1.23.2
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/rs/zerolog v1.33.0
|
github.com/rs/zerolog v1.33.0
|
||||||
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/urfave/cli/v2 v2.27.5
|
github.com/urfave/cli/v2 v2.27.5
|
||||||
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04
|
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||||
golang.org/x/sys v0.12.0 // indirect
|
golang.org/x/sys v0.12.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
10
go.sum
10
go.sum
@ -1,6 +1,8 @@
|
|||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
@ -8,11 +10,15 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
|||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
|
||||||
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||||
@ -23,3 +29,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
Loading…
Reference in New Issue
Block a user