From ec2f321c22ec5372c83a9fd4e29596855a295da0 Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Tue, 14 Jan 2020 13:59:59 +0100 Subject: [PATCH] switch to gomod and add option to ignore pre-releases --- .drone.star | 223 + .drone.yml | 305 + .travis.yml | 14 - LICENSE | 2 +- README.md | 3 +- VERSION | 1 - Dockerfile => docker/Dockerfile | 0 go.mod | 14 + go.sum | 29 + main.go | 14 +- release.go | 11 +- releasechecker.go | 67 +- screenshot.png | Bin 34324 -> 0 bytes vendor/github.com/alexflint/go-arg/LICENSE | 24 - vendor/github.com/alexflint/go-arg/README.md | 321 - vendor/github.com/alexflint/go-arg/doc.go | 36 - vendor/github.com/alexflint/go-arg/parse.go | 482 - vendor/github.com/alexflint/go-arg/usage.go | 142 - vendor/github.com/alexflint/go-scalar/LICENSE | 24 - .../github.com/alexflint/go-scalar/README.md | 28 - .../github.com/alexflint/go-scalar/scalar.go | 154 - vendor/github.com/go-kit/kit/LICENSE | 22 - vendor/github.com/go-kit/kit/log/README.md | 147 - .../go-kit/kit/log/cover.coverprofile | 123 - vendor/github.com/go-kit/kit/log/doc.go | 116 - .../github.com/go-kit/kit/log/json_logger.go | 92 - .../go-kit/kit/log/level/cover.coverprofile | 43 - vendor/github.com/go-kit/kit/log/level/doc.go | 22 - .../github.com/go-kit/kit/log/level/level.go | 210 - vendor/github.com/go-kit/kit/log/log.go | 135 - .../go-kit/kit/log/logfmt_logger.go | 62 - .../github.com/go-kit/kit/log/nop_logger.go | 8 - vendor/github.com/go-kit/kit/log/stdlib.go | 116 - vendor/github.com/go-kit/kit/log/sync.go | 116 - vendor/github.com/go-kit/kit/log/value.go | 102 - vendor/github.com/go-logfmt/logfmt/LICENSE | 22 - vendor/github.com/go-logfmt/logfmt/README.md | 33 - vendor/github.com/go-logfmt/logfmt/decode.go | 237 - vendor/github.com/go-logfmt/logfmt/doc.go | 6 - vendor/github.com/go-logfmt/logfmt/encode.go | 321 - vendor/github.com/go-logfmt/logfmt/fuzz.go | 126 - .../github.com/go-logfmt/logfmt/jsonstring.go | 277 - vendor/github.com/go-stack/stack/LICENSE.md | 21 - vendor/github.com/go-stack/stack/README.md | 38 - vendor/github.com/go-stack/stack/stack.go | 349 - vendor/github.com/golang/protobuf/LICENSE | 31 - .../github.com/golang/protobuf/proto/Makefile | 43 - .../github.com/golang/protobuf/proto/clone.go | 229 - .../golang/protobuf/proto/decode.go | 970 - .../golang/protobuf/proto/encode.go | 1362 - .../github.com/golang/protobuf/proto/equal.go | 300 - .../golang/protobuf/proto/extensions.go | 587 - .../github.com/golang/protobuf/proto/lib.go | 897 - .../golang/protobuf/proto/message_set.go | 311 - .../golang/protobuf/proto/pointer_reflect.go | 484 - .../golang/protobuf/proto/pointer_unsafe.go | 270 - .../golang/protobuf/proto/properties.go | 872 - .../github.com/golang/protobuf/proto/text.go | 854 - .../golang/protobuf/proto/text_parser.go | 895 - vendor/github.com/joho/godotenv/LICENCE | 23 - vendor/github.com/joho/godotenv/README.md | 133 - vendor/github.com/joho/godotenv/godotenv.go | 247 - vendor/github.com/kr/logfmt/Readme | 12 - vendor/github.com/kr/logfmt/decode.go | 184 - vendor/github.com/kr/logfmt/scanner.go | 149 - vendor/github.com/kr/logfmt/unquote.go | 149 - vendor/github.com/shurcooL/githubql/LICENSE | 21 - vendor/github.com/shurcooL/githubql/README.md | 317 - vendor/github.com/shurcooL/githubql/doc.go | 13 - vendor/github.com/shurcooL/githubql/enum.go | 430 - .../github.com/shurcooL/githubql/githubql.go | 44 - vendor/github.com/shurcooL/githubql/input.go | 428 - .../internal/hacky/caseconv/caseconv.go | 150 - .../githubql/internal/jsonutil/graphql.go | 297 - vendor/github.com/shurcooL/githubql/scalar.go | 141 - .../github.com/shurcooL/githubql/schema.json | 34079 ---------------- .../github.com/shurcooL/go/ctxhttp/ctxhttp.go | 78 - vendor/github.com/shurcooL/graphql/LICENSE | 21 - vendor/github.com/shurcooL/graphql/README.md | 219 - vendor/github.com/shurcooL/graphql/doc.go | 11 - vendor/github.com/shurcooL/graphql/graphql.go | 123 - .../shurcooL/graphql/ident/ident.go | 215 - .../graphql/internal/jsonutil/graphql.go | 299 - vendor/github.com/shurcooL/graphql/query.go | 112 - vendor/github.com/shurcooL/graphql/scalar.go | 51 - vendor/golang.org/x/net/LICENSE | 27 - vendor/golang.org/x/net/PATENTS | 22 - vendor/golang.org/x/net/context/context.go | 156 - vendor/golang.org/x/net/context/go17.go | 72 - vendor/golang.org/x/net/context/pre_go17.go | 300 - vendor/golang.org/x/oauth2/AUTHORS | 3 - vendor/golang.org/x/oauth2/CONTRIBUTING.md | 31 - vendor/golang.org/x/oauth2/CONTRIBUTORS | 3 - vendor/golang.org/x/oauth2/LICENSE | 27 - vendor/golang.org/x/oauth2/README.md | 74 - .../golang.org/x/oauth2/client_appengine.go | 25 - vendor/golang.org/x/oauth2/internal/oauth2.go | 76 - vendor/golang.org/x/oauth2/internal/token.go | 249 - .../golang.org/x/oauth2/internal/transport.go | 69 - vendor/golang.org/x/oauth2/oauth2.go | 340 - vendor/golang.org/x/oauth2/token.go | 158 - vendor/golang.org/x/oauth2/transport.go | 132 - vendor/google.golang.org/appengine/LICENSE | 202 - .../appengine/internal/api.go | 675 - .../appengine/internal/api_classic.go | 159 - .../appengine/internal/api_common.go | 116 - .../appengine/internal/app_id.go | 28 - .../appengine/internal/base/api_base.pb.go | 133 - .../appengine/internal/base/api_base.proto | 33 - .../internal/datastore/datastore_v3.pb.go | 2778 -- .../internal/datastore/datastore_v3.proto | 541 - .../appengine/internal/identity.go | 14 - .../appengine/internal/identity_classic.go | 27 - .../appengine/internal/identity_vm.go | 97 - .../appengine/internal/internal.go | 110 - .../appengine/internal/log/log_service.pb.go | 899 - .../appengine/internal/log/log_service.proto | 150 - .../appengine/internal/main.go | 15 - .../appengine/internal/main_vm.go | 48 - .../appengine/internal/metadata.go | 61 - .../appengine/internal/net.go | 56 - .../appengine/internal/regen.sh | 40 - .../internal/remote_api/remote_api.pb.go | 231 - .../internal/remote_api/remote_api.proto | 44 - .../appengine/internal/transaction.go | 107 - .../internal/urlfetch/urlfetch_service.pb.go | 355 - .../internal/urlfetch/urlfetch_service.proto | 64 - .../appengine/urlfetch/urlfetch.go | 210 - vendor/vendor.json | 164 - 129 files changed, 624 insertions(+), 59186 deletions(-) create mode 100644 .drone.star create mode 100644 .drone.yml delete mode 100644 .travis.yml delete mode 100644 VERSION rename Dockerfile => docker/Dockerfile (100%) create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 screenshot.png delete mode 100644 vendor/github.com/alexflint/go-arg/LICENSE delete mode 100644 vendor/github.com/alexflint/go-arg/README.md delete mode 100644 vendor/github.com/alexflint/go-arg/doc.go delete mode 100644 vendor/github.com/alexflint/go-arg/parse.go delete mode 100644 vendor/github.com/alexflint/go-arg/usage.go delete mode 100644 vendor/github.com/alexflint/go-scalar/LICENSE delete mode 100644 vendor/github.com/alexflint/go-scalar/README.md delete mode 100644 vendor/github.com/alexflint/go-scalar/scalar.go delete mode 100644 vendor/github.com/go-kit/kit/LICENSE delete mode 100644 vendor/github.com/go-kit/kit/log/README.md delete mode 100644 vendor/github.com/go-kit/kit/log/cover.coverprofile delete mode 100644 vendor/github.com/go-kit/kit/log/doc.go delete mode 100644 vendor/github.com/go-kit/kit/log/json_logger.go delete mode 100644 vendor/github.com/go-kit/kit/log/level/cover.coverprofile delete mode 100644 vendor/github.com/go-kit/kit/log/level/doc.go delete mode 100644 vendor/github.com/go-kit/kit/log/level/level.go delete mode 100644 vendor/github.com/go-kit/kit/log/log.go delete mode 100644 vendor/github.com/go-kit/kit/log/logfmt_logger.go delete mode 100644 vendor/github.com/go-kit/kit/log/nop_logger.go delete mode 100644 vendor/github.com/go-kit/kit/log/stdlib.go delete mode 100644 vendor/github.com/go-kit/kit/log/sync.go delete mode 100644 vendor/github.com/go-kit/kit/log/value.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/LICENSE delete mode 100644 vendor/github.com/go-logfmt/logfmt/README.md delete mode 100644 vendor/github.com/go-logfmt/logfmt/decode.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/doc.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/encode.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/fuzz.go delete mode 100644 vendor/github.com/go-logfmt/logfmt/jsonstring.go delete mode 100644 vendor/github.com/go-stack/stack/LICENSE.md delete mode 100644 vendor/github.com/go-stack/stack/README.md delete mode 100644 vendor/github.com/go-stack/stack/stack.go delete mode 100644 vendor/github.com/golang/protobuf/LICENSE delete mode 100644 vendor/github.com/golang/protobuf/proto/Makefile delete mode 100644 vendor/github.com/golang/protobuf/proto/clone.go delete mode 100644 vendor/github.com/golang/protobuf/proto/decode.go delete mode 100644 vendor/github.com/golang/protobuf/proto/encode.go delete mode 100644 vendor/github.com/golang/protobuf/proto/equal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/extensions.go delete mode 100644 vendor/github.com/golang/protobuf/proto/lib.go delete mode 100644 vendor/github.com/golang/protobuf/proto/message_set.go delete mode 100644 vendor/github.com/golang/protobuf/proto/pointer_reflect.go delete mode 100644 vendor/github.com/golang/protobuf/proto/pointer_unsafe.go delete mode 100644 vendor/github.com/golang/protobuf/proto/properties.go delete mode 100644 vendor/github.com/golang/protobuf/proto/text.go delete mode 100644 vendor/github.com/golang/protobuf/proto/text_parser.go delete mode 100644 vendor/github.com/joho/godotenv/LICENCE delete mode 100644 vendor/github.com/joho/godotenv/README.md delete mode 100644 vendor/github.com/joho/godotenv/godotenv.go delete mode 100644 vendor/github.com/kr/logfmt/Readme delete mode 100644 vendor/github.com/kr/logfmt/decode.go delete mode 100644 vendor/github.com/kr/logfmt/scanner.go delete mode 100644 vendor/github.com/kr/logfmt/unquote.go delete mode 100644 vendor/github.com/shurcooL/githubql/LICENSE delete mode 100644 vendor/github.com/shurcooL/githubql/README.md delete mode 100644 vendor/github.com/shurcooL/githubql/doc.go delete mode 100644 vendor/github.com/shurcooL/githubql/enum.go delete mode 100644 vendor/github.com/shurcooL/githubql/githubql.go delete mode 100644 vendor/github.com/shurcooL/githubql/input.go delete mode 100644 vendor/github.com/shurcooL/githubql/internal/hacky/caseconv/caseconv.go delete mode 100644 vendor/github.com/shurcooL/githubql/internal/jsonutil/graphql.go delete mode 100644 vendor/github.com/shurcooL/githubql/scalar.go delete mode 100644 vendor/github.com/shurcooL/githubql/schema.json delete mode 100644 vendor/github.com/shurcooL/go/ctxhttp/ctxhttp.go delete mode 100644 vendor/github.com/shurcooL/graphql/LICENSE delete mode 100644 vendor/github.com/shurcooL/graphql/README.md delete mode 100644 vendor/github.com/shurcooL/graphql/doc.go delete mode 100644 vendor/github.com/shurcooL/graphql/graphql.go delete mode 100644 vendor/github.com/shurcooL/graphql/ident/ident.go delete mode 100644 vendor/github.com/shurcooL/graphql/internal/jsonutil/graphql.go delete mode 100644 vendor/github.com/shurcooL/graphql/query.go delete mode 100644 vendor/github.com/shurcooL/graphql/scalar.go delete mode 100644 vendor/golang.org/x/net/LICENSE delete mode 100644 vendor/golang.org/x/net/PATENTS delete mode 100644 vendor/golang.org/x/net/context/context.go delete mode 100644 vendor/golang.org/x/net/context/go17.go delete mode 100644 vendor/golang.org/x/net/context/pre_go17.go delete mode 100644 vendor/golang.org/x/oauth2/AUTHORS delete mode 100644 vendor/golang.org/x/oauth2/CONTRIBUTING.md delete mode 100644 vendor/golang.org/x/oauth2/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/oauth2/LICENSE delete mode 100644 vendor/golang.org/x/oauth2/README.md delete mode 100644 vendor/golang.org/x/oauth2/client_appengine.go delete mode 100644 vendor/golang.org/x/oauth2/internal/oauth2.go delete mode 100644 vendor/golang.org/x/oauth2/internal/token.go delete mode 100644 vendor/golang.org/x/oauth2/internal/transport.go delete mode 100644 vendor/golang.org/x/oauth2/oauth2.go delete mode 100644 vendor/golang.org/x/oauth2/token.go delete mode 100644 vendor/golang.org/x/oauth2/transport.go delete mode 100644 vendor/google.golang.org/appengine/LICENSE delete mode 100644 vendor/google.golang.org/appengine/internal/api.go delete mode 100644 vendor/google.golang.org/appengine/internal/api_classic.go delete mode 100644 vendor/google.golang.org/appengine/internal/api_common.go delete mode 100644 vendor/google.golang.org/appengine/internal/app_id.go delete mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.proto delete mode 100644 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go delete mode 100755 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto delete mode 100644 vendor/google.golang.org/appengine/internal/identity.go delete mode 100644 vendor/google.golang.org/appengine/internal/identity_classic.go delete mode 100644 vendor/google.golang.org/appengine/internal/identity_vm.go delete mode 100644 vendor/google.golang.org/appengine/internal/internal.go delete mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.proto delete mode 100644 vendor/google.golang.org/appengine/internal/main.go delete mode 100644 vendor/google.golang.org/appengine/internal/main_vm.go delete mode 100644 vendor/google.golang.org/appengine/internal/metadata.go delete mode 100644 vendor/google.golang.org/appengine/internal/net.go delete mode 100755 vendor/google.golang.org/appengine/internal/regen.sh delete mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto delete mode 100644 vendor/google.golang.org/appengine/internal/transaction.go delete mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go delete mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto delete mode 100644 vendor/google.golang.org/appengine/urlfetch/urlfetch.go delete mode 100644 vendor/vendor.json diff --git a/.drone.star b/.drone.star new file mode 100644 index 0000000..e896861 --- /dev/null +++ b/.drone.star @@ -0,0 +1,223 @@ +def main(ctx): + before = testing() + + stages = [ + linux('amd64'), + linux('arm64'), + linux('arm'), + ] + + after = notification() + + for b in before: + for s in stages: + s['depends_on'].append(b['name']) + + for s in stages: + for a in after: + a['depends_on'].append(s['name']) + + return before + stages + after + +def testing(): + return [{ + 'kind': 'pipeline', + 'type': 'docker', + 'name': 'testing', + 'platform': { + 'os': 'linux', + 'arch': 'amd64', + }, + 'steps': [ + { + 'name': 'vet', + 'image': 'golang:1.12', + 'commands': [ + 'go vet ./...' + ], + 'volumes': [ + { + 'name': 'gopath', + 'path': '/go' + } + ] + }, + { + 'name': 'test', + 'image': 'golang:1.12', + 'commands': [ + 'go test -cover ./...' + ], + 'volumes': [ + { + 'name': 'gopath', + 'path': '/go' + } + ] + } + ], + 'volumes': [ + { + 'name': 'gopath', + 'temp': {} + } + ], + 'trigger': { + 'ref': [ + 'refs/heads/master', + 'refs/tags/**', + 'refs/pull/**' + ] + } + }] + +def linux(arch): + return { + 'kind': 'pipeline', + 'type': 'docker', + 'name': 'linux-%s' % arch, + 'platform': { + 'os': 'linux', + 'arch': arch, + }, + 'steps': [ + { + 'name': 'build-push', + 'image': 'golang:1.12', + 'environment': { + 'CGO_ENABLED': '0' + }, + 'commands': [ + 'go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/%s/github-releases-notifier' % arch + ], + 'when': { + 'event': { + 'exclude': [ + 'tag' + ] + } + } + }, + { + 'name': 'build-tag', + 'image': 'golang:1.12', + 'environment': { + 'CGO_ENABLED': '0' + }, + 'commands': [ + 'go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/%s/github-releases-notifier' % arch + ], + 'when': { + 'event': [ + 'tag' + ] + } + }, + { + 'name': 'executable', + 'image': 'golang:1.12', + 'commands': [ + './release/linux/%s/github-releases-notifier --help' % arch + ] + }, + { + 'name': 'dryrun', + 'image': 'plugins/docker', + 'settings': { + 'dry_run': True, + 'tags': 'linux-%s' % arch, + 'dockerfile': 'docker/Dockerfile.linux.%s' % arch, + 'repo': 'xoxys/github-releases-notifier', + 'username': { + 'from_secret': 'docker_username' + }, + 'password': { + 'from_secret': 'docker_password' + } + }, + 'when': { + 'event': [ + 'pull_request' + ] + } + }, + { + 'name': 'publish', + 'image': 'plugins/docker', + 'settings': { + 'auto_tag': True, + 'auto_tag_suffix': 'linux-%s' % arch, + 'dockerfile': 'docker/Dockerfile.linux.%s' % arch, + 'repo': 'xoxys/github-releases-notifier', + 'username': { + 'from_secret': 'docker_username' + }, + 'password': { + 'from_secret': 'docker_password' + } + }, + 'when': { + 'event': { + 'exclude': [ + 'pull_request' + ] + } + } + } + ], + 'depends_on': [], + 'trigger': { + 'ref': [ + 'refs/heads/master', + 'refs/tags/**', + 'refs/pull/**' + ] + } + } + +def notification(): + return [{ + 'kind': 'pipeline', + 'type': 'docker', + 'name': 'notification', + 'clone': { + 'disable': True + }, + 'steps': [ + { + 'name': 'manifest', + 'image': 'plugins/manifest', + 'settings': { + 'auto_tag': 'true', + 'username': { + 'from_secret': 'docker_username' + }, + 'password': { + 'from_secret': 'docker_password' + }, + 'spec': 'docker/manifest.tmpl', + 'ignore_missing': 'true', + }, + }, + { + 'name': 'microbadger', + 'image': 'xoxys/github-releases-notifier', + 'settings': { + 'urls': { + 'from_secret': 'microbadger_url' + } + }, + }, + ], + 'depends_on': [], + 'trigger': { + 'ref': [ + 'refs/heads/master', + 'refs/tags/**' + ], + 'status': [ + 'success', + 'failure' + ] + } + }] diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..52cc467 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,305 @@ +--- +kind: pipeline +type: docker +name: testing + +platform: + os: linux + arch: amd64 + +steps: +- name: vet + image: golang:1.12 + commands: + - go vet ./... + volumes: + - name: gopath + path: /go + +- name: test + image: golang:1.12 + commands: + - go test -cover ./... + volumes: + - name: gopath + path: /go + +volumes: +- name: gopath + temp: {} + +trigger: + ref: + - refs/heads/master + - refs/tags/** + - refs/pull/** + +--- +kind: pipeline +type: docker +name: linux-amd64 + +platform: + os: linux + arch: amd64 + +steps: +- name: build-push + image: golang:1.12 + commands: + - go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/github-releases-notifier + environment: + CGO_ENABLED: 0 + when: + event: + exclude: + - tag + +- name: build-tag + image: golang:1.12 + commands: + - go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/amd64/github-releases-notifier + environment: + CGO_ENABLED: 0 + when: + event: + - tag + +- name: executable + image: golang:1.12 + commands: + - ./release/linux/amd64/github-releases-notifier --help + +- name: dryrun + image: plugins/docker + settings: + dockerfile: docker/Dockerfile.linux.amd64 + dry_run: true + password: + from_secret: docker_password + repo: xoxys/github-releases-notifier + tags: linux-amd64 + username: + from_secret: docker_username + when: + event: + - pull_request + +- name: publish + image: plugins/docker + settings: + auto_tag: true + auto_tag_suffix: linux-amd64 + dockerfile: docker/Dockerfile.linux.amd64 + password: + from_secret: docker_password + repo: xoxys/github-releases-notifier + username: + from_secret: docker_username + when: + event: + exclude: + - pull_request + +trigger: + ref: + - refs/heads/master + - refs/tags/** + - refs/pull/** + +depends_on: +- testing + +--- +kind: pipeline +type: docker +name: linux-arm64 + +platform: + os: linux + arch: arm64 + +steps: +- name: build-push + image: golang:1.12 + commands: + - go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm64/github-releases-notifier + environment: + CGO_ENABLED: 0 + when: + event: + exclude: + - tag + +- name: build-tag + image: golang:1.12 + commands: + - go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm64/github-releases-notifier + environment: + CGO_ENABLED: 0 + when: + event: + - tag + +- name: executable + image: golang:1.12 + commands: + - ./release/linux/arm64/github-releases-notifier --help + +- name: dryrun + image: plugins/docker + settings: + dockerfile: docker/Dockerfile.linux.arm64 + dry_run: true + password: + from_secret: docker_password + repo: xoxys/github-releases-notifier + tags: linux-arm64 + username: + from_secret: docker_username + when: + event: + - pull_request + +- name: publish + image: plugins/docker + settings: + auto_tag: true + auto_tag_suffix: linux-arm64 + dockerfile: docker/Dockerfile.linux.arm64 + password: + from_secret: docker_password + repo: xoxys/github-releases-notifier + username: + from_secret: docker_username + when: + event: + exclude: + - pull_request + +trigger: + ref: + - refs/heads/master + - refs/tags/** + - refs/pull/** + +depends_on: +- testing + +--- +kind: pipeline +type: docker +name: linux-arm + +platform: + os: linux + arch: arm + +steps: +- name: build-push + image: golang:1.12 + commands: + - go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/arm/github-releases-notifier + environment: + CGO_ENABLED: 0 + when: + event: + exclude: + - tag + +- name: build-tag + image: golang:1.12 + commands: + - go build -v -ldflags "-X main.version=${DRONE_TAG##v}" -a -tags netgo -o release/linux/arm/github-releases-notifier + environment: + CGO_ENABLED: 0 + when: + event: + - tag + +- name: executable + image: golang:1.12 + commands: + - ./release/linux/arm/github-releases-notifier --help + +- name: dryrun + image: plugins/docker + settings: + dockerfile: docker/Dockerfile.linux.arm + dry_run: true + password: + from_secret: docker_password + repo: xoxys/github-releases-notifier + tags: linux-arm + username: + from_secret: docker_username + when: + event: + - pull_request + +- name: publish + image: plugins/docker + settings: + auto_tag: true + auto_tag_suffix: linux-arm + dockerfile: docker/Dockerfile.linux.arm + password: + from_secret: docker_password + repo: xoxys/github-releases-notifier + username: + from_secret: docker_username + when: + event: + exclude: + - pull_request + +trigger: + ref: + - refs/heads/master + - refs/tags/** + - refs/pull/** + +depends_on: +- testing + +--- +kind: pipeline +type: docker +name: notification + +platform: + os: linux + arch: amd64 + +clone: + disable: true + +steps: +- name: manifest + image: plugins/manifest + settings: + auto_tag: true + ignore_missing: true + password: + from_secret: docker_password + spec: docker/manifest.tmpl + username: + from_secret: docker_username + +- name: microbadger + image: xoxys/github-releases-notifier + settings: + urls: + from_secret: microbadger_url + +trigger: + ref: + - refs/heads/master + - refs/tags/** + +depends_on: +- linux-amd64 +- linux-arm64 +- linux-arm + +... diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3413972..0000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go - -go: - - 1.8.x - -before_install: - - go get -v github.com/golang/lint/golint - -script: - - make clean - - make vet - - make lint - - make test - - make build diff --git a/LICENSE b/LICENSE index f593ef4..95ac905 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 JustWatch +Copyright (c) 2020 xoxys Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 4c4af34..1344513 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # github-releases-notifier -[![Build Status](https://travis-ci.org/justwatchcom/github-releases-notifier.svg?branch=master)](https://travis-ci.org/justwatchcom/github-releases-notifier) [![Go Report Card](https://goreportcard.com/badge/github.com/justwatchcom/github-releases-notifier)](https://goreportcard.com/report/github.com/justwatchcom/github-releases-notifier) [![Docker Pulls](https://img.shields.io/docker/pulls/justwatch/github-releases-notifier.svg?maxAge=604800)](https://hub.docker.com/r/justwatch/github-releases-notifier) @@ -42,4 +41,4 @@ After creating the secret with your credentials you can apply the deployment: `kubectl apply -f deployments/kubernetes.yml` -That's it. \ No newline at end of file +That's it. diff --git a/VERSION b/VERSION deleted file mode 100644 index 8a9ecc2..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.0.1 \ No newline at end of file diff --git a/Dockerfile b/docker/Dockerfile similarity index 100% rename from Dockerfile rename to docker/Dockerfile diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ab88287 --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module github.com/xoxys/github-releases-notifier + +go 1.13 + +require ( + github.com/alexflint/go-arg v1.2.0 + github.com/go-kit/kit v0.9.0 + github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/joho/godotenv v1.3.0 + github.com/shurcooL/githubql v0.0.0-20191127044304-8f68eb5628d0 + github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0 + github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..73b6c0f --- /dev/null +++ b/go.sum @@ -0,0 +1,29 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/alexflint/go-arg v1.2.0 h1:TOFkN8/Cn1VvbHhsCuYq+P6ol3P5FAmjKIqsk7D2U/Q= +github.com/alexflint/go-arg v1.2.0/go.mod h1:3Rj4baqzWaGGmZA2+bVTV8zQOZEjBQAPBnL5xLT+ftY= +github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= +github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shurcooL/githubql v0.0.0-20191127044304-8f68eb5628d0 h1:lPdYkfFdBjfpOQhcQO29XBvgA6p/01aN50b6ewTZoNY= +github.com/shurcooL/githubql v0.0.0-20191127044304-8f68eb5628d0/go.mod h1:iaroGwWDfkuasmvRaqq1Dlq6EQhPsZrg8srZhBQHA8A= +github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0 h1:T9uus1QvcPgeLShS30YOnnzk3r9Vvygp45muhlrufgY= +github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= +github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk= +github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/main.go b/main.go index 6f9bcc3..83b41c1 100644 --- a/main.go +++ b/main.go @@ -10,17 +10,18 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/joho/godotenv" - "github.com/shurcooL/githubql" + "github.com/shurcooL/githubv4" "golang.org/x/oauth2" ) // Config of env and args type Config struct { - GithubToken string `arg:"env:GITHUB_TOKEN"` + GithubToken string `arg:"env:GITHUB_TOKEN,required"` Interval time.Duration `arg:"env:INTERVAL"` LogLevel string `arg:"env:LOG_LEVEL"` - Repositories []string `arg:"-r,separate"` - SlackHook string `arg:"env:SLACK_HOOK"` + Repositories []string `arg:"env:GITHUB_REPOS,-r,separate"` + SlackHook string `arg:"env:SLACK_HOOK,required"` + IgnorePre bool `arg:"env:IGNORE_PRE"` } // Token returns an oauth2 token or an error. @@ -43,7 +44,6 @@ func main() { "caller", log.Caller(5), ) - level.SetKey("severity") switch strings.ToLower(c.LogLevel) { case "debug": logger = level.NewFilter(logger, level.AllowDebug()) @@ -59,11 +59,11 @@ func main() { client := oauth2.NewClient(context.Background(), tokenSource) checker := &Checker{ logger: logger, - client: githubql.NewClient(client), + client: githubv4.NewClient(client), } releases := make(chan Repository) - go checker.Run(c.Interval, c.Repositories, releases) + go checker.Run(c.Interval, c.Repositories, c.IgnorePre, releases) slack := SlackSender{Hook: c.SlackHook} diff --git a/release.go b/release.go index 7d58ae5..852ccdd 100644 --- a/release.go +++ b/release.go @@ -7,9 +7,10 @@ import ( // Release of a repository tagged via GitHub. type Release struct { - ID string - Name string - Description string - URL url.URL - PublishedAt time.Time + ID string + Name string + Description string + URL url.URL + PublishedAt time.Time + IsPrerelease bool } diff --git a/releasechecker.go b/releasechecker.go index d455df2..aa72889 100644 --- a/releasechecker.go +++ b/releasechecker.go @@ -8,19 +8,20 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" - "github.com/shurcooL/githubql" + "github.com/shurcooL/githubv4" ) -// Checker has a githubql client to run queries and also knows about +// Checker has a githubv4 client to run queries and also knows about // the current repositories releases to compare against. type Checker struct { logger log.Logger - client *githubql.Client + client *githubv4.Client releases map[string]Repository } // Run the queries and comparisons for the given repositories in a given interval. -func (c *Checker) Run(interval time.Duration, repositories []string, releases chan<- Repository) { +func (c *Checker) Run(interval time.Duration, repositories []string, + ignorePre bool, releases chan<- Repository) { if c.releases == nil { c.releases = make(map[string]Repository) } @@ -29,6 +30,7 @@ func (c *Checker) Run(interval time.Duration, repositories []string, releases ch for _, repoName := range repositories { s := strings.Split(repoName, "/") owner, name := s[0], s[1] + msg := "no new release for repository" nextRepo, err := c.query(owner, name) if err != nil { @@ -54,39 +56,45 @@ func (c *Checker) Run(interval time.Duration, repositories []string, releases ch } if nextRepo.Release.PublishedAt.After(currRepo.Release.PublishedAt) { - releases <- nextRepo - c.releases[repoName] = nextRepo - } else { - level.Debug(c.logger).Log( - "msg", "no new release for repository", - "owner", owner, - "name", name, - ) + if !(ignorePre && nextRepo.Release.IsPrerelease) { + releases <- nextRepo + c.releases[repoName] = nextRepo + msg = "found new release for repository" + } else { + msg = "ignoring new pre-release for repository" + } } + + level.Debug(c.logger).Log( + "msg", msg, + "owner", owner, + "name", name, + ) } time.Sleep(interval) } } // This should be improved in the future to make batch requests for all watched repositories at once -// TODO: https://github.com/shurcooL/githubql/issues/17 +// TODO: https://github.com/shurcooL/githubv4/issues/17 func (c *Checker) query(owner, name string) (Repository, error) { var query struct { Repository struct { - ID githubql.ID - Name githubql.String - Description githubql.String - URL githubql.URI + ID githubv4.ID + Name githubv4.String + Description githubv4.String + URL githubv4.URI Releases struct { Edges []struct { Node struct { - ID githubql.ID - Name githubql.String - Description githubql.String - URL githubql.URI - PublishedAt githubql.DateTime + ID githubv4.ID + Name githubv4.String + Description githubv4.String + URL githubv4.URI + PublishedAt githubv4.DateTime + IsPrerelease githubv4.Boolean } } } `graphql:"releases(last: 1)"` @@ -94,8 +102,8 @@ func (c *Checker) query(owner, name string) (Repository, error) { } variables := map[string]interface{}{ - "owner": githubql.String(owner), - "name": githubql.String(name), + "owner": githubv4.String(owner), + "name": githubv4.String(name), } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) @@ -127,11 +135,12 @@ func (c *Checker) query(owner, name string) (Repository, error) { URL: *query.Repository.URL.URL, Release: Release{ - ID: releaseID, - Name: string(latestRelease.Name), - Description: string(latestRelease.Description), - URL: *latestRelease.URL.URL, - PublishedAt: latestRelease.PublishedAt.Time, + ID: releaseID, + Name: string(latestRelease.Name), + Description: string(latestRelease.Description), + URL: *latestRelease.URL.URL, + PublishedAt: latestRelease.PublishedAt.Time, + IsPrerelease: bool(latestRelease.IsPrerelease), }, }, nil } diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index 4d8ffa6a5b95447387f82188965d0277eb873b24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34324 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 L7OoJ~_5FVUl|M6K diff --git a/vendor/github.com/alexflint/go-arg/LICENSE b/vendor/github.com/alexflint/go-arg/LICENSE deleted file mode 100644 index a50c494..0000000 --- a/vendor/github.com/alexflint/go-arg/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2015, Alex Flint -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/alexflint/go-arg/README.md b/vendor/github.com/alexflint/go-arg/README.md deleted file mode 100644 index 3f9223c..0000000 --- a/vendor/github.com/alexflint/go-arg/README.md +++ /dev/null @@ -1,321 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/alexflint/go-arg?status.svg)](https://godoc.org/github.com/alexflint/go-arg) -[![Build Status](https://travis-ci.org/alexflint/go-arg.svg?branch=master)](https://travis-ci.org/alexflint/go-arg) -[![Coverage Status](https://coveralls.io/repos/alexflint/go-arg/badge.svg?branch=master&service=github)](https://coveralls.io/github/alexflint/go-arg?branch=master) -[![Report Card](https://goreportcard.com/badge/github.com/alexflint/go-arg)](https://goreportcard.com/badge/github.com/alexflint/go-arg) - -## Structured argument parsing for Go - -```shell -go get github.com/alexflint/go-arg -``` - -Declare the command line arguments your program accepts by defining a struct. - -```go -var args struct { - Foo string - Bar bool -} -arg.MustParse(&args) -fmt.Println(args.Foo, args.Bar) -``` - -```shell -$ ./example --foo=hello --bar -hello true -``` - -### Required arguments - -```go -var args struct { - ID int `arg:"required"` - Timeout time.Duration -} -arg.MustParse(&args) -``` - -```shell -$ ./example -Usage: example --id ID [--timeout TIMEOUT] -error: --id is required -``` - -### Positional arguments - -```go -var args struct { - Input string `arg:"positional"` - Output []string `arg:"positional"` -} -arg.MustParse(&args) -fmt.Println("Input:", args.Input) -fmt.Println("Output:", args.Output) -``` - -``` -$ ./example src.txt x.out y.out z.out -Input: src.txt -Output: [x.out y.out z.out] -``` - -### Environment variables - -```go -var args struct { - Workers int `arg:"env"` -} -arg.MustParse(&args) -fmt.Println("Workers:", args.Workers) -``` - -``` -$ WORKERS=4 ./example -Workers: 4 -``` - -``` -$ WORKERS=4 ./example --workers=6 -Workers: 6 -``` - -You can also override the name of the environment variable: - -```go -var args struct { - Workers int `arg:"env:NUM_WORKERS"` -} -arg.MustParse(&args) -fmt.Println("Workers:", args.Workers) -``` - -``` -$ NUM_WORKERS=4 ./example -Workers: 4 -``` - -### Usage strings -```go -var args struct { - Input string `arg:"positional"` - Output []string `arg:"positional"` - Verbose bool `arg:"-v,help:verbosity level"` - Dataset string `arg:"help:dataset to use"` - Optimize int `arg:"-O,help:optimization level"` -} -arg.MustParse(&args) -``` - -```shell -$ ./example -h -Usage: [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] [--help] INPUT [OUTPUT [OUTPUT ...]] - -Positional arguments: - INPUT - OUTPUT - -Options: - --verbose, -v verbosity level - --dataset DATASET dataset to use - --optimize OPTIMIZE, -O OPTIMIZE - optimization level - --help, -h print this help message -``` - -### Default values - -```go -var args struct { - Foo string - Bar bool -} -args.Foo = "default value" -arg.MustParse(&args) -``` - -### Arguments with multiple values -```go -var args struct { - Database string - IDs []int64 -} -arg.MustParse(&args) -fmt.Printf("Fetching the following IDs from %s: %q", args.Database, args.IDs) -``` - -```shell -./example -database foo -ids 1 2 3 -Fetching the following IDs from foo: [1 2 3] -``` - -### Arguments that can be specified multiple times, mixed with positionals -```go -var args struct { - Commands []string `arg:"-c,separate"` - Files []string `arg:"-f,separate"` - Databases []string `arg:"positional"` -} -``` - -```shell -./example -c cmd1 db1 -f file1 db2 -c cmd2 -f file2 -f file3 db3 -c cmd3 -Commands: [cmd1 cmd2 cmd3] -Files [file1 file2 file3] -Databases [db1 db2 db3] -``` - -### Custom validation -```go -var args struct { - Foo string - Bar string -} -p := arg.MustParse(&args) -if args.Foo == "" && args.Bar == "" { - p.Fail("you must provide one of --foo and --bar") -} -``` - -```shell -./example -Usage: samples [--foo FOO] [--bar BAR] -error: you must provide one of --foo and --bar -``` - -### Version strings - -```go -type args struct { - ... -} - -func (args) Version() string { - return "someprogram 4.3.0" -} - -func main() { - var args args - arg.MustParse(&args) -} -``` - -```shell -$ ./example --version -someprogram 4.3.0 -``` - -### Embedded structs - -The fields of embedded structs are treated just like regular fields: - -```go - -type DatabaseOptions struct { - Host string - Username string - Password string -} - -type LogOptions struct { - LogFile string - Verbose bool -} - -func main() { - var args struct { - DatabaseOptions - LogOptions - } - arg.MustParse(&args) -} -``` - -As usual, any field tagged with `arg:"-"` is ignored. - -### Custom parsing - -You can implement your own argument parser by implementing `encoding.TextUnmarshaler`: - -```go -package main - -import ( - "fmt" - "strings" - - "github.com/alexflint/go-arg" -) - -// Accepts command line arguments of the form "head.tail" -type NameDotName struct { - Head, Tail string -} - -func (n *NameDotName) UnmarshalText(b []byte) error { - s := string(b) - pos := strings.Index(s, ".") - if pos == -1 { - return fmt.Errorf("missing period in %s", s) - } - n.Head = s[:pos] - n.Tail = s[pos+1:] - return nil -} - -func main() { - var args struct { - Name *NameDotName - } - arg.MustParse(&args) - fmt.Printf("%#v\n", args.Name) -} -``` -```shell -$ ./example --name=foo.bar -&main.NameDotName{Head:"foo", Tail:"bar"} - -$ ./example --name=oops -Usage: example [--name NAME] -error: error processing --name: missing period in "oops" -``` - -### Description strings - -```go -type args struct { - Foo string -} - -func (args) Description() string { - return "this program does this and that" -} - -func main() { - var args args - arg.MustParse(&args) -} -``` - -```shell -$ ./example -h -this program does this and that -Usage: example [--foo FOO] - -Options: - --foo FOO - --help, -h display this help and exit -``` - -### Documentation - -https://godoc.org/github.com/alexflint/go-arg - -### Rationale - -There are many command line argument parsing libraries for Go, including one in the standard library, so why build another? - -The shortcomings of the `flag` library that ships in the standard library are well known. Positional arguments must preceed options, so `./prog x --foo=1` does what you expect but `./prog --foo=1 x` does not. Arguments cannot have both long (`--foo`) and short (`-f`) forms. - -Many third-party argument parsing libraries are geared for writing sophisticated command line interfaces. The excellent `codegangsta/cli` is perfect for working with multiple sub-commands and nested flags, but is probably overkill for a simple script with a handful of flags. - -The main idea behind `go-arg` is that Go already has an excellent way to describe data structures using Go structs, so there is no need to develop more levels of abstraction on top of this. Instead of one API to specify which arguments your program accepts, and then another API to get the values of those arguments, why not replace both with a single struct? diff --git a/vendor/github.com/alexflint/go-arg/doc.go b/vendor/github.com/alexflint/go-arg/doc.go deleted file mode 100644 index 500ec83..0000000 --- a/vendor/github.com/alexflint/go-arg/doc.go +++ /dev/null @@ -1,36 +0,0 @@ -// Package arg parses command line arguments using the fields from a struct. -// -// For example, -// -// var args struct { -// Iter int -// Debug bool -// } -// arg.MustParse(&args) -// -// defines two command line arguments, which can be set using any of -// -// ./example --iter=1 --debug // debug is a boolean flag so its value is set to true -// ./example -iter 1 // debug defaults to its zero value (false) -// ./example --debug=true // iter defaults to its zero value (zero) -// -// The fastest way to see how to use go-arg is to read the examples below. -// -// Fields can be bool, string, any float type, or any signed or unsigned integer type. -// They can also be slices of any of the above, or slices of pointers to any of the above. -// -// Tags can be specified using the `arg` package name: -// -// var args struct { -// Input string `arg:"positional"` -// Log string `arg:"positional,required"` -// Debug bool `arg:"-d,help:turn on debug mode"` -// RealMode bool `arg:"--real" -// Wr io.Writer `arg:"-"` -// } -// -// The valid tag strings are `positional`, `required`, and `help`. Further, any tag string -// that starts with a single hyphen is the short form for an argument (e.g. `./example -d`), -// and any tag string that starts with two hyphens is the long form for the argument -// (instead of the field name). Fields can be excluded from processing with `arg:"-"`. -package arg diff --git a/vendor/github.com/alexflint/go-arg/parse.go b/vendor/github.com/alexflint/go-arg/parse.go deleted file mode 100644 index 4f62c60..0000000 --- a/vendor/github.com/alexflint/go-arg/parse.go +++ /dev/null @@ -1,482 +0,0 @@ -package arg - -import ( - "encoding" - "errors" - "fmt" - "os" - "path/filepath" - "reflect" - "strings" - - scalar "github.com/alexflint/go-scalar" -) - -// spec represents a command line option -type spec struct { - dest reflect.Value - long string - short string - multiple bool - required bool - positional bool - separate bool - help string - env string - wasPresent bool - boolean bool -} - -// ErrHelp indicates that -h or --help were provided -var ErrHelp = errors.New("help requested by user") - -// ErrVersion indicates that --version was provided -var ErrVersion = errors.New("version requested by user") - -// MustParse processes command line arguments and exits upon failure -func MustParse(dest ...interface{}) *Parser { - p, err := NewParser(Config{}, dest...) - if err != nil { - fmt.Println(err) - os.Exit(-1) - } - err = p.Parse(flags()) - if err == ErrHelp { - p.WriteHelp(os.Stdout) - os.Exit(0) - } - if err == ErrVersion { - fmt.Println(p.version) - os.Exit(0) - } - if err != nil { - p.Fail(err.Error()) - } - return p -} - -// Parse processes command line arguments and stores them in dest -func Parse(dest ...interface{}) error { - p, err := NewParser(Config{}, dest...) - if err != nil { - return err - } - return p.Parse(flags()) -} - -// flags gets all command line arguments other than the first (program name) -func flags() []string { - if len(os.Args) == 0 { // os.Args could be empty - return nil - } - return os.Args[1:] -} - -// Config represents configuration options for an argument parser -type Config struct { - Program string // Program is the name of the program used in the help text -} - -// Parser represents a set of command line options with destination values -type Parser struct { - spec []*spec - config Config - version string - description string -} - -// Versioned is the interface that the destination struct should implement to -// make a version string appear at the top of the help message. -type Versioned interface { - // Version returns the version string that will be printed on a line by itself - // at the top of the help message. - Version() string -} - -// Described is the interface that the destination struct should implement to -// make a description string appear at the top of the help message. -type Described interface { - // Description returns the string that will be printed on a line by itself - // at the top of the help message. - Description() string -} - -// walkFields calls a function for each field of a struct, recursively expanding struct fields. -func walkFields(v reflect.Value, visit func(field reflect.StructField, val reflect.Value, owner reflect.Type) bool) { - t := v.Type() - for i := 0; i < t.NumField(); i++ { - field := t.Field(i) - val := v.Field(i) - expand := visit(field, val, t) - if expand && field.Type.Kind() == reflect.Struct { - walkFields(val, visit) - } - } -} - -// NewParser constructs a parser from a list of destination structs -func NewParser(config Config, dests ...interface{}) (*Parser, error) { - p := Parser{ - config: config, - } - for _, dest := range dests { - if dest, ok := dest.(Versioned); ok { - p.version = dest.Version() - } - if dest, ok := dest.(Described); ok { - p.description = dest.Description() - } - v := reflect.ValueOf(dest) - if v.Kind() != reflect.Ptr { - panic(fmt.Sprintf("%s is not a pointer (did you forget an ampersand?)", v.Type())) - } - v = v.Elem() - if v.Kind() != reflect.Struct { - panic(fmt.Sprintf("%T is not a struct pointer", dest)) - } - - var errs []string - walkFields(v, func(field reflect.StructField, val reflect.Value, t reflect.Type) bool { - // Check for the ignore switch in the tag - tag := field.Tag.Get("arg") - if tag == "-" { - return false - } - - // If this is an embedded struct then recurse into its fields - if field.Anonymous && field.Type.Kind() == reflect.Struct { - return true - } - - spec := spec{ - long: strings.ToLower(field.Name), - dest: val, - } - - // Check whether this field is supported. It's good to do this here rather than - // wait until setScalar because it means that a program with invalid argument - // fields will always fail regardless of whether the arguments it received - // exercised those fields. - var parseable bool - parseable, spec.boolean, spec.multiple = canParse(field.Type) - if !parseable { - errs = append(errs, fmt.Sprintf("%s.%s: %s fields are not supported", - t.Name(), field.Name, field.Type.String())) - return false - } - - // Look at the tag - if tag != "" { - for _, key := range strings.Split(tag, ",") { - var value string - if pos := strings.Index(key, ":"); pos != -1 { - value = key[pos+1:] - key = key[:pos] - } - - switch { - case strings.HasPrefix(key, "---"): - errs = append(errs, fmt.Sprintf("%s.%s: too many hyphens", t.Name(), field.Name)) - case strings.HasPrefix(key, "--"): - spec.long = key[2:] - case strings.HasPrefix(key, "-"): - if len(key) != 2 { - errs = append(errs, fmt.Sprintf("%s.%s: short arguments must be one character only", - t.Name(), field.Name)) - return false - } - spec.short = key[1:] - case key == "required": - spec.required = true - case key == "positional": - spec.positional = true - case key == "separate": - spec.separate = true - case key == "help": - spec.help = value - case key == "env": - // Use override name if provided - if value != "" { - spec.env = value - } else { - spec.env = strings.ToUpper(field.Name) - } - default: - errs = append(errs, fmt.Sprintf("unrecognized tag '%s' on field %s", key, tag)) - return false - } - } - } - p.spec = append(p.spec, &spec) - - // if this was an embedded field then we already returned true up above - return false - }) - - if len(errs) > 0 { - return nil, errors.New(strings.Join(errs, "\n")) - } - } - if p.config.Program == "" { - p.config.Program = "program" - if len(os.Args) > 0 { - p.config.Program = filepath.Base(os.Args[0]) - } - } - return &p, nil -} - -// Parse processes the given command line option, storing the results in the field -// of the structs from which NewParser was constructed -func (p *Parser) Parse(args []string) error { - // If -h or --help were specified then print usage - for _, arg := range args { - if arg == "-h" || arg == "--help" { - return ErrHelp - } - if arg == "--version" { - return ErrVersion - } - if arg == "--" { - break - } - } - - // Process all command line arguments - err := process(p.spec, args) - if err != nil { - return err - } - - // Validate - return validate(p.spec) -} - -// process goes through arguments one-by-one, parses them, and assigns the result to -// the underlying struct field -func process(specs []*spec, args []string) error { - // construct a map from --option to spec - optionMap := make(map[string]*spec) - for _, spec := range specs { - if spec.positional { - continue - } - if spec.long != "" { - optionMap[spec.long] = spec - } - if spec.short != "" { - optionMap[spec.short] = spec - } - if spec.env != "" { - if value, found := os.LookupEnv(spec.env); found { - err := setScalar(spec.dest, value) - if err != nil { - return fmt.Errorf("error processing environment variable %s: %v", spec.env, err) - } - spec.wasPresent = true - } - } - } - - // process each string from the command line - var allpositional bool - var positionals []string - - // must use explicit for loop, not range, because we manipulate i inside the loop - for i := 0; i < len(args); i++ { - arg := args[i] - if arg == "--" { - allpositional = true - continue - } - - if !isFlag(arg) || allpositional { - positionals = append(positionals, arg) - continue - } - - // check for an equals sign, as in "--foo=bar" - var value string - opt := strings.TrimLeft(arg, "-") - if pos := strings.Index(opt, "="); pos != -1 { - value = opt[pos+1:] - opt = opt[:pos] - } - - // lookup the spec for this option - spec, ok := optionMap[opt] - if !ok { - return fmt.Errorf("unknown argument %s", arg) - } - spec.wasPresent = true - - // deal with the case of multiple values - if spec.multiple { - var values []string - if value == "" { - for i+1 < len(args) && !isFlag(args[i+1]) { - values = append(values, args[i+1]) - i++ - if spec.separate { - break - } - } - } else { - values = append(values, value) - } - err := setSlice(spec.dest, values, !spec.separate) - if err != nil { - return fmt.Errorf("error processing %s: %v", arg, err) - } - continue - } - - // if it's a flag and it has no value then set the value to true - // use boolean because this takes account of TextUnmarshaler - if spec.boolean && value == "" { - value = "true" - } - - // if we have something like "--foo" then the value is the next argument - if value == "" { - if i+1 == len(args) || isFlag(args[i+1]) { - return fmt.Errorf("missing value for %s", arg) - } - value = args[i+1] - i++ - } - - err := setScalar(spec.dest, value) - if err != nil { - return fmt.Errorf("error processing %s: %v", arg, err) - } - } - - // process positionals - for _, spec := range specs { - if spec.positional { - if spec.multiple { - err := setSlice(spec.dest, positionals, true) - if err != nil { - return fmt.Errorf("error processing %s: %v", spec.long, err) - } - positionals = nil - } else if len(positionals) > 0 { - err := setScalar(spec.dest, positionals[0]) - if err != nil { - return fmt.Errorf("error processing %s: %v", spec.long, err) - } - positionals = positionals[1:] - } else if spec.required { - return fmt.Errorf("%s is required", spec.long) - } - } - } - if len(positionals) > 0 { - return fmt.Errorf("too many positional arguments at '%s'", positionals[0]) - } - return nil -} - -// isFlag returns true if a token is a flag such as "-v" or "--user" but not "-" or "--" -func isFlag(s string) bool { - return strings.HasPrefix(s, "-") && strings.TrimLeft(s, "-") != "" -} - -// validate an argument spec after arguments have been parse -func validate(spec []*spec) error { - for _, arg := range spec { - if !arg.positional && arg.required && !arg.wasPresent { - return fmt.Errorf("--%s is required", arg.long) - } - } - return nil -} - -// parse a value as the appropriate type and store it in the struct -func setSlice(dest reflect.Value, values []string, trunc bool) error { - if !dest.CanSet() { - return fmt.Errorf("field is not writable") - } - - var ptr bool - elem := dest.Type().Elem() - if elem.Kind() == reflect.Ptr { - ptr = true - elem = elem.Elem() - } - - // Truncate the dest slice in case default values exist - if trunc && !dest.IsNil() { - dest.SetLen(0) - } - - for _, s := range values { - v := reflect.New(elem) - if err := setScalar(v.Elem(), s); err != nil { - return err - } - if !ptr { - v = v.Elem() - } - dest.Set(reflect.Append(dest, v)) - } - return nil -} - -// canParse returns true if the type can be parsed from a string -func canParse(t reflect.Type) (parseable, boolean, multiple bool) { - parseable, boolean = isScalar(t) - if parseable { - return - } - - // Look inside pointer types - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - // Look inside slice types - if t.Kind() == reflect.Slice { - multiple = true - t = t.Elem() - } - - parseable, boolean = isScalar(t) - if parseable { - return - } - - // Look inside pointer types (again, in case of []*Type) - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - - parseable, boolean = isScalar(t) - if parseable { - return - } - - return false, false, false -} - -var textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem() - -// isScalar returns true if the type can be parsed from a single string -func isScalar(t reflect.Type) (parseable, boolean bool) { - parseable = scalar.CanParse(t) - switch { - case t.Implements(textUnmarshalerType): - return parseable, false - case t.Kind() == reflect.Bool: - return parseable, true - case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Bool: - return parseable, true - default: - return parseable, false - } -} - -// set a value from a string -func setScalar(v reflect.Value, s string) error { - return scalar.ParseValue(v, s) -} diff --git a/vendor/github.com/alexflint/go-arg/usage.go b/vendor/github.com/alexflint/go-arg/usage.go deleted file mode 100644 index bf7fb83..0000000 --- a/vendor/github.com/alexflint/go-arg/usage.go +++ /dev/null @@ -1,142 +0,0 @@ -package arg - -import ( - "fmt" - "io" - "os" - "reflect" - "strings" -) - -// the width of the left column -const colWidth = 25 - -// Fail prints usage information to stderr and exits with non-zero status -func (p *Parser) Fail(msg string) { - p.WriteUsage(os.Stderr) - fmt.Fprintln(os.Stderr, "error:", msg) - os.Exit(-1) -} - -// WriteUsage writes usage information to the given writer -func (p *Parser) WriteUsage(w io.Writer) { - var positionals, options []*spec - for _, spec := range p.spec { - if spec.positional { - positionals = append(positionals, spec) - } else { - options = append(options, spec) - } - } - - if p.version != "" { - fmt.Fprintln(w, p.version) - } - - fmt.Fprintf(w, "Usage: %s", p.config.Program) - - // write the option component of the usage message - for _, spec := range options { - // prefix with a space - fmt.Fprint(w, " ") - if !spec.required { - fmt.Fprint(w, "[") - } - fmt.Fprint(w, synopsis(spec, "--"+spec.long)) - if !spec.required { - fmt.Fprint(w, "]") - } - } - - // write the positional component of the usage message - for _, spec := range positionals { - // prefix with a space - fmt.Fprint(w, " ") - up := strings.ToUpper(spec.long) - if spec.multiple { - fmt.Fprintf(w, "[%s [%s ...]]", up, up) - } else { - fmt.Fprint(w, up) - } - } - fmt.Fprint(w, "\n") -} - -// WriteHelp writes the usage string followed by the full help string for each option -func (p *Parser) WriteHelp(w io.Writer) { - var positionals, options []*spec - for _, spec := range p.spec { - if spec.positional { - positionals = append(positionals, spec) - } else { - options = append(options, spec) - } - } - - if p.description != "" { - fmt.Fprintln(w, p.description) - } - p.WriteUsage(w) - - // write the list of positionals - if len(positionals) > 0 { - fmt.Fprint(w, "\nPositional arguments:\n") - for _, spec := range positionals { - left := " " + strings.ToUpper(spec.long) - fmt.Fprint(w, left) - if spec.help != "" { - if len(left)+2 < colWidth { - fmt.Fprint(w, strings.Repeat(" ", colWidth-len(left))) - } else { - fmt.Fprint(w, "\n"+strings.Repeat(" ", colWidth)) - } - fmt.Fprint(w, spec.help) - } - fmt.Fprint(w, "\n") - } - } - - // write the list of options - fmt.Fprint(w, "\nOptions:\n") - for _, spec := range options { - printOption(w, spec) - } - - // write the list of built in options - printOption(w, &spec{boolean: true, long: "help", short: "h", help: "display this help and exit"}) - if p.version != "" { - printOption(w, &spec{boolean: true, long: "version", help: "display version and exit"}) - } -} - -func printOption(w io.Writer, spec *spec) { - left := " " + synopsis(spec, "--"+spec.long) - if spec.short != "" { - left += ", " + synopsis(spec, "-"+spec.short) - } - fmt.Fprint(w, left) - if spec.help != "" { - if len(left)+2 < colWidth { - fmt.Fprint(w, strings.Repeat(" ", colWidth-len(left))) - } else { - fmt.Fprint(w, "\n"+strings.Repeat(" ", colWidth)) - } - fmt.Fprint(w, spec.help) - } - // If spec.dest is not the zero value then a default value has been added. - v := spec.dest - if v.IsValid() { - z := reflect.Zero(v.Type()) - if (v.Type().Comparable() && z.Type().Comparable() && v.Interface() != z.Interface()) || v.Kind() == reflect.Slice && !v.IsNil() { - fmt.Fprintf(w, " [default: %v]", v) - } - } - fmt.Fprint(w, "\n") -} - -func synopsis(spec *spec, form string) string { - if spec.boolean { - return form - } - return form + " " + strings.ToUpper(spec.long) -} diff --git a/vendor/github.com/alexflint/go-scalar/LICENSE b/vendor/github.com/alexflint/go-scalar/LICENSE deleted file mode 100644 index a50c494..0000000 --- a/vendor/github.com/alexflint/go-scalar/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2015, Alex Flint -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/alexflint/go-scalar/README.md b/vendor/github.com/alexflint/go-scalar/README.md deleted file mode 100644 index e6f510e..0000000 --- a/vendor/github.com/alexflint/go-scalar/README.md +++ /dev/null @@ -1,28 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/alexflint/go-scalar?status.svg)](https://godoc.org/github.com/alexflint/go-scalar) -[![Build Status](https://travis-ci.org/alexflint/go-scalar.svg?branch=master)](https://travis-ci.org/alexflint/go-scalar) -[![Coverage Status](https://coveralls.io/repos/alexflint/go-scalar/badge.svg?branch=master&service=github)](https://coveralls.io/github/alexflint/go-scalar?branch=master) -[![Report Card](https://goreportcard.com/badge/github.com/alexflint/go-scalar)](https://goreportcard.com/badge/github.com/alexflint/go-scalar) - -## Scalar parsing library - -Scalar is a library for parsing strings into arbitrary scalars (integers, -floats, strings, booleans, etc). It is helpful for tasks such as parsing -strings passed as environment variables or command line arguments. - -```shell -go get github.com/alexflint/go-scalar -``` - -The main API works as follows: - -```go -var value int -err := scalar.Parse(&value, "123") -``` - -There is also a variant that takes a `reflect.Value`: - -```go -var value int -err := scalar.ParseValue(reflect.ValueOf(&value), "123") -``` diff --git a/vendor/github.com/alexflint/go-scalar/scalar.go b/vendor/github.com/alexflint/go-scalar/scalar.go deleted file mode 100644 index 663f143..0000000 --- a/vendor/github.com/alexflint/go-scalar/scalar.go +++ /dev/null @@ -1,154 +0,0 @@ -// Package scalar parses strings into values of scalar type. - -package scalar - -import ( - "encoding" - "errors" - "fmt" - "net" - "net/mail" - "reflect" - "strconv" - "time" -) - -// The reflected form of some special types -var ( - textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem() - durationType = reflect.TypeOf(time.Duration(0)) - mailAddressType = reflect.TypeOf(mail.Address{}) - ipType = reflect.TypeOf(net.IP{}) - macType = reflect.TypeOf(net.HardwareAddr{}) -) - -var ( - errNotSettable = errors.New("value is not settable") - errPtrNotSettable = errors.New("value is a nil pointer and is not settable") -) - -// Parse assigns a value to v by parsing s. -func Parse(dest interface{}, s string) error { - return ParseValue(reflect.ValueOf(dest), s) -} - -// ParseValue assigns a value to v by parsing s. -func ParseValue(v reflect.Value, s string) error { - // If we have a nil pointer then allocate a new object - if v.Kind() == reflect.Ptr && v.IsNil() { - if !v.CanSet() { - return errPtrNotSettable - } - - v.Set(reflect.New(v.Type().Elem())) - } - - // If it implements encoding.TextUnmarshaler then use that - if scalar, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return scalar.UnmarshalText([]byte(s)) - } - - // If we have a pointer then dereference it - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - if !v.CanSet() { - return errNotSettable - } - - // Switch on concrete type - switch scalar := v.Interface(); scalar.(type) { - case time.Duration: - duration, err := time.ParseDuration(s) - if err != nil { - return err - } - v.Set(reflect.ValueOf(duration)) - return nil - case mail.Address: - addr, err := mail.ParseAddress(s) - if err != nil { - return err - } - v.Set(reflect.ValueOf(*addr)) - return nil - case net.IP: - ip := net.ParseIP(s) - if ip == nil { - return fmt.Errorf(`invalid IP address: "%s"`, s) - } - v.Set(reflect.ValueOf(ip)) - return nil - case net.HardwareAddr: - ip, err := net.ParseMAC(s) - if err != nil { - return err - } - v.Set(reflect.ValueOf(ip)) - return nil - } - - // Switch on kind so that we can handle derived types - switch v.Kind() { - case reflect.String: - v.SetString(s) - case reflect.Bool: - x, err := strconv.ParseBool(s) - if err != nil { - return err - } - v.SetBool(x) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - x, err := strconv.ParseInt(s, 10, v.Type().Bits()) - if err != nil { - return err - } - v.SetInt(x) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - x, err := strconv.ParseUint(s, 10, v.Type().Bits()) - if err != nil { - return err - } - v.SetUint(x) - case reflect.Float32, reflect.Float64: - x, err := strconv.ParseFloat(s, v.Type().Bits()) - if err != nil { - return err - } - v.SetFloat(x) - default: - return fmt.Errorf("cannot parse into %v", v.Type()) - } - return nil -} - -// CanParse returns true if the type can be parsed from a string. -func CanParse(t reflect.Type) bool { - // If it implements encoding.TextUnmarshaler then use that - if t.Implements(textUnmarshalerType) { - return true - } - - // If we have a pointer then dereference it - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - - // Check for other special types - switch t { - case durationType, mailAddressType, ipType, macType: - return true - } - - // Fall back to checking the kind - switch t.Kind() { - case reflect.Bool: - return true - case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Float32, reflect.Float64: - return true - } - return false -} diff --git a/vendor/github.com/go-kit/kit/LICENSE b/vendor/github.com/go-kit/kit/LICENSE deleted file mode 100644 index 9d83342..0000000 --- a/vendor/github.com/go-kit/kit/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Peter Bourgon - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/github.com/go-kit/kit/log/README.md b/vendor/github.com/go-kit/kit/log/README.md deleted file mode 100644 index 7222f80..0000000 --- a/vendor/github.com/go-kit/kit/log/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# package log - -`package log` provides a minimal interface for structured logging in services. -It may be wrapped to encode conventions, enforce type-safety, provide leveled -logging, and so on. It can be used for both typical application log events, -and log-structured data streams. - -## Structured logging - -Structured logging is, basically, conceding to the reality that logs are -_data_, and warrant some level of schematic rigor. Using a stricter, -key/value-oriented message format for our logs, containing contextual and -semantic information, makes it much easier to get insight into the -operational activity of the systems we build. Consequently, `package log` is -of the strong belief that "[the benefits of structured logging outweigh the -minimal effort involved](https://www.thoughtworks.com/radar/techniques/structured-logging)". - -Migrating from unstructured to structured logging is probably a lot easier -than you'd expect. - -```go -// Unstructured -log.Printf("HTTP server listening on %s", addr) - -// Structured -logger.Log("transport", "HTTP", "addr", addr, "msg", "listening") -``` - -## Usage - -### Typical application logging - -```go -w := log.NewSyncWriter(os.Stderr) -logger := log.NewLogfmtLogger(w) -logger.Log("question", "what is the meaning of life?", "answer", 42) - -// Output: -// question="what is the meaning of life?" answer=42 -``` - -### Contextual Loggers - -```go -func main() { - var logger log.Logger - logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) - logger = log.With(logger, "instance_id", 123) - - logger.Log("msg", "starting") - NewWorker(log.With(logger, "component", "worker")).Run() - NewSlacker(log.With(logger, "component", "slacker")).Run() -} - -// Output: -// instance_id=123 msg=starting -// instance_id=123 component=worker msg=running -// instance_id=123 component=slacker msg=running -``` - -### Interact with stdlib logger - -Redirect stdlib logger to Go kit logger. - -```go -import ( - "os" - stdlog "log" - kitlog "github.com/go-kit/kit/log" -) - -func main() { - logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout)) - stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) - stdlog.Print("I sure like pie") -} - -// Output: -// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"} -``` - -Or, if, for legacy reasons, you need to pipe all of your logging through the -stdlib log package, you can redirect Go kit logger to the stdlib logger. - -```go -logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{}) -logger.Log("legacy", true, "msg", "at least it's something") - -// Output: -// 2016/01/01 12:34:56 legacy=true msg="at least it's something" -``` - -### Timestamps and callers - -```go -var logger log.Logger -logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) -logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) - -logger.Log("msg", "hello") - -// Output: -// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello -``` - -## Supported output formats - -- [Logfmt](https://brandur.org/logfmt) ([see also](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write)) -- JSON - -## Enhancements - -`package log` is centered on the one-method Logger interface. - -```go -type Logger interface { - Log(keyvals ...interface{}) error -} -``` - -This interface, and its supporting code like is the product of much iteration -and evaluation. For more details on the evolution of the Logger interface, -see [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1), -a talk by [Chris Hines](https://github.com/ChrisHines). -Also, please see -[#63](https://github.com/go-kit/kit/issues/63), -[#76](https://github.com/go-kit/kit/pull/76), -[#131](https://github.com/go-kit/kit/issues/131), -[#157](https://github.com/go-kit/kit/pull/157), -[#164](https://github.com/go-kit/kit/issues/164), and -[#252](https://github.com/go-kit/kit/pull/252) -to review historical conversations about package log and the Logger interface. - -Value-add packages and suggestions, -like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/kit/log/level), -are of course welcome. Good proposals should - -- Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/kit/log#With), -- Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/kit/log#Caller) in any wrapped contextual loggers, and -- Be friendly to packages that accept only an unadorned log.Logger. - -## Benchmarks & comparisons - -There are a few Go logging benchmarks and comparisons that include Go kit's package log. - -- [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) includes kit/log -- [uber-common/zap](https://github.com/uber-common/zap), a zero-alloc logging library, includes a comparison with kit/log diff --git a/vendor/github.com/go-kit/kit/log/cover.coverprofile b/vendor/github.com/go-kit/kit/log/cover.coverprofile deleted file mode 100644 index 19e714c..0000000 --- a/vendor/github.com/go-kit/kit/log/cover.coverprofile +++ /dev/null @@ -1,123 +0,0 @@ -mode: set -github.com/go-kit/kit/log/logfmt_logger.go:16.33,19.2 2 1 -github.com/go-kit/kit/log/logfmt_logger.go:22.26,26.3 3 1 -github.com/go-kit/kit/log/logfmt_logger.go:37.42,39.2 1 1 -github.com/go-kit/kit/log/logfmt_logger.go:41.57,46.54 4 1 -github.com/go-kit/kit/log/logfmt_logger.go:51.2,51.40 1 1 -github.com/go-kit/kit/log/logfmt_logger.go:58.2,58.54 1 1 -github.com/go-kit/kit/log/logfmt_logger.go:61.2,61.12 1 1 -github.com/go-kit/kit/log/logfmt_logger.go:46.54,48.3 1 0 -github.com/go-kit/kit/log/logfmt_logger.go:51.40,53.3 1 0 -github.com/go-kit/kit/log/logfmt_logger.go:58.54,60.3 1 0 -github.com/go-kit/kit/log/nop_logger.go:6.28,6.50 1 1 -github.com/go-kit/kit/log/nop_logger.go:8.44,8.58 1 1 -github.com/go-kit/kit/log/stdlib.go:19.52,22.2 2 1 -github.com/go-kit/kit/log/stdlib.go:38.51,39.32 1 0 -github.com/go-kit/kit/log/stdlib.go:39.32,39.56 1 0 -github.com/go-kit/kit/log/stdlib.go:43.46,44.32 1 0 -github.com/go-kit/kit/log/stdlib.go:44.32,44.51 1 0 -github.com/go-kit/kit/log/stdlib.go:48.49,49.32 1 0 -github.com/go-kit/kit/log/stdlib.go:49.32,49.54 1 0 -github.com/go-kit/kit/log/stdlib.go:54.80,61.33 2 1 -github.com/go-kit/kit/log/stdlib.go:64.2,64.10 1 1 -github.com/go-kit/kit/log/stdlib.go:61.33,63.3 1 0 -github.com/go-kit/kit/log/stdlib.go:67.53,71.50 4 1 -github.com/go-kit/kit/log/stdlib.go:74.2,74.50 1 1 -github.com/go-kit/kit/log/stdlib.go:80.2,80.21 1 1 -github.com/go-kit/kit/log/stdlib.go:83.2,83.50 1 1 -github.com/go-kit/kit/log/stdlib.go:86.2,86.34 1 1 -github.com/go-kit/kit/log/stdlib.go:89.2,89.49 1 1 -github.com/go-kit/kit/log/stdlib.go:92.2,92.20 1 1 -github.com/go-kit/kit/log/stdlib.go:71.50,73.3 1 1 -github.com/go-kit/kit/log/stdlib.go:74.50,75.22 1 1 -github.com/go-kit/kit/log/stdlib.go:78.3,78.20 1 1 -github.com/go-kit/kit/log/stdlib.go:75.22,77.4 1 1 -github.com/go-kit/kit/log/stdlib.go:80.21,82.3 1 1 -github.com/go-kit/kit/log/stdlib.go:83.50,85.3 1 1 -github.com/go-kit/kit/log/stdlib.go:86.34,88.3 1 1 -github.com/go-kit/kit/log/stdlib.go:89.49,91.3 1 0 -github.com/go-kit/kit/log/stdlib.go:106.45,108.43 2 1 -github.com/go-kit/kit/log/stdlib.go:111.2,112.47 2 1 -github.com/go-kit/kit/log/stdlib.go:115.2,115.15 1 1 -github.com/go-kit/kit/log/stdlib.go:108.43,110.3 1 0 -github.com/go-kit/kit/log/stdlib.go:112.47,114.3 1 1 -github.com/go-kit/kit/log/sync.go:25.56,27.28 2 1 -github.com/go-kit/kit/log/sync.go:30.2,30.26 1 1 -github.com/go-kit/kit/log/sync.go:27.28,29.3 1 1 -github.com/go-kit/kit/log/sync.go:35.42,37.2 1 1 -github.com/go-kit/kit/log/sync.go:49.43,50.23 1 1 -github.com/go-kit/kit/log/sync.go:51.16,52.36 1 1 -github.com/go-kit/kit/log/sync.go:53.10,54.32 1 1 -github.com/go-kit/kit/log/sync.go:66.57,71.2 4 1 -github.com/go-kit/kit/log/sync.go:88.59,93.2 4 1 -github.com/go-kit/kit/log/sync.go:105.42,107.2 1 1 -github.com/go-kit/kit/log/sync.go:111.56,116.2 4 1 -github.com/go-kit/kit/log/value.go:16.40,17.39 1 1 -github.com/go-kit/kit/log/value.go:17.39,18.39 1 1 -github.com/go-kit/kit/log/value.go:18.39,20.4 1 1 -github.com/go-kit/kit/log/value.go:26.49,27.39 1 1 -github.com/go-kit/kit/log/value.go:32.2,32.14 1 1 -github.com/go-kit/kit/log/value.go:27.39,28.39 1 1 -github.com/go-kit/kit/log/value.go:28.39,30.4 1 1 -github.com/go-kit/kit/log/value.go:40.43,41.28 1 1 -github.com/go-kit/kit/log/value.go:41.28,41.42 1 1 -github.com/go-kit/kit/log/value.go:51.64,52.28 1 1 -github.com/go-kit/kit/log/value.go:52.28,57.3 1 1 -github.com/go-kit/kit/log/value.go:67.38,69.2 1 1 -github.com/go-kit/kit/log/value.go:72.61,79.2 3 1 -github.com/go-kit/kit/log/value.go:83.31,84.28 1 1 -github.com/go-kit/kit/log/value.go:84.28,84.58 1 1 -github.com/go-kit/kit/log/value.go:95.20,95.47 1 0 -github.com/go-kit/kit/log/json_logger.go:19.40,21.2 1 1 -github.com/go-kit/kit/log/json_logger.go:23.56,26.39 3 1 -github.com/go-kit/kit/log/json_logger.go:34.2,34.44 1 1 -github.com/go-kit/kit/log/json_logger.go:26.39,29.25 3 1 -github.com/go-kit/kit/log/json_logger.go:32.3,32.17 1 1 -github.com/go-kit/kit/log/json_logger.go:29.25,31.4 1 1 -github.com/go-kit/kit/log/json_logger.go:37.58,39.23 2 1 -github.com/go-kit/kit/log/json_logger.go:47.2,47.28 1 1 -github.com/go-kit/kit/log/json_logger.go:54.2,54.23 1 1 -github.com/go-kit/kit/log/json_logger.go:63.2,63.14 1 1 -github.com/go-kit/kit/log/json_logger.go:40.14,41.10 1 1 -github.com/go-kit/kit/log/json_logger.go:42.20,43.22 1 1 -github.com/go-kit/kit/log/json_logger.go:44.10,45.22 1 0 -github.com/go-kit/kit/log/json_logger.go:47.28,49.3 1 1 -github.com/go-kit/kit/log/json_logger.go:55.22,55.22 0 1 -github.com/go-kit/kit/log/json_logger.go:56.30,56.30 0 1 -github.com/go-kit/kit/log/json_logger.go:57.13,58.19 1 0 -github.com/go-kit/kit/log/json_logger.go:59.20,60.20 1 1 -github.com/go-kit/kit/log/json_logger.go:66.46,67.15 1 1 -github.com/go-kit/kit/log/json_logger.go:76.2,77.8 2 1 -github.com/go-kit/kit/log/json_logger.go:67.15,68.45 1 1 -github.com/go-kit/kit/log/json_logger.go:68.45,69.71 1 1 -github.com/go-kit/kit/log/json_logger.go:69.71,71.5 1 1 -github.com/go-kit/kit/log/json_logger.go:71.5,72.20 1 0 -github.com/go-kit/kit/log/json_logger.go:80.43,81.15 1 1 -github.com/go-kit/kit/log/json_logger.go:90.2,91.8 2 1 -github.com/go-kit/kit/log/json_logger.go:81.15,82.45 1 1 -github.com/go-kit/kit/log/json_logger.go:82.45,83.71 1 1 -github.com/go-kit/kit/log/json_logger.go:83.71,85.5 1 1 -github.com/go-kit/kit/log/json_logger.go:85.5,86.20 1 0 -github.com/go-kit/kit/log/log.go:24.57,25.23 1 1 -github.com/go-kit/kit/log/log.go:28.2,30.21 3 1 -github.com/go-kit/kit/log/log.go:33.2,41.3 1 1 -github.com/go-kit/kit/log/log.go:25.23,27.3 1 1 -github.com/go-kit/kit/log/log.go:30.21,32.3 1 1 -github.com/go-kit/kit/log/log.go:50.63,51.23 1 1 -github.com/go-kit/kit/log/log.go:54.2,60.25 3 1 -github.com/go-kit/kit/log/log.go:63.2,65.21 3 1 -github.com/go-kit/kit/log/log.go:68.2,73.3 2 1 -github.com/go-kit/kit/log/log.go:51.23,53.3 1 0 -github.com/go-kit/kit/log/log.go:60.25,62.3 1 1 -github.com/go-kit/kit/log/log.go:65.21,67.3 1 1 -github.com/go-kit/kit/log/log.go:101.41,102.36 1 1 -github.com/go-kit/kit/log/log.go:105.2,105.33 1 1 -github.com/go-kit/kit/log/log.go:102.36,104.3 1 1 -github.com/go-kit/kit/log/log.go:111.53,113.21 2 1 -github.com/go-kit/kit/log/log.go:116.2,116.17 1 1 -github.com/go-kit/kit/log/log.go:124.2,124.29 1 1 -github.com/go-kit/kit/log/log.go:113.21,115.3 1 1 -github.com/go-kit/kit/log/log.go:116.17,119.24 1 1 -github.com/go-kit/kit/log/log.go:122.3,122.35 1 1 -github.com/go-kit/kit/log/log.go:119.24,121.4 1 1 -github.com/go-kit/kit/log/log.go:133.55,135.2 1 1 diff --git a/vendor/github.com/go-kit/kit/log/doc.go b/vendor/github.com/go-kit/kit/log/doc.go deleted file mode 100644 index 918c0af..0000000 --- a/vendor/github.com/go-kit/kit/log/doc.go +++ /dev/null @@ -1,116 +0,0 @@ -// Package log provides a structured logger. -// -// Structured logging produces logs easily consumed later by humans or -// machines. Humans might be interested in debugging errors, or tracing -// specific requests. Machines might be interested in counting interesting -// events, or aggregating information for off-line processing. In both cases, -// it is important that the log messages are structured and actionable. -// Package log is designed to encourage both of these best practices. -// -// Basic Usage -// -// The fundamental interface is Logger. Loggers create log events from -// key/value data. The Logger interface has a single method, Log, which -// accepts a sequence of alternating key/value pairs, which this package names -// keyvals. -// -// type Logger interface { -// Log(keyvals ...interface{}) error -// } -// -// Here is an example of a function using a Logger to create log events. -// -// func RunTask(task Task, logger log.Logger) string { -// logger.Log("taskID", task.ID, "event", "starting task") -// ... -// logger.Log("taskID", task.ID, "event", "task complete") -// } -// -// The keys in the above example are "taskID" and "event". The values are -// task.ID, "starting task", and "task complete". Every key is followed -// immediately by its value. -// -// Keys are usually plain strings. Values may be any type that has a sensible -// encoding in the chosen log format. With structured logging it is a good -// idea to log simple values without formatting them. This practice allows -// the chosen logger to encode values in the most appropriate way. -// -// Contextual Loggers -// -// A contextual logger stores keyvals that it includes in all log events. -// Building appropriate contextual loggers reduces repetition and aids -// consistency in the resulting log output. With and WithPrefix add context to -// a logger. We can use With to improve the RunTask example. -// -// func RunTask(task Task, logger log.Logger) string { -// logger = log.With(logger, "taskID", task.ID) -// logger.Log("event", "starting task") -// ... -// taskHelper(task.Cmd, logger) -// ... -// logger.Log("event", "task complete") -// } -// -// The improved version emits the same log events as the original for the -// first and last calls to Log. Passing the contextual logger to taskHelper -// enables each log event created by taskHelper to include the task.ID even -// though taskHelper does not have access to that value. Using contextual -// loggers this way simplifies producing log output that enables tracing the -// life cycle of individual tasks. (See the Contextual example for the full -// code of the above snippet.) -// -// Dynamic Contextual Values -// -// A Valuer function stored in a contextual logger generates a new value each -// time an event is logged. The Valuer example demonstrates how this feature -// works. -// -// Valuers provide the basis for consistently logging timestamps and source -// code location. The log package defines several valuers for that purpose. -// See Timestamp, DefaultTimestamp, DefaultTimestampUTC, Caller, and -// DefaultCaller. A common logger initialization sequence that ensures all log -// entries contain a timestamp and source location looks like this: -// -// logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) -// logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) -// -// Concurrent Safety -// -// Applications with multiple goroutines want each log event written to the -// same logger to remain separate from other log events. Package log provides -// two simple solutions for concurrent safe logging. -// -// NewSyncWriter wraps an io.Writer and serializes each call to its Write -// method. Using a SyncWriter has the benefit that the smallest practical -// portion of the logging logic is performed within a mutex, but it requires -// the formatting Logger to make only one call to Write per log event. -// -// NewSyncLogger wraps any Logger and serializes each call to its Log method. -// Using a SyncLogger has the benefit that it guarantees each log event is -// handled atomically within the wrapped logger, but it typically serializes -// both the formatting and output logic. Use a SyncLogger if the formatting -// logger may perform multiple writes per log event. -// -// Error Handling -// -// This package relies on the practice of wrapping or decorating loggers with -// other loggers to provide composable pieces of functionality. It also means -// that Logger.Log must return an error because some -// implementations—especially those that output log data to an io.Writer—may -// encounter errors that cannot be handled locally. This in turn means that -// Loggers that wrap other loggers should return errors from the wrapped -// logger up the stack. -// -// Fortunately, the decorator pattern also provides a way to avoid the -// necessity to check for errors every time an application calls Logger.Log. -// An application required to panic whenever its Logger encounters -// an error could initialize its logger as follows. -// -// fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) -// logger := log.LoggerFunc(func(keyvals ...interface{}) error { -// if err := fmtlogger.Log(keyvals...); err != nil { -// panic(err) -// } -// return nil -// }) -package log diff --git a/vendor/github.com/go-kit/kit/log/json_logger.go b/vendor/github.com/go-kit/kit/log/json_logger.go deleted file mode 100644 index 231e099..0000000 --- a/vendor/github.com/go-kit/kit/log/json_logger.go +++ /dev/null @@ -1,92 +0,0 @@ -package log - -import ( - "encoding" - "encoding/json" - "fmt" - "io" - "reflect" -) - -type jsonLogger struct { - io.Writer -} - -// NewJSONLogger returns a Logger that encodes keyvals to the Writer as a -// single JSON object. Each log event produces no more than one call to -// w.Write. The passed Writer must be safe for concurrent use by multiple -// goroutines if the returned Logger will be used concurrently. -func NewJSONLogger(w io.Writer) Logger { - return &jsonLogger{w} -} - -func (l *jsonLogger) Log(keyvals ...interface{}) error { - n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd - m := make(map[string]interface{}, n) - for i := 0; i < len(keyvals); i += 2 { - k := keyvals[i] - var v interface{} = ErrMissingValue - if i+1 < len(keyvals) { - v = keyvals[i+1] - } - merge(m, k, v) - } - return json.NewEncoder(l.Writer).Encode(m) -} - -func merge(dst map[string]interface{}, k, v interface{}) { - var key string - switch x := k.(type) { - case string: - key = x - case fmt.Stringer: - key = safeString(x) - default: - key = fmt.Sprint(x) - } - if x, ok := v.(error); ok { - v = safeError(x) - } - - // We want json.Marshaler and encoding.TextMarshaller to take priority over - // err.Error() and v.String(). But json.Marshall (called later) does that by - // default so we force a no-op if it's one of those 2 case. - switch x := v.(type) { - case json.Marshaler: - case encoding.TextMarshaler: - case error: - v = safeError(x) - case fmt.Stringer: - v = safeString(x) - } - - dst[key] = v -} - -func safeString(str fmt.Stringer) (s string) { - defer func() { - if panicVal := recover(); panicVal != nil { - if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() { - s = "NULL" - } else { - panic(panicVal) - } - } - }() - s = str.String() - return -} - -func safeError(err error) (s interface{}) { - defer func() { - if panicVal := recover(); panicVal != nil { - if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() { - s = nil - } else { - panic(panicVal) - } - } - }() - s = err.Error() - return -} diff --git a/vendor/github.com/go-kit/kit/log/level/cover.coverprofile b/vendor/github.com/go-kit/kit/log/level/cover.coverprofile deleted file mode 100644 index a7359f5..0000000 --- a/vendor/github.com/go-kit/kit/log/level/cover.coverprofile +++ /dev/null @@ -1,43 +0,0 @@ -mode: set -github.com/go-kit/kit/log/level/level.go:6.42,8.2 1 1 -github.com/go-kit/kit/log/level/level.go:11.41,13.2 1 1 -github.com/go-kit/kit/log/level/level.go:16.41,18.2 1 1 -github.com/go-kit/kit/log/level/level.go:21.42,23.2 1 1 -github.com/go-kit/kit/log/level/level.go:30.63,34.33 2 1 -github.com/go-kit/kit/log/level/level.go:37.2,37.10 1 1 -github.com/go-kit/kit/log/level/level.go:34.33,36.3 1 1 -github.com/go-kit/kit/log/level/level.go:48.52,50.39 2 1 -github.com/go-kit/kit/log/level/level.go:57.2,57.35 1 1 -github.com/go-kit/kit/log/level/level.go:60.2,60.31 1 1 -github.com/go-kit/kit/log/level/level.go:63.2,63.31 1 1 -github.com/go-kit/kit/log/level/level.go:50.39,51.44 1 1 -github.com/go-kit/kit/log/level/level.go:51.44,54.9 3 1 -github.com/go-kit/kit/log/level/level.go:57.35,59.3 1 1 -github.com/go-kit/kit/log/level/level.go:60.31,62.3 1 1 -github.com/go-kit/kit/log/level/level.go:70.24,72.2 1 1 -github.com/go-kit/kit/log/level/level.go:75.26,77.2 1 1 -github.com/go-kit/kit/log/level/level.go:80.25,82.2 1 1 -github.com/go-kit/kit/log/level/level.go:85.25,87.2 1 1 -github.com/go-kit/kit/log/level/level.go:90.26,92.2 1 1 -github.com/go-kit/kit/log/level/level.go:95.25,97.2 1 1 -github.com/go-kit/kit/log/level/level.go:99.36,100.25 1 1 -github.com/go-kit/kit/log/level/level.go:100.25,100.48 1 1 -github.com/go-kit/kit/log/level/level.go:107.38,108.25 1 1 -github.com/go-kit/kit/log/level/level.go:108.25,108.50 1 1 -github.com/go-kit/kit/log/level/level.go:115.42,116.25 1 1 -github.com/go-kit/kit/log/level/level.go:116.25,116.55 1 1 -github.com/go-kit/kit/log/level/level.go:122.35,123.25 1 1 -github.com/go-kit/kit/log/level/level.go:123.25,123.47 1 1 -github.com/go-kit/kit/log/level/level.go:129.59,134.2 1 1 -github.com/go-kit/kit/log/level/level.go:141.54,142.39 1 1 -github.com/go-kit/kit/log/level/level.go:147.2,150.27 4 1 -github.com/go-kit/kit/log/level/level.go:142.39,143.44 1 1 -github.com/go-kit/kit/log/level/level.go:143.44,145.4 1 1 -github.com/go-kit/kit/log/level/level.go:164.24,164.38 1 1 -github.com/go-kit/kit/log/level/level.go:169.28,169.39 1 0 -github.com/go-kit/kit/log/level/level.go:172.25,172.46 1 1 -github.com/go-kit/kit/log/level/level.go:175.24,175.44 1 1 -github.com/go-kit/kit/log/level/level.go:178.24,178.44 1 1 -github.com/go-kit/kit/log/level/level.go:181.25,181.46 1 1 -github.com/go-kit/kit/log/level/level.go:209.38,209.55 1 1 -github.com/go-kit/kit/log/level/level.go:210.38,210.40 0 0 diff --git a/vendor/github.com/go-kit/kit/log/level/doc.go b/vendor/github.com/go-kit/kit/log/level/doc.go deleted file mode 100644 index 5e9df7f..0000000 --- a/vendor/github.com/go-kit/kit/log/level/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// Package level implements leveled logging on top of package log. To use the -// level package, create a logger as per normal in your func main, and wrap it -// with level.NewFilter. -// -// var logger log.Logger -// logger = log.NewLogfmtLogger(os.Stderr) -// logger = level.NewFilter(logger, level.AllowInfoAndAbove()) // <-- -// logger = log.With(logger, "ts", log.DefaultTimestampUTC) -// -// Then, at the callsites, use one of the level.Debug, Info, Warn, or Error -// helper methods to emit leveled log events. -// -// logger.Log("foo", "bar") // as normal, no level -// level.Debug(logger).Log("request_id", reqID, "trace_data", trace.Get()) -// if value > 100 { -// level.Error(logger).Log("value", value) -// } -// -// NewFilter allows precise control over what happens when a log event is -// emitted without a level key, or if a squelched level is used. Check the -// Option functions for details. -package level diff --git a/vendor/github.com/go-kit/kit/log/level/level.go b/vendor/github.com/go-kit/kit/log/level/level.go deleted file mode 100644 index cac0c76..0000000 --- a/vendor/github.com/go-kit/kit/log/level/level.go +++ /dev/null @@ -1,210 +0,0 @@ -package level - -import "github.com/go-kit/kit/log" - -// Error returns a logger that includes a Key/ErrorValue pair. -func Error(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), ErrorValue()) -} - -// Warn returns a logger that includes a Key/WarnValue pair. -func Warn(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), WarnValue()) -} - -// Info returns a logger that includes a Key/InfoValue pair. -func Info(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), InfoValue()) -} - -// Debug returns a logger that includes a Key/DebugValue pair. -func Debug(logger log.Logger) log.Logger { - return log.WithPrefix(logger, Key(), DebugValue()) -} - -// NewFilter wraps next and implements level filtering. See the commentary on -// the Option functions for a detailed description of how to configure levels. -// If no options are provided, all leveled log events created with Debug, -// Info, Warn or Error helper methods are squelched and non-leveled log -// events are passed to next unmodified. -func NewFilter(next log.Logger, options ...Option) log.Logger { - l := &logger{ - next: next, - } - for _, option := range options { - option(l) - } - return l -} - -type logger struct { - next log.Logger - allowed level - squelchNoLevel bool - errNotAllowed error - errNoLevel error -} - -func (l *logger) Log(keyvals ...interface{}) error { - var hasLevel, levelAllowed bool - for i := 1; i < len(keyvals); i += 2 { - if v, ok := keyvals[i].(*levelValue); ok { - hasLevel = true - levelAllowed = l.allowed&v.level != 0 - break - } - } - if !hasLevel && l.squelchNoLevel { - return l.errNoLevel - } - if hasLevel && !levelAllowed { - return l.errNotAllowed - } - return l.next.Log(keyvals...) -} - -// Option sets a parameter for the leveled logger. -type Option func(*logger) - -// AllowAll is an alias for AllowDebug. -func AllowAll() Option { - return AllowDebug() -} - -// AllowDebug allows error, warn, info and debug level log events to pass. -func AllowDebug() Option { - return allowed(levelError | levelWarn | levelInfo | levelDebug) -} - -// AllowInfo allows error, warn and info level log events to pass. -func AllowInfo() Option { - return allowed(levelError | levelWarn | levelInfo) -} - -// AllowWarn allows error and warn level log events to pass. -func AllowWarn() Option { - return allowed(levelError | levelWarn) -} - -// AllowError allows only error level log events to pass. -func AllowError() Option { - return allowed(levelError) -} - -// AllowNone allows no leveled log events to pass. -func AllowNone() Option { - return allowed(0) -} - -func allowed(allowed level) Option { - return func(l *logger) { l.allowed = allowed } -} - -// ErrNotAllowed sets the error to return from Log when it squelches a log -// event disallowed by the configured Allow[Level] option. By default, -// ErrNotAllowed is nil; in this case the log event is squelched with no -// error. -func ErrNotAllowed(err error) Option { - return func(l *logger) { l.errNotAllowed = err } -} - -// SquelchNoLevel instructs Log to squelch log events with no level, so that -// they don't proceed through to the wrapped logger. If SquelchNoLevel is set -// to true and a log event is squelched in this way, the error value -// configured with ErrNoLevel is returned to the caller. -func SquelchNoLevel(squelch bool) Option { - return func(l *logger) { l.squelchNoLevel = squelch } -} - -// ErrNoLevel sets the error to return from Log when it squelches a log event -// with no level. By default, ErrNoLevel is nil; in this case the log event is -// squelched with no error. -func ErrNoLevel(err error) Option { - return func(l *logger) { l.errNoLevel = err } -} - -// NewInjector wraps next and returns a logger that adds a Key/level pair to -// the beginning of log events that don't already contain a level. In effect, -// this gives a default level to logs without a level. -func NewInjector(next log.Logger, level Value) log.Logger { - return &injector{ - next: next, - level: level, - } -} - -type injector struct { - next log.Logger - level interface{} -} - -func (l *injector) Log(keyvals ...interface{}) error { - for i := 1; i < len(keyvals); i += 2 { - if _, ok := keyvals[i].(*levelValue); ok { - return l.next.Log(keyvals...) - } - } - kvs := make([]interface{}, len(keyvals)+2) - kvs[0], kvs[1] = key, l.level - copy(kvs[2:], keyvals) - return l.next.Log(kvs...) -} - -// Value is the interface that each of the canonical level values implement. -// It contains unexported methods that prevent types from other packages from -// implementing it and guaranteeing that NewFilter can distinguish the levels -// defined in this package from all other values. -type Value interface { - String() string - levelVal() -} - -// Key returns the unique key added to log events by the loggers in this -// package. -func Key() interface{} { return key } - -// SetKey sets the unique key added to log events by the loggers in this -// package. This is useful for situations where log aggregation -// uses e.g. severity and not level. -func SetKey(k interface{}) { key = k } - -// ErrorValue returns the unique value added to log events by Error. -func ErrorValue() Value { return errorValue } - -// WarnValue returns the unique value added to log events by Warn. -func WarnValue() Value { return warnValue } - -// InfoValue returns the unique value added to log events by Info. -func InfoValue() Value { return infoValue } - -// DebugValue returns the unique value added to log events by Warn. -func DebugValue() Value { return debugValue } - -var ( - // key is of type interfae{} so that it allocates once during package - // initialization and avoids allocating every type the value is added to a - // []interface{} later. - key interface{} = "level" - - errorValue = &levelValue{level: levelError, name: "error"} - warnValue = &levelValue{level: levelWarn, name: "warn"} - infoValue = &levelValue{level: levelInfo, name: "info"} - debugValue = &levelValue{level: levelDebug, name: "debug"} -) - -type level byte - -const ( - levelDebug level = 1 << iota - levelInfo - levelWarn - levelError -) - -type levelValue struct { - name string - level -} - -func (v *levelValue) String() string { return v.name } -func (v *levelValue) levelVal() {} diff --git a/vendor/github.com/go-kit/kit/log/log.go b/vendor/github.com/go-kit/kit/log/log.go deleted file mode 100644 index 66a9e2f..0000000 --- a/vendor/github.com/go-kit/kit/log/log.go +++ /dev/null @@ -1,135 +0,0 @@ -package log - -import "errors" - -// Logger is the fundamental interface for all log operations. Log creates a -// log event from keyvals, a variadic sequence of alternating keys and values. -// Implementations must be safe for concurrent use by multiple goroutines. In -// particular, any implementation of Logger that appends to keyvals or -// modifies or retains any of its elements must make a copy first. -type Logger interface { - Log(keyvals ...interface{}) error -} - -// ErrMissingValue is appended to keyvals slices with odd length to substitute -// the missing value. -var ErrMissingValue = errors.New("(MISSING)") - -// With returns a new contextual logger with keyvals prepended to those passed -// to calls to Log. If logger is also a contextual logger created by With or -// WithPrefix, keyvals is appended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func With(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - kvs := append(l.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - return &context{ - logger: l.logger, - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - keyvals: kvs[:len(kvs):len(kvs)], - hasValuer: l.hasValuer || containsValuer(keyvals), - } -} - -// WithPrefix returns a new contextual logger with keyvals prepended to those -// passed to calls to Log. If logger is also a contextual logger created by -// With or WithPrefix, keyvals is prepended to the existing context. -// -// The returned Logger replaces all value elements (odd indexes) containing a -// Valuer with their generated value for each call to its Log method. -func WithPrefix(logger Logger, keyvals ...interface{}) Logger { - if len(keyvals) == 0 { - return logger - } - l := newContext(logger) - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow in Log or With. - // Using the extra capacity without copying risks a data race that - // would violate the Logger interface contract. - n := len(l.keyvals) + len(keyvals) - if len(keyvals)%2 != 0 { - n++ - } - kvs := make([]interface{}, 0, n) - kvs = append(kvs, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - kvs = append(kvs, l.keyvals...) - return &context{ - logger: l.logger, - keyvals: kvs, - hasValuer: l.hasValuer || containsValuer(keyvals), - } -} - -// context is the Logger implementation returned by With and WithPrefix. It -// wraps a Logger and holds keyvals that it includes in all log events. Its -// Log method calls bindValues to generate values for each Valuer in the -// context keyvals. -// -// A context must always have the same number of stack frames between calls to -// its Log method and the eventual binding of Valuers to their value. This -// requirement comes from the functional requirement to allow a context to -// resolve application call site information for a Caller stored in the -// context. To do this we must be able to predict the number of logging -// functions on the stack when bindValues is called. -// -// Two implementation details provide the needed stack depth consistency. -// -// 1. newContext avoids introducing an additional layer when asked to -// wrap another context. -// 2. With and WithPrefix avoid introducing an additional layer by -// returning a newly constructed context with a merged keyvals rather -// than simply wrapping the existing context. -type context struct { - logger Logger - keyvals []interface{} - hasValuer bool -} - -func newContext(logger Logger) *context { - if c, ok := logger.(*context); ok { - return c - } - return &context{logger: logger} -} - -// Log replaces all value elements (odd indexes) containing a Valuer in the -// stored context with their generated value, appends keyvals, and passes the -// result to the wrapped Logger. -func (l *context) Log(keyvals ...interface{}) error { - kvs := append(l.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingValue) - } - if l.hasValuer { - // If no keyvals were appended above then we must copy l.keyvals so - // that future log events will reevaluate the stored Valuers. - if len(keyvals) == 0 { - kvs = append([]interface{}{}, l.keyvals...) - } - bindValues(kvs[:len(l.keyvals)]) - } - return l.logger.Log(kvs...) -} - -// LoggerFunc is an adapter to allow use of ordinary functions as Loggers. If -// f is a function with the appropriate signature, LoggerFunc(f) is a Logger -// object that calls f. -type LoggerFunc func(...interface{}) error - -// Log implements Logger by calling f(keyvals...). -func (f LoggerFunc) Log(keyvals ...interface{}) error { - return f(keyvals...) -} diff --git a/vendor/github.com/go-kit/kit/log/logfmt_logger.go b/vendor/github.com/go-kit/kit/log/logfmt_logger.go deleted file mode 100644 index a003052..0000000 --- a/vendor/github.com/go-kit/kit/log/logfmt_logger.go +++ /dev/null @@ -1,62 +0,0 @@ -package log - -import ( - "bytes" - "io" - "sync" - - "github.com/go-logfmt/logfmt" -) - -type logfmtEncoder struct { - *logfmt.Encoder - buf bytes.Buffer -} - -func (l *logfmtEncoder) Reset() { - l.Encoder.Reset() - l.buf.Reset() -} - -var logfmtEncoderPool = sync.Pool{ - New: func() interface{} { - var enc logfmtEncoder - enc.Encoder = logfmt.NewEncoder(&enc.buf) - return &enc - }, -} - -type logfmtLogger struct { - w io.Writer -} - -// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in -// logfmt format. Each log event produces no more than one call to w.Write. -// The passed Writer must be safe for concurrent use by multiple goroutines if -// the returned Logger will be used concurrently. -func NewLogfmtLogger(w io.Writer) Logger { - return &logfmtLogger{w} -} - -func (l logfmtLogger) Log(keyvals ...interface{}) error { - enc := logfmtEncoderPool.Get().(*logfmtEncoder) - enc.Reset() - defer logfmtEncoderPool.Put(enc) - - if err := enc.EncodeKeyvals(keyvals...); err != nil { - return err - } - - // Add newline to the end of the buffer - if err := enc.EndRecord(); err != nil { - return err - } - - // The Logger interface requires implementations to be safe for concurrent - // use by multiple goroutines. For this implementation that means making - // only one call to l.w.Write() for each call to Log. - if _, err := l.w.Write(enc.buf.Bytes()); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/go-kit/kit/log/nop_logger.go b/vendor/github.com/go-kit/kit/log/nop_logger.go deleted file mode 100644 index 1047d62..0000000 --- a/vendor/github.com/go-kit/kit/log/nop_logger.go +++ /dev/null @@ -1,8 +0,0 @@ -package log - -type nopLogger struct{} - -// NewNopLogger returns a logger that doesn't do anything. -func NewNopLogger() Logger { return nopLogger{} } - -func (nopLogger) Log(...interface{}) error { return nil } diff --git a/vendor/github.com/go-kit/kit/log/stdlib.go b/vendor/github.com/go-kit/kit/log/stdlib.go deleted file mode 100644 index ff96b5d..0000000 --- a/vendor/github.com/go-kit/kit/log/stdlib.go +++ /dev/null @@ -1,116 +0,0 @@ -package log - -import ( - "io" - "log" - "regexp" - "strings" -) - -// StdlibWriter implements io.Writer by invoking the stdlib log.Print. It's -// designed to be passed to a Go kit logger as the writer, for cases where -// it's necessary to redirect all Go kit log output to the stdlib logger. -// -// If you have any choice in the matter, you shouldn't use this. Prefer to -// redirect the stdlib log to the Go kit logger via NewStdlibAdapter. -type StdlibWriter struct{} - -// Write implements io.Writer. -func (w StdlibWriter) Write(p []byte) (int, error) { - log.Print(strings.TrimSpace(string(p))) - return len(p), nil -} - -// StdlibAdapter wraps a Logger and allows it to be passed to the stdlib -// logger's SetOutput. It will extract date/timestamps, filenames, and -// messages, and place them under relevant keys. -type StdlibAdapter struct { - Logger - timestampKey string - fileKey string - messageKey string -} - -// StdlibAdapterOption sets a parameter for the StdlibAdapter. -type StdlibAdapterOption func(*StdlibAdapter) - -// TimestampKey sets the key for the timestamp field. By default, it's "ts". -func TimestampKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.timestampKey = key } -} - -// FileKey sets the key for the file and line field. By default, it's "caller". -func FileKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.fileKey = key } -} - -// MessageKey sets the key for the actual log message. By default, it's "msg". -func MessageKey(key string) StdlibAdapterOption { - return func(a *StdlibAdapter) { a.messageKey = key } -} - -// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed -// logger. It's designed to be passed to log.SetOutput. -func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer { - a := StdlibAdapter{ - Logger: logger, - timestampKey: "ts", - fileKey: "caller", - messageKey: "msg", - } - for _, option := range options { - option(&a) - } - return a -} - -func (a StdlibAdapter) Write(p []byte) (int, error) { - result := subexps(p) - keyvals := []interface{}{} - var timestamp string - if date, ok := result["date"]; ok && date != "" { - timestamp = date - } - if time, ok := result["time"]; ok && time != "" { - if timestamp != "" { - timestamp += " " - } - timestamp += time - } - if timestamp != "" { - keyvals = append(keyvals, a.timestampKey, timestamp) - } - if file, ok := result["file"]; ok && file != "" { - keyvals = append(keyvals, a.fileKey, file) - } - if msg, ok := result["msg"]; ok { - keyvals = append(keyvals, a.messageKey, msg) - } - if err := a.Logger.Log(keyvals...); err != nil { - return 0, err - } - return len(p), nil -} - -const ( - logRegexpDate = `(?P[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?` - logRegexpTime = `(?P