mirror of
https://github.com/thegeeklab/url-parser.git
synced 2024-09-30 03:08:17 +00:00
Compare commits
No commits in common. "main" and "v0.2.10" have entirely different histories.
23
.chglog/CHANGELOG.tpl.md
Executable file
23
.chglog/CHANGELOG.tpl.md
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
{{ range .Versions -}}
|
||||||
|
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
|
||||||
|
|
||||||
|
{{ range .CommitGroups -}}
|
||||||
|
### {{ .Title }}
|
||||||
|
|
||||||
|
{{ range .Commits -}}
|
||||||
|
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ (regexReplaceAll "(.*)/issues/(.*)" (regexReplaceAll "(Co-\\w*-by.*)" .Subject "") "${1}/pull/${2}") | trim }}
|
||||||
|
{{ end }}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if .NoteGroups -}}
|
||||||
|
{{ range .NoteGroups -}}
|
||||||
|
### {{ .Title }}
|
||||||
|
|
||||||
|
{{ range .Notes }}
|
||||||
|
{{ .Body }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
25
.chglog/config.yml
Executable file
25
.chglog/config.yml
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
style: github
|
||||||
|
template: CHANGELOG.tpl.md
|
||||||
|
info:
|
||||||
|
title: CHANGELOG
|
||||||
|
repository_url: https://github.com/thegeeklab/url-parser
|
||||||
|
options:
|
||||||
|
commit_groups:
|
||||||
|
title_maps:
|
||||||
|
feat: Features
|
||||||
|
fix: Bug Fixes
|
||||||
|
perf: Performance Improvements
|
||||||
|
refactor: Code Refactoring
|
||||||
|
chore: Others
|
||||||
|
test: Testing
|
||||||
|
ci: CI Pipeline
|
||||||
|
docs: Documentation
|
||||||
|
header:
|
||||||
|
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
|
||||||
|
pattern_maps:
|
||||||
|
- Type
|
||||||
|
- Scope
|
||||||
|
- Subject
|
||||||
|
notes:
|
||||||
|
keywords:
|
||||||
|
- BREAKING CHANGE
|
@ -1,4 +0,0 @@
|
|||||||
url-parser
|
|
||||||
herloct
|
|
||||||
multiarch
|
|
||||||
(P|p)rebuilt
|
|
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!dist/
|
174
.drone.jsonnet
Normal file
174
.drone.jsonnet
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
local PipelineTest = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'test',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'deps',
|
||||||
|
image: 'golang:1.18',
|
||||||
|
commands: [
|
||||||
|
'make deps',
|
||||||
|
],
|
||||||
|
volumes: [
|
||||||
|
{
|
||||||
|
name: 'godeps',
|
||||||
|
path: '/go',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'lint',
|
||||||
|
image: 'golang:1.18',
|
||||||
|
commands: [
|
||||||
|
'make lint',
|
||||||
|
],
|
||||||
|
volumes: [
|
||||||
|
{
|
||||||
|
name: 'godeps',
|
||||||
|
path: '/go',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test',
|
||||||
|
image: 'golang:1.18',
|
||||||
|
commands: [
|
||||||
|
'make test',
|
||||||
|
],
|
||||||
|
volumes: [
|
||||||
|
{
|
||||||
|
name: 'godeps',
|
||||||
|
path: '/go',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'coverage',
|
||||||
|
image: 'plugins/codecov',
|
||||||
|
settings: {
|
||||||
|
token: {
|
||||||
|
from_secret: 'codecov_token',
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
'coverage.out',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
volumes: [
|
||||||
|
{
|
||||||
|
name: 'godeps',
|
||||||
|
temp: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
local PipelineBuildBinaries = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'build-binaries',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'build',
|
||||||
|
image: 'techknowlogick/xgo:go-1.18.x',
|
||||||
|
commands: [
|
||||||
|
'make release',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'executable',
|
||||||
|
image: 'alpine',
|
||||||
|
commands: [
|
||||||
|
'$(find dist/ -executable -type f -iname ${DRONE_REPO_NAME}-linux-amd64) --help',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'changelog-generate',
|
||||||
|
image: 'thegeeklab/git-chglog',
|
||||||
|
commands: [
|
||||||
|
'git fetch -tq',
|
||||||
|
'git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'changelog-format',
|
||||||
|
image: 'thegeeklab/alpine-tools',
|
||||||
|
commands: [
|
||||||
|
'prettier CHANGELOG.md',
|
||||||
|
'prettier -w CHANGELOG.md',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publish',
|
||||||
|
image: 'plugins/github-release',
|
||||||
|
settings: {
|
||||||
|
overwrite: true,
|
||||||
|
api_key: {
|
||||||
|
from_secret: 'github_token',
|
||||||
|
},
|
||||||
|
files: ['dist/*'],
|
||||||
|
title: '${DRONE_TAG}',
|
||||||
|
note: 'CHANGELOG.md',
|
||||||
|
},
|
||||||
|
when: {
|
||||||
|
ref: [
|
||||||
|
'refs/tags/**',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'test',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
local PipelineNotifications = {
|
||||||
|
kind: 'pipeline',
|
||||||
|
name: 'notifications',
|
||||||
|
platform: {
|
||||||
|
os: 'linux',
|
||||||
|
arch: 'amd64',
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
name: 'matrix',
|
||||||
|
image: 'thegeeklab/drone-matrix',
|
||||||
|
settings: {
|
||||||
|
homeserver: { from_secret: 'matrix_homeserver' },
|
||||||
|
roomid: { from_secret: 'matrix_roomid' },
|
||||||
|
template: 'Status: **{{ build.Status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.Link }}){{#if build.Branch}} ({{ build.Branch }}){{/if}} by {{ commit.Author }}<br/> Message: {{ commit.Message.Title }}',
|
||||||
|
username: { from_secret: 'matrix_username' },
|
||||||
|
password: { from_secret: 'matrix_password' },
|
||||||
|
},
|
||||||
|
when: {
|
||||||
|
status: ['success', 'failure'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depends_on: [
|
||||||
|
'build-binaries',
|
||||||
|
],
|
||||||
|
trigger: {
|
||||||
|
ref: ['refs/heads/main', 'refs/tags/**'],
|
||||||
|
status: ['success', 'failure'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
[
|
||||||
|
PipelineTest,
|
||||||
|
PipelineBuildBinaries,
|
||||||
|
PipelineNotifications,
|
||||||
|
]
|
147
.drone.yml
Normal file
147
.drone.yml
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: test
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: deps
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make deps
|
||||||
|
volumes:
|
||||||
|
- name: godeps
|
||||||
|
path: /go
|
||||||
|
|
||||||
|
- name: lint
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make lint
|
||||||
|
volumes:
|
||||||
|
- name: godeps
|
||||||
|
path: /go
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
image: golang:1.18
|
||||||
|
commands:
|
||||||
|
- make test
|
||||||
|
volumes:
|
||||||
|
- name: godeps
|
||||||
|
path: /go
|
||||||
|
|
||||||
|
- name: coverage
|
||||||
|
image: plugins/codecov
|
||||||
|
settings:
|
||||||
|
files:
|
||||||
|
- coverage.out
|
||||||
|
token:
|
||||||
|
from_secret: codecov_token
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: godeps
|
||||||
|
temp: {}
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/main
|
||||||
|
- refs/tags/**
|
||||||
|
- refs/pull/**
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: build-binaries
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: techknowlogick/xgo:go-1.18.x
|
||||||
|
commands:
|
||||||
|
- make release
|
||||||
|
|
||||||
|
- name: executable
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- $(find dist/ -executable -type f -iname ${DRONE_REPO_NAME}-linux-amd64) --help
|
||||||
|
|
||||||
|
- name: changelog-generate
|
||||||
|
image: thegeeklab/git-chglog
|
||||||
|
commands:
|
||||||
|
- git fetch -tq
|
||||||
|
- git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}
|
||||||
|
|
||||||
|
- name: changelog-format
|
||||||
|
image: thegeeklab/alpine-tools
|
||||||
|
commands:
|
||||||
|
- prettier CHANGELOG.md
|
||||||
|
- prettier -w CHANGELOG.md
|
||||||
|
|
||||||
|
- name: publish
|
||||||
|
image: plugins/github-release
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: github_token
|
||||||
|
files:
|
||||||
|
- dist/*
|
||||||
|
note: CHANGELOG.md
|
||||||
|
overwrite: true
|
||||||
|
title: ${DRONE_TAG}
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/**
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/main
|
||||||
|
- refs/tags/**
|
||||||
|
- refs/pull/**
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- test
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: notifications
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: matrix
|
||||||
|
image: thegeeklab/drone-matrix
|
||||||
|
settings:
|
||||||
|
homeserver:
|
||||||
|
from_secret: matrix_homeserver
|
||||||
|
password:
|
||||||
|
from_secret: matrix_password
|
||||||
|
roomid:
|
||||||
|
from_secret: matrix_roomid
|
||||||
|
template: "Status: **{{ build.Status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.Link }}){{#if build.Branch}} ({{ build.Branch }}){{/if}} by {{ commit.Author }}<br/> Message: {{ commit.Message.Title }}"
|
||||||
|
username:
|
||||||
|
from_secret: matrix_username
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
- failure
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/heads/main
|
||||||
|
- refs/tags/**
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
- failure
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- build-binaries
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: signature
|
||||||
|
hmac: abe0019dfa9264a9509adaaa988e75b60d344269a70b699568bf0615035ecd6a
|
||||||
|
|
||||||
|
...
|
7
.github/settings.yml
vendored
7
.github/settings.yml
vendored
@ -50,9 +50,6 @@ branches:
|
|||||||
required_status_checks:
|
required_status_checks:
|
||||||
strict: false
|
strict: false
|
||||||
contexts:
|
contexts:
|
||||||
- ci/woodpecker/pr/test
|
- continuous-integration/drone/pr
|
||||||
- ci/woodpecker/pr/build-package
|
enforce_admins: null
|
||||||
- ci/woodpecker/pr/docs
|
|
||||||
enforce_admins: false
|
|
||||||
required_linear_history: true
|
|
||||||
restrictions: null
|
restrictions: null
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
/dist
|
/dist/
|
||||||
/release
|
/release/
|
||||||
/url-parser*
|
/url-parser*
|
||||||
|
|
||||||
coverage.out
|
coverage.out
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
---
|
|
||||||
version: "1.1"
|
|
||||||
|
|
||||||
versioning:
|
|
||||||
update-major: []
|
|
||||||
update-minor: [feat]
|
|
||||||
update-patch: [fix, perf, refactor, chore, test, ci, docs]
|
|
||||||
|
|
||||||
tag:
|
|
||||||
pattern: "v%d.%d.%d"
|
|
||||||
|
|
||||||
release-notes:
|
|
||||||
sections:
|
|
||||||
- name: Features
|
|
||||||
commit-types: [feat]
|
|
||||||
section-type: commits
|
|
||||||
- name: Bug Fixes
|
|
||||||
commit-types: [fix]
|
|
||||||
section-type: commits
|
|
||||||
- name: Performance Improvements
|
|
||||||
commit-types: [perf]
|
|
||||||
section-type: commits
|
|
||||||
- name: Code Refactoring
|
|
||||||
commit-types: [refactor]
|
|
||||||
section-type: commits
|
|
||||||
- name: Others
|
|
||||||
commit-types: [chore]
|
|
||||||
section-type: commits
|
|
||||||
- name: Testing
|
|
||||||
commit-types: [test]
|
|
||||||
section-type: commits
|
|
||||||
- name: CI Pipeline
|
|
||||||
commit-types: [ci]
|
|
||||||
section-type: commits
|
|
||||||
- name: Documentation
|
|
||||||
commit-types: [docs]
|
|
||||||
section-type: commits
|
|
||||||
- name: BREAKING CHANGES
|
|
||||||
section-type: breaking-changes
|
|
||||||
|
|
||||||
commit-message:
|
|
||||||
footer:
|
|
||||||
issue:
|
|
||||||
key: issue
|
|
||||||
add-value-prefix: "#"
|
|
||||||
issue:
|
|
||||||
regex: "#?[0-9]+"
|
|
105
.golangci.yml
105
.golangci.yml
@ -1,91 +1,25 @@
|
|||||||
linters:
|
linters:
|
||||||
|
enable:
|
||||||
|
- gosimple
|
||||||
|
- deadcode
|
||||||
|
- typecheck
|
||||||
|
- govet
|
||||||
|
- errcheck
|
||||||
|
- staticcheck
|
||||||
|
- unused
|
||||||
|
- structcheck
|
||||||
|
- varcheck
|
||||||
|
- dupl
|
||||||
|
- gofmt
|
||||||
|
- misspell
|
||||||
|
- gocritic
|
||||||
|
- bidichk
|
||||||
|
- ineffassign
|
||||||
|
- revive
|
||||||
|
- gofumpt
|
||||||
|
- depguard
|
||||||
enable-all: false
|
enable-all: false
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
|
||||||
- errcheck
|
|
||||||
- gosimple
|
|
||||||
- govet
|
|
||||||
- ineffassign
|
|
||||||
- staticcheck
|
|
||||||
- typecheck
|
|
||||||
- unused
|
|
||||||
- asasalint
|
|
||||||
- asciicheck
|
|
||||||
- bidichk
|
|
||||||
- bodyclose
|
|
||||||
- containedctx
|
|
||||||
- contextcheck
|
|
||||||
- decorder
|
|
||||||
- dogsled
|
|
||||||
- dupl
|
|
||||||
- dupword
|
|
||||||
- durationcheck
|
|
||||||
- errchkjson
|
|
||||||
- errname
|
|
||||||
- errorlint
|
|
||||||
- exhaustive
|
|
||||||
- exportloopref
|
|
||||||
- forcetypeassert
|
|
||||||
- ginkgolinter
|
|
||||||
- gocheckcompilerdirectives
|
|
||||||
- gochecknoglobals
|
|
||||||
- gochecknoinits
|
|
||||||
- gocognit
|
|
||||||
- goconst
|
|
||||||
- gocritic
|
|
||||||
- gocyclo
|
|
||||||
- godot
|
|
||||||
- godox
|
|
||||||
- err113
|
|
||||||
- gofmt
|
|
||||||
- gofumpt
|
|
||||||
- goheader
|
|
||||||
- goimports
|
|
||||||
- mnd
|
|
||||||
- gomoddirectives
|
|
||||||
- gomodguard
|
|
||||||
- goprintffuncname
|
|
||||||
- gosec
|
|
||||||
- grouper
|
|
||||||
- importas
|
|
||||||
- interfacebloat
|
|
||||||
- ireturn
|
|
||||||
- lll
|
|
||||||
- loggercheck
|
|
||||||
- maintidx
|
|
||||||
- makezero
|
|
||||||
- misspell
|
|
||||||
- musttag
|
|
||||||
- nakedret
|
|
||||||
- nestif
|
|
||||||
- nilerr
|
|
||||||
- nilnil
|
|
||||||
- nlreturn
|
|
||||||
- noctx
|
|
||||||
- nolintlint
|
|
||||||
- nonamedreturns
|
|
||||||
- nosprintfhostport
|
|
||||||
- prealloc
|
|
||||||
- predeclared
|
|
||||||
- promlinter
|
|
||||||
- reassign
|
|
||||||
- revive
|
|
||||||
# - rowserrcheck
|
|
||||||
# - sqlclosecheck
|
|
||||||
# - structcheck
|
|
||||||
- stylecheck
|
|
||||||
- tagliatelle
|
|
||||||
- tenv
|
|
||||||
- testableexamples
|
|
||||||
- thelper
|
|
||||||
- tparallel
|
|
||||||
- unconvert
|
|
||||||
- unparam
|
|
||||||
- usestdlibvars
|
|
||||||
# - wastedassign
|
|
||||||
- whitespace
|
|
||||||
- wsl
|
|
||||||
- zerologlint
|
|
||||||
fast: false
|
fast: false
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@ -94,3 +28,4 @@ run:
|
|||||||
linters-settings:
|
linters-settings:
|
||||||
gofumpt:
|
gofumpt:
|
||||||
extra-rules: true
|
extra-rules: true
|
||||||
|
lang-version: "1.18"
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
default: True
|
|
||||||
MD013: False
|
|
||||||
MD041: False
|
|
||||||
MD004:
|
|
||||||
style: dash
|
|
@ -1,2 +1,3 @@
|
|||||||
|
.drone.yml
|
||||||
*.tpl.md
|
*.tpl.md
|
||||||
LICENSE
|
LICENSE
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
when:
|
|
||||||
- event: [pull_request, tag]
|
|
||||||
- event: [push, manual]
|
|
||||||
branch:
|
|
||||||
- ${CI_REPO_DEFAULT_BRANCH}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
image: docker.io/techknowlogick/xgo:go-1.22.x
|
|
||||||
commands:
|
|
||||||
- ln -s $(pwd) /source
|
|
||||||
- make release
|
|
||||||
|
|
||||||
- name: executable
|
|
||||||
image: quay.io/thegeeklab/alpine-tools
|
|
||||||
commands:
|
|
||||||
- $(find dist/ -executable -type f -iname ${CI_REPO_NAME}-linux-amd64) --help
|
|
||||||
|
|
||||||
- name: changelog
|
|
||||||
image: quay.io/thegeeklab/git-sv
|
|
||||||
commands:
|
|
||||||
- git sv current-version
|
|
||||||
- git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md
|
|
||||||
- cat CHANGELOG.md
|
|
||||||
|
|
||||||
- name: publish-github
|
|
||||||
image: docker.io/plugins/github-release
|
|
||||||
settings:
|
|
||||||
api_key:
|
|
||||||
from_secret: github_token
|
|
||||||
files:
|
|
||||||
- dist/*
|
|
||||||
note: CHANGELOG.md
|
|
||||||
overwrite: true
|
|
||||||
title: ${CI_COMMIT_TAG}
|
|
||||||
when:
|
|
||||||
- event: [tag]
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- test
|
|
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
when:
|
|
||||||
- event: [pull_request, tag]
|
|
||||||
- event: [push, manual]
|
|
||||||
branch:
|
|
||||||
- ${CI_REPO_DEFAULT_BRANCH}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: markdownlint
|
|
||||||
image: quay.io/thegeeklab/markdownlint-cli
|
|
||||||
commands:
|
|
||||||
- markdownlint 'README.md' 'CONTRIBUTING.md'
|
|
||||||
|
|
||||||
- name: spellcheck
|
|
||||||
image: quay.io/thegeeklab/alpine-tools
|
|
||||||
commands:
|
|
||||||
- spellchecker --files 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls
|
|
||||||
environment:
|
|
||||||
FORCE_COLOR: "true"
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- build-package
|
|
@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
when:
|
|
||||||
- event: [tag]
|
|
||||||
- event: [push, manual]
|
|
||||||
branch:
|
|
||||||
- ${CI_REPO_DEFAULT_BRANCH}
|
|
||||||
|
|
||||||
runs_on: [success, failure]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: matrix
|
|
||||||
image: quay.io/thegeeklab/wp-matrix
|
|
||||||
settings:
|
|
||||||
homeserver:
|
|
||||||
from_secret: matrix_homeserver
|
|
||||||
room_id:
|
|
||||||
from_secret: matrix_room_id
|
|
||||||
user_id:
|
|
||||||
from_secret: matrix_user_id
|
|
||||||
access_token:
|
|
||||||
from_secret: matrix_access_token
|
|
||||||
when:
|
|
||||||
- status: [success, failure]
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- docs
|
|
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
when:
|
|
||||||
- event: [pull_request, tag]
|
|
||||||
- event: [push, manual]
|
|
||||||
branch:
|
|
||||||
- ${CI_REPO_DEFAULT_BRANCH}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: lint
|
|
||||||
image: docker.io/library/golang:1.23
|
|
||||||
commands:
|
|
||||||
- make lint
|
|
||||||
|
|
||||||
- name: test
|
|
||||||
image: docker.io/library/golang:1.23
|
|
||||||
commands:
|
|
||||||
- make test
|
|
@ -3,7 +3,7 @@
|
|||||||
## Security
|
## Security
|
||||||
|
|
||||||
If you think you have found a **security issue**, please do not mention it in this repository.
|
If you think you have found a **security issue**, please do not mention it in this repository.
|
||||||
Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential.
|
Instead, send an email to security@thegeeklab.de with as many details as possible so it can be handled confidential.
|
||||||
|
|
||||||
## Bug Reports and Feature Requests
|
## Bug Reports and Feature Requests
|
||||||
|
|
||||||
|
21
Makefile
21
Makefile
@ -1,7 +1,7 @@
|
|||||||
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
||||||
GOFUMPT_PACKAGE_VERSION := v0.7.0
|
GOFUMPT_PACKAGE_VERSION := v0.3.1
|
||||||
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
||||||
GOLANGCI_LINT_PACKAGE_VERSION := v1.61.0
|
GOLANGCI_LINT_PACKAGE_VERSION := v1.45.2
|
||||||
|
|
||||||
EXECUTABLE := url-parser
|
EXECUTABLE := url-parser
|
||||||
|
|
||||||
@ -17,22 +17,16 @@ SOURCES ?= $(shell find . -name "*.go" -type f)
|
|||||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION)
|
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION)
|
||||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION)
|
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION)
|
||||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||||
GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest
|
|
||||||
|
|
||||||
GENERATE ?=
|
GENERATE ?=
|
||||||
XGO_VERSION := go-1.22.x
|
XGO_VERSION := go-1.18.x
|
||||||
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
|
XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64
|
||||||
|
|
||||||
TARGETOS ?= linux
|
|
||||||
TARGETARCH ?= amd64
|
|
||||||
ifneq ("$(TARGETVARIANT)","")
|
|
||||||
GOARM ?= $(subst v,,$(TARGETVARIANT))
|
|
||||||
endif
|
|
||||||
TAGS ?= netgo
|
TAGS ?= netgo
|
||||||
|
|
||||||
ifndef VERSION
|
ifndef VERSION
|
||||||
ifneq ($(CI_COMMIT_TAG),)
|
ifneq ($(DRONE_TAG),)
|
||||||
VERSION ?= $(subst v,,$(CI_COMMIT_TAG))
|
VERSION ?= $(subst v,,$(DRONE_TAG))
|
||||||
else
|
else
|
||||||
VERSION ?= $(shell git rev-parse --short HEAD)
|
VERSION ?= $(shell git rev-parse --short HEAD)
|
||||||
endif
|
endif
|
||||||
@ -69,13 +63,13 @@ generate:
|
|||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
$(GO) run $(GOTESTSUM_PACKAGE) --no-color=false -- -coverprofile=coverage.out $(PACKAGES)
|
$(GO) test -v -coverprofile coverage.out $(PACKAGES)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: $(DIST)/$(EXECUTABLE)
|
build: $(DIST)/$(EXECUTABLE)
|
||||||
|
|
||||||
$(DIST)/$(EXECUTABLE): $(SOURCES)
|
$(DIST)/$(EXECUTABLE): $(SOURCES)
|
||||||
GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) GOARM=$(GOARM) $(GO) build -v -tags '$(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -o $@ ./cmd/$(EXECUTABLE)
|
$(GO) build -v -tags '$(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -o $@ ./cmd/$(EXECUTABLE)
|
||||||
|
|
||||||
$(DIST_DIRS):
|
$(DIST_DIRS):
|
||||||
mkdir -p $(DIST_DIRS)
|
mkdir -p $(DIST_DIRS)
|
||||||
@ -100,4 +94,3 @@ deps:
|
|||||||
$(GO) install $(GOFUMPT_PACKAGE)
|
$(GO) install $(GOFUMPT_PACKAGE)
|
||||||
$(GO) install $(GOLANGCI_LINT_PACKAGE)
|
$(GO) install $(GOLANGCI_LINT_PACKAGE)
|
||||||
$(GO) install $(XGO_PACKAGE)
|
$(GO) install $(XGO_PACKAGE)
|
||||||
$(GO) install $(GOTESTSUM_PACKAGE)
|
|
||||||
|
38
README.md
38
README.md
@ -1,9 +1,8 @@
|
|||||||
# url-parser
|
# url-parser
|
||||||
|
|
||||||
Simple command-line URL parser
|
[![Build Status](https://img.shields.io/drone/build/thegeeklab/url-parser?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/url-parser)
|
||||||
|
|
||||||
[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/url-parser/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/url-parser)
|
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/url-parser)](https://goreportcard.com/report/github.com/thegeeklab/url-parser)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/url-parser)](https://goreportcard.com/report/github.com/thegeeklab/url-parser)
|
||||||
|
[![Codecov](https://img.shields.io/codecov/c/github/thegeeklab/url-parser)](https://codecov.io/gh/thegeeklab/url-parser)
|
||||||
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/url-parser)](https://github.com/thegeeklab/url-parser/graphs/contributors)
|
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/url-parser)](https://github.com/thegeeklab/url-parser/graphs/contributors)
|
||||||
[![License: MIT](https://img.shields.io/github/license/thegeeklab/url-parser)](https://github.com/thegeeklab/url-parser/blob/main/LICENSE)
|
[![License: MIT](https://img.shields.io/github/license/thegeeklab/url-parser)](https://github.com/thegeeklab/url-parser/blob/main/LICENSE)
|
||||||
|
|
||||||
@ -11,11 +10,12 @@ Inspired by [herloct/url-parser](https://github.com/herloct/url-parser), a simpl
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Prebuilt multiarch binaries are available for Linux only.
|
Prebuild multiarch binaries are availabe for Linux only:
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
curl -SsfL https://github.com/thegeeklab/url-parser/releases/latest/download/url-parser-linux-amd64 -o /usr/local/bin/url-parser
|
curl -L https://github.com/thegeeklab/url-parser/releases/download/v0.1.0/url-parser-0.1.0-linux-amd64 > /usr/local/bin/url-parser
|
||||||
chmod +x /usr/local/bin/url-parser
|
chmod +x /usr/local/bin/url-parser
|
||||||
|
url-parser --help
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
@ -23,6 +23,11 @@ chmod +x /usr/local/bin/url-parser
|
|||||||
Build the binary from source with the following command:
|
Build the binary from source with the following command:
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
|
export GOOS=linux
|
||||||
|
export GOARCH=amd64
|
||||||
|
export CGO_ENABLED=0
|
||||||
|
export GO111MODULE=on
|
||||||
|
|
||||||
make build
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -53,39 +58,36 @@ COMMANDS:
|
|||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:
|
||||||
--url value source url to parse [$URL_PARSER_URL]
|
--url value source url to parse [$URL_PARSER_URL]
|
||||||
--help, -h show help
|
--help, -h show help (default: false)
|
||||||
--version, -v print the version
|
--version, -v print the version (default: false)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
```Shell
|
```Shell
|
||||||
$ url-parser --url https://somedomain.com host
|
$ url-parser host --url https://somedomain.com
|
||||||
somedomain.com
|
somedomain.com
|
||||||
|
|
||||||
$ url-parser --url https://herloct@somedomain.com user
|
$ url-parser user --url https://herloct@somedomain.com
|
||||||
herloct
|
herloct
|
||||||
|
|
||||||
$ url-parser --url https://somedomain.com/path/to path
|
$ url-parser path --url https://somedomain.com/path/to
|
||||||
/path/to
|
/path/to
|
||||||
|
|
||||||
$ url-parser --url https://somedomain.com/path/to path --path-index=1
|
$ url-parser path --path-index=1 --url https://somedomain.com/path/to
|
||||||
to
|
to
|
||||||
|
|
||||||
$ url-parser --url https://somedomain.com/?some-key=somevalue query
|
$ url-parser query --url https://somedomain.com/?some-key=somevalue
|
||||||
some-key=somevalue
|
some-key=somevalue
|
||||||
|
|
||||||
$ url-parser --url https://somedomain.com/?some-key=somevalue query --query-field=some-key
|
$ url-parser query --query-field=some-key --url https://somedomain.com/?some-key=somevalue
|
||||||
somevalue
|
somevalue
|
||||||
|
|
||||||
# It is also possible to read the URL from stdin
|
|
||||||
$ echo "https://somedomain.com" | url-parser host
|
|
||||||
somedomain.com
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
Special thanks to all [contributors](https://github.com/thegeeklab/url-parser/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/url-parser/blob/main/CONTRIBUTING.md).
|
Special thanks goes to all [contributors](https://github.com/thegeeklab/url-parser/graphs/contributors). If you would like to contribute,
|
||||||
|
please see the [instructions](https://github.com/thegeeklab/url-parser/blob/main/CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
84
cmd/url-parser/config.go
Normal file
84
cmd/url-parser/config.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/thegeeklab/url-parser/internal/command"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func globalFlags() []cli.Flag {
|
||||||
|
return []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "url",
|
||||||
|
Usage: "source url to parse",
|
||||||
|
EnvVars: []string{"URL_PARSER_URL"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func configCommands() []*cli.Command {
|
||||||
|
return []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "all",
|
||||||
|
Aliases: []string{"a"},
|
||||||
|
Usage: "Get all parts from url",
|
||||||
|
Action: command.Run,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "scheme",
|
||||||
|
Aliases: []string{"s"},
|
||||||
|
Usage: "Get scheme from url",
|
||||||
|
Action: command.Scheme,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "user",
|
||||||
|
Aliases: []string{"u"},
|
||||||
|
Usage: "Get username from url",
|
||||||
|
Action: command.User,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "password",
|
||||||
|
Aliases: []string{"pw"},
|
||||||
|
Usage: "Get password from url",
|
||||||
|
Action: command.Password,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "path",
|
||||||
|
Aliases: []string{"pt"},
|
||||||
|
Usage: "Get path from url",
|
||||||
|
Action: command.Path,
|
||||||
|
Flags: append(globalFlags(), command.PathFlags()...),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "host",
|
||||||
|
Aliases: []string{"h"},
|
||||||
|
Usage: "Get hostname from url",
|
||||||
|
Action: command.Host,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "port",
|
||||||
|
Aliases: []string{"p"},
|
||||||
|
Usage: "Get port from url",
|
||||||
|
Action: command.Port,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "query",
|
||||||
|
Aliases: []string{"q"},
|
||||||
|
Usage: "Get query from url",
|
||||||
|
Action: command.Query,
|
||||||
|
Flags: append(globalFlags(), command.QueryFlags()...),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "fragment",
|
||||||
|
Aliases: []string{"f"},
|
||||||
|
Usage: "Get fragment from url",
|
||||||
|
Action: command.Fragment,
|
||||||
|
Flags: globalFlags(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -2,124 +2,32 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/thegeeklab/url-parser/internal/command"
|
||||||
"github.com/thegeeklab/url-parser/command"
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:gochecknoglobals
|
|
||||||
var (
|
var (
|
||||||
BuildVersion = "devel"
|
BuildVersion = "devel"
|
||||||
BuildDate = "00000000"
|
BuildDate = "00000000"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
||||||
|
|
||||||
cli.VersionPrinter = func(c *cli.Context) {
|
cli.VersionPrinter = func(c *cli.Context) {
|
||||||
fmt.Printf("%s version=%s date=%s\n", c.App.Name, c.App.Version, BuildDate)
|
fmt.Printf("%s version=%s date=%s\n", c.App.Name, c.App.Version, BuildDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &config.Config{}
|
app := cli.NewApp()
|
||||||
|
app.Name = "url-parser"
|
||||||
app := &cli.App{
|
app.Usage = "Parse URL and shows the part of it."
|
||||||
Name: "url-parser",
|
app.Version = BuildVersion
|
||||||
Usage: "Parse URL and shows the part of it.",
|
app.Action = command.Run
|
||||||
Version: BuildVersion,
|
app.Flags = globalFlags()
|
||||||
Action: command.Run(cfg),
|
app.Commands = configCommands()
|
||||||
Flags: []cli.Flag{
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "url",
|
|
||||||
Usage: "source url to parse",
|
|
||||||
EnvVars: []string{"URL_PARSER_URL"},
|
|
||||||
Destination: &cfg.URL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Commands: []*cli.Command{
|
|
||||||
{
|
|
||||||
Name: "all",
|
|
||||||
Aliases: []string{"a"},
|
|
||||||
Usage: "Get all parts from url",
|
|
||||||
Action: command.Run(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "scheme",
|
|
||||||
Aliases: []string{"s"},
|
|
||||||
Usage: "Get scheme from url",
|
|
||||||
Action: command.Scheme(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "user",
|
|
||||||
Aliases: []string{"u"},
|
|
||||||
Usage: "Get username from url",
|
|
||||||
Action: command.User(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "password",
|
|
||||||
Aliases: []string{"pw"},
|
|
||||||
Usage: "Get password from url",
|
|
||||||
Action: command.Password(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "path",
|
|
||||||
Aliases: []string{"pt"},
|
|
||||||
Usage: "Get path from url",
|
|
||||||
Action: command.Path(cfg),
|
|
||||||
Flags: command.PathFlags(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "host",
|
|
||||||
Aliases: []string{"ht"},
|
|
||||||
Usage: "Get hostname from url",
|
|
||||||
Action: command.Host(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "port",
|
|
||||||
Aliases: []string{"p"},
|
|
||||||
Usage: "Get port from url",
|
|
||||||
Action: command.Port(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "query",
|
|
||||||
Aliases: []string{"q"},
|
|
||||||
Usage: "Get query from url",
|
|
||||||
Action: command.Query(cfg),
|
|
||||||
Flags: command.QueryFlags(cfg),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "fragment",
|
|
||||||
Aliases: []string{"f"},
|
|
||||||
Usage: "Get fragment from url",
|
|
||||||
Action: command.Fragment(cfg),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Before: func(_ *cli.Context) error {
|
|
||||||
if cfg.URL == "" {
|
|
||||||
stat, _ := os.Stdin.Stat()
|
|
||||||
if (stat.Mode() & os.ModeCharDevice) == 0 {
|
|
||||||
stdin, err := io.ReadAll(os.Stdin)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error: %w: %w", config.ErrReadStdin, err)
|
|
||||||
}
|
|
||||||
cfg.URL = strings.TrimSuffix(string(stdin), "\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.URL == "" {
|
|
||||||
return fmt.Errorf("error: %w", config.ErrEmptyURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
log.Fatal().Err(err).Msg("Execution error")
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Fragment prints out the fragment part from the url.
|
|
||||||
func Fragment(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
|
||||||
fmt.Println(parts.Fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Host prints out the host part from the url.
|
|
||||||
func Host(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
|
||||||
fmt.Println(parts.Hostname())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Password prints out the password part from url.
|
|
||||||
func Password(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if parts.User != nil {
|
|
||||||
pw, _ := parts.User.Password()
|
|
||||||
if len(pw) > 0 {
|
|
||||||
fmt.Println(pw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PathFlags defines flags for path subcommand.
|
|
||||||
func PathFlags(cfg *config.Config) []cli.Flag {
|
|
||||||
return []cli.Flag{
|
|
||||||
&cli.IntFlag{
|
|
||||||
Name: "path-index",
|
|
||||||
Usage: "filter parsed path by index",
|
|
||||||
EnvVars: []string{"URL_PARSER_PATH_INDEX"},
|
|
||||||
Value: -1,
|
|
||||||
Destination: &cfg.PathIndex,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path prints out the path part from url.
|
|
||||||
func Path(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
i := cfg.PathIndex
|
|
||||||
|
|
||||||
if len(parts.Path) > 0 {
|
|
||||||
if i > -1 {
|
|
||||||
path := strings.Split(parts.Path, "/")
|
|
||||||
|
|
||||||
if i++; i < len(path) {
|
|
||||||
fmt.Println(path[i])
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println(parts.Path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Port prints out the port from the url.
|
|
||||||
func Port(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
|
||||||
fmt.Println(parts.Port())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// QueryFlags defines flags for query subcommand.
|
|
||||||
func QueryFlags(cfg *config.Config) []cli.Flag {
|
|
||||||
return []cli.Flag{
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "query-field",
|
|
||||||
Usage: "filter parsed query string by field name",
|
|
||||||
EnvVars: []string{"URL_PARSER_QUERY_FIELD"},
|
|
||||||
Destination: &cfg.QueryField,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query prints out the query part from url.
|
|
||||||
func Query(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
f := cfg.QueryField
|
|
||||||
|
|
||||||
if len(parts.RawQuery) > 0 {
|
|
||||||
if f != "" {
|
|
||||||
if result := parts.Query().Get(f); result != "" {
|
|
||||||
fmt.Println(result)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println(parts.RawQuery)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Run default command and print out full url.
|
|
||||||
func Run(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if len(parts.String()) > 0 {
|
|
||||||
fmt.Println(parts)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Scheme prints out the scheme part from the url.
|
|
||||||
func Scheme(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if len(parts.Scheme) > 0 {
|
|
||||||
fmt.Println(parts.Scheme)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// User prints out the user part from url.
|
|
||||||
func User(cfg *config.Config) cli.ActionFunc {
|
|
||||||
return func(_ *cli.Context) error {
|
|
||||||
parts := parseURL(cfg.URL)
|
|
||||||
|
|
||||||
if parts.User != nil {
|
|
||||||
if len(parts.User.Username()) > 0 {
|
|
||||||
fmt.Println(parts.User.Username())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrEmptyURL = errors.New("no url provided either by \"url\" or \"stdin\"")
|
|
||||||
ErrReadStdin = errors.New("failed to read \"stdin\"")
|
|
||||||
ErrParseURL = errors.New("failed to parse url")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
URL string
|
|
||||||
QueryField string
|
|
||||||
PathIndex int
|
|
||||||
}
|
|
13
go.mod
13
go.mod
@ -1,18 +1,15 @@
|
|||||||
module github.com/thegeeklab/url-parser
|
module github.com/thegeeklab/url-parser
|
||||||
|
|
||||||
go 1.22
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/rs/zerolog v1.33.0
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/urfave/cli/v2 v2.27.4
|
github.com/urfave/cli/v2 v2.4.8
|
||||||
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.4 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.19 // 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
|
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect
|
||||||
golang.org/x/sys v0.12.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
36
go.sum
36
go.sum
@ -1,25 +1,19 @@
|
|||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
|
||||||
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/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
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/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/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/urfave/cli/v2 v2.4.8 h1:9HuvvddU3oEJr1tJlwUVVsk3snVWMuKSpyAO+SzTNuI=
|
||||||
|
github.com/urfave/cli/v2 v2.4.8/go.mod h1:oDzoM7pVwz6wHn5ogWgFUU1s4VJayeQS+aEZDqXIEJs=
|
||||||
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w=
|
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w=
|
||||||
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4=
|
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY=
|
||||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
|
@ -4,8 +4,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseURL(raw string) *url.URL {
|
func parseURL(raw string) *url.URL {
|
||||||
@ -13,7 +12,7 @@ func parseURL(raw string) *url.URL {
|
|||||||
|
|
||||||
url, err := url.Parse(urlString)
|
url, err := url.Parse(urlString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg(config.ErrParseURL.Error())
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return url
|
return url
|
@ -1,24 +1,19 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import "testing"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/thegeeklab/url-parser/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestParseData struct {
|
type TestParseData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseURL(t *testing.T) {
|
func TestParseURL(t *testing.T) {
|
||||||
//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{
|
tables := []TestParseData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: urlString,
|
expected: urlString,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
17
internal/command/fragment.go
Normal file
17
internal/command/fragment.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestFragmentData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFragment(t *testing.T) {
|
func TestFragment(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestFragment(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestFragmentData{
|
tables := []TestFragmentData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "some-fragment",
|
expected: "some-fragment",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Fragment(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Fragment(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL fragment `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL fragment `%v`, should be `%v`", result, table.expected)
|
17
internal/command/host.go
Normal file
17
internal/command/host.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestHostnameData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHost(t *testing.T) {
|
func TestHost(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestHost(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestHostnameData{
|
tables := []TestHostnameData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "host.com",
|
expected: "host.com",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Host(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Host(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL host `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL host `%v`, should be `%v`", result, table.expected)
|
21
internal/command/password.go
Normal file
21
internal/command/password.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Password prints out the password part from url
|
||||||
|
func Password(ctx *cli.Context) error {
|
||||||
|
parts := parseURL(ctx.String("url"))
|
||||||
|
|
||||||
|
if parts.User != nil {
|
||||||
|
pw, _ := parts.User.Password()
|
||||||
|
if len(pw) > 0 {
|
||||||
|
fmt.Println(pw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestPasswordData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPassword(t *testing.T) {
|
func TestPassword(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestPassword(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestPasswordData{
|
tables := []TestPasswordData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "pass",
|
expected: "pass",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Password(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Password(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL password `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL password `%v`, should be `%v`", result, table.expected)
|
40
internal/command/path.go
Normal file
40
internal/command/path.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PathFlags defines flags for path subcommand
|
||||||
|
func PathFlags() []cli.Flag {
|
||||||
|
return []cli.Flag{
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "path-index",
|
||||||
|
Usage: "filter parsed path by index",
|
||||||
|
EnvVars: []string{"URL_PARSER_PATH_INDEX"},
|
||||||
|
Value: -1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path prints out the path part from url
|
||||||
|
func Path(ctx *cli.Context) error {
|
||||||
|
parts := parseURL(ctx.String("url"))
|
||||||
|
i := ctx.Int("path-index")
|
||||||
|
|
||||||
|
if len(parts.Path) > 0 {
|
||||||
|
if i > -1 {
|
||||||
|
path := strings.Split(parts.Path, "/")
|
||||||
|
|
||||||
|
if i++; i < len(path) {
|
||||||
|
fmt.Println(path[i])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println(parts.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,17 +1,18 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestPathData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
pathIndex int
|
||||||
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPath(t *testing.T) {
|
func TestPath(t *testing.T) {
|
||||||
@ -19,20 +20,25 @@ func TestPath(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestPathData{
|
tables := []TestPathData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString, PathIndex: -1},
|
urlString: urlString,
|
||||||
expected: "/path/to",
|
pathIndex: -1,
|
||||||
|
expected: "/path/to",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString, PathIndex: 0},
|
urlString: urlString,
|
||||||
expected: "path",
|
pathIndex: 0,
|
||||||
|
expected: "path",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
set.Int("path-index", table.pathIndex, "index")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Path(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Path(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL path `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL path `%v`, should be `%v`", result, table.expected)
|
17
internal/command/port.go
Normal file
17
internal/command/port.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestPortData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPort(t *testing.T) {
|
func TestPort(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestPort(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestPortData{
|
tables := []TestPortData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "5432",
|
expected: "5432",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Port(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Port(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL port `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL port `%v`, should be `%v`", result, table.expected)
|
36
internal/command/query.go
Normal file
36
internal/command/query.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -1,16 +1,16 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestQueryData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
QueryField string
|
QueryField string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
@ -20,21 +20,24 @@ func TestQuery(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestQueryData{
|
tables := []TestQueryData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "key=value&other=other%20value",
|
expected: "key=value&other=other%20value",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString, QueryField: "other"},
|
urlString: urlString,
|
||||||
|
QueryField: "other",
|
||||||
expected: "other value",
|
expected: "other value",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
set.String("query-field", table.QueryField, "index")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Query(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Query(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL query `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL query `%v`, should be `%v`", result, table.expected)
|
17
internal/command/run.go
Normal file
17
internal/command/run.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run default command and print out full url
|
||||||
|
func Run(ctx *cli.Context) error {
|
||||||
|
parts := parseURL(ctx.String("url"))
|
||||||
|
|
||||||
|
if len(parts.String()) > 0 {
|
||||||
|
fmt.Println(parts)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestRunData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestRun(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestRunData{
|
tables := []TestRunData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: urlString,
|
expected: urlString,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Run(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Run(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL `%v`, should be `%v`", result, table.expected)
|
17
internal/command/scheme.go
Normal file
17
internal/command/scheme.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scheme prints out the scheme part from the url
|
||||||
|
func Scheme(ctx *cli.Context) error {
|
||||||
|
parts := parseURL(ctx.String("url"))
|
||||||
|
|
||||||
|
if len(parts.Scheme) > 0 {
|
||||||
|
fmt.Println(parts.Scheme)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestSchemeData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScheme(t *testing.T) {
|
func TestScheme(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestScheme(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestSchemeData{
|
tables := []TestSchemeData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "postgres",
|
expected: "postgres",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Scheme(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = Scheme(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL scheme `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL scheme `%v`, should be `%v`", result, table.expected)
|
19
internal/command/user.go
Normal file
19
internal/command/user.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// User prints out the user part from url
|
||||||
|
func User(ctx *cli.Context) error {
|
||||||
|
parts := parseURL(ctx.String("url"))
|
||||||
|
|
||||||
|
if parts.User != nil {
|
||||||
|
if len(parts.User.Username()) > 0 {
|
||||||
|
fmt.Println(parts.User.Username())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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 {
|
type TestUserData struct {
|
||||||
config *config.Config
|
urlString string
|
||||||
expected string
|
expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUser(t *testing.T) {
|
func TestUser(t *testing.T) {
|
||||||
@ -19,16 +19,18 @@ func TestUser(t *testing.T) {
|
|||||||
|
|
||||||
tables := []TestUserData{
|
tables := []TestUserData{
|
||||||
{
|
{
|
||||||
config: &config.Config{URL: urlString},
|
urlString: urlString,
|
||||||
expected: "user",
|
expected: "user",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
ctx := cli.NewContext(app, nil, nil)
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.String("url", table.urlString, "test url")
|
||||||
|
|
||||||
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = User(table.config)(ctx) }))
|
c := cli.NewContext(app, set, nil)
|
||||||
|
result := strings.TrimSpace(capturer.CaptureStdout(func() { _ = User(c) }))
|
||||||
|
|
||||||
if result != table.expected {
|
if result != table.expected {
|
||||||
t.Fatalf("URL user `%v`, should be `%v`", result, table.expected)
|
t.Fatalf("URL user `%v`, should be `%v`", result, table.expected)
|
Loading…
Reference in New Issue
Block a user