From 5caa00277852f1c17b0a9cebe50586e6a1429488 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Oct 2018 17:21:51 +0200 Subject: [PATCH 1/4] Moving from drone to travis-ci --- .drone.yml | 23 ----------------------- .travis.yml | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 23 deletions(-) delete mode 100644 .drone.yml create mode 100644 .travis.yml diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index f38ea839f39..00000000000 --- a/.drone.yml +++ /dev/null @@ -1,23 +0,0 @@ -workspace: - base: /go - path: src/github.com/arduino/arduino-cli - -pipeline: - build: - image: golang:1.10 - environment: - - DEP_RELEASE_TAG=v0.5.0 - commands: - - go generate - # Tools install dep, golangci-lint - - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.10 - - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - # Check the dependency, the -skip-lock is useful because the version are not fixed but depends from the branch master of the libraries so they change very often - - dep check - # Check if the code is formatted - - $(exit $(go fmt ./... | wc -l)) - # Build - - golangci-lint run - - go build - - go test -timeout 20m -v ./... - secrets: [TEST_USERNAME, TEST_PASSWORD] diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..68add67b317 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +language: go + +go: + - 1.11.x + +before_install: + - go get -t -v ./... + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.10 + - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + +script: + - cd $GOPATH/src/github.com/arduino/arduino-cli + # Check the dependency, -skip-lock may be useful because the version are not fixed but depends + # from the branch master of the libraries so they change very often + - dep check + # Check if the code is formatted + - $(exit $(go fmt ./... | wc -l)) + # Run linter + - golangci-lint run + # Build and test + - go build + - go test -timeout 20m -v -coverprofile=coverage.txt -covermode=atomic ./... + +after_success: + - bash <(curl -s https://codecov.io/bash) From 6fb298cf0d23ca4272a59936ed2d7748f1774897 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Oct 2018 18:57:02 +0200 Subject: [PATCH 2/4] Updating checks for go1.11.1 --- .golangci.yml | 1 + .travis.yml | 2 +- arduino/cores/board_test.go | 176 ++++++++++++++++++------------------ 3 files changed, 90 insertions(+), 89 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index df3907ee38f..d8763c0b1d1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -21,6 +21,7 @@ linters-settings: linters: enable-all: true disable: + - gosec - deadcode - dupl - errcheck diff --git a/.travis.yml b/.travis.yml index 68add67b317..f9f24c59f11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ go: before_install: - go get -t -v ./... - - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.10 + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.10.2 - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh script: diff --git a/arduino/cores/board_test.go b/arduino/cores/board_test.go index 4447737077f..15e94e6e749 100644 --- a/arduino/cores/board_test.go +++ b/arduino/cores/board_test.go @@ -67,31 +67,31 @@ var boardUno = &Board{ var boardMega = &Board{ BoardID: "mega", Properties: properties.NewFromHashmap(map[string]string{ - "name": "Arduino/Genuino Mega or Mega 2560", - "vid.0": "0x2341", - "pid.0": "0x0010", - "vid.1": "0x2341", - "pid.1": "0x0042", - "vid.2": "0x2A03", - "pid.2": "0x0010", - "vid.3": "0x2A03", - "pid.3": "0x0042", - "vid.4": "0x2341", - "pid.4": "0x0210", - "vid.5": "0x2341", - "pid.5": "0x0242", - "upload.tool": "avrdude", - "upload.maximum_data_size": "8192", - "bootloader.tool": "avrdude", - "bootloader.low_fuses": "0xFF", - "bootloader.unlock_bits": "0x3F", - "bootloader.lock_bits": "0x0F", - "build.f_cpu": "16000000L", - "build.core": "arduino", - "build.variant": "mega", - "build.board": "AVR_MEGA2560", - "menu.cpu.atmega2560": "ATmega2560 (Mega 2560)", - "menu.cpu.atmega2560.upload.protocol": "wiring", + "name": "Arduino/Genuino Mega or Mega 2560", + "vid.0": "0x2341", + "pid.0": "0x0010", + "vid.1": "0x2341", + "pid.1": "0x0042", + "vid.2": "0x2A03", + "pid.2": "0x0010", + "vid.3": "0x2A03", + "pid.3": "0x0042", + "vid.4": "0x2341", + "pid.4": "0x0210", + "vid.5": "0x2341", + "pid.5": "0x0242", + "upload.tool": "avrdude", + "upload.maximum_data_size": "8192", + "bootloader.tool": "avrdude", + "bootloader.low_fuses": "0xFF", + "bootloader.unlock_bits": "0x3F", + "bootloader.lock_bits": "0x0F", + "build.f_cpu": "16000000L", + "build.core": "arduino", + "build.variant": "mega", + "build.board": "AVR_MEGA2560", + "menu.cpu.atmega2560": "ATmega2560 (Mega 2560)", + "menu.cpu.atmega2560.upload.protocol": "wiring", "menu.cpu.atmega2560.upload.maximum_size": "253952", "menu.cpu.atmega2560.upload.speed": "115200", "menu.cpu.atmega2560.bootloader.high_fuses": "0xD8", @@ -189,19 +189,19 @@ func TestBoard(t *testing.T) { func TestBoardOptions(t *testing.T) { expConf2560 := properties.NewFromHashmap(map[string]string{ - "bootloader.extended_fuses": "0xFD", - "bootloader.file": "stk500v2/stk500boot_v2_mega2560.hex", - "bootloader.high_fuses": "0xD8", - "bootloader.lock_bits": "0x0F", - "bootloader.low_fuses": "0xFF", - "bootloader.tool": "avrdude", - "bootloader.unlock_bits": "0x3F", - "build.board": "AVR_MEGA2560", - "build.core": "arduino", - "build.f_cpu": "16000000L", - "build.mcu": "atmega2560", - "build.variant": "mega", - "menu.cpu.atmega1280": "ATmega1280", + "bootloader.extended_fuses": "0xFD", + "bootloader.file": "stk500v2/stk500boot_v2_mega2560.hex", + "bootloader.high_fuses": "0xD8", + "bootloader.lock_bits": "0x0F", + "bootloader.low_fuses": "0xFF", + "bootloader.tool": "avrdude", + "bootloader.unlock_bits": "0x3F", + "build.board": "AVR_MEGA2560", + "build.core": "arduino", + "build.f_cpu": "16000000L", + "build.mcu": "atmega2560", + "build.variant": "mega", + "menu.cpu.atmega1280": "ATmega1280", "menu.cpu.atmega1280.bootloader.extended_fuses": "0xF5", "menu.cpu.atmega1280.bootloader.file": "atmega/ATmegaBOOT_168_atmega1280.hex", "menu.cpu.atmega1280.bootloader.high_fuses": "0xDA", @@ -219,24 +219,24 @@ func TestBoardOptions(t *testing.T) { "menu.cpu.atmega2560.upload.maximum_size": "253952", "menu.cpu.atmega2560.upload.protocol": "wiring", "menu.cpu.atmega2560.upload.speed": "115200", - "name": "Arduino/Genuino Mega or Mega 2560", - "pid.0": "0x0010", - "pid.1": "0x0042", - "pid.2": "0x0010", - "pid.3": "0x0042", - "pid.4": "0x0210", - "pid.5": "0x0242", - "upload.maximum_data_size": "8192", - "upload.maximum_size": "253952", - "upload.protocol": "wiring", - "upload.speed": "115200", - "upload.tool": "avrdude", - "vid.0": "0x2341", - "vid.1": "0x2341", - "vid.2": "0x2A03", - "vid.3": "0x2A03", - "vid.4": "0x2341", - "vid.5": "0x2341", + "name": "Arduino/Genuino Mega or Mega 2560", + "pid.0": "0x0010", + "pid.1": "0x0042", + "pid.2": "0x0010", + "pid.3": "0x0042", + "pid.4": "0x0210", + "pid.5": "0x0242", + "upload.maximum_data_size": "8192", + "upload.maximum_size": "253952", + "upload.protocol": "wiring", + "upload.speed": "115200", + "upload.tool": "avrdude", + "vid.0": "0x2341", + "vid.1": "0x2341", + "vid.2": "0x2A03", + "vid.3": "0x2A03", + "vid.4": "0x2341", + "vid.5": "0x2341", }) conf2560, err := boardMega.GeneratePropertiesForConfiguration("cpu=atmega2560") @@ -244,19 +244,19 @@ func TestBoardOptions(t *testing.T) { require.EqualValues(t, expConf2560.AsMap(), conf2560.AsMap(), "configuration for cpu=atmega2560") expConf1280 := properties.NewFromHashmap(map[string]string{ - "bootloader.extended_fuses": "0xF5", - "bootloader.file": "atmega/ATmegaBOOT_168_atmega1280.hex", - "bootloader.high_fuses": "0xDA", - "bootloader.lock_bits": "0x0F", - "bootloader.low_fuses": "0xFF", - "bootloader.tool": "avrdude", - "bootloader.unlock_bits": "0x3F", - "build.board": "AVR_MEGA", - "build.core": "arduino", - "build.f_cpu": "16000000L", - "build.mcu": "atmega1280", - "build.variant": "mega", - "menu.cpu.atmega1280": "ATmega1280", + "bootloader.extended_fuses": "0xF5", + "bootloader.file": "atmega/ATmegaBOOT_168_atmega1280.hex", + "bootloader.high_fuses": "0xDA", + "bootloader.lock_bits": "0x0F", + "bootloader.low_fuses": "0xFF", + "bootloader.tool": "avrdude", + "bootloader.unlock_bits": "0x3F", + "build.board": "AVR_MEGA", + "build.core": "arduino", + "build.f_cpu": "16000000L", + "build.mcu": "atmega1280", + "build.variant": "mega", + "menu.cpu.atmega1280": "ATmega1280", "menu.cpu.atmega1280.bootloader.extended_fuses": "0xF5", "menu.cpu.atmega1280.bootloader.file": "atmega/ATmegaBOOT_168_atmega1280.hex", "menu.cpu.atmega1280.bootloader.high_fuses": "0xDA", @@ -274,24 +274,24 @@ func TestBoardOptions(t *testing.T) { "menu.cpu.atmega2560.upload.maximum_size": "253952", "menu.cpu.atmega2560.upload.protocol": "wiring", "menu.cpu.atmega2560.upload.speed": "115200", - "name": "Arduino/Genuino Mega or Mega 2560", - "pid.0": "0x0010", - "pid.1": "0x0042", - "pid.2": "0x0010", - "pid.3": "0x0042", - "pid.4": "0x0210", - "pid.5": "0x0242", - "upload.maximum_data_size": "8192", - "upload.maximum_size": "126976", - "upload.protocol": "arduino", - "upload.speed": "57600", - "upload.tool": "avrdude", - "vid.0": "0x2341", - "vid.1": "0x2341", - "vid.2": "0x2A03", - "vid.3": "0x2A03", - "vid.4": "0x2341", - "vid.5": "0x2341", + "name": "Arduino/Genuino Mega or Mega 2560", + "pid.0": "0x0010", + "pid.1": "0x0042", + "pid.2": "0x0010", + "pid.3": "0x0042", + "pid.4": "0x0210", + "pid.5": "0x0242", + "upload.maximum_data_size": "8192", + "upload.maximum_size": "126976", + "upload.protocol": "arduino", + "upload.speed": "57600", + "upload.tool": "avrdude", + "vid.0": "0x2341", + "vid.1": "0x2341", + "vid.2": "0x2A03", + "vid.3": "0x2A03", + "vid.4": "0x2341", + "vid.5": "0x2341", }) conf1280, err := boardMega.GeneratePropertiesForConfiguration("cpu=atmega1280") require.NoError(t, err, "generating cpu=atmega1280 configuration") @@ -331,7 +331,7 @@ func TestBoardOptions(t *testing.T) { "upload.tool": "micronucleus", "upload.use_1200bps_touch": "false", "upload.wait_for_upload_port": "false", - "vid.0": "0x16D0", + "vid.0": "0x16D0", }) confWatterott, err := boardWatterottTiny841.GeneratePropertiesForConfiguration("core=spencekonde,info=info") require.NoError(t, err, "generating core=spencekonde,info=info configuration") From 84169052dc7280ce5b3d9249bfaebfeeca48d81c Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Oct 2018 22:31:56 +0200 Subject: [PATCH 3/4] testing coverage across packages --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f9f24c59f11..b5a5795659f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ script: - golangci-lint run # Build and test - go build - - go test -timeout 20m -v -coverprofile=coverage.txt -covermode=atomic ./... + - go test -timeout 20m -v -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic ./... after_success: - bash <(curl -s https://codecov.io/bash) From 5bb44e463cd6c39724a22d2d51e3f26d0589f74a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 25 Oct 2018 13:21:09 +0200 Subject: [PATCH 4/4] Removed experimental sync with Create This feature is postponed. --- Gopkg.lock | 59 +- Gopkg.toml | 15 +- builder_client_helpers/alive.go | 53 -- builder_client_helpers/boards.go | 84 --- builder_client_helpers/boards_v2.go | 126 ---- builder_client_helpers/client.go | 55 -- builder_client_helpers/compilations.go | 67 -- builder_client_helpers/examples.go | 61 -- builder_client_helpers/files.go | 53 -- builder_client_helpers/libraries.go | 97 --- builder_client_helpers/media_types.go | 598 ---------------- builder_client_helpers/pinned_libraries.go | 123 ---- builder_client_helpers/public.go | 132 ---- builder_client_helpers/user_types.go | 570 --------------- commands/sketch/sync.go | 469 ------------- common/formatter/text.go | 1 - create_client_helpers/alive.go | 59 -- create_client_helpers/client.go | 55 -- create_client_helpers/files.go | 62 -- create_client_helpers/media_types.go | 267 ------- create_client_helpers/sketches.go | 242 ------- create_client_helpers/user_types.go | 146 ---- vendor/github.com/armon/go-metrics/.gitignore | 24 - vendor/github.com/armon/go-metrics/LICENSE | 20 - vendor/github.com/armon/go-metrics/README.md | 74 -- .../github.com/armon/go-metrics/const_unix.go | 12 - .../armon/go-metrics/const_windows.go | 13 - vendor/github.com/armon/go-metrics/inmem.go | 348 --------- .../armon/go-metrics/inmem_endpoint.go | 118 ---- .../armon/go-metrics/inmem_signal.go | 117 ---- vendor/github.com/armon/go-metrics/metrics.go | 216 ------ vendor/github.com/armon/go-metrics/sink.go | 115 --- vendor/github.com/armon/go-metrics/start.go | 129 ---- vendor/github.com/armon/go-metrics/statsd.go | 184 ----- .../github.com/armon/go-metrics/statsite.go | 172 ----- .../github.com/briandowns/spinner/.gitignore | 29 - .../github.com/briandowns/spinner/.travis.yml | 15 - vendor/github.com/briandowns/spinner/LICENSE | 174 ----- .../github.com/briandowns/spinner/README.md | 203 ------ .../briandowns/spinner/character_sets.go | 59 -- .../github.com/briandowns/spinner/spinner.go | 194 ----- .../github.com/dimfeld/httptreemux/.gitignore | 23 - .../dimfeld/httptreemux/.travis.yml | 14 - vendor/github.com/dimfeld/httptreemux/LICENSE | 21 - .../github.com/dimfeld/httptreemux/README.md | 240 ------- .../github.com/dimfeld/httptreemux/context.go | 123 ---- .../github.com/dimfeld/httptreemux/group.go | 195 ------ .../dimfeld/httptreemux/panichandler.go | 211 ------ vendor/github.com/dimfeld/httptreemux/path.go | 127 ---- .../github.com/dimfeld/httptreemux/router.go | 300 -------- vendor/github.com/dimfeld/httptreemux/tree.go | 340 --------- .../dimfeld/httptreemux/treemux_16.go | 86 --- .../dimfeld/httptreemux/treemux_17.go | 149 ---- .../dimfeld/httptreemux/unescape_17.go | 9 - .../dimfeld/httptreemux/unescape_18.go | 9 - vendor/github.com/goadesign/goa/.gitignore | 18 - .../github.com/goadesign/goa/.golint_exclude | 5 - vendor/github.com/goadesign/goa/.travis.yml | 17 - vendor/github.com/goadesign/goa/LICENSE | 21 - vendor/github.com/goadesign/goa/Makefile | 70 -- vendor/github.com/goadesign/goa/README.md | 339 --------- vendor/github.com/goadesign/goa/appveyor.yml | 24 - vendor/github.com/goadesign/goa/client/cli.go | 96 --- .../github.com/goadesign/goa/client/client.go | 251 ------- .../goadesign/goa/client/signers.go | 151 ---- vendor/github.com/goadesign/goa/context.go | 170 ----- vendor/github.com/goadesign/goa/doc.go | 114 --- vendor/github.com/goadesign/goa/encoding.go | 274 -------- vendor/github.com/goadesign/goa/error.go | 360 ---------- vendor/github.com/goadesign/goa/logging.go | 123 ---- vendor/github.com/goadesign/goa/metrics.go | 163 ----- .../goadesign/goa/metrics_appengine.go | 17 - vendor/github.com/goadesign/goa/metrics_js.go | 17 - vendor/github.com/goadesign/goa/middleware.go | 80 --- vendor/github.com/goadesign/goa/mux.go | 101 --- vendor/github.com/goadesign/goa/roadmap.md | 153 ---- vendor/github.com/goadesign/goa/security.go | 77 -- vendor/github.com/goadesign/goa/service.go | 455 ------------ .../github.com/goadesign/goa/uuid/common.go | 4 - vendor/github.com/goadesign/goa/uuid/uuid.go | 54 -- .../github.com/goadesign/goa/uuid/uuid_js.go | 90 --- vendor/github.com/goadesign/goa/validation.go | 149 ---- .../hashicorp/go-immutable-radix/.gitignore | 24 - .../hashicorp/go-immutable-radix/.travis.yml | 3 - .../hashicorp/go-immutable-radix/LICENSE | 363 ---------- .../hashicorp/go-immutable-radix/README.md | 41 -- .../hashicorp/go-immutable-radix/edges.go | 21 - .../hashicorp/go-immutable-radix/iradix.go | 662 ------------------ .../hashicorp/go-immutable-radix/iter.go | 91 --- .../hashicorp/go-immutable-radix/node.go | 292 -------- .../hashicorp/go-immutable-radix/raw_iter.go | 78 --- .../github.com/hashicorp/golang-lru/LICENSE | 362 ---------- .../hashicorp/golang-lru/simplelru/lru.go | 161 ----- .../golang-lru/simplelru/lru_interface.go | 37 - vendor/golang.org/x/net/websocket/client.go | 106 --- vendor/golang.org/x/net/websocket/dial.go | 24 - vendor/golang.org/x/net/websocket/hybi.go | 583 --------------- vendor/golang.org/x/net/websocket/server.go | 113 --- .../golang.org/x/net/websocket/websocket.go | 448 ------------ 99 files changed, 2 insertions(+), 14257 deletions(-) delete mode 100644 builder_client_helpers/alive.go delete mode 100644 builder_client_helpers/boards.go delete mode 100644 builder_client_helpers/boards_v2.go delete mode 100644 builder_client_helpers/client.go delete mode 100644 builder_client_helpers/compilations.go delete mode 100644 builder_client_helpers/examples.go delete mode 100644 builder_client_helpers/files.go delete mode 100644 builder_client_helpers/libraries.go delete mode 100644 builder_client_helpers/media_types.go delete mode 100644 builder_client_helpers/pinned_libraries.go delete mode 100644 builder_client_helpers/public.go delete mode 100644 builder_client_helpers/user_types.go delete mode 100644 commands/sketch/sync.go delete mode 100644 create_client_helpers/alive.go delete mode 100644 create_client_helpers/client.go delete mode 100644 create_client_helpers/files.go delete mode 100644 create_client_helpers/media_types.go delete mode 100644 create_client_helpers/sketches.go delete mode 100644 create_client_helpers/user_types.go delete mode 100644 vendor/github.com/armon/go-metrics/.gitignore delete mode 100644 vendor/github.com/armon/go-metrics/LICENSE delete mode 100644 vendor/github.com/armon/go-metrics/README.md delete mode 100644 vendor/github.com/armon/go-metrics/const_unix.go delete mode 100644 vendor/github.com/armon/go-metrics/const_windows.go delete mode 100644 vendor/github.com/armon/go-metrics/inmem.go delete mode 100644 vendor/github.com/armon/go-metrics/inmem_endpoint.go delete mode 100644 vendor/github.com/armon/go-metrics/inmem_signal.go delete mode 100644 vendor/github.com/armon/go-metrics/metrics.go delete mode 100644 vendor/github.com/armon/go-metrics/sink.go delete mode 100644 vendor/github.com/armon/go-metrics/start.go delete mode 100644 vendor/github.com/armon/go-metrics/statsd.go delete mode 100644 vendor/github.com/armon/go-metrics/statsite.go delete mode 100644 vendor/github.com/briandowns/spinner/.gitignore delete mode 100644 vendor/github.com/briandowns/spinner/.travis.yml delete mode 100644 vendor/github.com/briandowns/spinner/LICENSE delete mode 100644 vendor/github.com/briandowns/spinner/README.md delete mode 100644 vendor/github.com/briandowns/spinner/character_sets.go delete mode 100644 vendor/github.com/briandowns/spinner/spinner.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/.gitignore delete mode 100644 vendor/github.com/dimfeld/httptreemux/.travis.yml delete mode 100644 vendor/github.com/dimfeld/httptreemux/LICENSE delete mode 100644 vendor/github.com/dimfeld/httptreemux/README.md delete mode 100644 vendor/github.com/dimfeld/httptreemux/context.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/group.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/panichandler.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/path.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/router.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/tree.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/treemux_16.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/treemux_17.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/unescape_17.go delete mode 100644 vendor/github.com/dimfeld/httptreemux/unescape_18.go delete mode 100644 vendor/github.com/goadesign/goa/.gitignore delete mode 100644 vendor/github.com/goadesign/goa/.golint_exclude delete mode 100644 vendor/github.com/goadesign/goa/.travis.yml delete mode 100644 vendor/github.com/goadesign/goa/LICENSE delete mode 100644 vendor/github.com/goadesign/goa/Makefile delete mode 100644 vendor/github.com/goadesign/goa/README.md delete mode 100644 vendor/github.com/goadesign/goa/appveyor.yml delete mode 100644 vendor/github.com/goadesign/goa/client/cli.go delete mode 100644 vendor/github.com/goadesign/goa/client/client.go delete mode 100644 vendor/github.com/goadesign/goa/client/signers.go delete mode 100644 vendor/github.com/goadesign/goa/context.go delete mode 100644 vendor/github.com/goadesign/goa/doc.go delete mode 100644 vendor/github.com/goadesign/goa/encoding.go delete mode 100644 vendor/github.com/goadesign/goa/error.go delete mode 100644 vendor/github.com/goadesign/goa/logging.go delete mode 100644 vendor/github.com/goadesign/goa/metrics.go delete mode 100644 vendor/github.com/goadesign/goa/metrics_appengine.go delete mode 100644 vendor/github.com/goadesign/goa/metrics_js.go delete mode 100644 vendor/github.com/goadesign/goa/middleware.go delete mode 100644 vendor/github.com/goadesign/goa/mux.go delete mode 100644 vendor/github.com/goadesign/goa/roadmap.md delete mode 100644 vendor/github.com/goadesign/goa/security.go delete mode 100644 vendor/github.com/goadesign/goa/service.go delete mode 100644 vendor/github.com/goadesign/goa/uuid/common.go delete mode 100644 vendor/github.com/goadesign/goa/uuid/uuid.go delete mode 100644 vendor/github.com/goadesign/goa/uuid/uuid_js.go delete mode 100644 vendor/github.com/goadesign/goa/validation.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/.gitignore delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/.travis.yml delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/README.md delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/edges.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/iradix.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/iter.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/node.go delete mode 100644 vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/LICENSE delete mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go delete mode 100644 vendor/golang.org/x/net/websocket/client.go delete mode 100644 vendor/golang.org/x/net/websocket/dial.go delete mode 100644 vendor/golang.org/x/net/websocket/hybi.go delete mode 100644 vendor/golang.org/x/net/websocket/server.go delete mode 100644 vendor/golang.org/x/net/websocket/websocket.go diff --git a/Gopkg.lock b/Gopkg.lock index 290a5142b70..61510646415 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -60,14 +60,6 @@ pruneopts = "UT" revision = "ed041402e83b924251a5d65b4dfeb727c480c359" -[[projects]] - branch = "master" - digest = "1:66dfcb33994918d290a70f58ef42bda92a7268facf17bd937f5748dec853a320" - name = "github.com/armon/go-metrics" - packages = ["."] - pruneopts = "UT" - revision = "783273d703149aaeb9897cf58613d5af48861c25" - [[projects]] digest = "1:5978a502788ab7e2c0237bb65bdb2651a94d93733924701463af20717279fe6e" name = "github.com/aws/aws-sdk-go" @@ -121,14 +113,6 @@ pruneopts = "UT" revision = "5df1f207ff77e025801505ae4d903133a0b4353f" -[[projects]] - digest = "1:889290ee5c1f1888baa7caa2b4cdfa8a6abcfb86dd772fe6470ad7925cc44bff" - name = "github.com/briandowns/spinner" - packages = ["."] - pruneopts = "UT" - revision = "48dbb65d7bd5c74ab50d53d04c949f20e3d14944" - version = "1.0" - [[projects]] digest = "1:2209584c0f7c9b68c23374e659357ab546e1b70eec2761f03280f69a8fd23d77" name = "github.com/cenkalti/backoff" @@ -177,14 +161,6 @@ revision = "346938d642f2ec3594ed81d874461961cd0faa76" version = "v1.1.0" -[[projects]] - digest = "1:8d983343581370768675191a8695f52d663f50a9234c571128f3d146314892cf" - name = "github.com/dimfeld/httptreemux" - packages = ["."] - pruneopts = "UT" - revision = "7f532489e7739b3d49df5c602bf63549881fe753" - version = "v5.0.1" - [[projects]] digest = "1:4bb94bb2d837b5c7489d9e5e1fcffbc81fa1cb43024cbb4fe827787378f01e3b" name = "github.com/fatih/color" @@ -235,18 +211,6 @@ revision = "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506" version = "v1.2.1" -[[projects]] - digest = "1:408d3952c8a23aa0b8a78132a17bb34e1ceb66cb3b21d2246e83bc81e16ea78f" - name = "github.com/goadesign/goa" - packages = [ - ".", - "client", - "uuid", - ] - pruneopts = "UT" - revision = "fc29b77a218fb9e190849c81911ed12d25e771de" - version = "v1.3.1" - [[projects]] digest = "1:ffc060c551980d37ee9e428ef528ee2813137249ccebb0bfc412ef83071cac91" name = "github.com/golang/protobuf" @@ -275,22 +239,6 @@ pruneopts = "UT" revision = "e80d13ce29ede4452c43dea11e79b9bc8a15b478" -[[projects]] - branch = "master" - digest = "1:2394f5a25132b3868eff44599cc28d44bdd0330806e34c495d754dd052df612b" - name = "github.com/hashicorp/go-immutable-radix" - packages = ["."] - pruneopts = "UT" - revision = "7f3cd4390caab3250a57f30efdb2a65dd7649ecf" - -[[projects]] - branch = "master" - digest = "1:e0e3eb7886110c57a7c103fbc5fc419b1651d3014655b47b71f26809c2daeb1c" - name = "github.com/hashicorp/golang-lru" - packages = ["simplelru"] - pruneopts = "UT" - revision = "0fb14efe8c47ae851c0034ed7a448854d3d34cf3" - [[projects]] digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" name = "github.com/inconshreveable/mousetrap" @@ -482,7 +430,7 @@ [[projects]] branch = "master" - digest = "1:4e56875285bc955bbd6503d5c46fb1bc30a621aaee0f8efdd37e7c50bc8d0e98" + digest = "1:efa7281b594f7efa2f2c1adda314f45f1cb58d5ba2fa2f9f63c6b0ce50e040ac" name = "golang.org/x/net" packages = [ "bpf", @@ -491,7 +439,6 @@ "internal/socket", "ipv4", "ipv6", - "websocket", ] pruneopts = "UT" revision = "5f9ae10d9af5b1c89ae6904293b14b064d4ada23" @@ -585,13 +532,9 @@ "github.com/bcmi-labs/arduino-modules/sketches", "github.com/bgentry/go-netrc/netrc", "github.com/bouk/monkey", - "github.com/briandowns/spinner", "github.com/codeclysm/cc", "github.com/codeclysm/extract", "github.com/fatih/color", - "github.com/goadesign/goa", - "github.com/goadesign/goa/client", - "github.com/goadesign/goa/uuid", "github.com/gosuri/uitable", "github.com/mattn/go-colorable", "github.com/mitchellh/go-homedir", diff --git a/Gopkg.toml b/Gopkg.toml index 8d4fa16ca13..4b49b12e8f2 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -55,10 +55,6 @@ branch = "master" name = "github.com/bgentry/go-netrc" -[[constraint]] - name = "github.com/briandowns/spinner" - version = "1.0.0" - [[constraint]] name = "github.com/codeclysm/cc" version = "1.2.1" @@ -67,15 +63,6 @@ name = "github.com/codeclysm/extract" version = "1.1.1" -[[constraint]] - name = "github.com/goadesign/goa" - version = "1.3.1" - -# This is required for goa 1.3.1 to work -[[override]] - branch = "master" - name = "github.com/satori/go.uuid" - [[constraint]] branch = "master" name = "github.com/mitchellh/go-homedir" @@ -123,4 +110,4 @@ [prune] go-tests = true - unused-packages = true \ No newline at end of file + unused-packages = true diff --git a/builder_client_helpers/alive.go b/builder_client_helpers/alive.go deleted file mode 100644 index 65dee165453..00000000000 --- a/builder_client_helpers/alive.go +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// PingAlivePath computes a request path to the ping action of alive. -func PingAlivePath() string { - return fmt.Sprintf("/builder/alive") -} - -// PingAlive returns 200 if the instance is healthy. -func (c *Client) PingAlive(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewPingAliveRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewPingAliveRequest creates the request corresponding to the ping action endpoint of the alive resource. -func (c *Client) NewPingAliveRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/builder_client_helpers/boards.go b/builder_client_helpers/boards.go deleted file mode 100644 index 58060ee622c..00000000000 --- a/builder_client_helpers/boards.go +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// ListBoardsPath computes a request path to the list action of boards. -func ListBoardsPath() string { - return fmt.Sprintf("/builder/v1/boards") -} - -// ListBoards provides a list of all the boards supported by Arduino Create. Doesn't require any authentication. -func (c *Client) ListBoards(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewListBoardsRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewListBoardsRequest creates the request corresponding to the list action endpoint of the boards resource. -func (c *Client) NewListBoardsRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} - -// ShowBoardsPath computes a request path to the show action of boards. -func ShowBoardsPath(vid string, pid string) string { - param0 := vid - param1 := pid - - return fmt.Sprintf("/builder/v1/boards/%s/%s", param0, param1) -} - -// ShowBoards provides the board identified by the :vid and :pid params. Doesn't require authentication. -func (c *Client) ShowBoards(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewShowBoardsRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewShowBoardsRequest creates the request corresponding to the show action endpoint of the boards resource. -func (c *Client) NewShowBoardsRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/builder_client_helpers/boards_v2.go b/builder_client_helpers/boards_v2.go deleted file mode 100644 index 9e889ee9194..00000000000 --- a/builder_client_helpers/boards_v2.go +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" - "strconv" -) - -// ByVidPidBoardsV2Path computes a request path to the byVidPid action of boards_v2. -func ByVidPidBoardsV2Path(vid string, pid string) string { - param0 := vid - param1 := pid - - return fmt.Sprintf("/builder/v2/boards/byVidPid/%s/%s", param0, param1) -} - -// ByVidPidBoardsV2 provides the board identified by the :vid and :pid params. Doesn't require authentication. -func (c *Client) ByVidPidBoardsV2(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewByVidPidBoardsV2Request(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewByVidPidBoardsV2Request creates the request corresponding to the byVidPid action endpoint of the boards_v2 resource. -func (c *Client) NewByVidPidBoardsV2Request(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} - -// ListBoardsV2Path computes a request path to the list action of boards_v2. -func ListBoardsV2Path() string { - - return fmt.Sprintf("/builder/v2/boards") -} - -// ListBoardsV2 provides a list of all the boards supported by Arduino Create. Doesn't require any authentication. -func (c *Client) ListBoardsV2(ctx context.Context, path string, limit *int, offset *int) (*http.Response, error) { - req, err := c.NewListBoardsV2Request(ctx, path, limit, offset) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewListBoardsV2Request creates the request corresponding to the list action endpoint of the boards_v2 resource. -func (c *Client) NewListBoardsV2Request(ctx context.Context, path string, limit *int, offset *int) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - values := u.Query() - if limit != nil { - tmp15 := strconv.Itoa(*limit) - values.Set("limit", tmp15) - } - if offset != nil { - tmp16 := strconv.Itoa(*offset) - values.Set("offset", tmp16) - } - u.RawQuery = values.Encode() - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} - -// ShowBoardsV2Path computes a request path to the show action of boards_v2. -func ShowBoardsV2Path(fqbn string) string { - param0 := fqbn - - return fmt.Sprintf("/builder/v2/boards/%s", param0) -} - -// ShowBoardsV2 provides the board identified by an fqbn. Doesn't require authentication. -func (c *Client) ShowBoardsV2(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewShowBoardsV2Request(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewShowBoardsV2Request creates the request corresponding to the show action endpoint of the boards_v2 resource. -func (c *Client) NewShowBoardsV2Request(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/builder_client_helpers/client.go b/builder_client_helpers/client.go deleted file mode 100644 index 6ec3ff668f8..00000000000 --- a/builder_client_helpers/client.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "github.com/goadesign/goa" - goaclient "github.com/goadesign/goa/client" -) - -// Client is the ArduinoBuilderV1 service client. -type Client struct { - *goaclient.Client - Oauth2Signer goaclient.Signer - Encoder *goa.HTTPEncoder - Decoder *goa.HTTPDecoder -} - -// New instantiates the client. -func New(c goaclient.Doer) *Client { - client := &Client{ - Client: goaclient.New(c), - Encoder: goa.NewHTTPEncoder(), - Decoder: goa.NewHTTPDecoder(), - } - - // Setup encoders and decoders - client.Encoder.Register(goa.NewJSONEncoder, "application/json") - client.Decoder.Register(goa.NewJSONDecoder, "application/json") - - // Setup default encoder and decoder - client.Encoder.Register(goa.NewJSONEncoder, "*/*") - client.Decoder.Register(goa.NewJSONDecoder, "*/*") - - return client -} - -// SetOauth2Signer sets the request signer for the oauth2 security scheme. -func (c *Client) SetOauth2Signer(signer goaclient.Signer) { - c.Oauth2Signer = signer -} diff --git a/builder_client_helpers/compilations.go b/builder_client_helpers/compilations.go deleted file mode 100644 index 1cda1bd5299..00000000000 --- a/builder_client_helpers/compilations.go +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "bytes" - "context" - "fmt" - "net/http" - "net/url" -) - -// StartCompilationsPath computes a request path to the start action of compilations. -func StartCompilationsPath() string { - return fmt.Sprintf("/builder/v1/compile") -} - -// Start a compilation for the given user and saves the request (but not the generated files) on the database. -// requires authentication. -// Can return PreconditionFailed if the user has reached their maximum number of compilations per day. -// If the compilation failed it returns UnprocessableEntity -func (c *Client) StartCompilations(ctx context.Context, path string, payload *Compilation) (*http.Response, error) { - req, err := c.NewStartCompilationsRequest(ctx, path, payload) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewStartCompilationsRequest creates the request corresponding to the start action endpoint of the compilations resource. -func (c *Client) NewStartCompilationsRequest(ctx context.Context, path string, payload *Compilation) (*http.Request, error) { - var body bytes.Buffer - err := c.Encoder.Encode(payload, &body, "*/*") - if err != nil { - return nil, fmt.Errorf("failed to encode body: %s", err) - } - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("POST", u.String(), &body) - if err != nil { - return nil, err - } - header := req.Header - header.Set("Content-Type", "application/json") - if c.Oauth2Signer != nil { - c.Oauth2Signer.Sign(req) - } - return req, nil -} diff --git a/builder_client_helpers/examples.go b/builder_client_helpers/examples.go deleted file mode 100644 index 137f297cdaf..00000000000 --- a/builder_client_helpers/examples.go +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// ListExamplesPath computes a request path to the list action of examples. -func ListExamplesPath() string { - return fmt.Sprintf("/builder/v1/examples") -} - -// ListExamples provides a list of all the builtin examples -func (c *Client) ListExamples(ctx context.Context, path string, maintainer *string, libType *string) (*http.Response, error) { - req, err := c.NewListExamplesRequest(ctx, path, maintainer, libType) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewListExamplesRequest creates the request corresponding to the list action endpoint of the examples resource. -func (c *Client) NewListExamplesRequest(ctx context.Context, path string, maintainer *string, libType *string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - values := u.Query() - if maintainer != nil { - values.Set("maintainer", *maintainer) - } - if libType != nil { - values.Set("type", *libType) - } - u.RawQuery = values.Encode() - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/builder_client_helpers/files.go b/builder_client_helpers/files.go deleted file mode 100644 index f6d105b71ba..00000000000 --- a/builder_client_helpers/files.go +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// ShowFilesPath computes a request path to the show action of files. -func ShowFilesPath(path string) string { - return fmt.Sprintf("/builder/v1/files/%s", path) -} - -// ShowFiles provides the content of a file. -func (c *Client) ShowFiles(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewShowFilesRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewShowFilesRequest creates the request corresponding to the show action endpoint of the files resource. -func (c *Client) NewShowFilesRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/builder_client_helpers/libraries.go b/builder_client_helpers/libraries.go deleted file mode 100644 index a6866059308..00000000000 --- a/builder_client_helpers/libraries.go +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// ListLibrariesPath computes a request path to the list action of libraries. -func ListLibrariesPath() string { - return fmt.Sprintf("/builder/v1/libraries") -} - -// ListLibraries provides a list of all the latest versions of the libraries supported by Arduino Create. -// Doesn't require any authentication. -func (c *Client) ListLibraries( - ctx context.Context, - path string, maintainer *string, type1 *string, withoutType *string) (*http.Response, error) { - - req, err := c.NewListLibrariesRequest(ctx, path, maintainer, type1, withoutType) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewListLibrariesRequest creates the request corresponding to the list action endpoint of the libraries resource. -func (c *Client) NewListLibrariesRequest(ctx context.Context, path string, maintainer *string, libType *string, withoutType *string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - values := u.Query() - if maintainer != nil { - values.Set("maintainer", *maintainer) - } - if libType != nil { - values.Set("type", *libType) - } - if withoutType != nil { - values.Set("without_type", *withoutType) - } - u.RawQuery = values.Encode() - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} - -// ShowLibrariesPath computes a request path to the show action of libraries. -func ShowLibrariesPath(id string) string { - return fmt.Sprintf("/builder/v1/libraries/%s", id) -} - -// ShowLibraries provides the library identified by the :id and :pid param. Doesn't require authentication. -// Also contains a list of other versions of the library. -func (c *Client) ShowLibraries(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewShowLibrariesRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewShowLibrariesRequest creates the request corresponding to the show action endpoint of the libraries resource. -func (c *Client) NewShowLibrariesRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/builder_client_helpers/media_types.go b/builder_client_helpers/media_types.go deleted file mode 100644 index d1d170919c9..00000000000 --- a/builder_client_helpers/media_types.go +++ /dev/null @@ -1,598 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "net/http" - "time" - - "github.com/goadesign/goa" -) - -// ArduinoBuilderBoard is a physical board belonging to a certain architecture in a package. -// The most obvious package is arduino, which contains architectures avr, sam and samd. -// It can contain multiple versions of the upload commands and options. -// If there is a default version it means that it's the only version officially supported. -// Of course if there is only one version it will be called default (default view) -// -// Identifier: application/vnd.arduino.builder.board+json; view=default -type ArduinoBuilderBoard struct { - // The architecture of the board - Architecture *string `form:"architecture,omitempty" json:"architecture,omitempty" xml:"architecture,omitempty"` - Bootloader []*ArduinoBuilderBoardBootloader `form:"bootloader,omitempty" json:"bootloader,omitempty" xml:"bootloader,omitempty"` - Build []*ArduinoBuilderBoardBuild `form:"build,omitempty" json:"build,omitempty" xml:"build,omitempty"` - // The default flavor of the board - DefaultFlavour *string `form:"default_flavour,omitempty" json:"default_flavour,omitempty" xml:"default_flavour,omitempty"` - // An identifier used by the tools to determine which tools to use on it - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` - // The id of the board - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The name of the board - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The package to which the board belongs - Package *string `form:"package,omitempty" json:"package,omitempty" xml:"package,omitempty"` - // A list of possible pids - Pid []string `form:"pid,omitempty" json:"pid,omitempty" xml:"pid,omitempty"` - Upload []*ArduinoBuilderBoardUpload `form:"upload,omitempty" json:"upload,omitempty" xml:"upload,omitempty"` - // A list of possible vids - Vid []string `form:"vid,omitempty" json:"vid,omitempty" xml:"vid,omitempty"` -} - -// DecodeArduinoBuilderBoard decodes the ArduinoBuilderBoard instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoard(resp *http.Response) (*ArduinoBuilderBoard, error) { - var decoded ArduinoBuilderBoard - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardBootloader contains the info used to bootload a board. (default view) -// -// Identifier: application/vnd.arduino.builder.board.bootloader; view=default -type ArduinoBuilderBoardBootloader struct { - // The commandline used to bootload - Commandline *string `form:"commandline,omitempty" json:"commandline,omitempty" xml:"commandline,omitempty"` - // The flavor of the board. Usually it's default - Flavour *string `form:"flavour,omitempty" json:"flavour,omitempty" xml:"flavour,omitempty"` - // The signature of the commandline - Signature *string `form:"signature,omitempty" json:"signature,omitempty" xml:"signature,omitempty"` -} - -// DecodeArduinoBuilderBoardBootloader decodes the ArduinoBuilderBoardBootloader instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardBootloader(resp *http.Response) (*ArduinoBuilderBoardBootloader, error) { - var decoded ArduinoBuilderBoardBootloader - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardBuild contains the info used to compile for a certain flavor of board. (default view) -// -// Identifier: application/vnd.arduino.builder.board.build; view=default -type ArduinoBuilderBoardBuild struct { - // The flavor of the board. Usually it's default - Flavour *string `form:"flavour,omitempty" json:"flavour,omitempty" xml:"flavour,omitempty"` - // An identifier used by the tools to determine which tools to use on it - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` -} - -// DecodeArduinoBuilderBoardBuild decodes the ArduinoBuilderBoardBuild instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardBuild(resp *http.Response) (*ArduinoBuilderBoardBuild, error) { - var decoded ArduinoBuilderBoardBuild - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardUpload contains the info used to upload a certain flavor of board. (default view) -// -// Identifier: application/vnd.arduino.builder.board.upload; view=default -type ArduinoBuilderBoardUpload struct { - // The commandline used to upload sketches - Commandline *string `form:"commandline,omitempty" json:"commandline,omitempty" xml:"commandline,omitempty"` - // The extension of the binary file - Ext *string `form:"ext,omitempty" json:"ext,omitempty" xml:"ext,omitempty"` - // Files used by the programmer - Files ArduinoBuilderFileCollection `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The flavor of the board. Usually it's default - Flavour *string `form:"flavour,omitempty" json:"flavour,omitempty" xml:"flavour,omitempty"` - // Some options used for uploading, like the speed. - Options map[string]string `form:"options,omitempty" json:"options,omitempty" xml:"options,omitempty"` - // Some params used for uploading. Usually quiet and verbose. - Params map[string]string `form:"params,omitempty" json:"params,omitempty" xml:"params,omitempty"` - // The tool to use for uploading sketches - Tool *string `form:"tool,omitempty" json:"tool,omitempty" xml:"tool,omitempty"` - // The version of the tool - ToolVersion *string `form:"tool_version,omitempty" json:"tool_version,omitempty" xml:"tool_version,omitempty"` -} - -// DecodeArduinoBuilderBoardUpload decodes the ArduinoBuilderBoardUpload instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardUpload(resp *http.Response) (*ArduinoBuilderBoardUpload, error) { - var decoded ArduinoBuilderBoardUpload - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardCollection is the media type for an array of ArduinoBuilderBoard (default view) -// -// Identifier: application/vnd.arduino.builder.board+json; type=collection; view=default -type ArduinoBuilderBoardCollection []*ArduinoBuilderBoard - -// DecodeArduinoBuilderBoardCollection decodes the ArduinoBuilderBoardCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardCollection(resp *http.Response) (ArduinoBuilderBoardCollection, error) { - var decoded ArduinoBuilderBoardCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// ArduinoBuilderBoardsv2 is a paginated list of boards (default view) -// -// Identifier: application/vnd.arduino.builder.boardsv2+json; view=default -type ArduinoBuilderBoardsv2 struct { - // The list of sketches - Items ArduinoBuilderBoardv2Collection `form:"items" json:"items" xml:"items"` - // Link to the following page of results. Could be empty. - Next *string `form:"next,omitempty" json:"next,omitempty" xml:"next,omitempty"` - // Link to the previous page of results. Could be empty. - Prev *string `form:"prev,omitempty" json:"prev,omitempty" xml:"prev,omitempty"` -} - -// Validate validates the ArduinoBuilderBoardsv2 media type instance. -func (mt *ArduinoBuilderBoardsv2) Validate() (err error) { - if mt.Items == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "items")) - } - return -} - -// DecodeArduinoBuilderBoardsv2 decodes the ArduinoBuilderBoardsv2 instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardsv2(resp *http.Response) (*ArduinoBuilderBoardsv2, error) { - var decoded ArduinoBuilderBoardsv2 - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardv2 is a physical board belonging to a certain architecture in a package. -// The most obvious package is arduino, which contains architectures avr, sam and samd. -// It can contain multiple versions of the upload commands and options. -// If there is a default version it means that it's the only version officially supported. -// Of course if there is only one version it will be called default (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2+json; view=default -type ArduinoBuilderBoardv2 struct { - // The architecture of the board - Architecture *string `form:"architecture,omitempty" json:"architecture,omitempty" xml:"architecture,omitempty"` - Build ArduinoBuilderBoardv2BuildCollection `form:"build,omitempty" json:"build,omitempty" xml:"build,omitempty"` - // The default flavor of the board - DefaultFlavour *string `form:"default_flavour,omitempty" json:"default_flavour,omitempty" xml:"default_flavour,omitempty"` - // An identifier used by the tools to determine which tools to use on it - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` - // The url of the board - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The name of the board - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` -} - -// ArduinoBuilderBoardv2Full is a physical board belonging to a certain architecture in a package. -// The most obvious package is arduino, which contains architectures avr, sam and samd. -// It can contain multiple versions of the upload commands and options. -// If there is a default version it means that it's the only version officially supported. -// Of course if there is only one version it will be called default (full view) -// -// Identifier: application/vnd.arduino.builder.boardv2+json; view=full -type ArduinoBuilderBoardv2Full struct { - // The architecture of the board - Architecture *string `form:"architecture,omitempty" json:"architecture,omitempty" xml:"architecture,omitempty"` - Bootloader ArduinoBuilderBoardv2BootloaderCollection `form:"bootloader,omitempty" json:"bootloader,omitempty" xml:"bootloader,omitempty"` - Build ArduinoBuilderBoardv2BuildCollection `form:"build,omitempty" json:"build,omitempty" xml:"build,omitempty"` - // The default flavor of the board - DefaultFlavour *string `form:"default_flavour,omitempty" json:"default_flavour,omitempty" xml:"default_flavour,omitempty"` - // An identifier used by the tools to determine which tools to use on it - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` - // The url of the board - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The id of the board - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The name of the board - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The package to which the board belongs - Package *string `form:"package,omitempty" json:"package,omitempty" xml:"package,omitempty"` - // A list of possible pids - Pid []string `form:"pid,omitempty" json:"pid,omitempty" xml:"pid,omitempty"` - Upload ArduinoBuilderBoardv2UploadCollection `form:"upload,omitempty" json:"upload,omitempty" xml:"upload,omitempty"` - // A list of possible vids - Vid []string `form:"vid,omitempty" json:"vid,omitempty" xml:"vid,omitempty"` -} - -// DecodeArduinoBuilderBoardv2 decodes the ArduinoBuilderBoardv2 instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2(resp *http.Response) (*ArduinoBuilderBoardv2, error) { - var decoded ArduinoBuilderBoardv2 - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// DecodeArduinoBuilderBoardv2Full decodes the ArduinoBuilderBoardv2Full instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2Full(resp *http.Response) (*ArduinoBuilderBoardv2Full, error) { - var decoded ArduinoBuilderBoardv2Full - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardv2Bootloader contains the info used to bootload a board. (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2.bootloader; view=default -type ArduinoBuilderBoardv2Bootloader struct { - // The commandline used to bootload - Commandline *string `form:"commandline,omitempty" json:"commandline,omitempty" xml:"commandline,omitempty"` - // The flavor of the board. Usually it's default - Flavour *string `form:"flavour,omitempty" json:"flavour,omitempty" xml:"flavour,omitempty"` - // The signature of the commandline - Signature *string `form:"signature,omitempty" json:"signature,omitempty" xml:"signature,omitempty"` -} - -// DecodeArduinoBuilderBoardv2Bootloader decodes the ArduinoBuilderBoardv2Bootloader instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2Bootloader(resp *http.Response) (*ArduinoBuilderBoardv2Bootloader, error) { - var decoded ArduinoBuilderBoardv2Bootloader - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardv2BootloaderCollection is the media type for an array of ArduinoBuilderBoardv2Bootloader (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2.bootloader; type=collection; view=default -type ArduinoBuilderBoardv2BootloaderCollection []*ArduinoBuilderBoardv2Bootloader - -// DecodeArduinoBuilderBoardv2BootloaderCollection decodes the ArduinoBuilderBoardv2BootloaderCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2BootloaderCollection(resp *http.Response) (ArduinoBuilderBoardv2BootloaderCollection, error) { - var decoded ArduinoBuilderBoardv2BootloaderCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// Build contains the info used to compile for a certain flavor of board. (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2.build; view=default -type ArduinoBuilderBoardv2Build struct { - // The flavor of the board. Usually it's default - Flavour *string `form:"flavour,omitempty" json:"flavour,omitempty" xml:"flavour,omitempty"` - // An identifier used by the tools to determine which tools to use on it - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` -} - -// DecodeArduinoBuilderBoardv2Build decodes the ArduinoBuilderBoardv2Build instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2Build(resp *http.Response) (*ArduinoBuilderBoardv2Build, error) { - var decoded ArduinoBuilderBoardv2Build - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardv2BuildCollection is the media type for an array of ArduinoBuilderBoardv2Build (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2.build; type=collection; view=default -type ArduinoBuilderBoardv2BuildCollection []*ArduinoBuilderBoardv2Build - -// DecodeArduinoBuilderBoardv2BuildCollection decodes the ArduinoBuilderBoardv2BuildCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2BuildCollection(resp *http.Response) (ArduinoBuilderBoardv2BuildCollection, error) { - var decoded ArduinoBuilderBoardv2BuildCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// ArduinoBuilderBoardv2Upload contains the info used to upload a certain flavor of board. (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2.upload; view=default -type ArduinoBuilderBoardv2Upload struct { - // The commandline used to upload sketches - Commandline *string `form:"commandline,omitempty" json:"commandline,omitempty" xml:"commandline,omitempty"` - // The extension of the binary file - Ext *string `form:"ext,omitempty" json:"ext,omitempty" xml:"ext,omitempty"` - // Files used by the programmer - Files ArduinoBuilderFileCollection `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The flavor of the board. Usually it's default - Flavour *string `form:"flavour,omitempty" json:"flavour,omitempty" xml:"flavour,omitempty"` - // Some options used for uploading, like the speed. - Options map[string]string `form:"options,omitempty" json:"options,omitempty" xml:"options,omitempty"` - // Some params used for uploading. Usually quiet and verbose. - Params map[string]string `form:"params,omitempty" json:"params,omitempty" xml:"params,omitempty"` - // The tool to use for uploading sketches - Tool *string `form:"tool,omitempty" json:"tool,omitempty" xml:"tool,omitempty"` - // The version of the tool - ToolVersion *string `form:"tool_version,omitempty" json:"tool_version,omitempty" xml:"tool_version,omitempty"` -} - -// DecodeArduinoBuilderBoardv2Upload decodes the ArduinoBuilderBoardv2Upload instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2Upload(resp *http.Response) (*ArduinoBuilderBoardv2Upload, error) { - var decoded ArduinoBuilderBoardv2Upload - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderBoardv2UploadCollection is the media type for an array of ArduinoBuilderBoardv2Upload (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2.upload; type=collection; view=default -type ArduinoBuilderBoardv2UploadCollection []*ArduinoBuilderBoardv2Upload - -// DecodeArduinoBuilderBoardv2UploadCollection decodes the ArduinoBuilderBoardv2UploadCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2UploadCollection(resp *http.Response) (ArduinoBuilderBoardv2UploadCollection, error) { - var decoded ArduinoBuilderBoardv2UploadCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// ArduinoBuilderBoardv2Collection is the media type for an array of ArduinoBuilderBoardv2 (default view) -// -// Identifier: application/vnd.arduino.builder.boardv2+json; type=collection; view=default -type ArduinoBuilderBoardv2Collection []*ArduinoBuilderBoardv2 - -// ArduinoBuilderBoardv2FullCollection is the media type for an array of ArduinoBuilderBoardv2 (full view) -// -// Identifier: application/vnd.arduino.builder.boardv2+json; type=collection; view=full -type ArduinoBuilderBoardv2FullCollection []*ArduinoBuilderBoardv2Full - -// DecodeArduinoBuilderBoardv2Collection decodes the ArduinoBuilderBoardv2Collection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2Collection(resp *http.Response) (ArduinoBuilderBoardv2Collection, error) { - var decoded ArduinoBuilderBoardv2Collection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// DecodeArduinoBuilderBoardv2FullCollection decodes the ArduinoBuilderBoardv2FullCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderBoardv2FullCollection(resp *http.Response) (ArduinoBuilderBoardv2FullCollection, error) { - var decoded ArduinoBuilderBoardv2FullCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// ArduinoBuilderCompilationResult is the result of a compilation. -// It contains the output and the eventual errors. -// If successful it contains the generated files. (default view) -// -// Identifier: application/vnd.arduino.builder.compilation.result; view=default -type ArduinoBuilderCompilationResult struct { - // A base64 encoded file with the extension .bin. Can be one of the artifacts generated by the compilation. - Bin *string `form:"bin,omitempty" json:"bin,omitempty" xml:"bin,omitempty"` - // A base64 encoded file with the extension .elf. Can be one of the artifacts generated by the compilation. - Elf *string `form:"elf,omitempty" json:"elf,omitempty" xml:"elf,omitempty"` - // A base64 encoded file with the extension .hex. Can be one of the artifacts generated by the compilation. - Hex *string `form:"hex,omitempty" json:"hex,omitempty" xml:"hex,omitempty"` - // The id of the compilation that has been saved on the database - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The stderr of the compilation. If it's present the compilation wasn't successful. - Stderr *string `form:"stderr,omitempty" json:"stderr,omitempty" xml:"stderr,omitempty"` - // The stdout of the compilation. If the verbose parameter was true it will be much longer. - Stdout *string `form:"stdout,omitempty" json:"stdout,omitempty" xml:"stdout,omitempty"` -} - -// DecodeArduinoBuilderCompilationResult decodes the ArduinoBuilderCompilationResult instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderCompilationResult(resp *http.Response) (*ArduinoBuilderCompilationResult, error) { - var decoded ArduinoBuilderCompilationResult - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// An ArduinoBuilderExample is a simple sketch with the purpose of demonstrating the capabilities of the language. (default view) -// -// Identifier: application/vnd.arduino.builder.example+json; view=default -type ArduinoBuilderExample struct { - // The files contained in the example - Files []*ArduinoBuilderFile `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The folder of the example. It's a way to categorize them, it doesn't necessarily translate to a folder in the filesystem. - Folder *string `form:"folder,omitempty" json:"folder,omitempty" xml:"folder,omitempty"` - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The main file - Ino *ArduinoBuilderFile `form:"ino,omitempty" json:"ino,omitempty" xml:"ino,omitempty"` - // The name of the example - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The path of the example, where to find it on the filesystem - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` - // A list of tags. The builtin tag means that it's a builtin example. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` -} - -// An ArduinoBuilderExampleLink is a simple sketch with the purpose of demonstrating the capabilities of the language. -// (link view) -// Identifier: application/vnd.arduino.builder.example+json; view=link -type ArduinoBuilderExampleLink struct { - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` -} - -// DecodeArduinoBuilderExample decodes the ArduinoBuilderExample instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderExample(resp *http.Response) (*ArduinoBuilderExample, error) { - var decoded ArduinoBuilderExample - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// DecodeArduinoBuilderExampleLink decodes the ArduinoBuilderExampleLink instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderExampleLink(resp *http.Response) (*ArduinoBuilderExampleLink, error) { - var decoded ArduinoBuilderExampleLink - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderExampleCollection is the media type for an array of ArduinoBuilderExample (default view) -// -// Identifier: application/vnd.arduino.builder.example+json; type=collection; view=default -type ArduinoBuilderExampleCollection []*ArduinoBuilderExample - -// ArduinoBuilderExampleLinkCollection is the media type for an array of ArduinoBuilderExample (link view) -// -// Identifier: application/vnd.arduino.builder.example+json; type=collection; view=link -type ArduinoBuilderExampleLinkCollection []*ArduinoBuilderExampleLink - -// DecodeArduinoBuilderExampleCollection decodes the ArduinoBuilderExampleCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderExampleCollection(resp *http.Response) (ArduinoBuilderExampleCollection, error) { - var decoded ArduinoBuilderExampleCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// DecodeArduinoBuilderExampleLinkCollection decodes the ArduinoBuilderExampleLinkCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderExampleLinkCollection(resp *http.Response) (ArduinoBuilderExampleLinkCollection, error) { - var decoded ArduinoBuilderExampleLinkCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// ArduinoBuilderFile represents a file in the filesystem, belonging to a sketch, a library or an example (default view) -// -// Identifier: application/vnd.arduino.builder.file; view=default -type ArduinoBuilderFile struct { - // The contents of the file, in base64 - Data *string `form:"data,omitempty" json:"data,omitempty" xml:"data,omitempty"` - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The last time it has been modified - LastModified *time.Time `form:"last_modified,omitempty" json:"last_modified,omitempty" xml:"last_modified,omitempty"` - // The mimetype of the file. - Mimetype *string `form:"mimetype,omitempty" json:"mimetype,omitempty" xml:"mimetype,omitempty"` - // The name and extension of the file - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The path of the file, where to find it on the filesystem - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` -} - -// DecodeArduinoBuilderFile decodes the ArduinoBuilderFile instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderFile(resp *http.Response) (*ArduinoBuilderFile, error) { - var decoded ArduinoBuilderFile - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderFileCollection is the media type for an array of ArduinoBuilderFile (default view) -// -// Identifier: application/vnd.arduino.builder.file; type=collection; view=default -type ArduinoBuilderFileCollection []*ArduinoBuilderFile - -// DecodeArduinoBuilderFileCollection decodes the ArduinoBuilderFileCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderFileCollection(resp *http.Response) (ArduinoBuilderFileCollection, error) { - var decoded ArduinoBuilderFileCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} - -// ArduinoBuilderLibrary is a collection of header files containing arduino reusable code and functions. -// It typically contains its info in a library.properties files. -// The examples property contains a list of examples that use that library. (default view) -// -// Identifier: application/vnd.arduino.builder.library+json; view=default -type ArduinoBuilderLibrary struct { - // The architectures supported by the library. - Architectures []string `form:"architectures,omitempty" json:"architectures,omitempty" xml:"architectures,omitempty"` - // A category - Category *string `form:"category,omitempty" json:"category,omitempty" xml:"category,omitempty"` - // A snippet of code that includes all of the library header files - Code *string `form:"code,omitempty" json:"code,omitempty" xml:"code,omitempty"` - // The examples contained in the library - Examples []*ArduinoBuilderExample `form:"examples,omitempty" json:"examples,omitempty" xml:"examples,omitempty"` - // The number of examples that it contains - ExamplesNumber *int `form:"examples_number,omitempty" json:"examples_number,omitempty" xml:"examples_number,omitempty"` - // The files contained in the library - Files []*ArduinoBuilderFile `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The id of the library. - // It could be a combination of name and version, a combination of the package and architecture, or an uuid id - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The maintainer of the library - Maintainer *string `form:"maintainer,omitempty" json:"maintainer,omitempty" xml:"maintainer,omitempty"` - // The name of the library, shared between many versions - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // Other versions of this library - OtherVersions []string `form:"other_versions,omitempty" json:"other_versions,omitempty" xml:"other_versions,omitempty"` - // A short description - Sentence *string `form:"sentence,omitempty" json:"sentence,omitempty" xml:"sentence,omitempty"` - // A list of tags. The Arduino tag means that it's a builtin library. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` - // The homepage of the library - URL *string `form:"url,omitempty" json:"url,omitempty" xml:"url,omitempty"` - // The version of the library - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// ArduinoBuilderLibraryLink is a collection of header files containing arduino reusable code and functions. -// It typically contains its info in a library.properties files. -// The examples property contains a list of examples that use that library. (link view) -// -// Identifier: application/vnd.arduino.builder.library+json; view=link -type ArduinoBuilderLibraryLink struct { - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` -} - -// DecodeArduinoBuilderLibrary decodes the ArduinoBuilderLibrary instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderLibrary(resp *http.Response) (*ArduinoBuilderLibrary, error) { - var decoded ArduinoBuilderLibrary - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// DecodeArduinoBuilderLibraryLink decodes the ArduinoBuilderLibraryLink instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderLibraryLink(resp *http.Response) (*ArduinoBuilderLibraryLink, error) { - var decoded ArduinoBuilderLibraryLink - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderSlimlibrary is a partial view of a library. (default view) -// -// Identifier: application/vnd.arduino.builder.slimlibrary+json; view=default -type ArduinoBuilderSlimlibrary struct { - // The architectures supported by the library. - Architectures []string `form:"architectures,omitempty" json:"architectures,omitempty" xml:"architectures,omitempty"` - // A category - Category *string `form:"category,omitempty" json:"category,omitempty" xml:"category,omitempty"` - // A snippet of code that includes all of the library header files - Code *string `form:"code,omitempty" json:"code,omitempty" xml:"code,omitempty"` - // The number of examples that it contains - ExamplesNumber *int `form:"examples_number,omitempty" json:"examples_number,omitempty" xml:"examples_number,omitempty"` - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The id of the library. - // It could be a combination of name and version, a combination of the package and architecture, or an uuid id - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The maintainer of the library - Maintainer *string `form:"maintainer,omitempty" json:"maintainer,omitempty" xml:"maintainer,omitempty"` - // The name of the library, shared between many versions - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // A short description - Sentence *string `form:"sentence,omitempty" json:"sentence,omitempty" xml:"sentence,omitempty"` - // A list of tags. The Arduino tag means that it's a builtin library. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` - // The homepage of the library - URL *string `form:"url,omitempty" json:"url,omitempty" xml:"url,omitempty"` - // The version of the library - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// DecodeArduinoBuilderSlimlibrary decodes the ArduinoBuilderSlimlibrary instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderSlimlibrary(resp *http.Response) (*ArduinoBuilderSlimlibrary, error) { - var decoded ArduinoBuilderSlimlibrary - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoBuilderSlimlibraryCollection is the media type for an array of ArduinoBuilderSlimlibrary (default view) -// -// Identifier: application/vnd.arduino.builder.slimlibrary+json; type=collection; view=default -type ArduinoBuilderSlimlibraryCollection []*ArduinoBuilderSlimlibrary - -// DecodeArduinoBuilderSlimlibraryCollection decodes the ArduinoBuilderSlimlibraryCollection instance encoded in resp body. -func (c *Client) DecodeArduinoBuilderSlimlibraryCollection(resp *http.Response) (ArduinoBuilderSlimlibraryCollection, error) { - var decoded ArduinoBuilderSlimlibraryCollection - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return decoded, err -} diff --git a/builder_client_helpers/pinned_libraries.go b/builder_client_helpers/pinned_libraries.go deleted file mode 100644 index 3360c646ea8..00000000000 --- a/builder_client_helpers/pinned_libraries.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// AddPinnedLibrariesPath computes a request path to the add action of pinnedLibraries. -func AddPinnedLibrariesPath(id string) string { - param0 := id - - return fmt.Sprintf("/builder/pinned/%s", param0) -} - -// AddPinnedLibraries adds a new library to the list of libraries pinned by the user -func (c *Client) AddPinnedLibraries(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewAddPinnedLibrariesRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewAddPinnedLibrariesRequest creates the request -// corresponding to the add action endpoint of the pinnedLibraries resource. -func (c *Client) NewAddPinnedLibrariesRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("PUT", u.String(), nil) - if err != nil { - return nil, err - } - if c.Oauth2Signer != nil { - c.Oauth2Signer.Sign(req) - } - return req, nil -} - -// ListPinnedLibrariesPath computes a request path to the list action of pinnedLibraries. -func ListPinnedLibrariesPath() string { - return fmt.Sprintf("/builder/pinned") -} - -// ListPinnedLibraries provides a list of all the libraries pinned by the user -func (c *Client) ListPinnedLibraries(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewListPinnedLibrariesRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewListPinnedLibrariesRequest creates the request corresponding to the list action endpoint of the pinnedLibraries resource. -func (c *Client) NewListPinnedLibrariesRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - if c.Oauth2Signer != nil { - c.Oauth2Signer.Sign(req) - } - return req, nil -} - -// RemovePinnedLibrariesPath computes a request path to the remove action of pinnedLibraries. -func RemovePinnedLibrariesPath(id string) string { - param0 := id - - return fmt.Sprintf("/builder/pinned/%s", param0) -} - -// RemovePinnedLibraries removes a library to the list of libraries pinned by the user -func (c *Client) RemovePinnedLibraries(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewRemovePinnedLibrariesRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewRemovePinnedLibrariesRequest creates the request corresponding to the remove action endpoint of the pinnedLibraries resource. -func (c *Client) NewRemovePinnedLibrariesRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("DELETE", u.String(), nil) - if err != nil { - return nil, err - } - if c.Oauth2Signer != nil { - c.Oauth2Signer.Sign(req) - } - return req, nil -} diff --git a/builder_client_helpers/public.go b/builder_client_helpers/public.go deleted file mode 100644 index 9416f7f3f38..00000000000 --- a/builder_client_helpers/public.go +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -/* -import ( - "context" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" -) - -// DownloadDocs downloads docs.html and writes it to the file dest. -// It returns the number of bytes downloaded in case of success. -func (c *Client) DownloadDocs(ctx context.Context, dest string) (int64, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: "/builder/docs"} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return 0, err - } - resp, err := c.Client.Do(ctx, req) - if err != nil { - return 0, err - } - if resp.StatusCode != 200 { - var body string - if b, err := ioutil.ReadAll(resp.Body); err != nil { - if len(b) > 0 { - body = ": " + string(b) - } - } - return 0, fmt.Errorf("%s%s", resp.Status, body) - } - defer resp.Body.Close() - out, err := os.Create(dest) - if err != nil { - return 0, err - } - defer out.Close() - return io.Copy(out, resp.Body) -} - -// DownloadSwaggerJSON downloads swagger.json and writes it to the file dest. -// It returns the number of bytes downloaded in case of success. -func (c *Client) DownloadSwaggerJSON(ctx context.Context, dest string) (int64, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: "/builder/v1/swagger.json"} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return 0, err - } - resp, err := c.Client.Do(ctx, req) - if err != nil { - return 0, err - } - if resp.StatusCode != 200 { - var body string - if b, err := ioutil.ReadAll(resp.Body); err != nil { - if len(b) > 0 { - body = ": " + string(b) - } - } - return 0, fmt.Errorf("%s%s", resp.Status, body) - } - defer resp.Body.Close() - out, err := os.Create(dest) - if err != nil { - return 0, err - } - defer out.Close() - return io.Copy(out, resp.Body) -} - -// DownloadSwaggerJSON downloads swagger.json and writes it to the file dest. -// It returns the number of bytes downloaded in case of success. -func (c *Client) DownloadSwaggerJSON(ctx context.Context, dest string) (int64, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: "/builder/swagger.json"} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return 0, err - } - resp, err := c.Client.Do(ctx, req) - if err != nil { - return 0, err - } - if resp.StatusCode != 200 { - var body string - if b, err := ioutil.ReadAll(resp.Body); err != nil { - if len(b) > 0 { - body = ": " + string(b) - } - } - return 0, fmt.Errorf("%s%s", resp.Status, body) - } - defer resp.Body.Close() - out, err := os.Create(dest) - if err != nil { - return 0, err - } - defer out.Close() - return io.Copy(out, resp.Body) -} -*/ diff --git a/builder_client_helpers/user_types.go b/builder_client_helpers/user_types.go deleted file mode 100644 index b4bb9440c7d..00000000000 --- a/builder_client_helpers/user_types.go +++ /dev/null @@ -1,570 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package builderclient - -import ( - "github.com/goadesign/goa" -) - -// A compilation is made up of a sketch (or a path to a sketch) and an fqbn. -// Eventual libraries are automatically determined and linked. -// NOTE: swagger will force you to define the files inside the sketch because of a bug. But they are not mandatory. -type compilation struct { - // The fully qualified board name - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` - // The path of the sketch or example to compile. Mandatory if sketch parameter is missing. - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` - // The full sketch to compile. Mandatory if path parameter is missing. - Sketch *sketch `form:"sketch,omitempty" json:"sketch,omitempty" xml:"sketch,omitempty"` - // An option stating if the output should be verbose. Defaults to false. - Verbose *bool `form:"verbose,omitempty" json:"verbose,omitempty" xml:"verbose,omitempty"` -} - -// Finalize sets the default values for compilation type instance. -func (ut *compilation) Finalize() { - var defaultVerbose = false - if ut.Verbose == nil { - ut.Verbose = &defaultVerbose - } -} - -// Validate validates the compilation type instance. -func (ut *compilation) Validate() (err error) { - if ut.Fqbn == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "fqbn")) - } - if ut.Sketch != nil { - if err2 := ut.Sketch.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - return -} - -// Publicize creates Compilation from compilation -func (ut *compilation) Publicize() *Compilation { - var pub Compilation - if ut.Fqbn != nil { - pub.Fqbn = *ut.Fqbn - } - if ut.Path != nil { - pub.Path = ut.Path - } - if ut.Sketch != nil { - pub.Sketch = ut.Sketch.Publicize() - } - if ut.Verbose != nil { - pub.Verbose = *ut.Verbose - } - return &pub -} - -// A Compilation is made up of a sketch (or a path to a sketch) and an fqbn. -// Eventual libraries are automatically determined and linked. -// NOTE: swagger will force you to define the files inside the sketch because of a bug. But they are not mandatory. -type Compilation struct { - // The fully qualified board name - Fqbn string `form:"fqbn" json:"fqbn" xml:"fqbn"` - // The path of the sketch or example to compile. Mandatory if sketch parameter is missing. - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` - // The full sketch to compile. Mandatory if path parameter is missing. - Sketch *Sketch `form:"sketch,omitempty" json:"sketch,omitempty" xml:"sketch,omitempty"` - // An option stating if the output should be verbose. Defaults to false. - Verbose bool `form:"verbose" json:"verbose" xml:"verbose"` -} - -// Validate validates the Compilation type instance. -func (ut *Compilation) Validate() (err error) { - if ut.Fqbn == "" { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "fqbn")) - } - if ut.Sketch != nil { - if err2 := ut.Sketch.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - return -} - -// An example is a simple sketch with the purpose of demonstrating the capabilities of the language. -type example struct { - // Other files contained in the example - Files []*filemeta `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The folder of the example. It's a way to categorize them, it doesn't necessarily translate to a folder in the filesystem. - Folder *string `form:"folder,omitempty" json:"folder,omitempty" xml:"folder,omitempty"` - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The main file - Ino *filemeta `form:"ino,omitempty" json:"ino,omitempty" xml:"ino,omitempty"` - // The name of the example - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The path of the example, where to find it on the filesystem - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` - // A list of tags. The builtin tag means that it's a builtin example. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` -} - -// Validate validates the example type instance. -func (ut *example) Validate() (err error) { - for _, e := range ut.Files { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - if ut.Ino != nil { - if err2 := ut.Ino.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - return -} - -// Publicize creates Example from example -func (ut *example) Publicize() *Example { - var pub Example - if ut.Files != nil { - pub.Files = make([]*Filemeta, len(ut.Files)) - for i2, elem2 := range ut.Files { - pub.Files[i2] = elem2.Publicize() - } - } - if ut.Folder != nil { - pub.Folder = ut.Folder - } - if ut.Href != nil { - pub.Href = ut.Href - } - if ut.Ino != nil { - pub.Ino = ut.Ino.Publicize() - } - if ut.Name != nil { - pub.Name = ut.Name - } - if ut.Path != nil { - pub.Path = ut.Path - } - if ut.Types != nil { - pub.Types = ut.Types - } - return &pub -} - -// An example is a simple sketch with the purpose of demonstrating the capabilities of the language. -type Example struct { - // Other files contained in the example - Files []*Filemeta `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The folder of the example. It's a way to categorize them, it doesn't necessarily translate to a folder in the filesystem. - Folder *string `form:"folder,omitempty" json:"folder,omitempty" xml:"folder,omitempty"` - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The main file - Ino *Filemeta `form:"ino,omitempty" json:"ino,omitempty" xml:"ino,omitempty"` - // The name of the example - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The path of the example, where to find it on the filesystem - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` - // A list of tags. The builtin tag means that it's a builtin example. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` -} - -// Validate validates the Example type instance. -func (ut *Example) Validate() (err error) { - for _, e := range ut.Files { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - if ut.Ino != nil { - if err2 := ut.Ino.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - return -} - -// FileFull represent a file in the filesystem, belonging to a sketch, a library or an example. Must contain a data property with the content of the file. -type filefull struct { - // The contents of the file, in base64 - Data *string `form:"data,omitempty" json:"data,omitempty" xml:"data,omitempty"` - // The name and extension of the file - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` -} - -// Validate validates the filefull type instance. -func (ut *filefull) Validate() (err error) { - if ut.Name == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "name")) - } - if ut.Data == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "data")) - } - return -} - -// Publicize creates Filefull from filefull -func (ut *filefull) Publicize() *Filefull { - var pub Filefull - if ut.Data != nil { - pub.Data = *ut.Data - } - if ut.Name != nil { - pub.Name = *ut.Name - } - return &pub -} - -// FileFull represent a file in the filesystem, belonging to a sketch, a library or an example. Must contain a data property with the content of the file. -type Filefull struct { - // The contents of the file, in base64 - Data string `form:"data" json:"data" xml:"data"` - // The name and extension of the file - Name string `form:"name" json:"name" xml:"name"` -} - -// Validate validates the Filefull type instance. -func (ut *Filefull) Validate() (err error) { - if ut.Name == "" { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "name")) - } - if ut.Data == "" { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "data")) - } - return -} - -// FileMeta represent a file in the filesystem, belonging to a sketch, a library or an example. Can contain a data property with the content of the file. -type filemeta struct { - // The contents of the file, in base64 - Data *string `form:"data,omitempty" json:"data,omitempty" xml:"data,omitempty"` - // The name and extension of the file - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` -} - -// Validate validates the filemeta type instance. -func (ut *filemeta) Validate() (err error) { - if ut.Name == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "name")) - } - return -} - -// Publicize creates Filemeta from filemeta -func (ut *filemeta) Publicize() *Filemeta { - var pub Filemeta - if ut.Data != nil { - pub.Data = ut.Data - } - if ut.Name != nil { - pub.Name = *ut.Name - } - return &pub -} - -// FileMeta represent a file in the filesystem, belonging to a sketch, a library or an example. -// Can contain a data property with the content of the file. -type Filemeta struct { - // The contents of the file, in base64 - Data *string `form:"data,omitempty" json:"data,omitempty" xml:"data,omitempty"` - // The name and extension of the file - Name string `form:"name" json:"name" xml:"name"` -} - -// Validate validates the Filemeta type instance. -func (ut *Filemeta) Validate() (err error) { - if ut.Name == "" { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "name")) - } - return -} - -// Library is a collection of header files containing arduino reusable code and functions. -// It typically contains its info in a library.properties files. -// The examples property contains a list of examples that use that library. -type library struct { - // The architectures supported by the library. - Architectures []string `form:"architectures,omitempty" json:"architectures,omitempty" xml:"architectures,omitempty"` - // A category - Category *string `form:"category,omitempty" json:"category,omitempty" xml:"category,omitempty"` - // A snippet of code that includes all of the library header files - Code *string `form:"code,omitempty" json:"code,omitempty" xml:"code,omitempty"` - // The examples contained in the library - Examples []*example `form:"examples,omitempty" json:"examples,omitempty" xml:"examples,omitempty"` - // The number of examples that it contains - ExamplesNumber *int `form:"examples_number,omitempty" json:"examples_number,omitempty" xml:"examples_number,omitempty"` - // The files contained in the library - Files []*filemeta `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The id of the library. It could be a combination of name and version, a combination of the package and architecture, or an uuid id - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The maintainer of the library - Maintainer *string `form:"maintainer,omitempty" json:"maintainer,omitempty" xml:"maintainer,omitempty"` - // The name of the library, shared between many versions - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // A short description - Sentence *string `form:"sentence,omitempty" json:"sentence,omitempty" xml:"sentence,omitempty"` - // A list of tags. The Arduino tag means that it's a builtin library. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` - // The homepage of the library - URL *string `form:"url,omitempty" json:"url,omitempty" xml:"url,omitempty"` - // The version of the library - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// Validate validates the library type instance. -func (ut *library) Validate() (err error) { - for _, e := range ut.Examples { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - for _, e := range ut.Files { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - return -} - -// Publicize creates Library from library -func (ut *library) Publicize() *Library { - var pub Library - if ut.Architectures != nil { - pub.Architectures = ut.Architectures - } - if ut.Category != nil { - pub.Category = ut.Category - } - if ut.Code != nil { - pub.Code = ut.Code - } - if ut.Examples != nil { - pub.Examples = make([]*Example, len(ut.Examples)) - for i2, elem2 := range ut.Examples { - pub.Examples[i2] = elem2.Publicize() - } - } - if ut.ExamplesNumber != nil { - pub.ExamplesNumber = ut.ExamplesNumber - } - if ut.Files != nil { - pub.Files = make([]*Filemeta, len(ut.Files)) - for i2, elem2 := range ut.Files { - pub.Files[i2] = elem2.Publicize() - } - } - if ut.ID != nil { - pub.ID = ut.ID - } - if ut.Maintainer != nil { - pub.Maintainer = ut.Maintainer - } - if ut.Name != nil { - pub.Name = ut.Name - } - if ut.Sentence != nil { - pub.Sentence = ut.Sentence - } - if ut.Types != nil { - pub.Types = ut.Types - } - if ut.URL != nil { - pub.URL = ut.URL - } - if ut.Version != nil { - pub.Version = ut.Version - } - return &pub -} - -// Library is a collection of header files containing arduino reusable code and functions. -// It typically contains its info in a library.properties files. -// The examples property contains a list of examples that use that library. -type Library struct { - // The architectures supported by the library. - Architectures []string `form:"architectures,omitempty" json:"architectures,omitempty" xml:"architectures,omitempty"` - // A category - Category *string `form:"category,omitempty" json:"category,omitempty" xml:"category,omitempty"` - // A snippet of code that includes all of the library header files - Code *string `form:"code,omitempty" json:"code,omitempty" xml:"code,omitempty"` - // The examples contained in the library - Examples []*Example `form:"examples,omitempty" json:"examples,omitempty" xml:"examples,omitempty"` - // The number of examples that it contains - ExamplesNumber *int `form:"examples_number,omitempty" json:"examples_number,omitempty" xml:"examples_number,omitempty"` - // The files contained in the library - Files []*Filemeta `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The id of the library. It could be a combination of name and version, a combination of the package and architecture, or an uuid id - ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The maintainer of the library - Maintainer *string `form:"maintainer,omitempty" json:"maintainer,omitempty" xml:"maintainer,omitempty"` - // The name of the library, shared between many versions - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // A short description - Sentence *string `form:"sentence,omitempty" json:"sentence,omitempty" xml:"sentence,omitempty"` - // A list of tags. The Arduino tag means that it's a builtin library. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` - // The homepage of the library - URL *string `form:"url,omitempty" json:"url,omitempty" xml:"url,omitempty"` - // The version of the library - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// Validate validates the Library type instance. -func (ut *Library) Validate() (err error) { - for _, e := range ut.Examples { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - for _, e := range ut.Files { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - return -} - -// pinnedLib user type. -type pinnedLib struct { - // The slugified name of the library - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The version of the library. Can be latest - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// Publicize creates PinnedLib from pinnedLib -func (ut *pinnedLib) Publicize() *PinnedLib { - var pub PinnedLib - if ut.Name != nil { - pub.Name = ut.Name - } - if ut.Version != nil { - pub.Version = ut.Version - } - return &pub -} - -// PinnedLib user type. -type PinnedLib struct { - // The slugified name of the library - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The version of the library. Can be latest - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// A sketch is a program intended to run on an arduino board. -// It's composed by a main .ino file and optional other files. -// You should upload only .ino and .h files. -type sketch struct { - // Other files contained in the example - Files []*filefull `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The main file - Ino *filefull `form:"ino,omitempty" json:"ino,omitempty" xml:"ino,omitempty"` - Metadata *struct { - IncludedLibs []*pinnedLib `form:"included_libs,omitempty" json:"included_libs,omitempty" xml:"included_libs,omitempty"` - } `form:"metadata,omitempty" json:"metadata,omitempty" xml:"metadata,omitempty"` - // The name of the sketch - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` -} - -// Validate validates the sketch type instance. -func (ut *sketch) Validate() (err error) { - for _, e := range ut.Files { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - if ut.Ino != nil { - if err2 := ut.Ino.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - return -} - -// Publicize creates Sketch from sketch -func (ut *sketch) Publicize() *Sketch { - var pub Sketch - if ut.Files != nil { - pub.Files = make([]*Filefull, len(ut.Files)) - for i2, elem2 := range ut.Files { - pub.Files[i2] = elem2.Publicize() - } - } - if ut.Ino != nil { - pub.Ino = ut.Ino.Publicize() - } - if ut.Metadata != nil { - pub.Metadata = &struct { - IncludedLibs []*PinnedLib `form:"included_libs,omitempty" json:"included_libs,omitempty" xml:"included_libs,omitempty"` - }{} - if ut.Metadata.IncludedLibs != nil { - pub.Metadata.IncludedLibs = make([]*PinnedLib, len(ut.Metadata.IncludedLibs)) - for i3, elem3 := range ut.Metadata.IncludedLibs { - pub.Metadata.IncludedLibs[i3] = elem3.Publicize() - } - } - } - if ut.Name != nil { - pub.Name = ut.Name - } - return &pub -} - -// A sketch is a program intended to run on an arduino board. -// It's composed by a main .ino file and optional other files. You should upload only .ino and .h files. -type Sketch struct { - // Other files contained in the example - Files []*Filefull `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The main file - Ino *Filefull `form:"ino,omitempty" json:"ino,omitempty" xml:"ino,omitempty"` - Metadata *struct { - IncludedLibs []*PinnedLib `form:"included_libs,omitempty" json:"included_libs,omitempty" xml:"included_libs,omitempty"` - } `form:"metadata,omitempty" json:"metadata,omitempty" xml:"metadata,omitempty"` - // The name of the sketch - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` -} - -// Validate validates the Sketch type instance. -func (ut *Sketch) Validate() (err error) { - for _, e := range ut.Files { - if e != nil { - if err2 := e.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - } - if ut.Ino != nil { - if err2 := ut.Ino.Validate(); err2 != nil { - err = goa.MergeErrors(err, err2) - } - } - return -} diff --git a/commands/sketch/sync.go b/commands/sketch/sync.go deleted file mode 100644 index 11f399b62af..00000000000 --- a/commands/sketch/sync.go +++ /dev/null @@ -1,469 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package sketch - -import ( - "context" - "encoding/base64" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" - - "github.com/arduino/arduino-cli/auth" - "github.com/arduino/arduino-cli/commands" - "github.com/arduino/arduino-cli/common/formatter" - "github.com/arduino/arduino-cli/common/formatter/output" - "github.com/arduino/arduino-cli/create_client_helpers" - "github.com/arduino/go-paths-helper" - "github.com/bcmi-labs/arduino-modules/sketches" - "github.com/bgentry/go-netrc/netrc" - "github.com/briandowns/spinner" - homedir "github.com/mitchellh/go-homedir" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -const ( - priorityPullRemote = "pull-remote" - priorityPushLocal = "push-local" - prioritySkip = "skip" -) - -func initSyncCommand() *cobra.Command { - syncCommand := &cobra.Command{ - Use: "sync", - Short: "Arduino CLI Sketch Commands.", - Long: "Arduino CLI Sketch Commands.", - Example: " " + commands.AppName + " sketch sync", - Args: cobra.NoArgs, - Run: runSyncCommand, - } - usage := "The decision made by default on conflicting sketches. Can be push-local, pull-remote, skip, ask-once, ask-always." - syncCommand.Flags().StringVar(&syncFlags.priority, "conflict-policy", prioritySkip, usage) - return syncCommand -} - -var syncFlags struct { - priority string // The decisive resource when we have conflicts. Can be local, remote, skip-conflict. -} - -func runSyncCommand(cmd *cobra.Command, args []string) { - logrus.Info("Executing `arduino sketch sync`") - - sketchbook := commands.Config.SketchbookDir - isTextMode := formatter.IsCurrentFormat("text") - - logrus.Info("Setting priority") - priority := syncFlags.priority - - if priority == "ask-once" { - if !isTextMode { - formatter.PrintErrorMessage("Ask mode for this command is only supported using text format.") - os.Exit(commands.ErrBadCall) - } - firstAsk := true - for priority != priorityPullRemote && - priority != priorityPushLocal && - priority != prioritySkip { - if !firstAsk { - formatter.Print("Invalid option: " + priority) - } - formatter.Print("What should I do when I detect a conflict? [pull-remote | push-local | skip]") - fmt.Scanln(&priority) - firstAsk = false - } - } - - logrus.Infof("Priority set to %s", priority) - - logrus.Info("Preparing") - - var loader *spinner.Spinner - - if isTextMode && !commands.GlobalFlags.Debug { - loader = spinner.New(spinner.CharSets[27], 100*time.Millisecond) - loader.Prefix = "Syncing Sketches... " - - loader.Start() - } - - stopSpinner := func() { - if isTextMode && !commands.GlobalFlags.Debug { - loader.Stop() - } - } - - startSpinner := func() { - if isTextMode && !commands.GlobalFlags.Debug { - loader.Start() - } - } - - logrus.Info("Logging in") - username, bearerToken, err := login() - if err != nil { - stopSpinner() - formatter.PrintError(err, "Cannot login") - os.Exit(commands.ErrNetwork) - } - - logrus.Info("Finding local sketches") - sketchMap := sketches.Find(sketchbook.String(), "libraries") // Exclude libraries dirs. - - logrus.Info("Finding online sketches") - client := createclient.New(nil) - tok := "Bearer " + bearerToken - resp, err := client.SearchSketches(context.Background(), createclient.SearchSketchesPath(), nil, &username, &tok) - if err != nil { - stopSpinner() - formatter.PrintError(err, "Cannot get create sketches, sync failed.") - os.Exit(commands.ErrNetwork) - } - defer resp.Body.Close() - - onlineSketches, err := client.DecodeArduinoCreateSketches(resp) - if err != nil { - stopSpinner() - formatter.PrintError(err, "Cannot unmarshal response from create, sync failed.") - os.Exit(commands.ErrGeneric) - } - - onlineSketchesMap := make(map[string]*createclient.ArduinoCreateSketch, len(onlineSketches.Sketches)) - for _, item := range onlineSketches.Sketches { - onlineSketchesMap[*item.Name] = item - } - - maxLength := len(sketchMap) + len(onlineSketchesMap) - - logrus.Info("Syncing sketches") - // Create output result struct with empty arrays. - result := output.SketchSyncResult{ - PushedSketches: make([]string, 0, maxLength), - PulledSketches: make([]string, 0, maxLength), - SkippedSketches: make([]string, 0, maxLength), - Errors: make([]output.SketchSyncError, 0, maxLength), - } - - for _, item := range sketchMap { - itemOnline, hasConflict := onlineSketchesMap[item.Name] - if hasConflict { - logrus.Warnf("Conflict found for sketch `%s`", item.Name) - item.ID = itemOnline.ID.String() - // Resolve conflicts. - if priority == "ask-always" { - stopSpinner() - - logrus.Warn("Asking user what to do") - if !isTextMode { - logrus.WithField("format", commands.GlobalFlags.Format).Error("ask mode for this command is only supported using text format") - formatter.PrintErrorMessage("ask mode for this command is only supported using text format.") - os.Exit(commands.ErrBadCall) - } - - firstAsk := true - for priority != priorityPullRemote && - priority != priorityPushLocal && - priority != prioritySkip { - if !firstAsk { - formatter.Print("Invalid option: " + priority) - } - formatter.Print(fmt.Sprintf("Conflict detected for `%s` sketch, what should I do? [pull-remote | push-local | skip]", item.Name)) - fmt.Scanln(&priority) - firstAsk = false - } - logrus.Warnf("Decision has been taken: %s", priority) - - startSpinner() - } - switch priority { - case priorityPushLocal: - logrus.Infof("Pushing local sketch `%s` as edit", item.Name) - err := editSketch(*item, sketchbook, bearerToken) - if err != nil { - logrus.WithError(err).Warnf("Cannot push `%s`", item.Name) - result.Errors = append(result.Errors, output.SketchSyncError{ - Sketch: item.Name, - Error: err, - }) - } else { - logrus.Infof("`%s` pushed", item.Name) - result.PushedSketches = append(result.PushedSketches, item.Name) - } - break - case priorityPullRemote: - logrus.Infof("Pulling remote sketch `%s`", item.Name) - err := pullSketch(itemOnline, sketchbook, bearerToken) - if err != nil { - logrus.WithError(err).Warnf("Cannot pull `%s`", item.Name) - result.Errors = append(result.Errors, output.SketchSyncError{ - Sketch: item.Name, - Error: err, - }) - } else { - logrus.Infof("`%s` pulled", item.Name) - result.PulledSketches = append(result.PulledSketches, item.Name) - } - break - case prioritySkip: - logrus.Warnf("Skipping `%s`", item.Name) - result.SkippedSketches = append(result.SkippedSketches, item.Name) - break - default: - logrus.Warnf("Skipping by default `%s`", item.Name) - priority = prioritySkip - result.SkippedSketches = append(result.SkippedSketches, item.Name) - } - } else { // Only local, push. - logrus.Infof("No conflict, pushing `%s` as new sketch", item.Name) - err := pushSketch(*item, sketchbook, bearerToken) - if err != nil { - logrus.WithError(err).Warnf("Cannot push `%s`", item.Name) - result.Errors = append(result.Errors, output.SketchSyncError{ - Sketch: item.Name, - Error: err, - }) - } else { - logrus.Infof("`%s` pushed", item.Name) - result.PushedSketches = append(result.PushedSketches, item.Name) - } - } - } - for _, item := range onlineSketches.Sketches { - if sketchMap[*item.Name] != nil { - continue - } - // Only online, pull. - logrus.Infof("Pulling only online sketch `%s`", *item.Name) - err := pullSketch(item, sketchbook, bearerToken) - if err != nil { - logrus.WithError(err).Warnf("Cannot pull `%s`", *item.Name) - result.Errors = append(result.Errors, output.SketchSyncError{ - Sketch: *item.Name, - Error: err, - }) - } else { - logrus.Infof("`%s` pulled", *item.Name) - result.PulledSketches = append(result.PulledSketches, *item.Name) - } - } - - stopSpinner() - formatter.Print(result) - logrus.Info("Done") -} - -func pushSketch(sketch sketches.Sketch, sketchbook *paths.Path, bearerToken string) error { - client := createclient.New(nil) - - resp, err := client.CreateSketches(context.Background(), createclient.CreateSketchesPath(), createclient.ConvertFrom(sketch), "Bearer "+bearerToken) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - errorMsg, err := client.DecodeErrorResponse(resp) - if err != nil { - return errors.New(resp.Status) - } - return errorMsg - } - _, err = client.DecodeArduinoCreateSketch(resp) - if err != nil { - return err - } - - return nil -} - -func editSketch(sketch sketches.Sketch, sketchbook *paths.Path, bearerToken string) error { - client := createclient.New(nil) - resp, err := client.EditSketches( - context.Background(), - createclient.EditSketchesPath(sketch.ID), - createclient.ConvertFrom(sketch), - "Bearer "+bearerToken) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - errorMsg, err := client.DecodeErrorResponse(resp) - if err != nil { - return errors.New(resp.Status) - } - return errorMsg - } - _, err = client.DecodeArduinoCreateSketch(resp) - if err != nil { - return err - } - - return nil -} - -func pullSketch(sketch *createclient.ArduinoCreateSketch, sketchbook *paths.Path, bearerToken string) error { - client := createclient.New(nil) - bearer := "Bearer " + bearerToken - - resp, err := client.ShowSketches(context.Background(), createclient.ShowSketchesPath(fmt.Sprint(sketch.ID)), &bearer) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - errorMsg, err := client.DecodeErrorResponse(resp) - if err != nil { - return errors.New(resp.Status) - } - return errorMsg - } - - r, err := client.DecodeArduinoCreateSketch(resp) - if err != nil { - return err - } - - sketchDir, err := sketchbook.MkTempDir(fmt.Sprintf("%s-temp", *sketch.Name)) - if err != nil { - return err - } - defer sketchDir.RemoveAll() - - destDir := sketchbook.Join(*sketch.Name) - - for _, file := range append(r.Files, sketch.Ino) { - path := findPathOf(*sketch.Name, *file.Path) - - err = os.MkdirAll(filepath.Dir(path), 0755) - if err != nil { - return err - } - - resp, err = client.ShowFiles(context.Background(), createclient.ShowFilesPath("sketch", sketch.ID.String(), path)) - if err != nil { - return err - } - filewithData, err := client.DecodeArduinoCreateFile(resp) - if err != nil { - if resp.StatusCode != 200 { - errResp, err := client.DecodeErrorResponse(resp) - if err != nil { - return errors.New(resp.Status) - } - return errResp - } - } - - decodedData, err := base64.StdEncoding.DecodeString(*filewithData.Data) - if err != nil { - return err - } - - destFile := sketchDir.Join(path) - err = destFile.WriteFile(decodedData) - if err != nil { - return errors.New("copy of a file of the downloaded sketch failed, sync failed") - } - } - - if err := destDir.RemoveAll(); err != nil { - return err - } - - err = sketchDir.Rename(destDir) - if err != nil { - return err - } - return nil -} - -func findPathOf(sketchName string, path string) string { - list := strings.Split(path, "/") - - for i := len(list) - 1; i > -1; i-- { - //fmt.Println(list[i], "==", sketchName, "?", list[i] == sketchName) - if list[i] == sketchName { - return filepath.Join(list[i+1:]...) - } - } - return "" -} - -func login() (string, string, error) { - authConf := auth.New() - - home, err := homedir.Dir() - if err != nil { - return "", "", err - } - - logrus.Info("Reading ~/.netrc file") - netRCFile := filepath.Join(home, ".netrc") - file, err := os.OpenFile(netRCFile, os.O_CREATE|os.O_RDONLY, 0666) - if err != nil { - logrus.WithError(err).Error("Cannot read ~/.netrc file") - return "", "", err - } - NetRC, err := netrc.Parse(file) - if err != nil { - logrus.WithError(err).Error("Cannot parse ~/.netrc file") - return "", "", err - } - - logrus.Info("Searching for user credentials into the ~/.netrc file") - arduinoMachine := NetRC.FindMachine("arduino.cc") - if arduinoMachine == nil || arduinoMachine.Name != "arduino.cc" { - logrus.WithError(err).Error("Credentials not found") - return "", "", errors.New("credentials not found, try typing `arduino login` to login") - } - - logrus.Info("Refreshing user session") - newToken, err := authConf.Refresh(arduinoMachine.Password) - if err != nil { - logrus.WithError(err).Error("Session expired, try typing `arduino login` to login again") - return "", "", err - } - - var token string - if newToken.TTL != 0 { // We haven't recently requested a valid token, which is in .netrc under "account", so we have to update it. - arduinoMachine.UpdatePassword(newToken.Refresh) - arduinoMachine.UpdateAccount(newToken.Access) - token = newToken.Access - } else { - token = arduinoMachine.Account - } - - content, err := NetRC.MarshalText() - if err == nil { //serialize new info - err = ioutil.WriteFile(netRCFile, content, 0666) - if err != nil { - logrus.WithError(err).Error("Cannot write new ~/.netrc file") - } - } else { - logrus.WithError(err).Error("Cannot serialize ~/.netrc file") - } - logrus.Info("Login successful") - return arduinoMachine.Login, token, nil -} diff --git a/common/formatter/text.go b/common/formatter/text.go index 4486c350869..9860c833477 100644 --- a/common/formatter/text.go +++ b/common/formatter/text.go @@ -23,7 +23,6 @@ import ( "time" "go.bug.st/downloader" - pb "gopkg.in/cheggaaa/pb.v1" ) diff --git a/create_client_helpers/alive.go b/create_client_helpers/alive.go deleted file mode 100644 index e5a33f2e6b7..00000000000 --- a/create_client_helpers/alive.go +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package createclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// PingAlivePath computes a request path to the ping action of alive. -func PingAlivePath() string { - - return fmt.Sprintf("/create/alive") -} - -// Returns 200 if the instance is healthy. -func (c *Client) PingAlive(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewPingAliveRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewPingAliveRequest creates the request corresponding to the ping action endpoint of the alive resource. -func (c *Client) NewPingAliveRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/create_client_helpers/client.go b/create_client_helpers/client.go deleted file mode 100644 index bbdc7498787..00000000000 --- a/create_client_helpers/client.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package createclient - -import ( - "github.com/goadesign/goa" - goaclient "github.com/goadesign/goa/client" -) - -// Client is the ArduinoCreateV1 service client. -type Client struct { - *goaclient.Client - SsoSigner goaclient.Signer - Encoder *goa.HTTPEncoder - Decoder *goa.HTTPDecoder -} - -// New instantiates the client. -func New(c goaclient.Doer) *Client { - client := &Client{ - Client: goaclient.New(c), - Encoder: goa.NewHTTPEncoder(), - Decoder: goa.NewHTTPDecoder(), - } - - // Setup encoders and decoders - client.Encoder.Register(goa.NewJSONEncoder, "application/json") - client.Decoder.Register(goa.NewJSONDecoder, "application/json") - - // Setup default encoder and decoder - client.Encoder.Register(goa.NewJSONEncoder, "*/*") - client.Decoder.Register(goa.NewJSONDecoder, "*/*") - - return client -} - -// SetSsoSigner sets the request signer for the sso security scheme. -func (c *Client) SetSsoSigner(signer goaclient.Signer) { - c.SsoSigner = signer -} diff --git a/create_client_helpers/files.go b/create_client_helpers/files.go deleted file mode 100644 index c895c6fc76d..00000000000 --- a/create_client_helpers/files.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package createclient - -import ( - "context" - "fmt" - "net/http" - "net/url" -) - -// ShowFilesPath computes a request path to the show action of files. -func ShowFilesPath(fileType string, id string, name string) string { - param0 := fileType - param1 := id - param2 := name - - return fmt.Sprintf("/create/v1/files/%s/%s/%s", param0, param1, param2) -} - -// ShowFiles provides the content of the file identified by :name and :id. -func (c *Client) ShowFiles(ctx context.Context, path string) (*http.Response, error) { - req, err := c.NewShowFilesRequest(ctx, path) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewShowFilesRequest creates the request corresponding to the show action endpoint of the files resource. -func (c *Client) NewShowFilesRequest(ctx context.Context, path string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - return req, nil -} diff --git a/create_client_helpers/media_types.go b/create_client_helpers/media_types.go deleted file mode 100644 index 2084ca0df8b..00000000000 --- a/create_client_helpers/media_types.go +++ /dev/null @@ -1,267 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package createclient - -import ( - "net/http" - "time" - - "github.com/goadesign/goa" - uuid "github.com/goadesign/goa/uuid" -) - -// A file saved on the virtual filesystem (default view) -// -// Identifier: application/vnd.arduino.create.file+json; view=default -type ArduinoCreateFile struct { - // The contents of the file, encoded in base64 - Data *string `form:"data,omitempty" json:"data,omitempty" xml:"data,omitempty"` - // The url to use to load the file - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The mimetype of the file, from its extension - Mimetype *string `form:"mimetype,omitempty" json:"mimetype,omitempty" xml:"mimetype,omitempty"` - // The name of the file - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The path of the file - Path *string `form:"path,omitempty" json:"path,omitempty" xml:"path,omitempty"` - // The size in bytes - Size *int `form:"size,omitempty" json:"size,omitempty" xml:"size,omitempty"` -} - -// DecodeArduinoCreateFile decodes the ArduinoCreateFile instance encoded in resp body. -func (c *Client) DecodeArduinoCreateFile(resp *http.Response) (*ArduinoCreateFile, error) { - var decoded ArduinoCreateFile - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// A paginated list of libraries (default view) -// -// Identifier: application/vnd.arduino.create.libraries+json; view=default -type ArduinoCreateLibraries struct { - // The list of libraries - Libraries []*ArduinoCreateLibrary `form:"libraries" json:"libraries" xml:"libraries"` - // Link to the following page of results. Could be empty. - Next *string `form:"next,omitempty" json:"next,omitempty" xml:"next,omitempty"` - // Link to the previous page of results. Could be empty. - Prev *string `form:"prev,omitempty" json:"prev,omitempty" xml:"prev,omitempty"` -} - -// Validate validates the ArduinoCreateLibraries media type instance. -func (mt *ArduinoCreateLibraries) Validate() (err error) { - if mt.Libraries == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "libraries")) - } - return -} - -// DecodeArduinoCreateLibraries decodes the ArduinoCreateLibraries instance encoded in resp body. -func (c *Client) DecodeArduinoCreateLibraries(resp *http.Response) (*ArduinoCreateLibraries, error) { - var decoded ArduinoCreateLibraries - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// Library is a collection of header files containing arduino reusable code and functions. -// It typically contains its info in a library.properties files. -// The examples property contains a list of examples that use that library. (default view) -// -// Identifier: application/vnd.arduino.create.library+json; view=default -type ArduinoCreateLibrary struct { - // The architectures supported by the library. - Architectures []string `form:"architectures,omitempty" json:"architectures,omitempty" xml:"architectures,omitempty"` - // A category - Category *string `form:"category,omitempty" json:"category,omitempty" xml:"category,omitempty"` - // A snippet of code that includes all of the library header files - Code *string `form:"code,omitempty" json:"code,omitempty" xml:"code,omitempty"` - Created *time.Time `form:"created,omitempty" json:"created,omitempty" xml:"created,omitempty"` - // The examples contained in the library - Examples []*ArduinoCreateSketch `form:"examples,omitempty" json:"examples,omitempty" xml:"examples,omitempty"` - // The number of examples that it contains - ExamplesNumber *int `form:"examples_number,omitempty" json:"examples_number,omitempty" xml:"examples_number,omitempty"` - // The files contained in the library - Files []*ArduinoCreateFile `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The id of the library - ID *uuid.UUID `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The maintainer of the library - Maintainer *string `form:"maintainer,omitempty" json:"maintainer,omitempty" xml:"maintainer,omitempty"` - Modified *time.Time `form:"modified,omitempty" json:"modified,omitempty" xml:"modified,omitempty"` - // The name of the library, shared between many versions - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // A private sketch is only visible to its owner. - Private bool `form:"private" json:"private" xml:"private"` - // A short description - Sentence *string `form:"sentence,omitempty" json:"sentence,omitempty" xml:"sentence,omitempty"` - // A list of tags. The Arduino tag means that it's a builtin library. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` - // The homepage of the library - URL *string `form:"url,omitempty" json:"url,omitempty" xml:"url,omitempty"` - // The version of the library - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// Library is a collection of header files containing arduino reusable code and functions. -// It typically contains its info in a library.properties files. -// The examples property contains a list of examples that use that library. (link view) -// -// Identifier: application/vnd.arduino.create.library+json; view=link -type ArduinoCreateLibraryLink struct { - // The url where to find the details - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` -} - -// DecodeArduinoCreateLibrary decodes the ArduinoCreateLibrary instance encoded in resp body. -func (c *Client) DecodeArduinoCreateLibrary(resp *http.Response) (*ArduinoCreateLibrary, error) { - var decoded ArduinoCreateLibrary - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// DecodeArduinoCreateLibraryLink decodes the ArduinoCreateLibraryLink instance encoded in resp body. -func (c *Client) DecodeArduinoCreateLibraryLink(resp *http.Response) (*ArduinoCreateLibraryLink, error) { - var decoded ArduinoCreateLibraryLink - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// A program meant to be uploaded onto a board (default view) -// -// Identifier: application/vnd.arduino.create.sketch+json; view=default -type ArduinoCreateSketch struct { - Created *time.Time `form:"created,omitempty" json:"created,omitempty" xml:"created,omitempty"` - // The other files contained in the sketch - Files []*ArduinoCreateFile `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The folder path where the sketch is saved - Folder *string `form:"folder,omitempty" json:"folder,omitempty" xml:"folder,omitempty"` - // The url to use to modify or delete the sketch - Href *string `form:"href,omitempty" json:"href,omitempty" xml:"href,omitempty"` - // The id of the sketch - ID *uuid.UUID `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` - // The main file of the sketch - Ino *ArduinoCreateFile `form:"ino,omitempty" json:"ino,omitempty" xml:"ino,omitempty"` - Metadata *ArduinoCreateSketchMetadata `form:"metadata,omitempty" json:"metadata,omitempty" xml:"metadata,omitempty"` - Modified *time.Time `form:"modified,omitempty" json:"modified,omitempty" xml:"modified,omitempty"` - // The name of the sketch - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The username of the owner of the sketch - Owner *string `form:"owner,omitempty" json:"owner,omitempty" xml:"owner,omitempty"` - // A private sketch is only visible to its owner. - Private bool `form:"private" json:"private" xml:"private"` - // The total size of the sketch. Only available if the sketch is fully loaded. - Size *int `form:"size,omitempty" json:"size,omitempty" xml:"size,omitempty"` - // A list of links to hackster tutorials. - Tutorials []string `form:"tutorials,omitempty" json:"tutorials,omitempty" xml:"tutorials,omitempty"` - // A list of tags. The builtin tag means that it's a builtin example. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` -} - -// DecodeArduinoCreateSketch decodes the ArduinoCreateSketch instance encoded in resp body. -func (c *Client) DecodeArduinoCreateSketch(resp *http.Response) (*ArduinoCreateSketch, error) { - var decoded ArduinoCreateSketch - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoCreateSketchMetadata media type (default view) -// -// Identifier: application/vnd.arduino.create.sketch.metadata+json; view=default -type ArduinoCreateSketchMetadata struct { - CPU *ArduinoCreateSketchMetadataCPU `form:"cpu,omitempty" json:"cpu,omitempty" xml:"cpu,omitempty"` - IncludedLibs []*ArduinoCreateSketchMetadataIncludedLib `form:"included_libs,omitempty" json:"included_libs,omitempty" xml:"included_libs,omitempty"` -} - -// DecodeArduinoCreateSketchMetadata decodes the ArduinoCreateSketchMetadata instance encoded in resp body. -func (c *Client) DecodeArduinoCreateSketchMetadata(resp *http.Response) (*ArduinoCreateSketchMetadata, error) { - var decoded ArduinoCreateSketchMetadata - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoCreateSketchMetadataCpu media type (default view) -// -// Identifier: application/vnd.arduino.create.sketch.metadata.cpu+json; view=default -type ArduinoCreateSketchMetadataCPU struct { - // The fqbn of the board - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` - // The name of the board - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // Requires an upload via network - Network *bool `form:"network,omitempty" json:"network,omitempty" xml:"network,omitempty"` - // The port of the board - Port *string `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` -} - -// DecodeArduinoCreateSketchMetadataCPU decodes the ArduinoCreateSketchMetadataCPU instance encoded in resp body. -func (c *Client) DecodeArduinoCreateSketchMetadataCPU(resp *http.Response) (*ArduinoCreateSketchMetadataCPU, error) { - var decoded ArduinoCreateSketchMetadataCPU - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// ArduinoCreateSketchMetadataIncluded_lib media type (default view) -// -// Identifier: application/vnd.arduino.create.sketch.metadata.included_lib+json; view=default -type ArduinoCreateSketchMetadataIncludedLib struct { - // The name of the library - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The version of the library - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} - -// DecodeArduinoCreateSketchMetadataIncludedLib decodes the ArduinoCreateSketchMetadataIncludedLib instance encoded in resp body. -func (c *Client) DecodeArduinoCreateSketchMetadataIncludedLib(resp *http.Response) (*ArduinoCreateSketchMetadataIncludedLib, error) { - var decoded ArduinoCreateSketchMetadataIncludedLib - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// A paginated list of sketches (default view) -// -// Identifier: application/vnd.arduino.create.sketches+json; view=default -type ArduinoCreateSketches struct { - // Link to the following page of results. Could be empty. - Next *string `form:"next,omitempty" json:"next,omitempty" xml:"next,omitempty"` - // Link to the previous page of results. Could be empty. - Prev *string `form:"prev,omitempty" json:"prev,omitempty" xml:"prev,omitempty"` - // The list of sketches - Sketches []*ArduinoCreateSketch `form:"sketches" json:"sketches" xml:"sketches"` -} - -// Validate validates the ArduinoCreateSketches media type instance. -func (mt *ArduinoCreateSketches) Validate() (err error) { - if mt.Sketches == nil { - err = goa.MergeErrors(err, goa.MissingAttributeError(`response`, "sketches")) - } - return -} - -// DecodeArduinoCreateSketches decodes the ArduinoCreateSketches instance encoded in resp body. -func (c *Client) DecodeArduinoCreateSketches(resp *http.Response) (*ArduinoCreateSketches, error) { - var decoded ArduinoCreateSketches - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} - -// DecodeErrorResponse decodes the ErrorResponse instance encoded in resp body. -func (c *Client) DecodeErrorResponse(resp *http.Response) (*goa.ErrorResponse, error) { - var decoded goa.ErrorResponse - err := c.Decoder.Decode(&decoded, resp.Body, resp.Header.Get("Content-Type")) - return &decoded, err -} diff --git a/create_client_helpers/sketches.go b/create_client_helpers/sketches.go deleted file mode 100644 index 5fdfd861859..00000000000 --- a/create_client_helpers/sketches.go +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package createclient - -import ( - "bytes" - "context" - "fmt" - "net/http" - "net/url" -) - -// CreateSketchesPath computes a request path to the create action of sketches. -func CreateSketchesPath() string { - return fmt.Sprintf("/create/v1/sketches") -} - -const ( - devURL = "api-dev.arduino.cc" - prodURL = "api.arduino.cc" - prod = true -) - -// CreateSketches adds a new sketch. -func (c *Client) CreateSketches(ctx context.Context, path string, payload *Sketch, authorization string) (*http.Response, error) { - req, err := c.NewCreateSketchesRequest(ctx, path, payload, authorization) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewCreateSketchesRequest creates the request corresponding to the create action endpoint of the sketches resource. -func (c *Client) NewCreateSketchesRequest(ctx context.Context, path string, payload *Sketch, authorization string) (*http.Request, error) { - var body bytes.Buffer - err := c.Encoder.Encode(payload, &body, "*/*") - if err != nil { - return nil, fmt.Errorf("failed to encode body: %s", err) - } - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("PUT", u.String(), &body) - if err != nil { - return nil, err - } - header := req.Header - header.Set("Content-Type", "application/json") - - header.Set("Authorization", authorization) - - return req, nil -} - -// DeleteSketchesPath computes a request path to the delete action of sketches. -func DeleteSketchesPath(id string) string { - return fmt.Sprintf("/create/v1/sketches/%s", id) -} - -// DeleteSketches removes the sketch identified by the :id param. -func (c *Client) DeleteSketches(ctx context.Context, path string, authorization string) (*http.Response, error) { - req, err := c.NewDeleteSketchesRequest(ctx, path, authorization) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewDeleteSketchesRequest creates the request corresponding to the delete action endpoint of the sketches resource. -func (c *Client) NewDeleteSketchesRequest(ctx context.Context, path string, authorization string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("DELETE", u.String(), nil) - if err != nil { - return nil, err - } - header := req.Header - - header.Set("Authorization", authorization) - - return req, nil -} - -// EditSketchesPath computes a request path to the edit action of sketches. -func EditSketchesPath(id string) string { - param0 := id - - return fmt.Sprintf("/create/v1/sketches/%s", param0) -} - -// EditSketches modifies the sketch identified by the :id param. -// If a file has a valid data field, it will be modified too. -func (c *Client) EditSketches(ctx context.Context, path string, payload *Sketch, authorization string) (*http.Response, error) { - req, err := c.NewEditSketchesRequest(ctx, path, payload, authorization) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewEditSketchesRequest creates the request corresponding to the edit action endpoint of the sketches resource. -func (c *Client) NewEditSketchesRequest(ctx context.Context, path string, payload *Sketch, authorization string) (*http.Request, error) { - var body bytes.Buffer - err := c.Encoder.Encode(payload, &body, "*/*") - if err != nil { - return nil, fmt.Errorf("failed to encode body: %s", err) - } - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("POST", u.String(), &body) - if err != nil { - return nil, err - } - header := req.Header - header.Set("Content-Type", "application/json") - - header.Set("Authorization", authorization) - - return req, nil -} - -// SearchSketchesPath computes a request path to the search action of sketches. -func SearchSketchesPath() string { - return fmt.Sprintf("/create/v1/sketches") -} - -// SearchSketches provides a paginated list of sketches filtered according to the params. The page size is 100 items. -func (c *Client) SearchSketches(ctx context.Context, path string, offset *string, owner *string, authorization *string) (*http.Response, error) { - req, err := c.NewSearchSketchesRequest(ctx, path, offset, owner, authorization) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewSearchSketchesRequest creates the request corresponding to the search action endpoint of the sketches resource. -func (c *Client) NewSearchSketchesRequest(ctx context.Context, path string, offset *string, owner *string, authorization *string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - values := u.Query() - if offset != nil { - values.Set("offset", *offset) - } - if owner != nil { - values.Set("owner", *owner) - } - u.RawQuery = values.Encode() - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - header := req.Header - if authorization != nil { - header.Set("Authorization", *authorization) - } - return req, nil -} - -// ShowSketchesPath computes a request path to the show action of sketches. -func ShowSketchesPath(id string) string { - param0 := id - - return fmt.Sprintf("/create/v1/sketches/%s", param0) -} - -// ShowSketches provides the sketch identified by the :id param. -func (c *Client) ShowSketches(ctx context.Context, path string, authorization *string) (*http.Response, error) { - req, err := c.NewShowSketchesRequest(ctx, path, authorization) - if err != nil { - return nil, err - } - return c.Client.Do(ctx, req) -} - -// NewShowSketchesRequest creates the request corresponding to the show action endpoint of the sketches resource. -func (c *Client) NewShowSketchesRequest(ctx context.Context, path string, authorization *string) (*http.Request, error) { - scheme := c.Scheme - if scheme == "" { - scheme = "http" - } - if prod { - path = prodURL + path - } else { - path = devURL + path - } - u := url.URL{Host: c.Host, Scheme: scheme, Path: path} - req, err := http.NewRequest("GET", u.String(), nil) - if err != nil { - return nil, err - } - header := req.Header - if authorization != nil { - header.Set("Authorization", *authorization) - } - return req, nil -} diff --git a/create_client_helpers/user_types.go b/create_client_helpers/user_types.go deleted file mode 100644 index 2dc74f54e9d..00000000000 --- a/create_client_helpers/user_types.go +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of arduino-cli. - * - * Copyright 2018 ARDUINO SA (http://www.arduino.cc/) - * - * This software is released under the GNU General Public License version 3, - * which covers the main part of arduino-cli. - * The terms of this license can be found at: - * https://www.gnu.org/licenses/gpl-3.0.en.html - * - * You can be released from the requirements of the above licenses by purchasing - * a commercial license. Buying such a license is mandatory if you want to modify or - * otherwise use the software for commercial activities involving the Arduino - * software without disclosing the source code of your own applications. To purchase - * a commercial license, send an email to license@arduino.cc. - */ - -package createclient - -import ( - "encoding/base64" - "io/ioutil" - "path/filepath" - - "github.com/bcmi-labs/arduino-modules/sketches" -) - -// File is a file saved on the virtual filesystem. -type File struct { - // The contents of the file, encoded in base64. - Data *string `form:"data,omitempty" json:"data,omitempty" xml:"data,omitempty"` - // The name of the file. - Name string `form:"name" json:"name" xml:"name"` -} - -// Sketch is a program meant to be uploaded onto a board. -type Sketch struct { - // The name of the sketch. - Name string `form:"name" json:"name" xml:"name"` - // The other files contained in the sketch. - Files []*File `form:"files,omitempty" json:"files,omitempty" xml:"files,omitempty"` - // The folder path where the sketch is saved. - Folder *string `form:"folder,omitempty" json:"folder,omitempty" xml:"folder,omitempty"` - // The main file of the sketch. - Ino *File `form:"ino" json:"ino" xml:"ino"` - Metadata *SketchMetadata `form:"metadata,omitempty" json:"metadata,omitempty" xml:"metadata,omitempty"` - // The username of the owner of the sketch. - Owner *string `form:"owner,omitempty" json:"owner,omitempty" xml:"owner,omitempty"` - // A private sketch is only visible to its owner. - Private bool `form:"private" json:"private" xml:"private"` - // A list of links to hackster tutorials. - Tutorials []string `form:"tutorials,omitempty" json:"tutorials,omitempty" xml:"tutorials,omitempty"` - // A list of tags. The builtin tag means that it's a builtin example. - Types []string `form:"types,omitempty" json:"types,omitempty" xml:"types,omitempty"` -} - -// ConvertFrom converts from a local sketch to an Arduino Create sketch. -func ConvertFrom(sketch sketches.Sketch) *Sketch { - _, inoPath := filepath.Split(sketch.Ino.Path) - content, err := ioutil.ReadFile(filepath.Join(sketch.FullPath, inoPath)) - if err != nil { - return nil - } - - ino := base64.StdEncoding.EncodeToString(content) - ret := Sketch{ - Name: sketch.Name, - Folder: &sketch.Path, - Ino: &File{ - Data: &ino, - Name: sketch.Ino.Name, - }, - Private: sketch.Private, - Tutorials: sketch.Tutorials, - Types: sketch.Types, - Metadata: ConvertMetadataFrom(sketch.Metadata), - } - for _, f := range sketch.Files { - if f.Name == "sketch.json" { // Skipping sketch.json file, since it is Metadata of the sketch. - continue - } - _, filePath := filepath.Split(f.Path) - content, err := ioutil.ReadFile(filepath.Join(sketch.FullPath, filePath)) - if err != nil { - return nil - } - - data := base64.StdEncoding.EncodeToString(content) - ret.Files = append(ret.Files, &File{ - Data: &data, - Name: f.Name, - }) - } - return &ret -} - -// SketchMetadata user type. -type SketchMetadata struct { - CPU *SketchMetadataCPU `form:"cpu,omitempty" json:"cpu,omitempty" xml:"cpu,omitempty"` - IncludedLibs []*SketchMetadataLib `form:"included_libs,omitempty" json:"included_libs,omitempty" xml:"included_libs,omitempty"` -} - -// ConvertMetadataFrom creates SketchMetadata object from sketches.Metadata. -func ConvertMetadataFrom(metadata *sketches.Metadata) *SketchMetadata { - if metadata == nil { - return nil - } - network := metadata.CPU.Type == "network" - ret := SketchMetadata{ - CPU: &SketchMetadataCPU{ - Fqbn: &metadata.CPU.Fqbn, - Name: &metadata.CPU.Name, - Network: &network, - Port: &metadata.CPU.Port, - }, - } - ret.IncludedLibs = make([]*SketchMetadataLib, len(metadata.IncludedLibs)) - for i, lib := range metadata.IncludedLibs { - ret.IncludedLibs[i] = &SketchMetadataLib{ - Name: &lib.Name, - Version: &lib.Version, - } - } - - return &ret -} - -// SketchMetadataCPU is the board associated with the sketch. -type SketchMetadataCPU struct { - // The fqbn of the board. - Fqbn *string `form:"fqbn,omitempty" json:"fqbn,omitempty" xml:"fqbn,omitempty"` - // The name of the board. - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // Requires an upload via network. - Network *bool `form:"network,omitempty" json:"network,omitempty" xml:"network,omitempty"` - // The port of the board. - Port *string `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` -} - -// SketchMetadataLib is a library associated with the sketch. -type SketchMetadataLib struct { - // The name of the library. - Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` - // The version of the library. - Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` -} diff --git a/vendor/github.com/armon/go-metrics/.gitignore b/vendor/github.com/armon/go-metrics/.gitignore deleted file mode 100644 index 8c03ec112a4..00000000000 --- a/vendor/github.com/armon/go-metrics/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -/metrics.out diff --git a/vendor/github.com/armon/go-metrics/LICENSE b/vendor/github.com/armon/go-metrics/LICENSE deleted file mode 100644 index 106569e542b..00000000000 --- a/vendor/github.com/armon/go-metrics/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Armon Dadgar - -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/armon/go-metrics/README.md b/vendor/github.com/armon/go-metrics/README.md deleted file mode 100644 index a7399cddffa..00000000000 --- a/vendor/github.com/armon/go-metrics/README.md +++ /dev/null @@ -1,74 +0,0 @@ -go-metrics -========== - -This library provides a `metrics` package which can be used to instrument code, -expose application metrics, and profile runtime performance in a flexible manner. - -Current API: [![GoDoc](https://godoc.org/github.com/armon/go-metrics?status.svg)](https://godoc.org/github.com/armon/go-metrics) - -Sinks -===== - -The `metrics` package makes use of a `MetricSink` interface to support delivery -to any type of backend. Currently the following sinks are provided: - -* StatsiteSink : Sinks to a [statsite](https://github.com/armon/statsite/) instance (TCP) -* StatsdSink: Sinks to a [StatsD](https://github.com/etsy/statsd/) / statsite instance (UDP) -* PrometheusSink: Sinks to a [Prometheus](http://prometheus.io/) metrics endpoint (exposed via HTTP for scrapes) -* InmemSink : Provides in-memory aggregation, can be used to export stats -* FanoutSink : Sinks to multiple sinks. Enables writing to multiple statsite instances for example. -* BlackholeSink : Sinks to nowhere - -In addition to the sinks, the `InmemSignal` can be used to catch a signal, -and dump a formatted output of recent metrics. For example, when a process gets -a SIGUSR1, it can dump to stderr recent performance metrics for debugging. - -Examples -======== - -Here is an example of using the package: - -```go -func SlowMethod() { - // Profiling the runtime of a method - defer metrics.MeasureSince([]string{"SlowMethod"}, time.Now()) -} - -// Configure a statsite sink as the global metrics sink -sink, _ := metrics.NewStatsiteSink("statsite:8125") -metrics.NewGlobal(metrics.DefaultConfig("service-name"), sink) - -// Emit a Key/Value pair -metrics.EmitKey([]string{"questions", "meaning of life"}, 42) -``` - -Here is an example of setting up a signal handler: - -```go -// Setup the inmem sink and signal handler -inm := metrics.NewInmemSink(10*time.Second, time.Minute) -sig := metrics.DefaultInmemSignal(inm) -metrics.NewGlobal(metrics.DefaultConfig("service-name"), inm) - -// Run some code -inm.SetGauge([]string{"foo"}, 42) -inm.EmitKey([]string{"bar"}, 30) - -inm.IncrCounter([]string{"baz"}, 42) -inm.IncrCounter([]string{"baz"}, 1) -inm.IncrCounter([]string{"baz"}, 80) - -inm.AddSample([]string{"method", "wow"}, 42) -inm.AddSample([]string{"method", "wow"}, 100) -inm.AddSample([]string{"method", "wow"}, 22) - -.... -``` - -When a signal comes in, output like the following will be dumped to stderr: - - [2014-01-28 14:57:33.04 -0800 PST][G] 'foo': 42.000 - [2014-01-28 14:57:33.04 -0800 PST][P] 'bar': 30.000 - [2014-01-28 14:57:33.04 -0800 PST][C] 'baz': Count: 3 Min: 1.000 Mean: 41.000 Max: 80.000 Stddev: 39.509 - [2014-01-28 14:57:33.04 -0800 PST][S] 'method.wow': Count: 3 Min: 22.000 Mean: 54.667 Max: 100.000 Stddev: 40.513 - diff --git a/vendor/github.com/armon/go-metrics/const_unix.go b/vendor/github.com/armon/go-metrics/const_unix.go deleted file mode 100644 index 31098dd57e5..00000000000 --- a/vendor/github.com/armon/go-metrics/const_unix.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !windows - -package metrics - -import ( - "syscall" -) - -const ( - // DefaultSignal is used with DefaultInmemSignal - DefaultSignal = syscall.SIGUSR1 -) diff --git a/vendor/github.com/armon/go-metrics/const_windows.go b/vendor/github.com/armon/go-metrics/const_windows.go deleted file mode 100644 index 38136af3e42..00000000000 --- a/vendor/github.com/armon/go-metrics/const_windows.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build windows - -package metrics - -import ( - "syscall" -) - -const ( - // DefaultSignal is used with DefaultInmemSignal - // Windows has no SIGUSR1, use SIGBREAK - DefaultSignal = syscall.Signal(21) -) diff --git a/vendor/github.com/armon/go-metrics/inmem.go b/vendor/github.com/armon/go-metrics/inmem.go deleted file mode 100644 index 4e2d6a709e2..00000000000 --- a/vendor/github.com/armon/go-metrics/inmem.go +++ /dev/null @@ -1,348 +0,0 @@ -package metrics - -import ( - "bytes" - "fmt" - "math" - "net/url" - "strings" - "sync" - "time" -) - -// InmemSink provides a MetricSink that does in-memory aggregation -// without sending metrics over a network. It can be embedded within -// an application to provide profiling information. -type InmemSink struct { - // How long is each aggregation interval - interval time.Duration - - // Retain controls how many metrics interval we keep - retain time.Duration - - // maxIntervals is the maximum length of intervals. - // It is retain / interval. - maxIntervals int - - // intervals is a slice of the retained intervals - intervals []*IntervalMetrics - intervalLock sync.RWMutex - - rateDenom float64 -} - -// IntervalMetrics stores the aggregated metrics -// for a specific interval -type IntervalMetrics struct { - sync.RWMutex - - // The start time of the interval - Interval time.Time - - // Gauges maps the key to the last set value - Gauges map[string]GaugeValue - - // Points maps the string to the list of emitted values - // from EmitKey - Points map[string][]float32 - - // Counters maps the string key to a sum of the counter - // values - Counters map[string]SampledValue - - // Samples maps the key to an AggregateSample, - // which has the rolled up view of a sample - Samples map[string]SampledValue -} - -// NewIntervalMetrics creates a new IntervalMetrics for a given interval -func NewIntervalMetrics(intv time.Time) *IntervalMetrics { - return &IntervalMetrics{ - Interval: intv, - Gauges: make(map[string]GaugeValue), - Points: make(map[string][]float32), - Counters: make(map[string]SampledValue), - Samples: make(map[string]SampledValue), - } -} - -// AggregateSample is used to hold aggregate metrics -// about a sample -type AggregateSample struct { - Count int // The count of emitted pairs - Rate float64 // The values rate per time unit (usually 1 second) - Sum float64 // The sum of values - SumSq float64 `json:"-"` // The sum of squared values - Min float64 // Minimum value - Max float64 // Maximum value - LastUpdated time.Time `json:"-"` // When value was last updated -} - -// Computes a Stddev of the values -func (a *AggregateSample) Stddev() float64 { - num := (float64(a.Count) * a.SumSq) - math.Pow(a.Sum, 2) - div := float64(a.Count * (a.Count - 1)) - if div == 0 { - return 0 - } - return math.Sqrt(num / div) -} - -// Computes a mean of the values -func (a *AggregateSample) Mean() float64 { - if a.Count == 0 { - return 0 - } - return a.Sum / float64(a.Count) -} - -// Ingest is used to update a sample -func (a *AggregateSample) Ingest(v float64, rateDenom float64) { - a.Count++ - a.Sum += v - a.SumSq += (v * v) - if v < a.Min || a.Count == 1 { - a.Min = v - } - if v > a.Max || a.Count == 1 { - a.Max = v - } - a.Rate = float64(a.Sum) / rateDenom - a.LastUpdated = time.Now() -} - -func (a *AggregateSample) String() string { - if a.Count == 0 { - return "Count: 0" - } else if a.Stddev() == 0 { - return fmt.Sprintf("Count: %d Sum: %0.3f LastUpdated: %s", a.Count, a.Sum, a.LastUpdated) - } else { - return fmt.Sprintf("Count: %d Min: %0.3f Mean: %0.3f Max: %0.3f Stddev: %0.3f Sum: %0.3f LastUpdated: %s", - a.Count, a.Min, a.Mean(), a.Max, a.Stddev(), a.Sum, a.LastUpdated) - } -} - -// NewInmemSinkFromURL creates an InmemSink from a URL. It is used -// (and tested) from NewMetricSinkFromURL. -func NewInmemSinkFromURL(u *url.URL) (MetricSink, error) { - params := u.Query() - - interval, err := time.ParseDuration(params.Get("interval")) - if err != nil { - return nil, fmt.Errorf("Bad 'interval' param: %s", err) - } - - retain, err := time.ParseDuration(params.Get("retain")) - if err != nil { - return nil, fmt.Errorf("Bad 'retain' param: %s", err) - } - - return NewInmemSink(interval, retain), nil -} - -// NewInmemSink is used to construct a new in-memory sink. -// Uses an aggregation interval and maximum retention period. -func NewInmemSink(interval, retain time.Duration) *InmemSink { - rateTimeUnit := time.Second - i := &InmemSink{ - interval: interval, - retain: retain, - maxIntervals: int(retain / interval), - rateDenom: float64(interval.Nanoseconds()) / float64(rateTimeUnit.Nanoseconds()), - } - i.intervals = make([]*IntervalMetrics, 0, i.maxIntervals) - return i -} - -func (i *InmemSink) SetGauge(key []string, val float32) { - i.SetGaugeWithLabels(key, val, nil) -} - -func (i *InmemSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - k, name := i.flattenKeyLabels(key, labels) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - intv.Gauges[k] = GaugeValue{Name: name, Value: val, Labels: labels} -} - -func (i *InmemSink) EmitKey(key []string, val float32) { - k := i.flattenKey(key) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - vals := intv.Points[k] - intv.Points[k] = append(vals, val) -} - -func (i *InmemSink) IncrCounter(key []string, val float32) { - i.IncrCounterWithLabels(key, val, nil) -} - -func (i *InmemSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - k, name := i.flattenKeyLabels(key, labels) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - - agg, ok := intv.Counters[k] - if !ok { - agg = SampledValue{ - Name: name, - AggregateSample: &AggregateSample{}, - Labels: labels, - } - intv.Counters[k] = agg - } - agg.Ingest(float64(val), i.rateDenom) -} - -func (i *InmemSink) AddSample(key []string, val float32) { - i.AddSampleWithLabels(key, val, nil) -} - -func (i *InmemSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - k, name := i.flattenKeyLabels(key, labels) - intv := i.getInterval() - - intv.Lock() - defer intv.Unlock() - - agg, ok := intv.Samples[k] - if !ok { - agg = SampledValue{ - Name: name, - AggregateSample: &AggregateSample{}, - Labels: labels, - } - intv.Samples[k] = agg - } - agg.Ingest(float64(val), i.rateDenom) -} - -// Data is used to retrieve all the aggregated metrics -// Intervals may be in use, and a read lock should be acquired -func (i *InmemSink) Data() []*IntervalMetrics { - // Get the current interval, forces creation - i.getInterval() - - i.intervalLock.RLock() - defer i.intervalLock.RUnlock() - - n := len(i.intervals) - intervals := make([]*IntervalMetrics, n) - - copy(intervals[:n-1], i.intervals[:n-1]) - current := i.intervals[n-1] - - // make its own copy for current interval - intervals[n-1] = &IntervalMetrics{} - copyCurrent := intervals[n-1] - current.RLock() - *copyCurrent = *current - - copyCurrent.Gauges = make(map[string]GaugeValue, len(current.Gauges)) - for k, v := range current.Gauges { - copyCurrent.Gauges[k] = v - } - // saved values will be not change, just copy its link - copyCurrent.Points = make(map[string][]float32, len(current.Points)) - for k, v := range current.Points { - copyCurrent.Points[k] = v - } - copyCurrent.Counters = make(map[string]SampledValue, len(current.Counters)) - for k, v := range current.Counters { - copyCurrent.Counters[k] = v - } - copyCurrent.Samples = make(map[string]SampledValue, len(current.Samples)) - for k, v := range current.Samples { - copyCurrent.Samples[k] = v - } - current.RUnlock() - - return intervals -} - -func (i *InmemSink) getExistingInterval(intv time.Time) *IntervalMetrics { - i.intervalLock.RLock() - defer i.intervalLock.RUnlock() - - n := len(i.intervals) - if n > 0 && i.intervals[n-1].Interval == intv { - return i.intervals[n-1] - } - return nil -} - -func (i *InmemSink) createInterval(intv time.Time) *IntervalMetrics { - i.intervalLock.Lock() - defer i.intervalLock.Unlock() - - // Check for an existing interval - n := len(i.intervals) - if n > 0 && i.intervals[n-1].Interval == intv { - return i.intervals[n-1] - } - - // Add the current interval - current := NewIntervalMetrics(intv) - i.intervals = append(i.intervals, current) - n++ - - // Truncate the intervals if they are too long - if n >= i.maxIntervals { - copy(i.intervals[0:], i.intervals[n-i.maxIntervals:]) - i.intervals = i.intervals[:i.maxIntervals] - } - return current -} - -// getInterval returns the current interval to write to -func (i *InmemSink) getInterval() *IntervalMetrics { - intv := time.Now().Truncate(i.interval) - if m := i.getExistingInterval(intv); m != nil { - return m - } - return i.createInterval(intv) -} - -// Flattens the key for formatting, removes spaces -func (i *InmemSink) flattenKey(parts []string) string { - buf := &bytes.Buffer{} - replacer := strings.NewReplacer(" ", "_") - - if len(parts) > 0 { - replacer.WriteString(buf, parts[0]) - } - for _, part := range parts[1:] { - replacer.WriteString(buf, ".") - replacer.WriteString(buf, part) - } - - return buf.String() -} - -// Flattens the key for formatting along with its labels, removes spaces -func (i *InmemSink) flattenKeyLabels(parts []string, labels []Label) (string, string) { - buf := &bytes.Buffer{} - replacer := strings.NewReplacer(" ", "_") - - if len(parts) > 0 { - replacer.WriteString(buf, parts[0]) - } - for _, part := range parts[1:] { - replacer.WriteString(buf, ".") - replacer.WriteString(buf, part) - } - - key := buf.String() - - for _, label := range labels { - replacer.WriteString(buf, fmt.Sprintf(";%s=%s", label.Name, label.Value)) - } - - return buf.String(), key -} diff --git a/vendor/github.com/armon/go-metrics/inmem_endpoint.go b/vendor/github.com/armon/go-metrics/inmem_endpoint.go deleted file mode 100644 index 504f1b37485..00000000000 --- a/vendor/github.com/armon/go-metrics/inmem_endpoint.go +++ /dev/null @@ -1,118 +0,0 @@ -package metrics - -import ( - "fmt" - "net/http" - "sort" - "time" -) - -// MetricsSummary holds a roll-up of metrics info for a given interval -type MetricsSummary struct { - Timestamp string - Gauges []GaugeValue - Points []PointValue - Counters []SampledValue - Samples []SampledValue -} - -type GaugeValue struct { - Name string - Hash string `json:"-"` - Value float32 - - Labels []Label `json:"-"` - DisplayLabels map[string]string `json:"Labels"` -} - -type PointValue struct { - Name string - Points []float32 -} - -type SampledValue struct { - Name string - Hash string `json:"-"` - *AggregateSample - Mean float64 - Stddev float64 - - Labels []Label `json:"-"` - DisplayLabels map[string]string `json:"Labels"` -} - -// DisplayMetrics returns a summary of the metrics from the most recent finished interval. -func (i *InmemSink) DisplayMetrics(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - data := i.Data() - - var interval *IntervalMetrics - n := len(data) - switch { - case n == 0: - return nil, fmt.Errorf("no metric intervals have been initialized yet") - case n == 1: - // Show the current interval if it's all we have - interval = i.intervals[0] - default: - // Show the most recent finished interval if we have one - interval = i.intervals[n-2] - } - - summary := MetricsSummary{ - Timestamp: interval.Interval.Round(time.Second).UTC().String(), - Gauges: make([]GaugeValue, 0, len(interval.Gauges)), - Points: make([]PointValue, 0, len(interval.Points)), - } - - // Format and sort the output of each metric type, so it gets displayed in a - // deterministic order. - for name, points := range interval.Points { - summary.Points = append(summary.Points, PointValue{name, points}) - } - sort.Slice(summary.Points, func(i, j int) bool { - return summary.Points[i].Name < summary.Points[j].Name - }) - - for hash, value := range interval.Gauges { - value.Hash = hash - value.DisplayLabels = make(map[string]string) - for _, label := range value.Labels { - value.DisplayLabels[label.Name] = label.Value - } - value.Labels = nil - - summary.Gauges = append(summary.Gauges, value) - } - sort.Slice(summary.Gauges, func(i, j int) bool { - return summary.Gauges[i].Hash < summary.Gauges[j].Hash - }) - - summary.Counters = formatSamples(interval.Counters) - summary.Samples = formatSamples(interval.Samples) - - return summary, nil -} - -func formatSamples(source map[string]SampledValue) []SampledValue { - output := make([]SampledValue, 0, len(source)) - for hash, sample := range source { - displayLabels := make(map[string]string) - for _, label := range sample.Labels { - displayLabels[label.Name] = label.Value - } - - output = append(output, SampledValue{ - Name: sample.Name, - Hash: hash, - AggregateSample: sample.AggregateSample, - Mean: sample.AggregateSample.Mean(), - Stddev: sample.AggregateSample.Stddev(), - DisplayLabels: displayLabels, - }) - } - sort.Slice(output, func(i, j int) bool { - return output[i].Hash < output[j].Hash - }) - - return output -} diff --git a/vendor/github.com/armon/go-metrics/inmem_signal.go b/vendor/github.com/armon/go-metrics/inmem_signal.go deleted file mode 100644 index 0937f4aedf7..00000000000 --- a/vendor/github.com/armon/go-metrics/inmem_signal.go +++ /dev/null @@ -1,117 +0,0 @@ -package metrics - -import ( - "bytes" - "fmt" - "io" - "os" - "os/signal" - "strings" - "sync" - "syscall" -) - -// InmemSignal is used to listen for a given signal, and when received, -// to dump the current metrics from the InmemSink to an io.Writer -type InmemSignal struct { - signal syscall.Signal - inm *InmemSink - w io.Writer - sigCh chan os.Signal - - stop bool - stopCh chan struct{} - stopLock sync.Mutex -} - -// NewInmemSignal creates a new InmemSignal which listens for a given signal, -// and dumps the current metrics out to a writer -func NewInmemSignal(inmem *InmemSink, sig syscall.Signal, w io.Writer) *InmemSignal { - i := &InmemSignal{ - signal: sig, - inm: inmem, - w: w, - sigCh: make(chan os.Signal, 1), - stopCh: make(chan struct{}), - } - signal.Notify(i.sigCh, sig) - go i.run() - return i -} - -// DefaultInmemSignal returns a new InmemSignal that responds to SIGUSR1 -// and writes output to stderr. Windows uses SIGBREAK -func DefaultInmemSignal(inmem *InmemSink) *InmemSignal { - return NewInmemSignal(inmem, DefaultSignal, os.Stderr) -} - -// Stop is used to stop the InmemSignal from listening -func (i *InmemSignal) Stop() { - i.stopLock.Lock() - defer i.stopLock.Unlock() - - if i.stop { - return - } - i.stop = true - close(i.stopCh) - signal.Stop(i.sigCh) -} - -// run is a long running routine that handles signals -func (i *InmemSignal) run() { - for { - select { - case <-i.sigCh: - i.dumpStats() - case <-i.stopCh: - return - } - } -} - -// dumpStats is used to dump the data to output writer -func (i *InmemSignal) dumpStats() { - buf := bytes.NewBuffer(nil) - - data := i.inm.Data() - // Skip the last period which is still being aggregated - for j := 0; j < len(data)-1; j++ { - intv := data[j] - intv.RLock() - for _, val := range intv.Gauges { - name := i.flattenLabels(val.Name, val.Labels) - fmt.Fprintf(buf, "[%v][G] '%s': %0.3f\n", intv.Interval, name, val.Value) - } - for name, vals := range intv.Points { - for _, val := range vals { - fmt.Fprintf(buf, "[%v][P] '%s': %0.3f\n", intv.Interval, name, val) - } - } - for _, agg := range intv.Counters { - name := i.flattenLabels(agg.Name, agg.Labels) - fmt.Fprintf(buf, "[%v][C] '%s': %s\n", intv.Interval, name, agg.AggregateSample) - } - for _, agg := range intv.Samples { - name := i.flattenLabels(agg.Name, agg.Labels) - fmt.Fprintf(buf, "[%v][S] '%s': %s\n", intv.Interval, name, agg.AggregateSample) - } - intv.RUnlock() - } - - // Write out the bytes - i.w.Write(buf.Bytes()) -} - -// Flattens the key for formatting along with its labels, removes spaces -func (i *InmemSignal) flattenLabels(name string, labels []Label) string { - buf := bytes.NewBufferString(name) - replacer := strings.NewReplacer(" ", "_", ":", "_") - - for _, label := range labels { - replacer.WriteString(buf, ".") - replacer.WriteString(buf, label.Value) - } - - return buf.String() -} diff --git a/vendor/github.com/armon/go-metrics/metrics.go b/vendor/github.com/armon/go-metrics/metrics.go deleted file mode 100644 index d260bd4b29e..00000000000 --- a/vendor/github.com/armon/go-metrics/metrics.go +++ /dev/null @@ -1,216 +0,0 @@ -package metrics - -import ( - "runtime" - "strings" - "time" - - "github.com/hashicorp/go-immutable-radix" -) - -type Label struct { - Name string - Value string -} - -func (m *Metrics) SetGauge(key []string, val float32) { - m.SetGaugeWithLabels(key, val, nil) -} - -func (m *Metrics) SetGaugeWithLabels(key []string, val float32, labels []Label) { - if m.HostName != "" { - if m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } else if m.EnableHostname { - key = insert(0, m.HostName, key) - } - } - if m.EnableTypePrefix { - key = insert(0, "gauge", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - if !m.allowMetric(key) { - return - } - m.sink.SetGaugeWithLabels(key, val, labels) -} - -func (m *Metrics) EmitKey(key []string, val float32) { - if m.EnableTypePrefix { - key = insert(0, "kv", key) - } - if m.ServiceName != "" { - key = insert(0, m.ServiceName, key) - } - if !m.allowMetric(key) { - return - } - m.sink.EmitKey(key, val) -} - -func (m *Metrics) IncrCounter(key []string, val float32) { - m.IncrCounterWithLabels(key, val, nil) -} - -func (m *Metrics) IncrCounterWithLabels(key []string, val float32, labels []Label) { - if m.HostName != "" && m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } - if m.EnableTypePrefix { - key = insert(0, "counter", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - if !m.allowMetric(key) { - return - } - m.sink.IncrCounterWithLabels(key, val, labels) -} - -func (m *Metrics) AddSample(key []string, val float32) { - m.AddSampleWithLabels(key, val, nil) -} - -func (m *Metrics) AddSampleWithLabels(key []string, val float32, labels []Label) { - if m.HostName != "" && m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } - if m.EnableTypePrefix { - key = insert(0, "sample", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - if !m.allowMetric(key) { - return - } - m.sink.AddSampleWithLabels(key, val, labels) -} - -func (m *Metrics) MeasureSince(key []string, start time.Time) { - m.MeasureSinceWithLabels(key, start, nil) -} - -func (m *Metrics) MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { - if m.HostName != "" && m.EnableHostnameLabel { - labels = append(labels, Label{"host", m.HostName}) - } - if m.EnableTypePrefix { - key = insert(0, "timer", key) - } - if m.ServiceName != "" { - if m.EnableServiceLabel { - labels = append(labels, Label{"service", m.ServiceName}) - } else { - key = insert(0, m.ServiceName, key) - } - } - if !m.allowMetric(key) { - return - } - now := time.Now() - elapsed := now.Sub(start) - msec := float32(elapsed.Nanoseconds()) / float32(m.TimerGranularity) - m.sink.AddSampleWithLabels(key, msec, labels) -} - -// UpdateFilter overwrites the existing filter with the given rules. -func (m *Metrics) UpdateFilter(allow, block []string) { - m.filterLock.Lock() - defer m.filterLock.Unlock() - - m.AllowedPrefixes = allow - m.BlockedPrefixes = block - - m.filter = iradix.New() - for _, prefix := range m.AllowedPrefixes { - m.filter, _, _ = m.filter.Insert([]byte(prefix), true) - } - for _, prefix := range m.BlockedPrefixes { - m.filter, _, _ = m.filter.Insert([]byte(prefix), false) - } -} - -// Returns whether the metric should be allowed based on configured prefix filters -func (m *Metrics) allowMetric(key []string) bool { - m.filterLock.RLock() - defer m.filterLock.RUnlock() - - if m.filter == nil || m.filter.Len() == 0 { - return m.Config.FilterDefault - } - - _, allowed, ok := m.filter.Root().LongestPrefix([]byte(strings.Join(key, "."))) - if !ok { - return m.Config.FilterDefault - } - return allowed.(bool) -} - -// Periodically collects runtime stats to publish -func (m *Metrics) collectStats() { - for { - time.Sleep(m.ProfileInterval) - m.emitRuntimeStats() - } -} - -// Emits various runtime statsitics -func (m *Metrics) emitRuntimeStats() { - // Export number of Goroutines - numRoutines := runtime.NumGoroutine() - m.SetGauge([]string{"runtime", "num_goroutines"}, float32(numRoutines)) - - // Export memory stats - var stats runtime.MemStats - runtime.ReadMemStats(&stats) - m.SetGauge([]string{"runtime", "alloc_bytes"}, float32(stats.Alloc)) - m.SetGauge([]string{"runtime", "sys_bytes"}, float32(stats.Sys)) - m.SetGauge([]string{"runtime", "malloc_count"}, float32(stats.Mallocs)) - m.SetGauge([]string{"runtime", "free_count"}, float32(stats.Frees)) - m.SetGauge([]string{"runtime", "heap_objects"}, float32(stats.HeapObjects)) - m.SetGauge([]string{"runtime", "total_gc_pause_ns"}, float32(stats.PauseTotalNs)) - m.SetGauge([]string{"runtime", "total_gc_runs"}, float32(stats.NumGC)) - - // Export info about the last few GC runs - num := stats.NumGC - - // Handle wrap around - if num < m.lastNumGC { - m.lastNumGC = 0 - } - - // Ensure we don't scan more than 256 - if num-m.lastNumGC >= 256 { - m.lastNumGC = num - 255 - } - - for i := m.lastNumGC; i < num; i++ { - pause := stats.PauseNs[i%256] - m.AddSample([]string{"runtime", "gc_pause_ns"}, float32(pause)) - } - m.lastNumGC = num -} - -// Inserts a string value at an index into the slice -func insert(i int, v string, s []string) []string { - s = append(s, "") - copy(s[i+1:], s[i:]) - s[i] = v - return s -} diff --git a/vendor/github.com/armon/go-metrics/sink.go b/vendor/github.com/armon/go-metrics/sink.go deleted file mode 100644 index 0b7d6e4be43..00000000000 --- a/vendor/github.com/armon/go-metrics/sink.go +++ /dev/null @@ -1,115 +0,0 @@ -package metrics - -import ( - "fmt" - "net/url" -) - -// The MetricSink interface is used to transmit metrics information -// to an external system -type MetricSink interface { - // A Gauge should retain the last value it is set to - SetGauge(key []string, val float32) - SetGaugeWithLabels(key []string, val float32, labels []Label) - - // Should emit a Key/Value pair for each call - EmitKey(key []string, val float32) - - // Counters should accumulate values - IncrCounter(key []string, val float32) - IncrCounterWithLabels(key []string, val float32, labels []Label) - - // Samples are for timing information, where quantiles are used - AddSample(key []string, val float32) - AddSampleWithLabels(key []string, val float32, labels []Label) -} - -// BlackholeSink is used to just blackhole messages -type BlackholeSink struct{} - -func (*BlackholeSink) SetGauge(key []string, val float32) {} -func (*BlackholeSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {} -func (*BlackholeSink) EmitKey(key []string, val float32) {} -func (*BlackholeSink) IncrCounter(key []string, val float32) {} -func (*BlackholeSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {} -func (*BlackholeSink) AddSample(key []string, val float32) {} -func (*BlackholeSink) AddSampleWithLabels(key []string, val float32, labels []Label) {} - -// FanoutSink is used to sink to fanout values to multiple sinks -type FanoutSink []MetricSink - -func (fh FanoutSink) SetGauge(key []string, val float32) { - fh.SetGaugeWithLabels(key, val, nil) -} - -func (fh FanoutSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - for _, s := range fh { - s.SetGaugeWithLabels(key, val, labels) - } -} - -func (fh FanoutSink) EmitKey(key []string, val float32) { - for _, s := range fh { - s.EmitKey(key, val) - } -} - -func (fh FanoutSink) IncrCounter(key []string, val float32) { - fh.IncrCounterWithLabels(key, val, nil) -} - -func (fh FanoutSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - for _, s := range fh { - s.IncrCounterWithLabels(key, val, labels) - } -} - -func (fh FanoutSink) AddSample(key []string, val float32) { - fh.AddSampleWithLabels(key, val, nil) -} - -func (fh FanoutSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - for _, s := range fh { - s.AddSampleWithLabels(key, val, labels) - } -} - -// sinkURLFactoryFunc is an generic interface around the *SinkFromURL() function provided -// by each sink type -type sinkURLFactoryFunc func(*url.URL) (MetricSink, error) - -// sinkRegistry supports the generic NewMetricSink function by mapping URL -// schemes to metric sink factory functions -var sinkRegistry = map[string]sinkURLFactoryFunc{ - "statsd": NewStatsdSinkFromURL, - "statsite": NewStatsiteSinkFromURL, - "inmem": NewInmemSinkFromURL, -} - -// NewMetricSinkFromURL allows a generic URL input to configure any of the -// supported sinks. The scheme of the URL identifies the type of the sink, the -// and query parameters are used to set options. -// -// "statsd://" - Initializes a StatsdSink. The host and port are passed through -// as the "addr" of the sink -// -// "statsite://" - Initializes a StatsiteSink. The host and port become the -// "addr" of the sink -// -// "inmem://" - Initializes an InmemSink. The host and port are ignored. The -// "interval" and "duration" query parameters must be specified with valid -// durations, see NewInmemSink for details. -func NewMetricSinkFromURL(urlStr string) (MetricSink, error) { - u, err := url.Parse(urlStr) - if err != nil { - return nil, err - } - - sinkURLFactoryFunc := sinkRegistry[u.Scheme] - if sinkURLFactoryFunc == nil { - return nil, fmt.Errorf( - "cannot create metric sink, unrecognized sink name: %q", u.Scheme) - } - - return sinkURLFactoryFunc(u) -} diff --git a/vendor/github.com/armon/go-metrics/start.go b/vendor/github.com/armon/go-metrics/start.go deleted file mode 100644 index dd41861c909..00000000000 --- a/vendor/github.com/armon/go-metrics/start.go +++ /dev/null @@ -1,129 +0,0 @@ -package metrics - -import ( - "os" - "sync" - "sync/atomic" - "time" - - "github.com/hashicorp/go-immutable-radix" -) - -// Config is used to configure metrics settings -type Config struct { - ServiceName string // Prefixed with keys to separate services - HostName string // Hostname to use. If not provided and EnableHostname, it will be os.Hostname - EnableHostname bool // Enable prefixing gauge values with hostname - EnableHostnameLabel bool // Enable adding hostname to labels - EnableServiceLabel bool // Enable adding service to labels - EnableRuntimeMetrics bool // Enables profiling of runtime metrics (GC, Goroutines, Memory) - EnableTypePrefix bool // Prefixes key with a type ("counter", "gauge", "timer") - TimerGranularity time.Duration // Granularity of timers. - ProfileInterval time.Duration // Interval to profile runtime metrics - - AllowedPrefixes []string // A list of metric prefixes to allow, with '.' as the separator - BlockedPrefixes []string // A list of metric prefixes to block, with '.' as the separator - FilterDefault bool // Whether to allow metrics by default -} - -// Metrics represents an instance of a metrics sink that can -// be used to emit -type Metrics struct { - Config - lastNumGC uint32 - sink MetricSink - filter *iradix.Tree - filterLock sync.RWMutex -} - -// Shared global metrics instance -var globalMetrics atomic.Value // *Metrics - -func init() { - // Initialize to a blackhole sink to avoid errors - globalMetrics.Store(&Metrics{sink: &BlackholeSink{}}) -} - -// DefaultConfig provides a sane default configuration -func DefaultConfig(serviceName string) *Config { - c := &Config{ - ServiceName: serviceName, // Use client provided service - HostName: "", - EnableHostname: true, // Enable hostname prefix - EnableRuntimeMetrics: true, // Enable runtime profiling - EnableTypePrefix: false, // Disable type prefix - TimerGranularity: time.Millisecond, // Timers are in milliseconds - ProfileInterval: time.Second, // Poll runtime every second - FilterDefault: true, // Don't filter metrics by default - } - - // Try to get the hostname - name, _ := os.Hostname() - c.HostName = name - return c -} - -// New is used to create a new instance of Metrics -func New(conf *Config, sink MetricSink) (*Metrics, error) { - met := &Metrics{} - met.Config = *conf - met.sink = sink - met.UpdateFilter(conf.AllowedPrefixes, conf.BlockedPrefixes) - - // Start the runtime collector - if conf.EnableRuntimeMetrics { - go met.collectStats() - } - return met, nil -} - -// NewGlobal is the same as New, but it assigns the metrics object to be -// used globally as well as returning it. -func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) { - metrics, err := New(conf, sink) - if err == nil { - globalMetrics.Store(metrics) - } - return metrics, err -} - -// Proxy all the methods to the globalMetrics instance -func SetGauge(key []string, val float32) { - globalMetrics.Load().(*Metrics).SetGauge(key, val) -} - -func SetGaugeWithLabels(key []string, val float32, labels []Label) { - globalMetrics.Load().(*Metrics).SetGaugeWithLabels(key, val, labels) -} - -func EmitKey(key []string, val float32) { - globalMetrics.Load().(*Metrics).EmitKey(key, val) -} - -func IncrCounter(key []string, val float32) { - globalMetrics.Load().(*Metrics).IncrCounter(key, val) -} - -func IncrCounterWithLabels(key []string, val float32, labels []Label) { - globalMetrics.Load().(*Metrics).IncrCounterWithLabels(key, val, labels) -} - -func AddSample(key []string, val float32) { - globalMetrics.Load().(*Metrics).AddSample(key, val) -} - -func AddSampleWithLabels(key []string, val float32, labels []Label) { - globalMetrics.Load().(*Metrics).AddSampleWithLabels(key, val, labels) -} - -func MeasureSince(key []string, start time.Time) { - globalMetrics.Load().(*Metrics).MeasureSince(key, start) -} - -func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { - globalMetrics.Load().(*Metrics).MeasureSinceWithLabels(key, start, labels) -} - -func UpdateFilter(allow, block []string) { - globalMetrics.Load().(*Metrics).UpdateFilter(allow, block) -} diff --git a/vendor/github.com/armon/go-metrics/statsd.go b/vendor/github.com/armon/go-metrics/statsd.go deleted file mode 100644 index 1bfffce46e2..00000000000 --- a/vendor/github.com/armon/go-metrics/statsd.go +++ /dev/null @@ -1,184 +0,0 @@ -package metrics - -import ( - "bytes" - "fmt" - "log" - "net" - "net/url" - "strings" - "time" -) - -const ( - // statsdMaxLen is the maximum size of a packet - // to send to statsd - statsdMaxLen = 1400 -) - -// StatsdSink provides a MetricSink that can be used -// with a statsite or statsd metrics server. It uses -// only UDP packets, while StatsiteSink uses TCP. -type StatsdSink struct { - addr string - metricQueue chan string -} - -// NewStatsdSinkFromURL creates an StatsdSink from a URL. It is used -// (and tested) from NewMetricSinkFromURL. -func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) { - return NewStatsdSink(u.Host) -} - -// NewStatsdSink is used to create a new StatsdSink -func NewStatsdSink(addr string) (*StatsdSink, error) { - s := &StatsdSink{ - addr: addr, - metricQueue: make(chan string, 4096), - } - go s.flushMetrics() - return s, nil -} - -// Close is used to stop flushing to statsd -func (s *StatsdSink) Shutdown() { - close(s.metricQueue) -} - -func (s *StatsdSink) SetGauge(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsdSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsdSink) EmitKey(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val)) -} - -func (s *StatsdSink) IncrCounter(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsdSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsdSink) AddSample(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -func (s *StatsdSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -// Flattens the key for formatting, removes spaces -func (s *StatsdSink) flattenKey(parts []string) string { - joined := strings.Join(parts, ".") - return strings.Map(func(r rune) rune { - switch r { - case ':': - fallthrough - case ' ': - return '_' - default: - return r - } - }, joined) -} - -// Flattens the key along with labels for formatting, removes spaces -func (s *StatsdSink) flattenKeyLabels(parts []string, labels []Label) string { - for _, label := range labels { - parts = append(parts, label.Value) - } - return s.flattenKey(parts) -} - -// Does a non-blocking push to the metrics queue -func (s *StatsdSink) pushMetric(m string) { - select { - case s.metricQueue <- m: - default: - } -} - -// Flushes metrics -func (s *StatsdSink) flushMetrics() { - var sock net.Conn - var err error - var wait <-chan time.Time - ticker := time.NewTicker(flushInterval) - defer ticker.Stop() - -CONNECT: - // Create a buffer - buf := bytes.NewBuffer(nil) - - // Attempt to connect - sock, err = net.Dial("udp", s.addr) - if err != nil { - log.Printf("[ERR] Error connecting to statsd! Err: %s", err) - goto WAIT - } - - for { - select { - case metric, ok := <-s.metricQueue: - // Get a metric from the queue - if !ok { - goto QUIT - } - - // Check if this would overflow the packet size - if len(metric)+buf.Len() > statsdMaxLen { - _, err := sock.Write(buf.Bytes()) - buf.Reset() - if err != nil { - log.Printf("[ERR] Error writing to statsd! Err: %s", err) - goto WAIT - } - } - - // Append to the buffer - buf.WriteString(metric) - - case <-ticker.C: - if buf.Len() == 0 { - continue - } - - _, err := sock.Write(buf.Bytes()) - buf.Reset() - if err != nil { - log.Printf("[ERR] Error flushing to statsd! Err: %s", err) - goto WAIT - } - } - } - -WAIT: - // Wait for a while - wait = time.After(time.Duration(5) * time.Second) - for { - select { - // Dequeue the messages to avoid backlog - case _, ok := <-s.metricQueue: - if !ok { - goto QUIT - } - case <-wait: - goto CONNECT - } - } -QUIT: - s.metricQueue = nil -} diff --git a/vendor/github.com/armon/go-metrics/statsite.go b/vendor/github.com/armon/go-metrics/statsite.go deleted file mode 100644 index 6c0d284d2dd..00000000000 --- a/vendor/github.com/armon/go-metrics/statsite.go +++ /dev/null @@ -1,172 +0,0 @@ -package metrics - -import ( - "bufio" - "fmt" - "log" - "net" - "net/url" - "strings" - "time" -) - -const ( - // We force flush the statsite metrics after this period of - // inactivity. Prevents stats from getting stuck in a buffer - // forever. - flushInterval = 100 * time.Millisecond -) - -// NewStatsiteSinkFromURL creates an StatsiteSink from a URL. It is used -// (and tested) from NewMetricSinkFromURL. -func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) { - return NewStatsiteSink(u.Host) -} - -// StatsiteSink provides a MetricSink that can be used with a -// statsite metrics server -type StatsiteSink struct { - addr string - metricQueue chan string -} - -// NewStatsiteSink is used to create a new StatsiteSink -func NewStatsiteSink(addr string) (*StatsiteSink, error) { - s := &StatsiteSink{ - addr: addr, - metricQueue: make(chan string, 4096), - } - go s.flushMetrics() - return s, nil -} - -// Close is used to stop flushing to statsite -func (s *StatsiteSink) Shutdown() { - close(s.metricQueue) -} - -func (s *StatsiteSink) SetGauge(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsiteSink) SetGaugeWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val)) -} - -func (s *StatsiteSink) EmitKey(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val)) -} - -func (s *StatsiteSink) IncrCounter(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsiteSink) IncrCounterWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val)) -} - -func (s *StatsiteSink) AddSample(key []string, val float32) { - flatKey := s.flattenKey(key) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -func (s *StatsiteSink) AddSampleWithLabels(key []string, val float32, labels []Label) { - flatKey := s.flattenKeyLabels(key, labels) - s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val)) -} - -// Flattens the key for formatting, removes spaces -func (s *StatsiteSink) flattenKey(parts []string) string { - joined := strings.Join(parts, ".") - return strings.Map(func(r rune) rune { - switch r { - case ':': - fallthrough - case ' ': - return '_' - default: - return r - } - }, joined) -} - -// Flattens the key along with labels for formatting, removes spaces -func (s *StatsiteSink) flattenKeyLabels(parts []string, labels []Label) string { - for _, label := range labels { - parts = append(parts, label.Value) - } - return s.flattenKey(parts) -} - -// Does a non-blocking push to the metrics queue -func (s *StatsiteSink) pushMetric(m string) { - select { - case s.metricQueue <- m: - default: - } -} - -// Flushes metrics -func (s *StatsiteSink) flushMetrics() { - var sock net.Conn - var err error - var wait <-chan time.Time - var buffered *bufio.Writer - ticker := time.NewTicker(flushInterval) - defer ticker.Stop() - -CONNECT: - // Attempt to connect - sock, err = net.Dial("tcp", s.addr) - if err != nil { - log.Printf("[ERR] Error connecting to statsite! Err: %s", err) - goto WAIT - } - - // Create a buffered writer - buffered = bufio.NewWriter(sock) - - for { - select { - case metric, ok := <-s.metricQueue: - // Get a metric from the queue - if !ok { - goto QUIT - } - - // Try to send to statsite - _, err := buffered.Write([]byte(metric)) - if err != nil { - log.Printf("[ERR] Error writing to statsite! Err: %s", err) - goto WAIT - } - case <-ticker.C: - if err := buffered.Flush(); err != nil { - log.Printf("[ERR] Error flushing to statsite! Err: %s", err) - goto WAIT - } - } - } - -WAIT: - // Wait for a while - wait = time.After(time.Duration(5) * time.Second) - for { - select { - // Dequeue the messages to avoid backlog - case _, ok := <-s.metricQueue: - if !ok { - goto QUIT - } - case <-wait: - goto CONNECT - } - } -QUIT: - s.metricQueue = nil -} diff --git a/vendor/github.com/briandowns/spinner/.gitignore b/vendor/github.com/briandowns/spinner/.gitignore deleted file mode 100644 index 21ec6b71b71..00000000000 --- a/vendor/github.com/briandowns/spinner/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Created by .gitignore support plugin (hsz.mobi) -### Go template -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -.idea -*.iml diff --git a/vendor/github.com/briandowns/spinner/.travis.yml b/vendor/github.com/briandowns/spinner/.travis.yml deleted file mode 100644 index 2cf02a4aff6..00000000000 --- a/vendor/github.com/briandowns/spinner/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go: - - 1.6.3 - - 1.7.3 -env: - - GOARCH: amd64 - - GOARCH: 386 -script: - - go test -v -notifications: - email: - recipients: - - brian.downs@gmail.com - on_success: change - on_failure: always diff --git a/vendor/github.com/briandowns/spinner/LICENSE b/vendor/github.com/briandowns/spinner/LICENSE deleted file mode 100644 index dd5b3a58aa1..00000000000 --- a/vendor/github.com/briandowns/spinner/LICENSE +++ /dev/null @@ -1,174 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/vendor/github.com/briandowns/spinner/README.md b/vendor/github.com/briandowns/spinner/README.md deleted file mode 100644 index fd5416fc465..00000000000 --- a/vendor/github.com/briandowns/spinner/README.md +++ /dev/null @@ -1,203 +0,0 @@ -# Spinner - -[![GoDoc](https://godoc.org/github.com/briandowns/spinner?status.svg)](https://godoc.org/github.com/briandowns/spinner) [![Build Status](https://travis-ci.org/briandowns/spinner.svg?branch=master)](https://travis-ci.org/briandowns/spinner) - -spinner is a simple package to add a spinner / progress indicator to any terminal application. Examples can be found below as well as full examples in the examples directory. - -For more detail about the library and its features, reference your local godoc once installed. - -Contributions welcome! - -## Installation - -```bash -go get github.com/briandowns/spinner -``` - -## Available Character Sets -(Numbered by their slice index) - -index | character set -------|--------------- -0 | ```←↖↑↗→↘↓↙``` -1 | ```▁▃▄▅▆▇█▇▆▅▄▃▁``` -2 | ```▖▘▝▗``` -3 | ```┤┘┴└├┌┬┐``` -4 | ```◢◣◤◥``` -5 | ```◰◳◲◱``` -6 | ```◴◷◶◵``` -7 | ```◐◓◑◒``` -8 | ```.oO@*``` -9 | ```|/-\``` -10 | ```◡◡⊙⊙◠◠``` -11 | ```⣾⣽⣻⢿⡿⣟⣯⣷``` -12 | ```>))'> >))'> >))'> >))'> >))'> <'((< <'((< <'((<``` -13 | ```⠁⠂⠄⡀⢀⠠⠐⠈``` -14 | ```⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏``` -15 | ```abcdefghijklmnopqrstuvwxyz``` -16 | ```▉▊▋▌▍▎▏▎▍▌▋▊▉``` -17 | ```■□▪▫``` -18 | ```←↑→↓``` -19 | ```╫╪``` -20 | ```⇐⇖⇑⇗⇒⇘⇓⇙``` -21 | ```⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈``` -22 | ```⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈``` -23 | ```⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁``` -24 | ```⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋``` -25 | ```ヲァィゥェォャュョッアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン``` -26 | ```. .. ...``` -27 | ```▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▏▎▍▌▋▊▉█▇▆▅▄▃▂▁``` -28 | ```.oO°Oo.``` -29 | ```+x``` -30 | ```v<^>``` -31 | ```>>---> >>---> >>---> >>---> >>---> <---<< <---<< <---<< <---<< <---<<``` -32 | ```| || ||| |||| ||||| |||||| ||||| |||| ||| || |``` -33 | ```[] [=] [==] [===] [====] [=====] [======] [=======] [========] [=========] [==========]``` -34 | ```(*---------) (-*--------) (--*-------) (---*------) (----*-----) (-----*----) (------*---) (-------*--) (--------*-) (---------*)``` -35 | ```█▒▒▒▒▒▒▒▒▒ ███▒▒▒▒▒▒▒ █████▒▒▒▒▒ ███████▒▒▒ ██████████``` -36 | ```[ ] [=> ] [===> ] [=====> ] [======> ] [========> ] [==========> ] [============> ] [==============> ] [================> ] [==================> ] [===================>]``` -37 | ```🕐 🕑 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚 🕛``` -38 | ```🕐 🕜 🕑 🕝 🕒 🕞 🕓 🕟 🕔 🕠 🕕 🕡 🕖 🕢 🕗 🕣 🕘 🕤 🕙 🕥 🕚 🕦 🕛 🕧``` -39 | ```🌍 🌎 🌏``` -40 | ```◜ ◝ ◞ ◟``` -41 | ```⬒ ⬔ ⬓ ⬕``` -42 | ```⬖ ⬘ ⬗ ⬙``` -43 | ```[>>> >] []>>>> [] [] >>>> [] [] >>>> [] [] >>>> [] [] >>>>[] [>> >>]``` - -## Features - -* Start -* Stop -* Restart -* Reverse direction -* Update the spinner character set -* Update the spinner speed -* Prefix or append text -* Change spinner color -* Get spinner status -* Chain, pipe, redirect output -* Output final string on spinner/indicator completion - -## Examples - -```Go -package main - -import ( - "github.com/briandowns/spinner" - "time" -) - -func main() { - s := spinner.New(spinner.CharSets[9], 100*time.Millisecond) // Build our new spinner - s.Start() // Start the spinner - time.Sleep(4 * time.Second) // Run for some time to simulate work - s.Stop() -} -``` - -## Update the character set and restart the spinner - -```Go -s.UpdateCharSet(spinner.CharSets[1]) // Update spinner to use a different character set -s.Restart() // Restart the spinner -time.Sleep(4 * time.Second) -s.Stop() -``` - -## Update spin speed and restart the spinner - -```Go -s.UpdateSpeed(200 * time.Millisecond) // Update the speed the spinner spins at -s.Restart() -time.Sleep(4 * time.Second) -s.Stop() -``` - -## Reverse the direction of the spinner - -```Go -s.Reverse() // Reverse the direction the spinner is spinning -s.Restart() -time.Sleep(4 * time.Second) -s.Stop() -``` - -## Provide your own spinner - -(or send me an issue or pull request to add to the project) - -```Go -someSet := []string{"+", "-"} -s := spinner.New(someSet, 100*time.Millisecond) -``` - -## Prefix or append text to the spinner - -```Go -s.Prefix = "prefixed text: " // Prefix text before the spinner -s.Suffix = " :appended text" // Append text after the spinner -``` - -## Set or change the color of the spinner. Default color is white. This will restart the spinner with the new color. - -```Go -s.Color("red") // Set the spinner color to red -``` - -## Generate a sequence of numbers - -```Go -setOfDigits := spinner.GenerateNumberSequence(25) // Generate a 25 digit string of numbers -s := spinner.New(setOfDigits, 100*time.Millisecond) -``` - -## Get spinner status - -```Go -fmt.Println(s.ST) -``` - -## Unix pipe and redirect - -Feature suggested and write up by [dekz](https://github.com/dekz) - -Setting the Spinner Writer to Stderr helps show progress to the user, with the enhancement to chain, pipe or redirect the output. - -```go -s := spinner.New(spinner.CharSets[11], 100*time.Millisecond) -s.Suffix = " Encrypting data..." -s.Writer = os.Stderr -s.Start() -// Encrypt the data into ciphertext -fmt.Println(os.Stdout, ciphertext) -``` - -```sh -> myprog encrypt "Secret text" > encrypted.txt -⣯ Encrypting data... -``` - -```sh -> cat encrypted.txt -1243hjkbas23i9ah27sj39jghv237n2oa93hg83 -``` - -## Final String Output - -Add additional output when the spinner/indicator has completed. The "final" output string can be multi-lined and will be written to wherever the `io.Writer` has been configured for. - -```Go -s := spinner.New(spinner.CharSets[9], 100*time.Millisecond) -s.FinalMSG = "Complete!\nNew line!\nAnother one!\n" -s.Start() -time.Sleep(4 * time.Second) -s.Stop() -``` - -Output -```sh -Complete! -New line! -Another one! -``` diff --git a/vendor/github.com/briandowns/spinner/character_sets.go b/vendor/github.com/briandowns/spinner/character_sets.go deleted file mode 100644 index 1efe6e6ed4f..00000000000 --- a/vendor/github.com/briandowns/spinner/character_sets.go +++ /dev/null @@ -1,59 +0,0 @@ -package spinner - -const ( - clockOneOClock = '\U0001F550' - clockOneThirty = '\U0001F55C' -) - -// CharSets contains the available character sets -var CharSets = map[int][]string{ - 0: {"←", "↖", "↑", "↗", "→", "↘", "↓", "↙"}, - 1: {"▁", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃", "▁"}, - 2: {"▖", "▘", "▝", "▗"}, - 3: {"┤", "┘", "┴", "└", "├", "┌", "┬", "┐"}, - 4: {"◢", "◣", "◤", "◥"}, - 5: {"◰", "◳", "◲", "◱"}, - 6: {"◴", "◷", "◶", "◵"}, - 7: {"◐", "◓", "◑", "◒"}, - 8: {".", "o", "O", "@", "*"}, - 9: {"|", "/", "-", "\\"}, - 10: {"◡◡", "⊙⊙", "◠◠"}, - 11: {"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"}, - 12: {">))'>", " >))'>", " >))'>", " >))'>", " >))'>", " <'((<", " <'((<", " <'((<"}, - 13: {"⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"}, - 14: {"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}, - 15: {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}, - 16: {"▉", "▊", "▋", "▌", "▍", "▎", "▏", "▎", "▍", "▌", "▋", "▊", "▉"}, - 17: {"■", "□", "▪", "▫"}, - 18: {"←", "↑", "→", "↓"}, - 19: {"╫", "╪"}, - 20: {"⇐", "⇖", "⇑", "⇗", "⇒", "⇘", "⇓", "⇙"}, - 21: {"⠁", "⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈", "⠈"}, - 22: {"⠈", "⠉", "⠋", "⠓", "⠒", "⠐", "⠐", "⠒", "⠖", "⠦", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈"}, - 23: {"⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄", "⠤", "⠴", "⠲", "⠒", "⠂", "⠂", "⠒", "⠚", "⠙", "⠉", "⠁"}, - 24: {"⠋", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋"}, - 25: {"ヲ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ン"}, - 26: {".", "..", "..."}, - 27: {"▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█", "▇", "▆", "▅", "▄", "▃", "▂", "▁"}, - 28: {".", "o", "O", "°", "O", "o", "."}, - 29: {"+", "x"}, - 30: {"v", "<", "^", ">"}, - 31: {">>--->", " >>--->", " >>--->", " >>--->", " >>--->", " <---<<", " <---<<", " <---<<", " <---<<", "<---<<"}, - 32: {"|", "||", "|||", "||||", "|||||", "|||||||", "||||||||", "|||||||", "||||||", "|||||", "||||", "|||", "||", "|"}, - 33: {"[ ]", "[= ]", "[== ]", "[=== ]", "[==== ]", "[===== ]", "[====== ]", "[======= ]", "[======== ]", "[========= ]", "[==========]"}, - 34: {"(*---------)", "(-*--------)", "(--*-------)", "(---*------)", "(----*-----)", "(-----*----)", "(------*---)", "(-------*--)", "(--------*-)", "(---------*)"}, - 35: {"█▒▒▒▒▒▒▒▒▒", "███▒▒▒▒▒▒▒", "█████▒▒▒▒▒", "███████▒▒▒", "██████████"}, - 36: {"[ ]", "[=> ]", "[===> ]", "[=====> ]", "[======> ]", "[========> ]", "[==========> ]", "[============> ]", "[==============> ]", "[================> ]", "[==================> ]", "[===================>]"}, - 39: {"🌍", "🌎", "🌏"}, - 40: {"◜", "◝", "◞", "◟"}, - 41: {"⬒", "⬔", "⬓", "⬕"}, - 42: {"⬖", "⬘", "⬗", "⬙"}, - 43: {"[>>> >]", "[]>>>> []", "[] >>>> []", "[] >>>> []", "[] >>>> []", "[] >>>>[]", "[>> >>]"}, -} - -func init() { - for i := rune(0); i < 12; i++ { - CharSets[37] = append(CharSets[37], string([]rune{clockOneOClock + i})) - CharSets[38] = append(CharSets[38], string([]rune{clockOneOClock + i}), string([]rune{clockOneThirty + i})) - } -} diff --git a/vendor/github.com/briandowns/spinner/spinner.go b/vendor/github.com/briandowns/spinner/spinner.go deleted file mode 100644 index c25a466234e..00000000000 --- a/vendor/github.com/briandowns/spinner/spinner.go +++ /dev/null @@ -1,194 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package spinner is a simple package to add a spinner / progress indicator to any terminal application. -package spinner - -import ( - "errors" - "fmt" - "io" - "strconv" - "sync" - "time" - "unicode/utf8" - - "github.com/fatih/color" -) - -// errInvalidColor is returned when attempting to set an invalid color -var errInvalidColor = errors.New("invalid color") - -// validColors holds an array of the only colors allowed -var validColors = map[string]bool{ - "red": true, - "green": true, - "yellow": true, - "blue": true, - "magenta": true, - "cyan": true, - "white": true, -} - -// returns a valid color's foreground text color attribute -var colorAttributeMap = map[string]color.Attribute{ - "red": color.FgRed, - "green": color.FgGreen, - "yellow": color.FgYellow, - "blue": color.FgBlue, - "magenta": color.FgMagenta, - "cyan": color.FgCyan, - "white": color.FgWhite, -} - -// validColor will make sure the given color is actually allowed -func validColor(c string) bool { - valid := false - if validColors[c] { - valid = true - } - return valid -} - -// Spinner struct to hold the provided options -type Spinner struct { - Delay time.Duration // Delay is the speed of the indicator - chars []string // chars holds the chosen character set - Prefix string // Prefix is the text preppended to the indicator - Suffix string // Suffix is the text appended to the indicator - FinalMSG string // string displayed after Stop() is called - lastOutput string // last character(set) written - color func(a ...interface{}) string // default color is white - lock *sync.RWMutex // - Writer io.Writer // to make testing better, exported so users have access - active bool // active holds the state of the spinner - stopChan chan struct{} // stopChan is a channel used to stop the indicator -} - -// New provides a pointer to an instance of Spinner with the supplied options -func New(cs []string, d time.Duration) *Spinner { - return &Spinner{ - Delay: d, - chars: cs, - color: color.New(color.FgWhite).SprintFunc(), - lock: &sync.RWMutex{}, - Writer: color.Output, - active: false, - stopChan: make(chan struct{}, 1), - } -} - -// Start will start the indicator -func (s *Spinner) Start() { - if s.active { - return - } - s.active = true - - go func() { - for { - for i := 0; i < len(s.chars); i++ { - select { - case <-s.stopChan: - return - default: - s.lock.Lock() - s.erase() - outColor := fmt.Sprintf("%s%s%s ", s.Prefix, s.color(s.chars[i]), s.Suffix) - outPlain := fmt.Sprintf("%s%s%s ", s.Prefix, s.chars[i], s.Suffix) - fmt.Fprint(s.Writer, outColor) - s.lastOutput = outPlain - delay := s.Delay - s.lock.Unlock() - - time.Sleep(delay) - } - } - } - }() -} - -// Stop stops the indicator -func (s *Spinner) Stop() { - s.lock.Lock() - defer s.lock.Unlock() - if s.active { - s.active = false - s.erase() - if s.FinalMSG != "" { - fmt.Fprintf(s.Writer, s.FinalMSG) - } - s.stopChan <- struct{}{} - } -} - -// Restart will stop and start the indicator -func (s *Spinner) Restart() { - s.Stop() - s.Start() -} - -// Reverse will reverse the order of the slice assigned to the indicator -func (s *Spinner) Reverse() { - s.lock.Lock() - defer s.lock.Unlock() - for i, j := 0, len(s.chars)-1; i < j; i, j = i+1, j-1 { - s.chars[i], s.chars[j] = s.chars[j], s.chars[i] - } -} - -// Color will set the struct field for the given color to be used -func (s *Spinner) Color(c string) error { - if !validColor(c) { - return errInvalidColor - } - s.color = color.New(colorAttributeMap[c]).SprintFunc() - s.Restart() - return nil -} - -// UpdateSpeed will set the indicator delay to the given value -func (s *Spinner) UpdateSpeed(d time.Duration) { - s.lock.Lock() - defer s.lock.Unlock() - s.Delay = d -} - -// UpdateCharSet will change the current character set to the given one -func (s *Spinner) UpdateCharSet(cs []string) { - s.lock.Lock() - defer s.lock.Unlock() - s.chars = cs -} - -// erase deletes written characters -// -// Caller must already hold s.lock. -func (s *Spinner) erase() { - n := utf8.RuneCountInString(s.lastOutput) - for _, c := range []string{"\b", " ", "\b"} { - for i := 0; i < n; i++ { - fmt.Fprintf(s.Writer, c) - } - } - s.lastOutput = "" -} - -// GenerateNumberSequence will generate a slice of integers at the -// provided length and convert them each to a string -func GenerateNumberSequence(length int) []string { - numSeq := make([]string, length) - for i := 0; i < length; i++ { - numSeq[i] = strconv.Itoa(i) - } - return numSeq -} diff --git a/vendor/github.com/dimfeld/httptreemux/.gitignore b/vendor/github.com/dimfeld/httptreemux/.gitignore deleted file mode 100644 index 836562412fe..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test diff --git a/vendor/github.com/dimfeld/httptreemux/.travis.yml b/vendor/github.com/dimfeld/httptreemux/.travis.yml deleted file mode 100644 index 9267a02e76a..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go - -gobuild_args: "-v -race" -go: - - 1.5 - - 1.6 - - 1.7 - - 1.8 - - 1.9 - - tip - -matrix: - allow_failures: - - go: tip diff --git a/vendor/github.com/dimfeld/httptreemux/LICENSE b/vendor/github.com/dimfeld/httptreemux/LICENSE deleted file mode 100644 index 32c75c9b1eb..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014,2015 Daniel Imfeld - -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/dimfeld/httptreemux/README.md b/vendor/github.com/dimfeld/httptreemux/README.md deleted file mode 100644 index 6d3fb8a5c69..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/README.md +++ /dev/null @@ -1,240 +0,0 @@ -httptreemux [![Build Status](https://travis-ci.org/dimfeld/httptreemux.png?branch=master)](https://travis-ci.org/dimfeld/httptreemux) [![GoDoc](https://godoc.org/github.com/dimfeld/httptreemux?status.svg)](https://godoc.org/github.com/dimfeld/httptreemux) -=========== - -High-speed, flexible, tree-based HTTP router for Go. - -This is inspired by [Julien Schmidt's httprouter](https://www.github.com/julienschmidt/httprouter), in that it uses a patricia tree, but the implementation is rather different. Specifically, the routing rules are relaxed so that a single path segment may be a wildcard in one route and a static token in another. This gives a nice combination of high performance with a lot of convenience in designing the routing patterns. In [benchmarks](https://github.com/julienschmidt/go-http-routing-benchmark), httptreemux is close to, but slightly slower than, httprouter. - -Release notes may be found using the [Github releases tab](https://github.com/dimfeld/httptreemux/releases). Version numbers are compatible with the [Semantic Versioning 2.0.0](http://semver.org/) convention, and a new release is made after every change to the code. - -## Why? -There are a lot of good routers out there. But looking at the ones that were really lightweight, I couldn't quite get something that fit with the route patterns I wanted. The code itself is simple enough, so I spent an evening writing this. - -## Handler -The handler is a simple function with the prototype `func(w http.ResponseWriter, r *http.Request, params map[string]string)`. The params argument contains the parameters parsed from wildcards and catch-alls in the URL, as described below. This type is aliased as httptreemux.HandlerFunc. - -### Using http.HandlerFunc -Due to the inclusion of the [context](https://godoc.org/context) package as of Go 1.7, `httptreemux` now supports handlers of type [http.HandlerFunc](https://godoc.org/net/http#HandlerFunc). There are two ways to enable this support. - -#### Adapting an Existing Router - -The `UsingContext` method will wrap the router or group in a new group at the same path, but adapted for use with `context` and `http.HandlerFunc`. - -```go -router := httptreemux.New() - -group := router.NewGroup("/api") -group.GET("/v1/:id", func(w http.ResponseWriter, r *http.Request, params map[string]string) { - id := params["id"] - fmt.Fprintf(w, "GET /api/v1/%s", id) -}) - -// UsingContext returns a version of the router or group with context support. -ctxGroup := group.UsingContext() // sibling to 'group' node in tree -ctxGroup.GET("/v2/:id", func(w http.ResponseWriter, r *http.Request) { - params := httptreemux.ContextParams(r.Context()) - id := params["id"] - fmt.Fprintf(w, "GET /api/v2/%s", id) -}) - -http.ListenAndServe(":8080", router) -``` - -#### New Router with Context Support - -The `NewContextMux` function returns a router preconfigured for use with `context` and `http.HandlerFunc`. - -```go -router := httptreemux.NewContextMux() - -router.GET("/:page", func(w http.ResponseWriter, r *http.Request) { - params := httptreemux.ContextParams(r.Context()) - fmt.Fprintf(w, "GET /%s", params["page"]) -}) - -group := tree.NewGroup("/api") -group.GET("/v1/:id", func(w http.ResponseWriter, r *http.Request) { - params := httptreemux.ContextParams(r.Context()) - id := params["id"] - fmt.Fprintf(w, "GET /api/v1/%s", id) -}) - -http.ListenAndServe(":8080", router) -``` - - - -## Routing Rules -The syntax here is also modeled after httprouter. Each variable in a path may match on one segment only, except for an optional catch-all variable at the end of the URL. - -Some examples of valid URL patterns are: -* `/post/all` -* `/post/:postid` -* `/post/:postid/page/:page` -* `/post/:postid/:page` -* `/images/*path` -* `/favicon.ico` -* `/:year/:month/` -* `/:year/:month/:post` -* `/:page` - -Note that all of the above URL patterns may exist concurrently in the router. - -Path elements starting with `:` indicate a wildcard in the path. A wildcard will only match on a single path segment. That is, the pattern `/post/:postid` will match on `/post/1` or `/post/1/`, but not `/post/1/2`. - -A path element starting with `*` is a catch-all, whose value will be a string containing all text in the URL matched by the wildcards. For example, with a pattern of `/images/*path` and a requested URL `images/abc/def`, path would contain `abc/def`. - -#### Using : and * in routing patterns - -The characters `:` and `*` can be used at the beginning of a path segment by escaping them with a backslash. A double backslash at the beginning of a segment is interpreted as a single backslash. These escapes are only checked at the very beginning of a path segment; they are not necessary or processed elsewhere in a token. - -```go -router.GET("/foo/\\*starToken", handler) // matches /foo/*starToken -router.GET("/foo/star*inTheMiddle", handler) // matches /foo/star*inTheMiddle -router.GET("/foo/starBackslash\\*", handler) // matches /foo/starBackslash\* -router.GET("/foo/\\\\*backslashWithStar") // matches /foo/\*backslashWithStar -``` - -### Routing Groups -Lets you create a new group of routes with a given path prefix. Makes it easier to create clusters of paths like: -* `/api/v1/foo` -* `/api/v1/bar` - -To use this you do: -```go -router = httptreemux.New() -api := router.NewGroup("/api/v1") -api.GET("/foo", fooHandler) // becomes /api/v1/foo -api.GET("/bar", barHandler) // becomes /api/v1/bar -``` - -### Routing Priority -The priority rules in the router are simple. - -1. Static path segments take the highest priority. If a segment and its subtree are able to match the URL, that match is returned. -2. Wildcards take second priority. For a particular wildcard to match, that wildcard and its subtree must match the URL. -3. Finally, a catch-all rule will match when the earlier path segments have matched, and none of the static or wildcard conditions have matched. Catch-all rules must be at the end of a pattern. - -So with the following patterns adapted from [simpleblog](https://www.github.com/dimfeld/simpleblog), we'll see certain matches: -```go -router = httptreemux.New() -router.GET("/:page", pageHandler) -router.GET("/:year/:month/:post", postHandler) -router.GET("/:year/:month", archiveHandler) -router.GET("/images/*path", staticHandler) -router.GET("/favicon.ico", staticHandler) -``` - -#### Example scenarios - -- `/abc` will match `/:page` -- `/2014/05` will match `/:year/:month` -- `/2014/05/really-great-blog-post` will match `/:year/:month/:post` -- `/images/CoolImage.gif` will match `/images/*path` -- `/images/2014/05/MayImage.jpg` will also match `/images/*path`, with all the text after `/images` stored in the variable path. -- `/favicon.ico` will match `/favicon.ico` - -### Special Method Behavior -If TreeMux.HeadCanUseGet is set to true, the router will call the GET handler for a pattern when a HEAD request is processed, if no HEAD handler has been added for that pattern. This behavior is enabled by default. - -Go's http.ServeContent and related functions already handle the HEAD method correctly by sending only the header, so in most cases your handlers will not need any special cases for it. - -By default TreeMux.OptionsHandler is a null handler that doesn't affect your routing. If you set the handler, it will be called on OPTIONS requests to a path already registered by another method. If you set a path specific handler by using `router.OPTIONS`, it will override the global Options Handler for that path. - -### Trailing Slashes -The router has special handling for paths with trailing slashes. If a pattern is added to the router with a trailing slash, any matches on that pattern without a trailing slash will be redirected to the version with the slash. If a pattern does not have a trailing slash, matches on that pattern with a trailing slash will be redirected to the version without. - -The trailing slash flag is only stored once for a pattern. That is, if a pattern is added for a method with a trailing slash, all other methods for that pattern will also be considered to have a trailing slash, regardless of whether or not it is specified for those methods too. -However this behavior can be turned off by setting TreeMux.RedirectTrailingSlash to false. By default it is set to true. - -One exception to this rule is catch-all patterns. By default, trailing slash redirection is disabled on catch-all patterns, since the structure of the entire URL and the desired patterns can not be predicted. If trailing slash removal is desired on catch-all patterns, set TreeMux.RemoveCatchAllTrailingSlash to true. - -```go -router = httptreemux.New() -router.GET("/about", pageHandler) -router.GET("/posts/", postIndexHandler) -router.POST("/posts", postFormHandler) - -GET /about will match normally. -GET /about/ will redirect to /about. -GET /posts will redirect to /posts/. -GET /posts/ will match normally. -POST /posts will redirect to /posts/, because the GET method used a trailing slash. -``` - -### Custom Redirects - -RedirectBehavior sets the behavior when the router redirects the request to the canonical version of the requested URL using RedirectTrailingSlash or RedirectClean. The default behavior is to return a 301 status, redirecting the browser to the version of the URL that matches the given pattern. - -These are the values accepted for RedirectBehavior. You may also add these values to the RedirectMethodBehavior map to define custom per-method redirect behavior. - -* Redirect301 - HTTP 301 Moved Permanently; this is the default. -* Redirect307 - HTTP/1.1 Temporary Redirect -* Redirect308 - RFC7538 Permanent Redirect -* UseHandler - Don't redirect to the canonical path. Just call the handler instead. - -#### Rationale/Usage -On a POST request, most browsers that receive a 301 will submit a GET request to the redirected URL, meaning that any data will likely be lost. If you want to handle and avoid this behavior, you may use Redirect307, which causes most browsers to resubmit the request using the original method and request body. - -Since 307 is supposed to be a temporary redirect, the new 308 status code has been proposed, which is treated the same, except it indicates correctly that the redirection is permanent. The big caveat here is that the RFC is relatively recent, and older or non-compliant browsers will not handle it. Therefore its use is not recommended unless you really know what you're doing. - -Finally, the UseHandler value will simply call the handler function for the pattern, without redirecting to the canonical version of the URL. - -### RequestURI vs. URL.Path - -#### Escaped Slashes -Go automatically processes escaped characters in a URL, converting + to a space and %XX to the corresponding character. This can present issues when the URL contains a %2f, which is unescaped to '/'. This isn't an issue for most applications, but it will prevent the router from correctly matching paths and wildcards. - -For example, the pattern `/post/:post` would not match on `/post/abc%2fdef`, which is unescaped to `/post/abc/def`. The desired behavior is that it matches, and the `post` wildcard is set to `abc/def`. - -Therefore, this router defaults to using the raw URL, stored in the Request.RequestURI variable. Matching wildcards and catch-alls are then unescaped, to give the desired behavior. - -TL;DR: If a requested URL contains a %2f, this router will still do the right thing. Some Go HTTP routers may not due to [Go issue 3659](https://code.google.com/p/go/issues/detail?id=3659). - -#### Escaped Characters - -As mentioned above, characters in the URL are not unescaped when using RequestURI to determine the matched route. If this is a problem for you and you are unable to switch to URL.Path for the above reasons, you may set `router.EscapeAddedRoutes` to `true`. This option will run each added route through the `URL.EscapedPath` function, and add an additional route if the escaped version differs. - -#### http Package Utility Functions - -Although using RequestURI avoids the issue described above, certain utility functions such as `http.StripPrefix` modify URL.Path, and expect that the underlying router is using that field to make its decision. If you are using some of these functions, set the router's `PathSource` member to `URLPath`. This will give up the proper handling of escaped slashes described above, while allowing the router to work properly with these utility functions. - -## Concurrency - -The router contains an `RWMutex` that arbitrates access to the tree. This allows routes to be safely added from multiple goroutines at once. - -No concurrency controls are needed when only reading from the tree, so the default behavior is to not use the `RWMutex` when serving a request. This avoids a theoretical slowdown under high-usage scenarios from competing atomic integer operations inside the `RWMutex`. If your application adds routes to the router after it has begun serving requests, you should avoid potential race conditions by setting `router.SafeAddRoutesWhileRunning` to `true` to use the `RWMutex` when serving requests. - -## Error Handlers - -### NotFoundHandler -TreeMux.NotFoundHandler can be set to provide custom 404-error handling. The default implementation is Go's `http.NotFound` function. - -### MethodNotAllowedHandler -If a pattern matches, but the pattern does not have an associated handler for the requested method, the router calls the MethodNotAllowedHandler. The default -version of this handler just writes the status code `http.StatusMethodNotAllowed` and sets the response header's `Allowed` field appropriately. - -### Panic Handling -TreeMux.PanicHandler can be set to provide custom panic handling. The `SimplePanicHandler` just writes the status code `http.StatusInternalServerError`. The function `ShowErrorsPanicHandler`, adapted from [gocraft/web](https://github.com/gocraft/web), will print panic errors to the browser in an easily-readable format. - -## Unexpected Differences from Other Routers - -This router is intentionally light on features in the name of simplicity and -performance. When coming from another router that does heavier processing behind -the scenes, you may encounter some unexpected behavior. This list is by no means -exhaustive, but covers some nonobvious cases that users have encountered. - -### gorilla/pat query string modifications - -When matching on parameters in a route, the `gorilla/pat` router will modify -`Request.URL.RawQuery` to make it appear like the parameters were in the -query string. `httptreemux` does not do this. See [Issue #26](https://github.com/dimfeld/httptreemux/issues/26) for more details and a -code snippet that can perform this transformation for you, should you want it. - -## Middleware -This package provides no middleware. But there are a lot of great options out there and it's pretty easy to write your own. - -# Acknowledgements - -* Inspiration from Julien Schmidt's [httprouter](https://github.com/julienschmidt/httprouter) -* Show Errors panic handler from [gocraft/web](https://github.com/gocraft/web) diff --git a/vendor/github.com/dimfeld/httptreemux/context.go b/vendor/github.com/dimfeld/httptreemux/context.go deleted file mode 100644 index de5ad449a0e..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/context.go +++ /dev/null @@ -1,123 +0,0 @@ -// +build go1.7 - -package httptreemux - -import ( - "context" - "net/http" -) - -// ContextGroup is a wrapper around Group, with the purpose of mimicking its API, but with the use of http.HandlerFunc-based handlers. -// Instead of passing a parameter map via the handler (i.e. httptreemux.HandlerFunc), the path parameters are accessed via the request -// object's context. -type ContextGroup struct { - group *Group -} - -// UsingContext wraps the receiver to return a new instance of a ContextGroup. -// The returned ContextGroup is a sibling to its wrapped Group, within the parent TreeMux. -// The choice of using a *Group as the receiver, as opposed to a function parameter, allows chaining -// while method calls between a TreeMux, Group, and ContextGroup. For example: -// -// tree := httptreemux.New() -// group := tree.NewGroup("/api") -// -// group.GET("/v1", func(w http.ResponseWriter, r *http.Request, params map[string]string) { -// w.Write([]byte(`GET /api/v1`)) -// }) -// -// group.UsingContext().GET("/v2", func(w http.ResponseWriter, r *http.Request) { -// w.Write([]byte(`GET /api/v2`)) -// }) -// -// http.ListenAndServe(":8080", tree) -// -func (g *Group) UsingContext() *ContextGroup { - return &ContextGroup{g} -} - -// NewContextGroup adds a child context group to its path. -func (cg *ContextGroup) NewContextGroup(path string) *ContextGroup { - return &ContextGroup{cg.group.NewGroup(path)} -} - -func (cg *ContextGroup) NewGroup(path string) *ContextGroup { - return cg.NewContextGroup(path) -} - -// Handle allows handling HTTP requests via an http.HandlerFunc, as opposed to an httptreemux.HandlerFunc. -// Any parameters from the request URL are stored in a map[string]string in the request's context. -func (cg *ContextGroup) Handle(method, path string, handler http.HandlerFunc) { - cg.group.Handle(method, path, func(w http.ResponseWriter, r *http.Request, params map[string]string) { - if params != nil { - r = r.WithContext(AddParamsToContext(r.Context(), params)) - } - handler(w, r) - }) -} - -// Handler allows handling HTTP requests via an http.Handler interface, as opposed to an httptreemux.HandlerFunc. -// Any parameters from the request URL are stored in a map[string]string in the request's context. -func (cg *ContextGroup) Handler(method, path string, handler http.Handler) { - cg.group.Handle(method, path, func(w http.ResponseWriter, r *http.Request, params map[string]string) { - if params != nil { - r = r.WithContext(AddParamsToContext(r.Context(), params)) - } - handler.ServeHTTP(w, r) - }) -} - -// GET is convenience method for handling GET requests on a context group. -func (cg *ContextGroup) GET(path string, handler http.HandlerFunc) { - cg.Handle("GET", path, handler) -} - -// POST is convenience method for handling POST requests on a context group. -func (cg *ContextGroup) POST(path string, handler http.HandlerFunc) { - cg.Handle("POST", path, handler) -} - -// PUT is convenience method for handling PUT requests on a context group. -func (cg *ContextGroup) PUT(path string, handler http.HandlerFunc) { - cg.Handle("PUT", path, handler) -} - -// DELETE is convenience method for handling DELETE requests on a context group. -func (cg *ContextGroup) DELETE(path string, handler http.HandlerFunc) { - cg.Handle("DELETE", path, handler) -} - -// PATCH is convenience method for handling PATCH requests on a context group. -func (cg *ContextGroup) PATCH(path string, handler http.HandlerFunc) { - cg.Handle("PATCH", path, handler) -} - -// HEAD is convenience method for handling HEAD requests on a context group. -func (cg *ContextGroup) HEAD(path string, handler http.HandlerFunc) { - cg.Handle("HEAD", path, handler) -} - -// OPTIONS is convenience method for handling OPTIONS requests on a context group. -func (cg *ContextGroup) OPTIONS(path string, handler http.HandlerFunc) { - cg.Handle("OPTIONS", path, handler) -} - -// ContextParams returns the params map associated with the given context if one exists. Otherwise, an empty map is returned. -func ContextParams(ctx context.Context) map[string]string { - if p, ok := ctx.Value(paramsContextKey).(map[string]string); ok { - return p - } - return map[string]string{} -} - -// AddParamsToContext inserts a parameters map into a context using -// the package's internal context key. Clients of this package should -// really only use this for unit tests. -func AddParamsToContext(ctx context.Context, params map[string]string) context.Context { - return context.WithValue(ctx, paramsContextKey, params) -} - -type contextKey int - -// paramsContextKey is used to retrieve a path's params map from a request's context. -const paramsContextKey contextKey = 0 diff --git a/vendor/github.com/dimfeld/httptreemux/group.go b/vendor/github.com/dimfeld/httptreemux/group.go deleted file mode 100644 index 7ed533e7b27..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/group.go +++ /dev/null @@ -1,195 +0,0 @@ -package httptreemux - -import ( - "fmt" - "net/url" - "strings" -) - -type Group struct { - path string - mux *TreeMux -} - -// Add a sub-group to this group -func (g *Group) NewGroup(path string) *Group { - if len(path) < 1 { - panic("Group path must not be empty") - } - - checkPath(path) - path = g.path + path - //Don't want trailing slash as all sub-paths start with slash - if path[len(path)-1] == '/' { - path = path[:len(path)-1] - } - return &Group{path, g.mux} -} - -// Path elements starting with : indicate a wildcard in the path. A wildcard will only match on a -// single path segment. That is, the pattern `/post/:postid` will match on `/post/1` or `/post/1/`, -// but not `/post/1/2`. -// -// A path element starting with * is a catch-all, whose value will be a string containing all text -// in the URL matched by the wildcards. For example, with a pattern of `/images/*path` and a -// requested URL `images/abc/def`, path would contain `abc/def`. -// -// # Routing Rule Priority -// -// The priority rules in the router are simple. -// -// 1. Static path segments take the highest priority. If a segment and its subtree are able to match the URL, that match is returned. -// -// 2. Wildcards take second priority. For a particular wildcard to match, that wildcard and its subtree must match the URL. -// -// 3. Finally, a catch-all rule will match when the earlier path segments have matched, and none of the static or wildcard conditions have matched. Catch-all rules must be at the end of a pattern. -// -// So with the following patterns, we'll see certain matches: -// router = httptreemux.New() -// router.GET("/:page", pageHandler) -// router.GET("/:year/:month/:post", postHandler) -// router.GET("/:year/:month", archiveHandler) -// router.GET("/images/*path", staticHandler) -// router.GET("/favicon.ico", staticHandler) -// -// /abc will match /:page -// /2014/05 will match /:year/:month -// /2014/05/really-great-blog-post will match /:year/:month/:post -// /images/CoolImage.gif will match /images/*path -// /images/2014/05/MayImage.jpg will also match /images/*path, with all the text after /images stored in the variable path. -// /favicon.ico will match /favicon.ico -// -// # Trailing Slashes -// -// The router has special handling for paths with trailing slashes. If a pattern is added to the -// router with a trailing slash, any matches on that pattern without a trailing slash will be -// redirected to the version with the slash. If a pattern does not have a trailing slash, matches on -// that pattern with a trailing slash will be redirected to the version without. -// -// The trailing slash flag is only stored once for a pattern. That is, if a pattern is added for a -// method with a trailing slash, all other methods for that pattern will also be considered to have a -// trailing slash, regardless of whether or not it is specified for those methods too. -// -// This behavior can be turned off by setting TreeMux.RedirectTrailingSlash to false. By -// default it is set to true. The specifics of the redirect depend on RedirectBehavior. -// -// One exception to this rule is catch-all patterns. By default, trailing slash redirection is -// disabled on catch-all patterns, since the structure of the entire URL and the desired patterns -// can not be predicted. If trailing slash removal is desired on catch-all patterns, set -// TreeMux.RemoveCatchAllTrailingSlash to true. -// -// router = httptreemux.New() -// router.GET("/about", pageHandler) -// router.GET("/posts/", postIndexHandler) -// router.POST("/posts", postFormHandler) -// -// GET /about will match normally. -// GET /about/ will redirect to /about. -// GET /posts will redirect to /posts/. -// GET /posts/ will match normally. -// POST /posts will redirect to /posts/, because the GET method used a trailing slash. -func (g *Group) Handle(method string, path string, handler HandlerFunc) { - g.mux.mutex.Lock() - defer g.mux.mutex.Unlock() - - addSlash := false - addOne := func(thePath string) { - node := g.mux.root.addPath(thePath[1:], nil, false) - if addSlash { - node.addSlash = true - } - node.setHandler(method, handler, false) - - if g.mux.HeadCanUseGet && method == "GET" && node.leafHandler["HEAD"] == nil { - node.setHandler("HEAD", handler, true) - } - } - - checkPath(path) - path = g.path + path - if len(path) == 0 { - panic("Cannot map an empty path") - } - - if len(path) > 1 && path[len(path)-1] == '/' && g.mux.RedirectTrailingSlash { - addSlash = true - path = path[:len(path)-1] - } - - if g.mux.EscapeAddedRoutes { - u, err := url.ParseRequestURI(path) - if err != nil { - panic("URL parsing error " + err.Error() + " on url " + path) - } - escapedPath := unescapeSpecial(u.String()) - - if escapedPath != path { - addOne(escapedPath) - } - } - - addOne(path) -} - -// Syntactic sugar for Handle("GET", path, handler) -func (g *Group) GET(path string, handler HandlerFunc) { - g.Handle("GET", path, handler) -} - -// Syntactic sugar for Handle("POST", path, handler) -func (g *Group) POST(path string, handler HandlerFunc) { - g.Handle("POST", path, handler) -} - -// Syntactic sugar for Handle("PUT", path, handler) -func (g *Group) PUT(path string, handler HandlerFunc) { - g.Handle("PUT", path, handler) -} - -// Syntactic sugar for Handle("DELETE", path, handler) -func (g *Group) DELETE(path string, handler HandlerFunc) { - g.Handle("DELETE", path, handler) -} - -// Syntactic sugar for Handle("PATCH", path, handler) -func (g *Group) PATCH(path string, handler HandlerFunc) { - g.Handle("PATCH", path, handler) -} - -// Syntactic sugar for Handle("HEAD", path, handler) -func (g *Group) HEAD(path string, handler HandlerFunc) { - g.Handle("HEAD", path, handler) -} - -// Syntactic sugar for Handle("OPTIONS", path, handler) -func (g *Group) OPTIONS(path string, handler HandlerFunc) { - g.Handle("OPTIONS", path, handler) -} - -func checkPath(path string) { - // All non-empty paths must start with a slash - if len(path) > 0 && path[0] != '/' { - panic(fmt.Sprintf("Path %s must start with slash", path)) - } -} - -func unescapeSpecial(s string) string { - // Look for sequences of \*, *, and \: that were escaped, and undo some of that escaping. - - // Unescape /* since it references a wildcard token. - s = strings.Replace(s, "/%2A", "/*", -1) - - // Unescape /\: since it references a literal colon - s = strings.Replace(s, "/%5C:", "/\\:", -1) - - // Replace escaped /\\: with /\: - s = strings.Replace(s, "/%5C%5C:", "/%5C:", -1) - - // Replace escaped /\* with /* - s = strings.Replace(s, "/%5C%2A", "/%2A", -1) - - // Replace escaped /\\* with /\* - s = strings.Replace(s, "/%5C%5C%2A", "/%5C%2A", -1) - - return s -} diff --git a/vendor/github.com/dimfeld/httptreemux/panichandler.go b/vendor/github.com/dimfeld/httptreemux/panichandler.go deleted file mode 100644 index cebb661bc4e..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/panichandler.go +++ /dev/null @@ -1,211 +0,0 @@ -package httptreemux - -import ( - "bufio" - "encoding/json" - "html/template" - "net/http" - "os" - "runtime" - "strings" -) - -// SimplePanicHandler just returns error 500. -func SimplePanicHandler(w http.ResponseWriter, r *http.Request, err interface{}) { - w.WriteHeader(http.StatusInternalServerError) -} - -// ShowErrorsPanicHandler prints a nice representation of an error to the browser. -// This was taken from github.com/gocraft/web, which adapted it from the Traffic project. -func ShowErrorsPanicHandler(w http.ResponseWriter, r *http.Request, err interface{}) { - const size = 4096 - stack := make([]byte, size) - stack = stack[:runtime.Stack(stack, false)] - renderPrettyError(w, r, err, stack) -} - -func makeErrorData(r *http.Request, err interface{}, stack []byte, filePath string, line int) map[string]interface{} { - - data := map[string]interface{}{ - "Stack": string(stack), - "Params": r.URL.Query(), - "Method": r.Method, - "FilePath": filePath, - "Line": line, - "Lines": readErrorFileLines(filePath, line), - } - - if e, ok := err.(error); ok { - data["Error"] = e.Error() - } else { - data["Error"] = err - } - - return data -} - -func renderPrettyError(rw http.ResponseWriter, req *http.Request, err interface{}, stack []byte) { - _, filePath, line, _ := runtime.Caller(5) - - data := makeErrorData(req, err, stack, filePath, line) - rw.Header().Set("Content-Type", "text/html") - rw.WriteHeader(http.StatusInternalServerError) - - tpl := template.Must(template.New("ErrorPage").Parse(panicPageTpl)) - tpl.Execute(rw, data) -} - -func ShowErrorsJsonPanicHandler(w http.ResponseWriter, r *http.Request, err interface{}) { - const size = 4096 - stack := make([]byte, size) - stack = stack[:runtime.Stack(stack, false)] - - _, filePath, line, _ := runtime.Caller(4) - data := makeErrorData(r, err, stack, filePath, line) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusInternalServerError) - json.NewEncoder(w).Encode(data) -} - -func readErrorFileLines(filePath string, errorLine int) map[int]string { - lines := make(map[int]string) - - file, err := os.Open(filePath) - if err != nil { - return lines - } - - defer file.Close() - - reader := bufio.NewReader(file) - currentLine := 0 - for { - line, err := reader.ReadString('\n') - if err != nil || currentLine > errorLine+5 { - break - } - - currentLine++ - - if currentLine >= errorLine-5 { - lines[currentLine] = strings.Replace(line, "\n", "", -1) - } - } - - return lines -} - -const panicPageTpl string = ` - - - Panic - - - - -
-
-

Error

-
-
- -
-

{{ .Error }}

-
- -
-

- In {{ .FilePath }}:{{ .Line }}

-

- - - - - - -
-
{{ range $lineNumber, $line :=  .Lines }}{{ $lineNumber }}{{ end }}
-
-
{{ range $lineNumber, $line :=  .Lines }}{{ $line }}
{{ end }}
-
-

Stack

-
{{ .Stack }}
-

Request

-

Method: {{ .Method }}

-

Parameters:

-
    - {{ range $key, $value := .Params }} -
  • {{ $key }}: {{ $value }}
  • - {{ end }} -
-
- - - ` diff --git a/vendor/github.com/dimfeld/httptreemux/path.go b/vendor/github.com/dimfeld/httptreemux/path.go deleted file mode 100644 index 506ac38469f..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/path.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2013 Julien Schmidt. All rights reserved. -// Based on the path package, Copyright 2009 The Go Authors. -// Use of this source code is governed by a BSD-style license that can be found -// in the LICENSE file. - -package httptreemux - -// Clean is the URL version of path.Clean, it returns a canonical URL path -// for p, eliminating . and .. elements. -// -// The following rules are applied iteratively until no further processing can -// be done: -// 1. Replace multiple slashes with a single slash. -// 2. Eliminate each . path name element (the current directory). -// 3. Eliminate each inner .. path name element (the parent directory) -// along with the non-.. element that precedes it. -// 4. Eliminate .. elements that begin a rooted path: -// that is, replace "/.." by "/" at the beginning of a path. -// -// If the result of this process is an empty string, "/" is returned -func Clean(p string) string { - if p == "" { - return "/" - } - - n := len(p) - var buf []byte - - // Invariants: - // reading from path; r is index of next byte to process. - // writing to buf; w is index of next byte to write. - - // path must start with '/' - r := 1 - w := 1 - - if p[0] != '/' { - r = 0 - buf = make([]byte, n+1) - buf[0] = '/' - } - - trailing := n > 2 && p[n-1] == '/' - - // A bit more clunky without a 'lazybuf' like the path package, but the loop - // gets completely inlined (bufApp). So in contrast to the path package this - // loop has no expensive function calls (except 1x make) - - for r < n { - switch { - case p[r] == '/': - // empty path element, trailing slash is added after the end - r++ - - case p[r] == '.' && r+1 == n: - trailing = true - r++ - - case p[r] == '.' && p[r+1] == '/': - // . element - r++ - - case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): - // .. element: remove to last / - r += 2 - - if w > 1 { - // can backtrack - w-- - - if buf == nil { - for w > 1 && p[w] != '/' { - w-- - } - } else { - for w > 1 && buf[w] != '/' { - w-- - } - } - } - - default: - // real path element. - // add slash if needed - if w > 1 { - bufApp(&buf, p, w, '/') - w++ - } - - // copy element - for r < n && p[r] != '/' { - bufApp(&buf, p, w, p[r]) - w++ - r++ - } - } - } - - // re-append trailing slash - if trailing && w > 1 { - bufApp(&buf, p, w, '/') - w++ - } - - // Turn empty string into "/" - if w == 0 { - return "/" - } - - if buf == nil { - return p[:w] - } - return string(buf[:w]) -} - -// internal helper to lazily create a buffer if necessary -func bufApp(buf *[]byte, s string, w int, c byte) { - if *buf == nil { - if s[w] == c { - return - } - - *buf = make([]byte, len(s)) - copy(*buf, s[:w]) - } - (*buf)[w] = c -} diff --git a/vendor/github.com/dimfeld/httptreemux/router.go b/vendor/github.com/dimfeld/httptreemux/router.go deleted file mode 100644 index b8063e4d227..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/router.go +++ /dev/null @@ -1,300 +0,0 @@ -// This is inspired by Julien Schmidt's httprouter, in that it uses a patricia tree, but the -// implementation is rather different. Specifically, the routing rules are relaxed so that a -// single path segment may be a wildcard in one route and a static token in another. This gives a -// nice combination of high performance with a lot of convenience in designing the routing patterns. -package httptreemux - -import ( - "fmt" - "net/http" - "net/url" -) - -// The params argument contains the parameters parsed from wildcards and catch-alls in the URL. -type HandlerFunc func(http.ResponseWriter, *http.Request, map[string]string) -type PanicHandler func(http.ResponseWriter, *http.Request, interface{}) - -// RedirectBehavior sets the behavior when the router redirects the request to the -// canonical version of the requested URL using RedirectTrailingSlash or RedirectClean. -// The default behavior is to return a 301 status, redirecting the browser to the version -// of the URL that matches the given pattern. -// -// On a POST request, most browsers that receive a 301 will submit a GET request to -// the redirected URL, meaning that any data will likely be lost. If you want to handle -// and avoid this behavior, you may use Redirect307, which causes most browsers to -// resubmit the request using the original method and request body. -// -// Since 307 is supposed to be a temporary redirect, the new 308 status code has been -// proposed, which is treated the same, except it indicates correctly that the redirection -// is permanent. The big caveat here is that the RFC is relatively recent, and older -// browsers will not know what to do with it. Therefore its use is not recommended -// unless you really know what you're doing. -// -// Finally, the UseHandler value will simply call the handler function for the pattern. -type RedirectBehavior int - -type PathSource int - -const ( - Redirect301 RedirectBehavior = iota // Return 301 Moved Permanently - Redirect307 // Return 307 HTTP/1.1 Temporary Redirect - Redirect308 // Return a 308 RFC7538 Permanent Redirect - UseHandler // Just call the handler function - - RequestURI PathSource = iota // Use r.RequestURI - URLPath // Use r.URL.Path -) - -// LookupResult contains information about a route lookup, which is returned from Lookup and -// can be passed to ServeLookupResult if the request should be served. -type LookupResult struct { - // StatusCode informs the caller about the result of the lookup. - // This will generally be `http.StatusNotFound` or `http.StatusMethodNotAllowed` for an - // error case. On a normal success, the statusCode will be `http.StatusOK`. A redirect code - // will also be used in the case - StatusCode int - handler HandlerFunc - params map[string]string - leafHandler map[string]HandlerFunc // Only has a value when StatusCode is MethodNotAllowed. -} - -// Dump returns a text representation of the routing tree. -func (t *TreeMux) Dump() string { - return t.root.dumpTree("", "") -} - -func (t *TreeMux) serveHTTPPanic(w http.ResponseWriter, r *http.Request) { - if err := recover(); err != nil { - t.PanicHandler(w, r, err) - } -} - -func (t *TreeMux) redirectStatusCode(method string) (int, bool) { - var behavior RedirectBehavior - var ok bool - if behavior, ok = t.RedirectMethodBehavior[method]; !ok { - behavior = t.RedirectBehavior - } - switch behavior { - case Redirect301: - return http.StatusMovedPermanently, true - case Redirect307: - return http.StatusTemporaryRedirect, true - case Redirect308: - // Go doesn't have a constant for this yet. Yet another sign - // that you probably shouldn't use it. - return 308, true - case UseHandler: - return 0, false - default: - return http.StatusMovedPermanently, true - } -} - -func redirectHandler(newPath string, statusCode int) HandlerFunc { - return func(w http.ResponseWriter, r *http.Request, params map[string]string) { - redirect(w, r, newPath, statusCode) - } -} - -func redirect(w http.ResponseWriter, r *http.Request, newPath string, statusCode int) { - newURL := url.URL{ - Path: newPath, - RawQuery: r.URL.RawQuery, - Fragment: r.URL.Fragment, - } - http.Redirect(w, r, newURL.String(), statusCode) -} - -func (t *TreeMux) lookup(w http.ResponseWriter, r *http.Request) (result LookupResult, found bool) { - result.StatusCode = http.StatusNotFound - path := r.RequestURI - unescapedPath := r.URL.Path - pathLen := len(path) - if pathLen > 0 && t.PathSource == RequestURI { - rawQueryLen := len(r.URL.RawQuery) - - if rawQueryLen != 0 || path[pathLen-1] == '?' { - // Remove any query string and the ?. - path = path[:pathLen-rawQueryLen-1] - pathLen = len(path) - } - } else { - // In testing with http.NewRequest, - // RequestURI is not set so just grab URL.Path instead. - path = r.URL.Path - pathLen = len(path) - } - - trailingSlash := path[pathLen-1] == '/' && pathLen > 1 - if trailingSlash && t.RedirectTrailingSlash { - path = path[:pathLen-1] - unescapedPath = unescapedPath[:len(unescapedPath)-1] - } - - n, handler, params := t.root.search(r.Method, path[1:]) - if n == nil { - if t.RedirectCleanPath { - // Path was not found. Try cleaning it up and search again. - // TODO Test this - cleanPath := Clean(unescapedPath) - n, handler, params = t.root.search(r.Method, cleanPath[1:]) - if n == nil { - // Still nothing found. - return - } - if statusCode, ok := t.redirectStatusCode(r.Method); ok { - // Redirect to the actual path - return LookupResult{statusCode, redirectHandler(cleanPath, statusCode), nil, nil}, true - } - } else { - // Not found. - return - } - } - - if handler == nil { - if r.Method == "OPTIONS" && t.OptionsHandler != nil { - handler = t.OptionsHandler - } - - if handler == nil { - result.leafHandler = n.leafHandler - result.StatusCode = http.StatusMethodNotAllowed - return - } - } - - if !n.isCatchAll || t.RemoveCatchAllTrailingSlash { - if trailingSlash != n.addSlash && t.RedirectTrailingSlash { - if statusCode, ok := t.redirectStatusCode(r.Method); ok { - var h HandlerFunc - if n.addSlash { - // Need to add a slash. - h = redirectHandler(unescapedPath+"/", statusCode) - } else if path != "/" { - // We need to remove the slash. This was already done at the - // beginning of the function. - h = redirectHandler(unescapedPath, statusCode) - } - - if h != nil { - return LookupResult{statusCode, h, nil, nil}, true - } - } - } - } - - var paramMap map[string]string - if len(params) != 0 { - if len(params) != len(n.leafWildcardNames) { - // Need better behavior here. Should this be a panic? - panic(fmt.Sprintf("httptreemux parameter list length mismatch: %v, %v", - params, n.leafWildcardNames)) - } - - paramMap = make(map[string]string) - numParams := len(params) - for index := 0; index < numParams; index++ { - paramMap[n.leafWildcardNames[numParams-index-1]] = params[index] - } - } - - return LookupResult{http.StatusOK, handler, paramMap, nil}, true -} - -// Lookup performs a lookup without actually serving the request or mutating the request or response. -// The return values are a LookupResult and a boolean. The boolean will be true when a handler -// was found or the lookup resulted in a redirect which will point to a real handler. It is false -// for requests which would result in a `StatusNotFound` or `StatusMethodNotAllowed`. -// -// Regardless of the returned boolean's value, the LookupResult may be passed to ServeLookupResult -// to be served appropriately. -func (t *TreeMux) Lookup(w http.ResponseWriter, r *http.Request) (LookupResult, bool) { - if t.SafeAddRoutesWhileRunning { - // In concurrency safe mode, we acquire a read lock on the mutex for any access. - // This is optional to avoid potential performance loss in high-usage scenarios. - t.mutex.RLock() - } - - result, found := t.lookup(w, r) - - if t.SafeAddRoutesWhileRunning { - t.mutex.RUnlock() - } - - return result, found -} - -// ServeLookupResult serves a request, given a lookup result from the Lookup function. -func (t *TreeMux) ServeLookupResult(w http.ResponseWriter, r *http.Request, lr LookupResult) { - if lr.handler == nil { - if lr.StatusCode == http.StatusMethodNotAllowed && lr.leafHandler != nil { - if t.SafeAddRoutesWhileRunning { - t.mutex.RLock() - } - - t.MethodNotAllowedHandler(w, r, lr.leafHandler) - - if t.SafeAddRoutesWhileRunning { - t.mutex.RUnlock() - } - } else { - t.NotFoundHandler(w, r) - } - } else { - r = t.setDefaultRequestContext(r) - lr.handler(w, r, lr.params) - } -} - -func (t *TreeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if t.PanicHandler != nil { - defer t.serveHTTPPanic(w, r) - } - - if t.SafeAddRoutesWhileRunning { - // In concurrency safe mode, we acquire a read lock on the mutex for any access. - // This is optional to avoid potential performance loss in high-usage scenarios. - t.mutex.RLock() - } - - result, _ := t.lookup(w, r) - - if t.SafeAddRoutesWhileRunning { - t.mutex.RUnlock() - } - - t.ServeLookupResult(w, r, result) -} - -// MethodNotAllowedHandler is the default handler for TreeMux.MethodNotAllowedHandler, -// which is called for patterns that match, but do not have a handler installed for the -// requested method. It simply writes the status code http.StatusMethodNotAllowed and fills -// in the `Allow` header value appropriately. -func MethodNotAllowedHandler(w http.ResponseWriter, r *http.Request, - methods map[string]HandlerFunc) { - - for m := range methods { - w.Header().Add("Allow", m) - } - - w.WriteHeader(http.StatusMethodNotAllowed) -} - -func New() *TreeMux { - tm := &TreeMux{ - root: &node{path: "/"}, - NotFoundHandler: http.NotFound, - MethodNotAllowedHandler: MethodNotAllowedHandler, - HeadCanUseGet: true, - RedirectTrailingSlash: true, - RedirectCleanPath: true, - RedirectBehavior: Redirect301, - RedirectMethodBehavior: make(map[string]RedirectBehavior), - PathSource: RequestURI, - EscapeAddedRoutes: false, - } - tm.Group.mux = tm - return tm -} diff --git a/vendor/github.com/dimfeld/httptreemux/tree.go b/vendor/github.com/dimfeld/httptreemux/tree.go deleted file mode 100644 index 530d427848f..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/tree.go +++ /dev/null @@ -1,340 +0,0 @@ -package httptreemux - -import ( - "fmt" - "strings" -) - -type node struct { - path string - - priority int - - // The list of static children to check. - staticIndices []byte - staticChild []*node - - // If none of the above match, check the wildcard children - wildcardChild *node - - // If none of the above match, then we use the catch-all, if applicable. - catchAllChild *node - - // Data for the node is below. - - addSlash bool - isCatchAll bool - // If true, the head handler was set implicitly, so let it also be set explicitly. - implicitHead bool - // If this node is the end of the URL, then call the handler, if applicable. - leafHandler map[string]HandlerFunc - - // The names of the parameters to apply. - leafWildcardNames []string -} - -func (n *node) sortStaticChild(i int) { - for i > 0 && n.staticChild[i].priority > n.staticChild[i-1].priority { - n.staticChild[i], n.staticChild[i-1] = n.staticChild[i-1], n.staticChild[i] - n.staticIndices[i], n.staticIndices[i-1] = n.staticIndices[i-1], n.staticIndices[i] - i -= 1 - } -} - -func (n *node) setHandler(verb string, handler HandlerFunc, implicitHead bool) { - if n.leafHandler == nil { - n.leafHandler = make(map[string]HandlerFunc) - } - _, ok := n.leafHandler[verb] - if ok && (verb != "HEAD" || !n.implicitHead) { - panic(fmt.Sprintf("%s already handles %s", n.path, verb)) - } - n.leafHandler[verb] = handler - - if verb == "HEAD" { - n.implicitHead = implicitHead - } -} - -func (n *node) addPath(path string, wildcards []string, inStaticToken bool) *node { - leaf := len(path) == 0 - if leaf { - if wildcards != nil { - // Make sure the current wildcards are the same as the old ones. - // If not then we have an ambiguous path. - if n.leafWildcardNames != nil { - if len(n.leafWildcardNames) != len(wildcards) { - // This should never happen. - panic("Reached leaf node with differing wildcard array length. Please report this as a bug.") - } - - for i := 0; i < len(wildcards); i++ { - if n.leafWildcardNames[i] != wildcards[i] { - panic(fmt.Sprintf("Wildcards %v are ambiguous with wildcards %v", - n.leafWildcardNames, wildcards)) - } - } - } else { - // No wildcards yet, so just add the existing set. - n.leafWildcardNames = wildcards - } - } - - return n - } - - c := path[0] - nextSlash := strings.Index(path, "/") - var thisToken string - var tokenEnd int - - if c == '/' { - // Done processing the previous token, so reset inStaticToken to false. - thisToken = "/" - tokenEnd = 1 - } else if nextSlash == -1 { - thisToken = path - tokenEnd = len(path) - } else { - thisToken = path[0:nextSlash] - tokenEnd = nextSlash - } - remainingPath := path[tokenEnd:] - - if c == '*' && !inStaticToken { - // Token starts with a *, so it's a catch-all - thisToken = thisToken[1:] - if n.catchAllChild == nil { - n.catchAllChild = &node{path: thisToken, isCatchAll: true} - } - - if path[1:] != n.catchAllChild.path { - panic(fmt.Sprintf("Catch-all name in %s doesn't match %s. You probably tried to define overlapping catchalls", - path, n.catchAllChild.path)) - } - - if nextSlash != -1 { - panic("/ after catch-all found in " + path) - } - - if wildcards == nil { - wildcards = []string{thisToken} - } else { - wildcards = append(wildcards, thisToken) - } - n.catchAllChild.leafWildcardNames = wildcards - - return n.catchAllChild - } else if c == ':' && !inStaticToken { - // Token starts with a : - thisToken = thisToken[1:] - - if wildcards == nil { - wildcards = []string{thisToken} - } else { - wildcards = append(wildcards, thisToken) - } - - if n.wildcardChild == nil { - n.wildcardChild = &node{path: "wildcard"} - } - - return n.wildcardChild.addPath(remainingPath, wildcards, false) - - } else { - // if strings.ContainsAny(thisToken, ":*") { - // panic("* or : in middle of path component " + path) - // } - - unescaped := false - if len(thisToken) >= 2 && !inStaticToken { - if thisToken[0] == '\\' && (thisToken[1] == '*' || thisToken[1] == ':' || thisToken[1] == '\\') { - // The token starts with a character escaped by a backslash. Drop the backslash. - c = thisToken[1] - thisToken = thisToken[1:] - unescaped = true - } - } - - // Set inStaticToken to ensure that the rest of this token is not mistaken - // for a wildcard if a prefix split occurs at a '*' or ':'. - inStaticToken = (c != '/') - - // Do we have an existing node that starts with the same letter? - for i, index := range n.staticIndices { - if c == index { - // Yes. Split it based on the common prefix of the existing - // node and the new one. - child, prefixSplit := n.splitCommonPrefix(i, thisToken) - - child.priority++ - n.sortStaticChild(i) - if unescaped { - // Account for the removed backslash. - prefixSplit++ - } - return child.addPath(path[prefixSplit:], wildcards, inStaticToken) - } - } - - // No existing node starting with this letter, so create it. - child := &node{path: thisToken} - - if n.staticIndices == nil { - n.staticIndices = []byte{c} - n.staticChild = []*node{child} - } else { - n.staticIndices = append(n.staticIndices, c) - n.staticChild = append(n.staticChild, child) - } - return child.addPath(remainingPath, wildcards, inStaticToken) - } -} - -func (n *node) splitCommonPrefix(existingNodeIndex int, path string) (*node, int) { - childNode := n.staticChild[existingNodeIndex] - - if strings.HasPrefix(path, childNode.path) { - // No split needs to be done. Rather, the new path shares the entire - // prefix with the existing node, so the new node is just a child of - // the existing one. Or the new path is the same as the existing path, - // which means that we just move on to the next token. Either way, - // this return accomplishes that - return childNode, len(childNode.path) - } - - var i int - // Find the length of the common prefix of the child node and the new path. - for i = range childNode.path { - if i == len(path) { - break - } - if path[i] != childNode.path[i] { - break - } - } - - commonPrefix := path[0:i] - childNode.path = childNode.path[i:] - - // Create a new intermediary node in the place of the existing node, with - // the existing node as a child. - newNode := &node{ - path: commonPrefix, - priority: childNode.priority, - // Index is the first letter of the non-common part of the path. - staticIndices: []byte{childNode.path[0]}, - staticChild: []*node{childNode}, - } - n.staticChild[existingNodeIndex] = newNode - - return newNode, i -} - -func (n *node) search(method, path string) (found *node, handler HandlerFunc, params []string) { - // if test != nil { - // test.Logf("Searching for %s in %s", path, n.dumpTree("", "")) - // } - pathLen := len(path) - if pathLen == 0 { - if len(n.leafHandler) == 0 { - return nil, nil, nil - } else { - return n, n.leafHandler[method], nil - } - } - - // First see if this matches a static token. - firstChar := path[0] - for i, staticIndex := range n.staticIndices { - if staticIndex == firstChar { - child := n.staticChild[i] - childPathLen := len(child.path) - if pathLen >= childPathLen && child.path == path[:childPathLen] { - nextPath := path[childPathLen:] - found, handler, params = child.search(method, nextPath) - } - break - } - } - - // If we found a node and it had a valid handler, then return here. Otherwise - // let's remember that we found this one, but look for a better match. - if handler != nil { - return - } - - if n.wildcardChild != nil { - // Didn't find a static token, so check for a wildcard. - nextSlash := strings.IndexByte(path, '/') - if nextSlash < 0 { - nextSlash = pathLen - } - - thisToken := path[0:nextSlash] - nextToken := path[nextSlash:] - - if len(thisToken) > 0 { // Don't match on empty tokens. - wcNode, wcHandler, wcParams := n.wildcardChild.search(method, nextToken) - if wcHandler != nil || (found == nil && wcNode != nil) { - unescaped, err := unescape(thisToken) - if err != nil { - unescaped = thisToken - } - - if wcParams == nil { - wcParams = []string{unescaped} - } else { - wcParams = append(wcParams, unescaped) - } - - if wcHandler != nil { - return wcNode, wcHandler, wcParams - } - - // Didn't actually find a handler here, so remember that we - // found a node but also see if we can fall through to the - // catchall. - found = wcNode - handler = wcHandler - params = wcParams - } - } - } - - catchAllChild := n.catchAllChild - if catchAllChild != nil { - // Hit the catchall, so just assign the whole remaining path if it - // has a matching handler. - handler = catchAllChild.leafHandler[method] - // Found a handler, or we found a catchall node without a handler. - // Either way, return it since there's nothing left to check after this. - if handler != nil || found == nil { - unescaped, err := unescape(path) - if err != nil { - unescaped = path - } - - return catchAllChild, handler, []string{unescaped} - } - - } - - return found, handler, params -} - -func (n *node) dumpTree(prefix, nodeType string) string { - line := fmt.Sprintf("%s %02d %s%s [%d] %v wildcards %v\n", prefix, n.priority, nodeType, n.path, - len(n.staticChild), n.leafHandler, n.leafWildcardNames) - prefix += " " - for _, node := range n.staticChild { - line += node.dumpTree(prefix, "") - } - if n.wildcardChild != nil { - line += n.wildcardChild.dumpTree(prefix, ":") - } - if n.catchAllChild != nil { - line += n.catchAllChild.dumpTree(prefix, "*") - } - return line -} diff --git a/vendor/github.com/dimfeld/httptreemux/treemux_16.go b/vendor/github.com/dimfeld/httptreemux/treemux_16.go deleted file mode 100644 index 6bd5f2e97ab..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/treemux_16.go +++ /dev/null @@ -1,86 +0,0 @@ -// +build !go1.7 - -package httptreemux - -import ( - "net/http" - "sync" -) - -type TreeMux struct { - root *node - mutex sync.RWMutex - - Group - - // The default PanicHandler just returns a 500 code. - PanicHandler PanicHandler - - // The default NotFoundHandler is http.NotFound. - NotFoundHandler func(w http.ResponseWriter, r *http.Request) - - // Any OPTIONS request that matches a path without its own OPTIONS handler will use this handler, - // if set, instead of calling MethodNotAllowedHandler. - OptionsHandler HandlerFunc - - // MethodNotAllowedHandler is called when a pattern matches, but that - // pattern does not have a handler for the requested method. The default - // handler just writes the status code http.StatusMethodNotAllowed and adds - // the required Allowed header. - // The methods parameter contains the map of each method to the corresponding - // handler function. - MethodNotAllowedHandler func(w http.ResponseWriter, r *http.Request, - methods map[string]HandlerFunc) - - // HeadCanUseGet allows the router to use the GET handler to respond to - // HEAD requests if no explicit HEAD handler has been added for the - // matching pattern. This is true by default. - HeadCanUseGet bool - - // RedirectCleanPath allows the router to try clean the current request path, - // if no handler is registered for it, using CleanPath from github.com/dimfeld/httppath. - // This is true by default. - RedirectCleanPath bool - - // RedirectTrailingSlash enables automatic redirection in case router doesn't find a matching route - // for the current request path but a handler for the path with or without the trailing - // slash exists. This is true by default. - RedirectTrailingSlash bool - - // RemoveCatchAllTrailingSlash removes the trailing slash when a catch-all pattern - // is matched, if set to true. By default, catch-all paths are never redirected. - RemoveCatchAllTrailingSlash bool - - // RedirectBehavior sets the default redirect behavior when RedirectTrailingSlash or - // RedirectCleanPath are true. The default value is Redirect301. - RedirectBehavior RedirectBehavior - - // RedirectMethodBehavior overrides the default behavior for a particular HTTP method. - // The key is the method name, and the value is the behavior to use for that method. - RedirectMethodBehavior map[string]RedirectBehavior - - // PathSource determines from where the router gets its path to search. - // By default it pulls the data from the RequestURI member, but this can - // be overridden to use URL.Path instead. - // - // There is a small tradeoff here. Using RequestURI allows the router to handle - // encoded slashes (i.e. %2f) in the URL properly, while URL.Path provides - // better compatibility with some utility functions in the http - // library that modify the Request before passing it to the router. - PathSource PathSource - - // EscapeAddedRoutes controls URI escaping behavior when adding a route to the tree. - // If set to true, the router will add both the route as originally passed, and - // a version passed through URL.EscapedPath. This behavior is disabled by default. - EscapeAddedRoutes bool - - // SafeAddRoutesWhileRunning tells the router to protect all accesses to the tree with an RWMutex. This is only needed - // if you are going to add routes after the router has already begun serving requests. There is a potential - // performance penalty at high load. - SafeAddRoutesWhileRunning bool -} - -func (t *TreeMux) setDefaultRequestContext(r *http.Request) *http.Request { - // Nothing to do on Go 1.6 and before - return r -} diff --git a/vendor/github.com/dimfeld/httptreemux/treemux_17.go b/vendor/github.com/dimfeld/httptreemux/treemux_17.go deleted file mode 100644 index a80a500f3dc..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/treemux_17.go +++ /dev/null @@ -1,149 +0,0 @@ -// +build go1.7 - -package httptreemux - -import ( - "context" - "net/http" - "sync" -) - -type TreeMux struct { - root *node - mutex sync.RWMutex - - Group - - // The default PanicHandler just returns a 500 code. - PanicHandler PanicHandler - - // The default NotFoundHandler is http.NotFound. - NotFoundHandler func(w http.ResponseWriter, r *http.Request) - - // Any OPTIONS request that matches a path without its own OPTIONS handler will use this handler, - // if set, instead of calling MethodNotAllowedHandler. - OptionsHandler HandlerFunc - - // MethodNotAllowedHandler is called when a pattern matches, but that - // pattern does not have a handler for the requested method. The default - // handler just writes the status code http.StatusMethodNotAllowed and adds - // the required Allowed header. - // The methods parameter contains the map of each method to the corresponding - // handler function. - MethodNotAllowedHandler func(w http.ResponseWriter, r *http.Request, - methods map[string]HandlerFunc) - - // HeadCanUseGet allows the router to use the GET handler to respond to - // HEAD requests if no explicit HEAD handler has been added for the - // matching pattern. This is true by default. - HeadCanUseGet bool - - // RedirectCleanPath allows the router to try clean the current request path, - // if no handler is registered for it, using CleanPath from github.com/dimfeld/httppath. - // This is true by default. - RedirectCleanPath bool - - // RedirectTrailingSlash enables automatic redirection in case router doesn't find a matching route - // for the current request path but a handler for the path with or without the trailing - // slash exists. This is true by default. - RedirectTrailingSlash bool - - // RemoveCatchAllTrailingSlash removes the trailing slash when a catch-all pattern - // is matched, if set to true. By default, catch-all paths are never redirected. - RemoveCatchAllTrailingSlash bool - - // RedirectBehavior sets the default redirect behavior when RedirectTrailingSlash or - // RedirectCleanPath are true. The default value is Redirect301. - RedirectBehavior RedirectBehavior - - // RedirectMethodBehavior overrides the default behavior for a particular HTTP method. - // The key is the method name, and the value is the behavior to use for that method. - RedirectMethodBehavior map[string]RedirectBehavior - - // PathSource determines from where the router gets its path to search. - // By default it pulls the data from the RequestURI member, but this can - // be overridden to use URL.Path instead. - // - // There is a small tradeoff here. Using RequestURI allows the router to handle - // encoded slashes (i.e. %2f) in the URL properly, while URL.Path provides - // better compatibility with some utility functions in the http - // library that modify the Request before passing it to the router. - PathSource PathSource - - // EscapeAddedRoutes controls URI escaping behavior when adding a route to the tree. - // If set to true, the router will add both the route as originally passed, and - // a version passed through URL.EscapedPath. This behavior is disabled by default. - EscapeAddedRoutes bool - - // If present, override the default context with this one. - DefaultContext context.Context - - // SafeAddRoutesWhileRunning tells the router to protect all accesses to the tree with an RWMutex. This is only needed - // if you are going to add routes after the router has already begun serving requests. There is a potential - // performance penalty at high load. - SafeAddRoutesWhileRunning bool -} - -func (t *TreeMux) setDefaultRequestContext(r *http.Request) *http.Request { - if t.DefaultContext != nil { - r = r.WithContext(t.DefaultContext) - } - - return r -} - -type ContextMux struct { - *TreeMux - *ContextGroup -} - -// NewContextMux returns a TreeMux preconfigured to work with standard http -// Handler functions and context objects. -func NewContextMux() *ContextMux { - mux := New() - cg := mux.UsingContext() - - return &ContextMux{ - TreeMux: mux, - ContextGroup: cg, - } -} - -func (cm *ContextMux) NewGroup(path string) *ContextGroup { - return cm.ContextGroup.NewGroup(path) -} - -// GET is convenience method for handling GET requests on a context group. -func (cm *ContextMux) GET(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("GET", path, handler) -} - -// POST is convenience method for handling POST requests on a context group. -func (cm *ContextMux) POST(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("POST", path, handler) -} - -// PUT is convenience method for handling PUT requests on a context group. -func (cm *ContextMux) PUT(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("PUT", path, handler) -} - -// DELETE is convenience method for handling DELETE requests on a context group. -func (cm *ContextMux) DELETE(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("DELETE", path, handler) -} - -// PATCH is convenience method for handling PATCH requests on a context group. -func (cm *ContextMux) PATCH(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("PATCH", path, handler) -} - -// HEAD is convenience method for handling HEAD requests on a context group. -func (cm *ContextMux) HEAD(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("HEAD", path, handler) -} - -// OPTIONS is convenience method for handling OPTIONS requests on a context group. -func (cm *ContextMux) OPTIONS(path string, handler http.HandlerFunc) { - cm.ContextGroup.Handle("OPTIONS", path, handler) -} diff --git a/vendor/github.com/dimfeld/httptreemux/unescape_17.go b/vendor/github.com/dimfeld/httptreemux/unescape_17.go deleted file mode 100644 index 5d6d087875b..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/unescape_17.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !go1.8 - -package httptreemux - -import "net/url" - -func unescape(path string) (string, error) { - return url.QueryUnescape(path) -} diff --git a/vendor/github.com/dimfeld/httptreemux/unescape_18.go b/vendor/github.com/dimfeld/httptreemux/unescape_18.go deleted file mode 100644 index 254dfcdd7f1..00000000000 --- a/vendor/github.com/dimfeld/httptreemux/unescape_18.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build go1.8 - -package httptreemux - -import "net/url" - -func unescape(path string) (string, error) { - return url.PathUnescape(path) -} diff --git a/vendor/github.com/goadesign/goa/.gitignore b/vendor/github.com/goadesign/goa/.gitignore deleted file mode 100644 index 5b903edcc5b..00000000000 --- a/vendor/github.com/goadesign/goa/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# Golang tools artifacts -**/*.coverprofile -**/*.test -vendor - -# Executables and test outputs -goagen/goagen -_integration_tests/*/**/*.* - -# Editor / IDEs cruft -.idea/ -*.iml -.vscode/ -*~ -*.orig - -# OSes cruft -.DS_Store diff --git a/vendor/github.com/goadesign/goa/.golint_exclude b/vendor/github.com/goadesign/goa/.golint_exclude deleted file mode 100644 index 29bab24f212..00000000000 --- a/vendor/github.com/goadesign/goa/.golint_exclude +++ /dev/null @@ -1,5 +0,0 @@ -^examples/cellar/design -^examples/cellar/app -^examples/cellar/client -^examples/cellar/swagger -^metrics.go diff --git a/vendor/github.com/goadesign/goa/.travis.yml b/vendor/github.com/goadesign/goa/.travis.yml deleted file mode 100644 index e526414606e..00000000000 --- a/vendor/github.com/goadesign/goa/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: go -go: -- 1.8.x -sudo: false -install: -- export PATH=${PATH}:${HOME}/gopath/bin -- curl https://bitbucket.org/birkenfeld/pygments-main/get/2.1.tar.gz -L -o 2.1.tar.gz -- mkdir -p ${HOME}/bin -- tar -xf 2.1.tar.gz -- mv birkenfeld-pygments-main-34530db252d3/* ${HOME}/bin -- rm -rf birkenfeld-pygments-main-34530db252d3 -script: -- export PATH=${PATH}:${HOME}/bin -- make -notifications: - slack: - secure: bMYXaoSEGoNdqR0t1VnMAv/4V9PSOhEWyekdJM7p9WmKjJi2yKy0k77uRmwf+5Mrz5GLs3CkZnDha/8cSFld3KEN9SC6QYmIBF/1Pd/5mKHFQOI81i7sTlhrdMv897+6sofEtbBNq1jffhVGVttbMrMWwCTNZu0NrCGBVsDmb44= diff --git a/vendor/github.com/goadesign/goa/LICENSE b/vendor/github.com/goadesign/goa/LICENSE deleted file mode 100644 index d4c1b519a53..00000000000 --- a/vendor/github.com/goadesign/goa/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Raphael Simon and goa Contributors - -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/goadesign/goa/Makefile b/vendor/github.com/goadesign/goa/Makefile deleted file mode 100644 index 6862f394941..00000000000 --- a/vendor/github.com/goadesign/goa/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -#! /usr/bin/make -# -# Makefile for goa -# -# Targets: -# - "depend" retrieves the Go packages needed to run the linter and tests -# - "lint" runs the linter and checks the code format using goimports -# - "test" runs the tests -# -# Meta targets: -# - "all" is the default target, it runs all the targets in the order above. -# -DIRS=$(shell go list -f {{.Dir}} ./...) - -# Only list test and build dependencies -# Standard dependencies are installed via go get -DEPEND=\ - github.com/go-openapi/loads \ - github.com/goadesign/goa-cellar \ - github.com/goadesign/goa.design/tools/godoc2md \ - github.com/goadesign/goa.design/tools/mdc \ - github.com/golang/lint/golint \ - github.com/on99/gocyclo \ - github.com/onsi/ginkgo \ - github.com/onsi/ginkgo/ginkgo \ - github.com/onsi/gomega \ - github.com/pkg/errors \ - golang.org/x/tools/cmd/cover \ - golang.org/x/tools/cmd/goimports - -.PHONY: goagen - -all: depend lint cyclo goagen test - -docs: - @go get -v github.com/spf13/hugo - @git clone https://github.com/goadesign/goa.design - @rm -rf goa.design/content/reference goa.design/public - @mdc --exclude goa.design github.com/goadesign/goa goa.design/content/reference - @cd goa.design && hugo - @rm -rf public - @mv goa.design/public public - @rm -rf goa.design - -depend: - @go get -v ./... - @go get -v $(DEPEND) - -lint: - @for d in $(DIRS) ; do \ - if [ "`goimports -l $$d/*.go | tee /dev/stderr`" ]; then \ - echo "^ - Repo contains improperly formatted go files" && echo && exit 1; \ - fi \ - done - @if [ "`golint ./... | grep -vf .golint_exclude | tee /dev/stderr`" ]; then \ - echo "^ - Lint errors!" && echo && exit 1; \ - fi - -cyclo: - @if [ "`gocyclo -over 20 . | grep -v _integration_tests | grep -v _test.go | tee /dev/stderr`" ]; then \ - echo "^ - Cyclomatic complexity exceeds 20, refactor the code!" && echo && exit 1; \ - fi - -test: - @ginkgo -r --randomizeAllSpecs --failOnPending --randomizeSuites -skipPackage vendor - go test ./_integration_tests - -goagen: - @cd goagen && \ - go install diff --git a/vendor/github.com/goadesign/goa/README.md b/vendor/github.com/goadesign/goa/README.md deleted file mode 100644 index c0dc1451310..00000000000 --- a/vendor/github.com/goadesign/goa/README.md +++ /dev/null @@ -1,339 +0,0 @@ -# - -goa is a framework for building micro-services and REST APIs in Go using a -unique design-first approach. - -[![Build Status](https://travis-ci.org/goadesign/goa.svg?branch=master)](https://travis-ci.org/goadesign/goa) -[![Windows Build status](https://ci.appveyor.com/api/projects/status/vixp37loj5i6qmaf/branch/master?svg=true)](https://ci.appveyor.com/project/RaphaelSimon/goa-oqtis/branch/master) -[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/goadesign/goa/blob/master/LICENSE) -[![Godoc](https://godoc.org/github.com/goadesign/goa?status.svg)](http://godoc.org/github.com/goadesign/goa) -[![Slack](https://img.shields.io/badge/slack-gophers-orange.svg?style=flat)](https://gophers.slack.com/messages/goa/) - -## Why goa? - -goa takes a different approach to building micro-services. Instead of focusing -solely on helping with implementation, goa makes it possible to describe the -*design* of an API using a simple DSL. goa then uses that description to provide -specialized helper code to the implementation and to generate documentation, API -clients, tests, even custom artifacts. - -If DSLs are not your thing then consider this: you need to document your APIs so -that clients (be it internal e.g. other services or external e.g. UIs) may -consume them. Typically this requires maintaining a completely separate document -(for example an OpenAPI specification). Making sure that the document stays -up-to-date takes a lot of effort and at the end of the day you have to write -that document - why not use a simple and clear Go DSL to do that instead? - -Another aspect to consider is the need for properly designing APIs and making -sure that the design choices remain consistent across the endpoints or even -across multiple APIs. If the source code is the only place where design -decisions are kept then not only is it impossible to maintain consistency it's -also difficult to think about the design in the first place. The goa DSL makes -it possible to think about the design explicitly and - since it's code - to -re-use design elements for consistency. - -The goa DSL allows writing self-explanatory code that describes the resources -exposed by the API and for each resource the properties and actions. goa comes -with the `goagen` tool which runs the DSL and generates various types of -artifacts from the resulting data structures. - -One of the `goagen` output is glue code that binds your code with the underlying -HTTP server. This code is specific to your API so that for example there is no -need to cast or "bind" any handler argument prior to using them. Each generated -handler has a signature that is specific to the corresponding resource action. -It's not just the parameters though, each handler also has access to specific -helper methods that generate the possible responses for that action. The DSL can -also define validations in which case the generated code takes care of -validating the incoming request parameters and payload prior to invoking the -handler. - -The end result is controller code that is terse and clean, the boilerplate is -all gone. Another big benefit is the clean separation of concern between design -and implementation: on bigger projects it's often the case that API design -changes require careful review, being able to generate a new version of the -documentation without having to write a single line of implementation is a big -boon. - -This idea of separating design and implementation is not new, the -excellent [Praxis](http://praxis-framework.io) framework from RightScale follows -the same pattern and was an inspiration to goa. - -## Installation - -Assuming you have a working [Go](https://golang.org) setup: -``` -go get github.com/goadesign/goa/... -``` - -### Stable Versions - -goa follows [Semantic Versioning](http://semver.org/) which is a fancy way of saying it publishes -releases with version numbers of the form `vX.Y.Z` and makes sure that your code can upgrade to new -versions with the same `X` component without having to make changes. - -Releases are tagged with the corresponding version number. There is also a branch for each major -version (only `v1` at the moment). The recommended practice is to vendor the stable branch. - -Current Release: `v1.3.1` -Stable Branch: `v1` - -## Teaser - -### 1. Design - -Create the file `$GOPATH/src/goa-adder/design/design.go` with the following content: -```go -package design - -import ( - . "github.com/goadesign/goa/design" - . "github.com/goadesign/goa/design/apidsl" -) - -var _ = API("adder", func() { - Title("The adder API") - Description("A teaser for goa") - Host("localhost:8080") - Scheme("http") -}) - -var _ = Resource("operands", func() { - Action("add", func() { - Routing(GET("add/:left/:right")) - Description("add returns the sum of the left and right parameters in the response body") - Params(func() { - Param("left", Integer, "Left operand") - Param("right", Integer, "Right operand") - }) - Response(OK, "text/plain") - }) - -}) -``` -This file contains the design for an `adder` API which accepts HTTP GET requests to `/add/:x/:y` -where `:x` and `:y` are placeholders for integer values. The API returns the sum of `x` and `y` in -its body. - -### 2. Implement - -Now that the design is done, let's run `goagen` on the design package: -``` -cd $GOPATH/src/goa-adder -goagen bootstrap -d goa-adder/design -``` -This produces the following outputs: - -* `main.go` and `operands.go` contain scaffolding code to help bootstrap the implementation. - running `goagen` again does not recreate them so that it's safe to edit their content. -* an `app` package which contains glue code that binds the low level HTTP server to your - implementation. -* a `client` package with a `Client` struct that implements a `AddOperands` function which calls - the API with the given arguments and returns the `http.Response`. -* a `tool` directory that contains the complete source for a client CLI tool. -* a `swagger` package with implements the `GET /swagger.json` API endpoint. The response contains - the full Swagger specificiation of the API. - -### 3. Run - -First let's implement the API - edit the file `operands.go` and replace the content of the `Add` -function with: -``` -// Add import for strconv -import "strconv" - -// Add runs the add action. -func (c *OperandsController) Add(ctx *app.AddOperandsContext) error { - sum := ctx.Left + ctx.Right - return ctx.OK([]byte(strconv.Itoa(sum))) -} -``` -Now let's compile and run the service: -``` -cd $GOPATH/src/goa-adder -go build -./goa-adder -2016/04/05 20:39:10 [INFO] mount ctrl=Operands action=Add route=GET /add/:left/:right -2016/04/05 20:39:10 [INFO] listen transport=http addr=:8080 -``` -Open a new console and compile the generated CLI tool: -``` -cd $GOPATH/src/goa-adder/tool/adder-cli -go build -``` -The tool includes contextual help: -``` -./adder-cli --help -CLI client for the adder service - -Usage: - adder-cli [command] - -Available Commands: - add add returns the sum of the left and right parameters in the response body - -Flags: - --dump Dump HTTP request and response. - -H, --host string API hostname (default "localhost:8080") - -s, --scheme string Set the requests scheme - -t, --timeout duration Set the request timeout (default 20s) - -Use "adder-cli [command] --help" for more information about a command. -``` -To get information on how to call a specific API use: -``` -./adder-cli add operands --help -Usage: - adder-cli add operands [/add/LEFT/RIGHT] [flags] - -Flags: - --left int Left operand - --pp Pretty print response body - --right int Right operand - -Global Flags: - --dump Dump HTTP request and response. - -H, --host string API hostname (default "localhost:8080") - -s, --scheme string Set the requests scheme - -t, --timeout duration Set the request timeout (default 20s) -``` -Now let's run it: -``` -./adder-cli add operands /add/1/2 -2016/04/05 20:43:18 [INFO] started id=HffVaGiH GET=http://localhost:8080/add/1/2 -2016/04/05 20:43:18 [INFO] completed id=HffVaGiH status=200 time=1.028827ms -3⏎ -``` -This also works: -``` -$ ./adder-cli add operands --left=1 --right=2 -2016/04/25 00:08:59 [INFO] started id=ouKmwdWp GET=http://localhost:8080/add/1/2 -2016/04/25 00:08:59 [INFO] completed id=ouKmwdWp status=200 time=1.097749ms -3⏎ -``` -The console running the service shows the request that was just handled: -``` -2016/06/06 10:23:03 [INFO] started req_id=rLAtsSThLD-1 GET=/add/1/2 from=::1 ctrl=OperandsController action=Add -2016/06/06 10:23:03 [INFO] params req_id=rLAtsSThLD-1 right=2 left=1 -2016/06/06 10:23:03 [INFO] completed req_id=rLAtsSThLD-1 status=200 bytes=1 time=66.25µs -``` -Now let's see how robust our service is and try to use non integer values: -``` -./adder-cli add operands add/1/d -2016/06/06 10:24:22 [INFO] started id=Q2u/lPUc GET=http://localhost:8080/add/1/d -2016/06/06 10:24:22 [INFO] completed id=Q2u/lPUc status=400 time=1.301083ms -error: 400: {"code":"invalid_request","status":400,"detail":"invalid value \"d\" for parameter \"right\", must be a integer"} -``` -As you can see the generated code validated the incoming request against the types defined in the -design. - -### 4. Document - -The `swagger` directory contains the API Swagger (OpenAPI) specification in both -YAML and JSON format. - -For open source projects hosted on -github [swagger.goa.design](http://swagger.goa.design) provides a free service -that renders the Swagger representation dynamically from goa design packages. -Simply set the `url` query string with the import path to the design package. -For example displaying the docs for `github.com/goadesign/goa-cellar/design` is -done by browsing to: - -http://swagger.goa.design/?url=goadesign%2Fgoa-cellar%2Fdesign - -Note that the above generates the swagger spec dynamically and does not require it to be present in -the Github repo. - -The Swagger JSON can also easily be served from the documented service itself using a simple -[Files](http://goa.design/reference/goa/design/apidsl/#func-files-a-name-apidsl-files-a) -definition in the design. Edit the file `design/design.go` and add: - -```go -var _ = Resource("swagger", func() { - Origin("*", func() { - Methods("GET") // Allow all origins to retrieve the Swagger JSON (CORS) - }) - Files("/swagger.json", "swagger/swagger.json") -}) -``` - -Re-run `goagen bootstrap -d goa-adder/design` and note the new file -`swagger.go` containing the implementation for a controller that serves the -`swagger.json` file. - -Mount the newly generated controller by adding the following two lines to the `main` function in -`main.go`: - -```go -cs := NewSwaggerController(service) -app.MountSwaggerController(service, cs) -``` - -Recompile and restart the service: - -``` -^C -go build -./goa-adder -2016/06/06 10:31:14 [INFO] mount ctrl=Operands action=Add route=GET /add/:left/:right -2016/06/06 10:31:14 [INFO] mount ctrl=Swagger files=swagger/swagger.json route=GET /swagger.json -2016/06/06 10:31:14 [INFO] listen transport=http addr=:8080 -``` - -Note the new route `/swagger.json`. Requests made to it return the Swagger specification. The -generated controller also takes care of adding the proper CORS headers so that the JSON may be -retrieved from browsers using JavaScript served from a different origin (e.g. via Swagger UI). The -client also has a new `download` action: - -``` -cd tool/adder-cli -go build -./adder-cli download --help -Download file with given path - -Usage: - adder-cli download [PATH] [flags] - -Flags: - --out string Output file - -Global Flags: - --dump Dump HTTP request and response. - -H, --host string API hostname (default "localhost:8080") - -s, --scheme string Set the requests scheme - -t, --timeout duration Set the request timeout (default 20s) -``` - -Which can be used like this to download the file `swagger.json` in the current directory: - -``` -./adder-cli download swagger.json -2016/06/06 10:36:24 [INFO] started file=swagger.json id=ciHL2VLt GET=http://localhost:8080/swagger.json -2016/06/06 10:36:24 [INFO] completed file=swagger.json id=ciHL2VLt status=200 time=1.013307ms -``` - -We now have a self-documenting API and best of all the documentation is automatically updated as the -API design changes. - -## Resources - -Consult the following resources to learn more about goa. - -### goa.design - -[goa.design](https://goa.design) contains further information on goa including a getting -started guide, detailed DSL documentation as well as information on how to implement a goa service. - -### Examples - -The [examples](https://github.com/goadesign/examples) repo contains simple examples illustrating -basic concepts. - -The [goa-cellar](https://github.com/goadesign/goa-cellar) repo contains the implementation for a -goa service which demonstrates many aspects of the design language. It is kept up-to-date and -provides a reference for testing functionality. - -## Contributing - -Did you fix a bug? write docs or additional tests? or implement some new awesome functionality? -You're a rock star!! Just make sure that `make` succeeds (or that TravisCI is green) and send a PR -over. diff --git a/vendor/github.com/goadesign/goa/appveyor.yml b/vendor/github.com/goadesign/goa/appveyor.yml deleted file mode 100644 index 478f1f95cb4..00000000000 --- a/vendor/github.com/goadesign/goa/appveyor.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: "{build}" - -os: Windows Server 2012 R2 - -environment: - GOPATH: C:\gopath - -clone_folder: c:\gopath\src\github.com\goadesign\goa - -install: - - go version - - go env - - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe - - set PATH=%PATH%;c:\MinGW\bin;%GOPATH%\bin - -build_script: - - make depend - - go get -v .\... - - make goagen - - make test - -test: off - -deploy: off diff --git a/vendor/github.com/goadesign/goa/client/cli.go b/vendor/github.com/goadesign/goa/client/cli.go deleted file mode 100644 index 22633e56b04..00000000000 --- a/vendor/github.com/goadesign/goa/client/cli.go +++ /dev/null @@ -1,96 +0,0 @@ -package client - -import ( - "bufio" - "encoding/json" - "fmt" - "io/ioutil" - "log" - "net/http" - "os" - - "golang.org/x/net/websocket" -) - -// HandleResponse logs the response details and exits the process with a status computed from -// the response status code. The mapping of response status code to exit status is as follows: -// -// 401: 1 -// 402 to 500 (other than 403 and 404): 2 -// 403: 3 -// 404: 4 -// 500+: 5 -func HandleResponse(c *Client, resp *http.Response, pretty bool) { - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - fmt.Fprintf(os.Stderr, "failed to read body: %s", err) - os.Exit(-1) - } - if resp.StatusCode < 200 || resp.StatusCode > 299 { - // Let user know if something went wrong - var sbody string - if len(body) > 0 { - sbody = ": " + string(body) - } - fmt.Printf("error: %d%s", resp.StatusCode, sbody) - } else if !c.Dump && len(body) > 0 { - var out string - if pretty { - var jbody interface{} - err = json.Unmarshal(body, &jbody) - if err != nil { - out = string(body) - } else { - var b []byte - b, err = json.MarshalIndent(jbody, "", " ") - if err == nil { - out = string(b) - } else { - out = string(body) - } - } - } else { - out = string(body) - } - fmt.Print(out) - } - - // Figure out exit code - exitStatus := 0 - switch { - case resp.StatusCode == 401: - exitStatus = 1 - case resp.StatusCode == 403: - exitStatus = 3 - case resp.StatusCode == 404: - exitStatus = 4 - case resp.StatusCode > 399 && resp.StatusCode < 500: - exitStatus = 2 - case resp.StatusCode > 499: - exitStatus = 5 - } - os.Exit(exitStatus) -} - -// WSWrite sends STDIN lines to a websocket server. -func WSWrite(ws *websocket.Conn) { - scanner := bufio.NewScanner(os.Stdin) - for scanner.Scan() { - t := scanner.Text() - ws.Write([]byte(t)) - fmt.Printf(">> %s\n", t) - } -} - -// WSRead reads from a websocket and print the read messages to STDOUT. -func WSRead(ws *websocket.Conn) { - msg := make([]byte, 512) - for { - n, err := ws.Read(msg) - if err != nil { - log.Fatal(err) - } - fmt.Printf("<< %s\n", msg[:n]) - } -} diff --git a/vendor/github.com/goadesign/goa/client/client.go b/vendor/github.com/goadesign/goa/client/client.go deleted file mode 100644 index 5483cb7d04d..00000000000 --- a/vendor/github.com/goadesign/goa/client/client.go +++ /dev/null @@ -1,251 +0,0 @@ -package client - -import ( - "bytes" - "crypto/rand" - "encoding/base64" - "io" - "io/ioutil" - "net/http" - "net/http/httputil" - "time" - - "context" - - "github.com/goadesign/goa" -) - -type ( - // Doer defines the Do method of the http client. - Doer interface { - Do(context.Context, *http.Request) (*http.Response, error) - } - - // Client is the common client data structure for all goa service clients. - Client struct { - // Doer is the underlying http client. - Doer - // Scheme overrides the default action scheme. - Scheme string - // Host is the service hostname. - Host string - // UserAgent is the user agent set in requests made by the client. - UserAgent string - // Dump indicates whether to dump request response. - Dump bool - } -) - -// New creates a new API client that wraps c. -// If c is nil, the returned client wraps http.DefaultClient. -func New(c Doer) *Client { - if c == nil { - c = HTTPClientDoer(http.DefaultClient) - } - return &Client{Doer: c} -} - -// HTTPClientDoer turns a stdlib http.Client into a Doer. Use it to enable to call New() with an http.Client. -func HTTPClientDoer(hc *http.Client) Doer { - return doFunc(func(_ context.Context, req *http.Request) (*http.Response, error) { - return hc.Do(req) - }) -} - -// doFunc is the type definition of the Doer.Do method. It implements Doer. -type doFunc func(context.Context, *http.Request) (*http.Response, error) - -// Do implements Doer.Do -func (f doFunc) Do(ctx context.Context, req *http.Request) (*http.Response, error) { - return f(ctx, req) -} - -// Do wraps the underlying http client Do method and adds logging. -// The logger should be in the context. -func (c *Client) Do(ctx context.Context, req *http.Request) (*http.Response, error) { - // TODO: setting the request ID should be done via client middleware. For now only set it if the - // caller provided one in the ctx. - if ctxreqid := ContextRequestID(ctx); ctxreqid != "" { - req.Header.Set("X-Request-Id", ctxreqid) - } - if c.UserAgent != "" { - req.Header.Set("User-Agent", c.UserAgent) - } - startedAt := time.Now() - ctx, id := ContextWithRequestID(ctx) - goa.LogInfo(ctx, "started", "id", id, req.Method, req.URL.String()) - if c.Dump { - c.dumpRequest(ctx, req) - } - resp, err := c.Doer.Do(ctx, req) - if err != nil { - goa.LogError(ctx, "failed", "err", err) - return nil, err - } - goa.LogInfo(ctx, "completed", "id", id, "status", resp.StatusCode, "time", time.Since(startedAt).String()) - if c.Dump { - c.dumpResponse(ctx, resp) - } - return resp, err -} - -// Dump request if needed. -func (c *Client) dumpRequest(ctx context.Context, req *http.Request) { - reqBody, err := dumpReqBody(req) - if err != nil { - goa.LogError(ctx, "Failed to load request body for dump", "err", err.Error()) - } - goa.LogInfo(ctx, "request headers", headersToSlice(req.Header)...) - if reqBody != nil { - goa.LogInfo(ctx, "request", "body", string(reqBody)) - } -} - -// dumpResponse dumps the response and the request. -func (c *Client) dumpResponse(ctx context.Context, resp *http.Response) { - respBody, _ := dumpRespBody(resp) - goa.LogInfo(ctx, "response headers", headersToSlice(resp.Header)...) - if respBody != nil { - goa.LogInfo(ctx, "response", "body", string(respBody)) - } -} - -// headersToSlice produces a loggable slice from a HTTP header. -func headersToSlice(header http.Header) []interface{} { - res := make([]interface{}, 2*len(header)) - i := 0 - for k, v := range header { - res[i] = k - if len(v) == 1 { - res[i+1] = v[0] - } else { - res[i+1] = v - } - i += 2 - } - return res -} - -// Dump request body, strongly inspired from httputil.DumpRequest -func dumpReqBody(req *http.Request) ([]byte, error) { - if req.Body == nil { - return nil, nil - } - var save io.ReadCloser - var err error - save, req.Body, err = drainBody(req.Body) - if err != nil { - return nil, err - } - var b bytes.Buffer - var dest io.Writer = &b - chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" - if chunked { - dest = httputil.NewChunkedWriter(dest) - } - _, err = io.Copy(dest, req.Body) - if chunked { - dest.(io.Closer).Close() - io.WriteString(&b, "\r\n") - } - req.Body = save - return b.Bytes(), err -} - -// Dump response body, strongly inspired from httputil.DumpResponse -func dumpRespBody(resp *http.Response) ([]byte, error) { - if resp.Body == nil { - return nil, nil - } - var b bytes.Buffer - savecl := resp.ContentLength - var save io.ReadCloser - var err error - save, resp.Body, err = drainBody(resp.Body) - if err != nil { - return nil, err - } - _, err = io.Copy(&b, resp.Body) - if err != nil { - return nil, err - } - resp.Body = save - resp.ContentLength = savecl - if err != nil { - return nil, err - } - return b.Bytes(), nil -} - -// One of the copies, say from b to r2, could be avoided by using a more -// elaborate trick where the other copy is made during Request/Response.Write. -// This would complicate things too much, given that these functions are for -// debugging only. -func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) { - var buf bytes.Buffer - if _, err = buf.ReadFrom(b); err != nil { - return nil, nil, err - } - if err = b.Close(); err != nil { - return nil, nil, err - } - return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil -} - -// headerIterator is a HTTP header iterator. -type headerIterator func(name string, value []string) - -// filterHeaders iterates through the headers skipping hidden headers. -// It calls the given iterator for each header name/value pair. The values are serialized as -// strings. -func filterHeaders(headers http.Header, iterator headerIterator) { - for k, v := range headers { - // Skip sensitive headers - if k == "Authorization" || k == "Cookie" { - iterator(k, []string{"*****"}) - continue - } - iterator(k, v) - } -} - -// shortID produces a "unique" 6 bytes long string. -// Do not use as a reliable way to get unique IDs, instead use for things like logging. -func shortID() string { - b := make([]byte, 6) - io.ReadFull(rand.Reader, b) - return base64.StdEncoding.EncodeToString(b) -} - -// clientKey is the private type used to store values in the context. -// It is private to avoid possible collisions with keys used by other packages. -type clientKey int - -// ReqIDKey is the context key used to store the request ID value. -const reqIDKey clientKey = 1 - -// ContextRequestID extracts the Request ID from the context. -func ContextRequestID(ctx context.Context) string { - var reqID string - id := ctx.Value(reqIDKey) - if id != nil { - reqID = id.(string) - } - return reqID -} - -// ContextWithRequestID returns ctx and the request ID if it already has one or creates and returns a new context with -// a new request ID. -func ContextWithRequestID(ctx context.Context) (context.Context, string) { - reqID := ContextRequestID(ctx) - if reqID == "" { - reqID = shortID() - ctx = context.WithValue(ctx, reqIDKey, reqID) - } - return ctx, reqID -} - -// SetContextRequestID sets a request ID in the given context and returns a new context. -func SetContextRequestID(ctx context.Context, reqID string) context.Context { - return context.WithValue(ctx, reqIDKey, reqID) -} diff --git a/vendor/github.com/goadesign/goa/client/signers.go b/vendor/github.com/goadesign/goa/client/signers.go deleted file mode 100644 index 4b3dd3de307..00000000000 --- a/vendor/github.com/goadesign/goa/client/signers.go +++ /dev/null @@ -1,151 +0,0 @@ -package client - -import ( - "fmt" - "net/http" -) - -type ( - // Signer is the common interface implemented by all signers. - Signer interface { - // Sign adds required headers, cookies etc. - Sign(*http.Request) error - } - - // BasicSigner implements basic auth. - BasicSigner struct { - // Username is the basic auth user. - Username string - // Password is err guess what? the basic auth password. - Password string - } - - // APIKeySigner implements API Key auth. - APIKeySigner struct { - // SignQuery indicates whether to set the API key in the URL query with key KeyName - // or whether to use a header with name KeyName. - SignQuery bool - // KeyName is the name of the HTTP header or query string that contains the API key. - KeyName string - // KeyValue stores the actual key. - KeyValue string - // Format is the format used to render the key, e.g. "Bearer %s" - Format string - } - - // JWTSigner implements JSON Web Token auth. - JWTSigner struct { - // TokenSource is a JWT token source. - // See https://godoc.org/golang.org/x/oauth2/jwt#Config.TokenSource for an example - // of an implementation. - TokenSource TokenSource - } - - // OAuth2Signer adds a authorization header to the request using the given OAuth2 token - // source to produce the header value. - OAuth2Signer struct { - // TokenSource is an OAuth2 access token source. - // See package golang/oauth2 and its subpackage for implementations of token - // sources. - TokenSource TokenSource - } - - // Token is the interface to an OAuth2 token implementation. - // It can be implemented with https://godoc.org/golang.org/x/oauth2#Token. - Token interface { - // SetAuthHeader sets the Authorization header to r. - SetAuthHeader(r *http.Request) - // Valid reports whether Token can be used to properly sign requests. - Valid() bool - } - - // A TokenSource is anything that can return a token. - TokenSource interface { - // Token returns a token or an error. - // Token must be safe for concurrent use by multiple goroutines. - // The returned Token must not be modified. - Token() (Token, error) - } - - // StaticTokenSource implements a token source that always returns the same token. - StaticTokenSource struct { - StaticToken *StaticToken - } - - // StaticToken implements a token that sets the auth header with a given static value. - StaticToken struct { - // Value used to set the auth header. - Value string - // OAuth type, defaults to "Bearer". - Type string - } -) - -// Sign adds the basic auth header to the request. -func (s *BasicSigner) Sign(req *http.Request) error { - if s.Username != "" && s.Password != "" { - req.SetBasicAuth(s.Username, s.Password) - } - return nil -} - -// Sign adds the API key header to the request. -func (s *APIKeySigner) Sign(req *http.Request) error { - if s.KeyName == "" { - s.KeyName = "Authorization" - } - if s.Format == "" { - s.Format = "Bearer %s" - } - name := s.KeyName - format := s.Format - val := fmt.Sprintf(format, s.KeyValue) - if s.SignQuery && val != "" { - query := req.URL.Query() - query.Set(name, val) - req.URL.RawQuery = query.Encode() - } else { - req.Header.Set(name, val) - } - return nil -} - -// Sign adds the JWT auth header. -func (s *JWTSigner) Sign(req *http.Request) error { - return signFromSource(s.TokenSource, req) -} - -// Sign refreshes the access token if needed and adds the OAuth header. -func (s *OAuth2Signer) Sign(req *http.Request) error { - return signFromSource(s.TokenSource, req) -} - -// signFromSource generates a token using the given source and uses it to sign the request. -func signFromSource(source TokenSource, req *http.Request) error { - token, err := source.Token() - if err != nil { - return err - } - if !token.Valid() { - return fmt.Errorf("token expired or invalid") - } - token.SetAuthHeader(req) - return nil -} - -// Token returns the static token. -func (s *StaticTokenSource) Token() (Token, error) { - return s.StaticToken, nil -} - -// SetAuthHeader sets the Authorization header to r. -func (t *StaticToken) SetAuthHeader(r *http.Request) { - typ := t.Type - if typ == "" { - typ = "Bearer" - } - r.Header.Set("Authorization", typ+" "+t.Value) -} - -// Valid reports whether Token can be used to properly sign requests. -func (t *StaticToken) Valid() bool { return true } diff --git a/vendor/github.com/goadesign/goa/context.go b/vendor/github.com/goadesign/goa/context.go deleted file mode 100644 index 5434ff0ebc5..00000000000 --- a/vendor/github.com/goadesign/goa/context.go +++ /dev/null @@ -1,170 +0,0 @@ -package goa - -import ( - "net/http" - "net/url" - "strconv" - - "context" -) - -// Keys used to store data in context. -const ( - reqKey key = iota + 1 - respKey - ctrlKey - actionKey - paramsKey - logKey - logContextKey - errKey - securityScopesKey -) - -type ( - // RequestData provides access to the underlying HTTP request. - RequestData struct { - *http.Request - - // Payload returns the decoded request body. - Payload interface{} - // Params contains the raw values for the parameters defined in the design including - // path parameters, query string parameters and header parameters. - Params url.Values - } - - // ResponseData provides access to the underlying HTTP response. - ResponseData struct { - http.ResponseWriter - - // The service used to encode the response. - Service *Service - // ErrorCode is the code of the error returned by the action if any. - ErrorCode string - // Status is the response HTTP status code. - Status int - // Length is the response body length. - Length int - } - - // key is the type used to store internal values in the context. - // Context provides typed accessor methods to these values. - key int -) - -// NewContext builds a new goa request context. -// If ctx is nil then context.Background() is used. -func NewContext(ctx context.Context, rw http.ResponseWriter, req *http.Request, params url.Values) context.Context { - if ctx == nil { - ctx = context.Background() - } - request := &RequestData{Request: req, Params: params} - response := &ResponseData{ResponseWriter: rw} - ctx = context.WithValue(ctx, respKey, response) - ctx = context.WithValue(ctx, reqKey, request) - - return ctx -} - -// WithAction creates a context with the given action name. -func WithAction(ctx context.Context, action string) context.Context { - return context.WithValue(ctx, actionKey, action) -} - -// WithLogger sets the request context logger and returns the resulting new context. -func WithLogger(ctx context.Context, logger LogAdapter) context.Context { - return context.WithValue(ctx, logKey, logger) -} - -// WithLogContext instantiates a new logger by appending the given key/value pairs to the context -// logger and setting the resulting logger in the context. -func WithLogContext(ctx context.Context, keyvals ...interface{}) context.Context { - logger := ContextLogger(ctx) - if logger == nil { - return ctx - } - nl := logger.New(keyvals...) - return WithLogger(ctx, nl) -} - -// WithError creates a context with the given error. -func WithError(ctx context.Context, err error) context.Context { - return context.WithValue(ctx, errKey, err) -} - -// ContextController extracts the controller name from the given context. -func ContextController(ctx context.Context) string { - if c := ctx.Value(ctrlKey); c != nil { - return c.(string) - } - return "" -} - -// ContextAction extracts the action name from the given context. -func ContextAction(ctx context.Context) string { - if a := ctx.Value(actionKey); a != nil { - return a.(string) - } - return "" -} - -// ContextRequest extracts the request data from the given context. -func ContextRequest(ctx context.Context) *RequestData { - if r := ctx.Value(reqKey); r != nil { - return r.(*RequestData) - } - return nil -} - -// ContextResponse extracts the response data from the given context. -func ContextResponse(ctx context.Context) *ResponseData { - if r := ctx.Value(respKey); r != nil { - return r.(*ResponseData) - } - return nil -} - -// ContextLogger extracts the logger from the given context. -func ContextLogger(ctx context.Context) LogAdapter { - if v := ctx.Value(logKey); v != nil { - return v.(LogAdapter) - } - return nil -} - -// ContextError extracts the error from the given context. -func ContextError(ctx context.Context) error { - if err := ctx.Value(errKey); err != nil { - return err.(error) - } - return nil -} - -// SwitchWriter overrides the underlying response writer. It returns the response -// writer that was previously set. -func (r *ResponseData) SwitchWriter(rw http.ResponseWriter) http.ResponseWriter { - rwo := r.ResponseWriter - r.ResponseWriter = rw - return rwo -} - -// Written returns true if the response was written, false otherwise. -func (r *ResponseData) Written() bool { - return r.Status != 0 -} - -// WriteHeader records the response status code and calls the underlying writer. -func (r *ResponseData) WriteHeader(status int) { - go IncrCounter([]string{"goa", "response", strconv.Itoa(status)}, 1.0) - r.Status = status - r.ResponseWriter.WriteHeader(status) -} - -// Write records the amount of data written and calls the underlying writer. -func (r *ResponseData) Write(b []byte) (int, error) { - if !r.Written() { - r.WriteHeader(http.StatusOK) - } - r.Length += len(b) - return r.ResponseWriter.Write(b) -} diff --git a/vendor/github.com/goadesign/goa/doc.go b/vendor/github.com/goadesign/goa/doc.go deleted file mode 100644 index 1cf7fa8ff55..00000000000 --- a/vendor/github.com/goadesign/goa/doc.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Package goa provides the runtime support for goa microservices. - -Code Generation - -goa service development begins with writing the *design* of a service. The design is described using -the goa language implemented by the github.com/goadesign/goa/design/apidsl package. The `goagen` tool -consumes the metadata produced from executing the design language to generate service specific code -that glues the underlying HTTP server with action specific code and data structures. - -The goa package contains supporting functionality for the generated code including basic request -and response state management through the RequestData and ResponseData structs, error handling via -error classes, middleware support via the Middleware data structure as well as decoding and -encoding algorithms. - -Request Context - -The RequestData and ResponseData structs provides access to the request and response state. goa request -handlers also accept a context.Context interface as first parameter so that deadlines and cancelation -signals may easily be implemented. - -The request state exposes the underlying http.Request object as well as the deserialized payload (request -body) and parameters (both path and querystring parameters). Generated action specific contexts wrap -the context.Context, ResponseData and RequestData data structures. They expose properly typed fields -that correspond to the request parameters and body data structure descriptions appearing in the design. - -The response state exposes the response status and body length as well as the underlying ResponseWriter. -Action contexts provide action specific helper methods that write the responses as described in the -design optionally taking an instance of the media type for responses that contain a body. - -Here is an example showing an "update" action corresponding to following design (extract): - - Resource("bottle", func() { - DefaultMedia(Bottle) - Action("update", func() { - Params(func() { - Param("bottleID", Integer) - }) - Payload(UpdateBottlePayload) - Response(OK) - Response(NotFound) - }) - }) - -The action signature generated by goagen is: - - type BottleController interface { - goa.Controller - Update(*UpdateBottleContext) error - } - -where UpdateBottleContext is: - - type UpdateBottleContext struct { - context.Context // Timeout and deadline support - *goa.ResponseData // Response state access - *goa.RequestData // Request state access - Service *goa.Service // Service handling request - BottleID int // Properly typed parameter fields - Payload *UpdateBottlePayload // Properly typed payload - } - -and implements: - - func (ctx *UpdateBottleContext) OK(resp *Bottle) error - func (ctx *UpdateBottleContext) NotFound() error - -The definitions of the Bottle and UpdateBottlePayload data structures are ommitted for brievity. - -Controllers - -There is one controller interface generated per resource defined via the design language. The -interface exposes the controller actions. User code must provide data structures that implement these -interfaces when mounting a controller onto a service. The controller data structure should include -an anonymous field of type *goa.Controller which takes care of implementing the middleware handling. - -Middleware - -A goa middleware is a function that takes and returns a Handler. A Handler is a the low level -function which handles incoming HTTP requests. goagen generates the handlers code so each handler -creates the action specific context and calls the controller action with it. - -Middleware can be added to a goa service or a specific controller using the corresponding Use -methods. goa comes with a few stock middleware that handle common needs such as logging, panic -recovery or using the RequestID header to trace requests across multiple services. - -Error Handling - -The controller action methods generated by goagen such as the Update method of the BottleController -interface shown above all return an error value. goa defines an Error struct that action -implementations can use to describe the content of the corresponding HTTP response. Errors can be -created using error classes which are functions created via NewErrorClass. - -The ErrorHandler middleware maps errors to HTTP responses. Errors that are instances of the Error -struct are mapped using the struct fields while other types of errors return responses with status -code 500 and the error message in the body. - -Validation - -The goa design language documented in the dsl package makes it possible to attach validations to -data structure definitions. One specific type of validation consists of defining the format that a -data structure string field must follow. Example of formats include email, data time, hostnames etc. -The ValidateFormat function provides the implementation for the format validation invoked from the -code generated by goagen. - -Encoding - -The goa design language makes it possible to specify the encodings supported by the API both as -input (Consumes) and output (Produces). goagen uses that information to registed the corresponding -packages with the service encoders and decoders via their Register methods. The service exposes the -DecodeRequest and EncodeResponse that implement a simple content type negotiation algorithm for -picking the right encoder for the "Content-Type" (decoder) or "Accept" (encoder) request header. -*/ -package goa diff --git a/vendor/github.com/goadesign/goa/encoding.go b/vendor/github.com/goadesign/goa/encoding.go deleted file mode 100644 index 0e5e5ae8b5b..00000000000 --- a/vendor/github.com/goadesign/goa/encoding.go +++ /dev/null @@ -1,274 +0,0 @@ -package goa - -import ( - "encoding/gob" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "mime" - "sync" - "time" -) - -type ( - // DecoderFunc instantiates a decoder that decodes data read from the given io reader. - DecoderFunc func(r io.Reader) Decoder - - // A Decoder unmarshals an io.Reader into an interface. - Decoder interface { - Decode(v interface{}) error - } - - // ResettableDecoder is used to determine whether or not a Decoder can be reset and thus - // safely reused in a sync.Pool. - ResettableDecoder interface { - Decoder - Reset(r io.Reader) - } - - // decoderPool smartly determines whether to instantiate a new Decoder or reuse one from a - // sync.Pool. - decoderPool struct { - fn DecoderFunc - pool *sync.Pool - } - - // EncoderFunc instantiates an encoder that encodes data into the given writer. - EncoderFunc func(w io.Writer) Encoder - - // An Encoder marshals from an interface into an io.Writer. - Encoder interface { - Encode(v interface{}) error - } - - // The ResettableEncoder is used to determine whether or not a Encoder can be reset and - // thus safely reused in a sync.Pool. - ResettableEncoder interface { - Encoder - Reset(w io.Writer) - } - - // encoderPool smartly determines whether to instantiate a new Encoder or reuse one from a - // sync.Pool. - encoderPool struct { - fn EncoderFunc - pool *sync.Pool - } - - // HTTPDecoder is a Decoder that decodes HTTP request or response bodies given a set of - // known Content-Type to decoder mapping. - HTTPDecoder struct { - pools map[string]*decoderPool // Registered decoders - } - - // HTTPEncoder is a Encoder that encodes HTTP request or response bodies given a set of - // known Content-Type to encoder mapping. - HTTPEncoder struct { - pools map[string]*encoderPool // Registered encoders - contentTypes []string // List of content types for type negotiation - } -) - -// NewJSONEncoder is an adapter for the encoding package JSON encoder. -func NewJSONEncoder(w io.Writer) Encoder { return json.NewEncoder(w) } - -// NewJSONDecoder is an adapter for the encoding package JSON decoder. -func NewJSONDecoder(r io.Reader) Decoder { return json.NewDecoder(r) } - -// NewXMLEncoder is an adapter for the encoding package XML encoder. -func NewXMLEncoder(w io.Writer) Encoder { return xml.NewEncoder(w) } - -// NewXMLDecoder is an adapter for the encoding package XML decoder. -func NewXMLDecoder(r io.Reader) Decoder { return xml.NewDecoder(r) } - -// NewGobEncoder is an adapter for the encoding package gob encoder. -func NewGobEncoder(w io.Writer) Encoder { return gob.NewEncoder(w) } - -// NewGobDecoder is an adapter for the encoding package gob decoder. -func NewGobDecoder(r io.Reader) Decoder { return gob.NewDecoder(r) } - -// NewHTTPEncoder creates an encoder that maps HTTP content types to low level encoders. -func NewHTTPEncoder() *HTTPEncoder { - return &HTTPEncoder{ - pools: make(map[string]*encoderPool), - } -} - -// NewHTTPDecoder creates a decoder that maps HTTP content types to low level decoders. -func NewHTTPDecoder() *HTTPDecoder { - return &HTTPDecoder{ - pools: make(map[string]*decoderPool), - } -} - -// Decode uses registered Decoders to unmarshal a body based on the contentType. -func (decoder *HTTPDecoder) Decode(v interface{}, body io.Reader, contentType string) error { - now := time.Now() - defer MeasureSince([]string{"goa", "decode", contentType}, now) - var p *decoderPool - if contentType == "" { - // Default to JSON - contentType = "application/json" - } else { - if mediaType, _, err := mime.ParseMediaType(contentType); err == nil { - contentType = mediaType - } - } - p = decoder.pools[contentType] - if p == nil { - p = decoder.pools["*/*"] - } - if p == nil { - return nil - } - - // the decoderPool will handle whether or not a pool is actually in use - d := p.Get(body) - defer p.Put(d) - return d.Decode(v) -} - -// Register sets a specific decoder to be used for the specified content types. If a decoder is -// already registered, it is overwritten. -func (decoder *HTTPDecoder) Register(f DecoderFunc, contentTypes ...string) { - p := newDecodePool(f) - - for _, contentType := range contentTypes { - mediaType, _, err := mime.ParseMediaType(contentType) - if err != nil { - mediaType = contentType - } - decoder.pools[mediaType] = p - } -} - -// newDecodePool checks to see if the DecoderFunc returns reusable decoders and if so, creates a -// pool. -func newDecodePool(f DecoderFunc) *decoderPool { - // get a new decoder and type assert to see if it can be reset - d := f(nil) - rd, ok := d.(ResettableDecoder) - - p := &decoderPool{fn: f} - - // if the decoder can be reset, create a pool and put the typed decoder in - if ok { - p.pool = &sync.Pool{ - New: func() interface{} { return f(nil) }, - } - p.pool.Put(rd) - } - - return p -} - -// Get returns an already reset Decoder from the pool or creates a new one if necessary. -func (p *decoderPool) Get(r io.Reader) Decoder { - if p.pool == nil { - return p.fn(r) - } - - d := p.pool.Get().(ResettableDecoder) - d.Reset(r) - return d -} - -// Put returns a Decoder into the pool if possible. -func (p *decoderPool) Put(d Decoder) { - if p.pool == nil { - return - } - p.pool.Put(d) -} - -// Encode uses the registered encoders and given content type to marshal and write the given value -// using the given writer. -func (encoder *HTTPEncoder) Encode(v interface{}, resp io.Writer, accept string) error { - now := time.Now() - if accept == "" { - accept = "*/*" - } - var contentType string - for _, t := range encoder.contentTypes { - if accept == "*/*" || accept == t { - contentType = accept - break - } - } - defer MeasureSince([]string{"goa", "encode", contentType}, now) - p := encoder.pools[contentType] - if p == nil && contentType != "*/*" { - p = encoder.pools["*/*"] - } - if p == nil { - return fmt.Errorf("No encoder registered for %s and no default encoder", contentType) - } - - // the encoderPool will handle whether or not a pool is actually in use - e := p.Get(resp) - if err := e.Encode(v); err != nil { - return err - } - p.Put(e) - - return nil -} - -// Register sets a specific encoder to be used for the specified content types. If an encoder is -// already registered, it is overwritten. -func (encoder *HTTPEncoder) Register(f EncoderFunc, contentTypes ...string) { - p := newEncodePool(f) - for _, contentType := range contentTypes { - mediaType, _, err := mime.ParseMediaType(contentType) - if err != nil { - mediaType = contentType - } - encoder.pools[mediaType] = p - } - - // Rebuild a unique index of registered content encoders to be used in EncodeResponse - encoder.contentTypes = make([]string, 0, len(encoder.pools)) - for contentType := range encoder.pools { - encoder.contentTypes = append(encoder.contentTypes, contentType) - } -} - -// newEncodePool checks to see if the EncoderFactory returns reusable encoders and if so, creates -// a pool. -func newEncodePool(f EncoderFunc) *encoderPool { - // get a new encoder and type assert to see if it can be reset - e := f(nil) - re, ok := e.(ResettableEncoder) - - p := &encoderPool{fn: f} - - // if the encoder can be reset, create a pool and put the typed encoder in - if ok { - p.pool = &sync.Pool{ - New: func() interface{} { return f(nil) }, - } - p.pool.Put(re) - } - - return p -} - -// Get returns an already reset Encoder from the pool or creates a new one if necessary. -func (p *encoderPool) Get(w io.Writer) Encoder { - if p.pool == nil { - return p.fn(w) - } - - e := p.pool.Get().(ResettableEncoder) - e.Reset(w) - return e -} - -// Put returns a Decoder into the pool if possible. -func (p *encoderPool) Put(e Encoder) { - if p.pool == nil { - return - } - p.pool.Put(e) -} diff --git a/vendor/github.com/goadesign/goa/error.go b/vendor/github.com/goadesign/goa/error.go deleted file mode 100644 index 26e502b72cd..00000000000 --- a/vendor/github.com/goadesign/goa/error.go +++ /dev/null @@ -1,360 +0,0 @@ -/* -Package goa standardizes on structured error responses: a request that fails because of an -invalid input or an unexpected condition produces a response that contains a structured error. - -The error data structures returned to clients contains five fields: an ID, a code, a status, a -detail and metadata. The ID is unique for the occurrence of the error, it helps correlate the -content of the response with the content of the service logs. The code defines the class of error -(e.g. "invalid_parameter_type") and the status the corresponding HTTP status (e.g. 400). The detail -contains a message specific to the error occurrence. The metadata contains key/value pairs that -provide contextual information (name of parameters, value of invalid parameter etc.). - -Instances of Error can be created via Error Class functions. -See http://goa.design/implement/error_handling.html -All instance of errors created via a error class implement the ServiceError interface. This -interface is leveraged by the error handler middleware to produce the error responses. - -The code generated by goagen calls the helper functions exposed in this file when it encounters -invalid data (wrong type, validation errors etc.) such as InvalidParamTypeError, -InvalidAttributeTypeError etc. These methods return errors that get merged with any previously -encountered error via the Error Merge method. The helper functions are error classes stored in -global variable. This means your code can override their values to produce arbitrary error -responses. - -goa includes an error handler middleware that takes care of mapping back any error returned by -previously called middleware or action handler into HTTP responses. If the error was created via an -error class then the corresponding content including the HTTP status is used otherwise an internal -error is returned. Errors that bubble up all the way to the top (i.e. not handled by the error -middleware) also generate an internal error response. -*/ -package goa - -import ( - "crypto/rand" - "encoding/base64" - "fmt" - "io" - "strings" -) - -var ( - // ErrorMediaIdentifier is the media type identifier used for error responses. - ErrorMediaIdentifier = "application/vnd.goa.error" - - // ErrBadRequest is a generic bad request error. - ErrBadRequest = NewErrorClass("bad_request", 400) - - // ErrUnauthorized is a generic unauthorized error. - ErrUnauthorized = NewErrorClass("unauthorized", 401) - - // ErrInvalidRequest is the class of errors produced by the generated code when a request - // parameter or payload fails to validate. - ErrInvalidRequest = NewErrorClass("invalid_request", 400) - - // ErrInvalidEncoding is the error produced when a request body fails to be decoded. - ErrInvalidEncoding = NewErrorClass("invalid_encoding", 400) - - // ErrRequestBodyTooLarge is the error produced when the size of a request body exceeds - // MaxRequestBodyLength bytes. - ErrRequestBodyTooLarge = NewErrorClass("request_too_large", 413) - - // ErrNoAuthMiddleware is the error produced when no auth middleware is mounted for a - // security scheme defined in the design. - ErrNoAuthMiddleware = NewErrorClass("no_auth_middleware", 500) - - // ErrInvalidFile is the error produced by ServeFiles when requested to serve non-existant - // or non-readable files. - ErrInvalidFile = NewErrorClass("invalid_file", 404) - - // ErrNotFound is the error returned to requests that don't match a registered handler. - ErrNotFound = NewErrorClass("not_found", 404) - - // ErrMethodNotAllowed is the error returned to requests that match the path of a registered - // handler but not the HTTP method. - ErrMethodNotAllowed = NewErrorClass("method_not_allowed", 405) - - // ErrInternal is the class of error used for uncaught errors. - ErrInternal = NewErrorClass("internal", 500) -) - -type ( - // ErrorClass is an error generating function. - // It accepts a message and optional key value pairs and produces errors that implement - // ServiceError. - // If the message is a string or a fmt.Stringer then the string value is used. - // If the message is an error then the string returned by Error() is used. - // Otherwise the string produced using fmt.Sprintf("%v") is used. - // The optional key value pairs are intended to provide additional contextual information - // and are returned to the client. - ErrorClass func(message interface{}, keyvals ...interface{}) error - - // ServiceError is the interface implemented by all errors created using a ErrorClass - // function. - ServiceError interface { - // ServiceError extends the error interface - error - // ResponseStatus dictates the status used to build the response sent to the client. - ResponseStatus() int - // Token is a unique value associated with the occurrence of the error. - Token() string - } - - // ServiceMergeableError is the interface implemented by ServiceErrors that can merge - // another error into a combined error. - ServiceMergeableError interface { - // ServiceMergeableError extends from the ServiceError interface. - ServiceError - - // Merge updates an error by combining another error into it. - Merge(other error) error - } - - // ErrorResponse contains the details of a error response. It implements ServiceError. - // This struct is mainly intended for clients to decode error responses. - ErrorResponse struct { - // ID is the unique error instance identifier. - ID string `json:"id" xml:"id" form:"id"` - // Code identifies the class of errors. - Code string `json:"code" xml:"code" form:"code"` - // Status is the HTTP status code used by responses that cary the error. - Status int `json:"status" xml:"status" form:"status"` - // Detail describes the specific error occurrence. - Detail string `json:"detail" xml:"detail" form:"detail"` - // Meta contains additional key/value pairs useful to clients. - Meta map[string]interface{} `json:"meta,omitempty" xml:"meta,omitempty" form:"meta,omitempty"` - } -) - -// NewErrorClass creates a new error class. -// It is the responsibility of the client to guarantee uniqueness of code. -func NewErrorClass(code string, status int) ErrorClass { - return func(message interface{}, keyvals ...interface{}) error { - var msg string - switch actual := message.(type) { - case string: - msg = actual - case error: - msg = actual.Error() - case fmt.Stringer: - msg = actual.String() - default: - msg = fmt.Sprintf("%v", actual) - } - var meta map[string]interface{} - l := len(keyvals) - if l > 0 { - meta = make(map[string]interface{}) - } - for i := 0; i < l; i += 2 { - k := keyvals[i] - var v interface{} = "MISSING" - if i+1 < l { - v = keyvals[i+1] - } - meta[fmt.Sprintf("%v", k)] = v - } - return &ErrorResponse{ID: newErrorID(), Code: code, Status: status, Detail: msg, Meta: meta} - } -} - -// MissingPayloadError is the error produced when a request is missing a required payload. -func MissingPayloadError() error { - return ErrInvalidRequest("missing required payload") -} - -// InvalidParamTypeError is the error produced when the type of a parameter does not match the type -// defined in the design. -func InvalidParamTypeError(name string, val interface{}, expected string) error { - msg := fmt.Sprintf("invalid value %#v for parameter %#v, must be a %s", val, name, expected) - return ErrInvalidRequest(msg, "param", name, "value", val, "expected", expected) -} - -// MissingParamError is the error produced for requests that are missing path or querystring -// parameters. -func MissingParamError(name string) error { - msg := fmt.Sprintf("missing required parameter %#v", name) - return ErrInvalidRequest(msg, "name", name) -} - -// InvalidAttributeTypeError is the error produced when the type of payload field does not match -// the type defined in the design. -func InvalidAttributeTypeError(ctx string, val interface{}, expected string) error { - msg := fmt.Sprintf("type of %s must be %s but got value %#v", ctx, expected, val) - return ErrInvalidRequest(msg, "attribute", ctx, "value", val, "expected", expected) -} - -// MissingAttributeError is the error produced when a request payload is missing a required field. -func MissingAttributeError(ctx, name string) error { - msg := fmt.Sprintf("attribute %#v of %s is missing and required", name, ctx) - return ErrInvalidRequest(msg, "attribute", name, "parent", ctx) -} - -// MissingHeaderError is the error produced when a request is missing a required header. -func MissingHeaderError(name string) error { - msg := fmt.Sprintf("missing required HTTP header %#v", name) - return ErrInvalidRequest(msg, "name", name) -} - -// InvalidEnumValueError is the error produced when the value of a parameter or payload field does -// not match one the values defined in the design Enum validation. -func InvalidEnumValueError(ctx string, val interface{}, allowed []interface{}) error { - elems := make([]string, len(allowed)) - for i, a := range allowed { - elems[i] = fmt.Sprintf("%#v", a) - } - msg := fmt.Sprintf("value of %s must be one of %s but got value %#v", ctx, strings.Join(elems, ", "), val) - return ErrInvalidRequest(msg, "attribute", ctx, "value", val, "expected", strings.Join(elems, ", ")) -} - -// InvalidFormatError is the error produced when the value of a parameter or payload field does not -// match the format validation defined in the design. -func InvalidFormatError(ctx, target string, format Format, formatError error) error { - msg := fmt.Sprintf("%s must be formatted as a %s but got value %#v, %s", ctx, format, target, formatError.Error()) - return ErrInvalidRequest(msg, "attribute", ctx, "value", target, "expected", format, "error", formatError.Error()) -} - -// InvalidPatternError is the error produced when the value of a parameter or payload field does -// not match the pattern validation defined in the design. -func InvalidPatternError(ctx, target string, pattern string) error { - msg := fmt.Sprintf("%s must match the regexp %#v but got value %#v", ctx, pattern, target) - return ErrInvalidRequest(msg, "attribute", ctx, "value", target, "regexp", pattern) -} - -// InvalidRangeError is the error produced when the value of a parameter or payload field does -// not match the range validation defined in the design. value may be a int or a float64. -func InvalidRangeError(ctx string, target interface{}, value interface{}, min bool) error { - comp := "greater than or equal to" - if !min { - comp = "less than or equal to" - } - msg := fmt.Sprintf("%s must be %s %v but got value %#v", ctx, comp, value, target) - return ErrInvalidRequest(msg, "attribute", ctx, "value", target, "comp", comp, "expected", value) -} - -// InvalidLengthError is the error produced when the value of a parameter or payload field does -// not match the length validation defined in the design. -func InvalidLengthError(ctx string, target interface{}, ln, value int, min bool) error { - comp := "greater than or equal to" - if !min { - comp = "less than or equal to" - } - msg := fmt.Sprintf("length of %s must be %s %d but got value %#v (len=%d)", ctx, comp, value, target, ln) - return ErrInvalidRequest(msg, "attribute", ctx, "value", target, "len", ln, "comp", comp, "expected", value) -} - -// NoAuthMiddleware is the error produced when goa is unable to lookup a auth middleware for a -// security scheme defined in the design. -func NoAuthMiddleware(schemeName string) error { - msg := fmt.Sprintf("Auth middleware for security scheme %s is not mounted", schemeName) - return ErrNoAuthMiddleware(msg, "scheme", schemeName) -} - -// MethodNotAllowedError is the error produced to requests that match the path of a registered -// handler but not the HTTP method. -func MethodNotAllowedError(method string, allowed []string) error { - var plural string - if len(allowed) > 1 { - plural = " one of" - } - msg := fmt.Sprintf("Method %s must be%s %s", method, plural, strings.Join(allowed, ", ")) - return ErrMethodNotAllowed(msg, "method", method, "allowed", strings.Join(allowed, ", ")) -} - -// Error returns the error occurrence details. -func (e *ErrorResponse) Error() string { - msg := fmt.Sprintf("[%s] %d %s: %s", e.ID, e.Status, e.Code, e.Detail) - for k, v := range e.Meta { - msg += ", " + fmt.Sprintf("%s: %v", k, v) - } - return msg -} - -// ResponseStatus is the status used to build responses. -func (e *ErrorResponse) ResponseStatus() int { return e.Status } - -// Token is the unique error occurrence identifier. -func (e *ErrorResponse) Token() string { return e.ID } - -// MergeErrors updates an error by merging another into it. It first converts other into a -// ServiceError if not already one - producing an internal error in that case. The merge algorithm -// is: -// -// * If any of e or other implements ServiceMergableError, it is handled by its Merge method. -// -// * If any of e or other is an internal error then the result is an internal error -// -// * If the status or code of e and other don't match then the result is a 400 "bad_request" -// -// The Detail field is updated by concatenating the Detail fields of e and other separated -// by a semi-colon. The MetaValues field of is updated by merging the map of other MetaValues -// into e's where values in e with identical keys to values in other get overwritten. -// -// Merge returns the updated error. This is useful in case the error was initially nil in -// which case other is returned. -func MergeErrors(err, other error) error { - if err == nil { - if other == nil { - return nil - } - return asServiceError(other) - } - if other == nil { - return asServiceError(err) - } - - // If either error is a mergable error. - if me, ok := err.(ServiceMergeableError); ok { - return me.Merge(other) - } - if mo, ok := other.(ServiceMergeableError); ok { - return mo.Merge(err) - } - - e := asErrorResponse(err) - o := asErrorResponse(other) - switch { - case e.Status == 500 || o.Status == 500: - if e.Status != 500 { - e.Status = 500 - e.Code = "internal_error" - } - case e.Status != o.Status || e.Code != o.Code: - e.Status = 400 - e.Code = "bad_request" - } - e.Detail = e.Detail + "; " + o.Detail - - if e.Meta == nil && len(o.Meta) > 0 { - e.Meta = make(map[string]interface{}) - } - for k, v := range o.Meta { - e.Meta[k] = v - } - return e -} - -func asServiceError(err error) ServiceError { - e, ok := err.(ServiceError) - if !ok { - return asErrorResponse(err) - } - return e -} - -func asErrorResponse(err error) *ErrorResponse { - e, ok := err.(*ErrorResponse) - if !ok { - return &ErrorResponse{Status: 500, Code: "internal_error", Detail: err.Error()} - } - return e -} - -// If you're curious - simplifying a bit - the probability of 2 values being equal for n 6-bytes -// values is n^2 / 2^49. For n = 1 million this gives around 1 chance in 500. 6 bytes seems to be a -// good trade-off between probability of clashes and length of ID (6 * 4/3 = 8 chars) since clashes -// are not catastrophic. -func newErrorID() string { - b := make([]byte, 6) - io.ReadFull(rand.Reader, b) - return base64.StdEncoding.EncodeToString(b) -} diff --git a/vendor/github.com/goadesign/goa/logging.go b/vendor/github.com/goadesign/goa/logging.go deleted file mode 100644 index 54baf92570a..00000000000 --- a/vendor/github.com/goadesign/goa/logging.go +++ /dev/null @@ -1,123 +0,0 @@ -package goa - -import ( - "bytes" - "fmt" - "log" - - "context" -) - -// ErrMissingLogValue is the value used to log keys with missing values -const ErrMissingLogValue = "MISSING" - -type ( - // LogAdapter is the logger interface used by goa to log informational and error messages. - // Adapters to different logging backends are provided in the logging sub-packages. - // goa takes care of initializing the logging context with the service, controller and - // action names. - LogAdapter interface { - // Info logs an informational message. - Info(msg string, keyvals ...interface{}) - // Error logs an error. - Error(msg string, keyvals ...interface{}) - // New appends to the logger context and returns the updated logger logger. - New(keyvals ...interface{}) LogAdapter - } - - // adapter is the stdlib logger adapter. - adapter struct { - *log.Logger - keyvals []interface{} - } -) - -// NewLogger returns a goa log adpater backed by a log logger. -func NewLogger(logger *log.Logger) LogAdapter { - return &adapter{Logger: logger} -} - -// Logger returns the logger stored in the context if any, nil otherwise. -func Logger(ctx context.Context) *log.Logger { - logger := ContextLogger(ctx) - if a, ok := logger.(*adapter); ok { - return a.Logger - } - return nil -} - -func (a *adapter) Info(msg string, keyvals ...interface{}) { - a.logit(msg, keyvals, false) -} - -func (a *adapter) Error(msg string, keyvals ...interface{}) { - a.logit(msg, keyvals, true) -} - -func (a *adapter) New(keyvals ...interface{}) LogAdapter { - if len(keyvals) == 0 { - return a - } - kvs := append(a.keyvals, keyvals...) - if len(kvs)%2 != 0 { - kvs = append(kvs, ErrMissingLogValue) - } - return &adapter{ - Logger: a.Logger, - // Limiting the capacity of the stored keyvals ensures that a new - // backing array is created if the slice must grow. - keyvals: kvs[:len(kvs):len(kvs)], - } -} - -func (a *adapter) logit(msg string, keyvals []interface{}, iserror bool) { - n := (len(keyvals) + 1) / 2 - if len(keyvals)%2 != 0 { - keyvals = append(keyvals, ErrMissingLogValue) - } - m := (len(a.keyvals) + 1) / 2 - n += m - var fm bytes.Buffer - lvl := "INFO" - if iserror { - lvl = "EROR" - } - fm.WriteString(fmt.Sprintf("[%s] %s", lvl, msg)) - vals := make([]interface{}, n) - offset := len(a.keyvals) - for i := 0; i < offset; i += 2 { - k := a.keyvals[i] - v := a.keyvals[i+1] - vals[i/2] = v - fm.WriteString(fmt.Sprintf(" %s=%%+v", k)) - } - for i := 0; i < len(keyvals); i += 2 { - k := keyvals[i] - v := keyvals[i+1] - vals[i/2+offset/2] = v - fm.WriteString(fmt.Sprintf(" %s=%%+v", k)) - } - a.Logger.Printf(fm.String(), vals...) -} - -// LogInfo extracts the logger from the given context and calls Info on it. -// This is intended for code that needs portable logging such as the internal code of goa and -// middleware. User code should use the log adapters instead. -func LogInfo(ctx context.Context, msg string, keyvals ...interface{}) { - if l := ctx.Value(logKey); l != nil { - if logger, ok := l.(LogAdapter); ok { - logger.Info(msg, keyvals...) - } - } -} - -// LogError extracts the logger from the given context and calls Error on it. -// This is intended for code that needs portable logging such as the internal code of goa and -// middleware. User code should use the log adapters instead. -func LogError(ctx context.Context, msg string, keyvals ...interface{}) { - if l := ctx.Value(logKey); l != nil { - if logger, ok := l.(LogAdapter); ok { - logger.Error(msg, keyvals...) - } - } -} diff --git a/vendor/github.com/goadesign/goa/metrics.go b/vendor/github.com/goadesign/goa/metrics.go deleted file mode 100644 index 995f17e0a6b..00000000000 --- a/vendor/github.com/goadesign/goa/metrics.go +++ /dev/null @@ -1,163 +0,0 @@ -// +build !js,!appengine - -package goa - -import ( - "regexp" - "strings" - "sync" - "time" - - "github.com/armon/go-metrics" -) - -const ( - allMatcher string = "*/*" - allReplacement string = "all" - normalizedToken string = "_" -) - -var ( - // metriks contains current collector - metriks Collector - - // metriksMu is mutex for metriks variable - metriksMu sync.Mutex - - // invalidCharactersRE is the invert match of validCharactersRE - invalidCharactersRE = regexp.MustCompile(`[\*/]`) - - // Taken from https://github.com/prometheus/client_golang/blob/66058aac3a83021948e5fb12f1f408ff556b9037/prometheus/desc.go - validCharactersRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`) -) - -// Collector is the interface used for collecting metrics. -type Collector interface { - AddSample(key []string, val float32) - EmitKey(key []string, val float32) - IncrCounter(key []string, val float32) - MeasureSince(key []string, start time.Time) - SetGauge(key []string, val float32) -} - -func init() { - SetMetrics(NewNoOpCollector()) -} - -// newNoOpCollecter implements Collector, but provides no collection. -type noOpCollecter struct{} - -func (*noOpCollecter) AddSample(key []string, val float32) {} -func (*noOpCollecter) EmitKey(key []string, val float32) {} -func (*noOpCollecter) IncrCounter(key []string, val float32) {} -func (*noOpCollecter) MeasureSince(key []string, start time.Time) {} -func (*noOpCollecter) SetGauge(key []string, val float32) {} - -// NewNoOpCollector returns a Collector that does no collection. -func NewNoOpCollector() Collector { - return &noOpCollecter{} -} - -// NewNoOpSink returns a NOOP sink. -func NewNoOpSink() metrics.MetricSink { - return &NoOpSink{} -} - -// NoOpSink default NOOP metrics recorder -type NoOpSink struct{} - -func (*NoOpSink) SetGauge(key []string, val float32) {} -func (*NoOpSink) SetGaugeWithLabels(key []string, val float32, labels []metrics.Label) {} -func (*NoOpSink) EmitKey(key []string, val float32) {} -func (*NoOpSink) IncrCounter(key []string, val float32) {} -func (*NoOpSink) IncrCounterWithLabels(key []string, val float32, labels []metrics.Label) {} -func (*NoOpSink) AddSample(key []string, val float32) {} -func (*NoOpSink) AddSampleWithLabels(key []string, val float32, labels []metrics.Label) {} - -// NewMetrics initializes goa's metrics instance with the supplied -// configuration and metrics sink -// This method is deprecated and SetMetrics should be used instead. -func NewMetrics(conf *metrics.Config, sink metrics.MetricSink) (err error) { - m, err := metrics.NewGlobal(conf, sink) - SetMetrics(m) - - return nil -} - -// SetMetrics initializes goa's metrics instance with the supplied metrics adapter interface. -func SetMetrics(m Collector) { - metriksMu.Lock() - metriks = m - metriksMu.Unlock() -} - -// GetMetrics returns goa's metrics collector adapter interface. -func GetMetrics() Collector { - metriksMu.Lock() - m := metriks - metriksMu.Unlock() - return m -} - -// AddSample adds a sample to an aggregated metric -// reporting count, min, max, mean, and std deviation -// Usage: -// AddSample([]string{"my","namespace","key"}, 15.0) -func AddSample(key []string, val float32) { - normalizeKeys(key) - - GetMetrics().AddSample(key, val) -} - -// EmitKey emits a key/value pair -// Usage: -// EmitKey([]string{"my","namespace","key"}, 15.0) -func EmitKey(key []string, val float32) { - normalizeKeys(key) - - GetMetrics().EmitKey(key, val) -} - -// IncrCounter increments the counter named by `key` -// Usage: -// IncrCounter([]key{"my","namespace","counter"}, 1.0) -func IncrCounter(key []string, val float32) { - normalizeKeys(key) - - GetMetrics().IncrCounter(key, val) -} - -// MeasureSince creates a timing metric that records -// the duration of elapsed time since `start` -// Usage: -// MeasureSince([]string{"my","namespace","action}, time.Now()) -// Frequently used in a defer: -// defer MeasureSince([]string{"my","namespace","action}, time.Now()) -func MeasureSince(key []string, start time.Time) { - normalizeKeys(key) - - GetMetrics().MeasureSince(key, start) -} - -// SetGauge sets the named gauge to the specified value -// Usage: -// SetGauge([]string{"my","namespace"}, 2.0) -func SetGauge(key []string, val float32) { - normalizeKeys(key) - - GetMetrics().SetGauge(key, val) -} - -// This function is used to make metric names safe for all metric services. Specifically, prometheus does -// not support * or / in metric names. -func normalizeKeys(key []string) { - for i, k := range key { - if !validCharactersRE.MatchString(k) { - // first replace */* with all - k = strings.Replace(k, allMatcher, allReplacement, -1) - - // now replace all other invalid characters with a safe one. - key[i] = invalidCharactersRE.ReplaceAllString(k, normalizedToken) - } - } -} diff --git a/vendor/github.com/goadesign/goa/metrics_appengine.go b/vendor/github.com/goadesign/goa/metrics_appengine.go deleted file mode 100644 index 6fd413bb3a3..00000000000 --- a/vendor/github.com/goadesign/goa/metrics_appengine.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build appengine - -package goa - -import ( - "time" -) - -// Not supported in Google App Engine -func IncrCounter(key []string, val float32) { - // Do nothing -} - -// Not supported in Google App Engine -func MeasureSince(key []string, start time.Time) { - // Do nothing -} diff --git a/vendor/github.com/goadesign/goa/metrics_js.go b/vendor/github.com/goadesign/goa/metrics_js.go deleted file mode 100644 index 663672f0a3e..00000000000 --- a/vendor/github.com/goadesign/goa/metrics_js.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build js - -package goa - -import ( - "time" -) - -// Not supported in gopherjs -func IncrCounter(key []string, val float32) { - // Do nothing -} - -// Not supported in gopherjs -func MeasureSince(key []string, start time.Time) { - // Do nothing -} diff --git a/vendor/github.com/goadesign/goa/middleware.go b/vendor/github.com/goadesign/goa/middleware.go deleted file mode 100644 index 4347a87c283..00000000000 --- a/vendor/github.com/goadesign/goa/middleware.go +++ /dev/null @@ -1,80 +0,0 @@ -package goa - -import ( - "fmt" - "net/http" - - "context" -) - -type ( - // Middleware represents the canonical goa middleware signature. - Middleware func(Handler) Handler -) - -// NewMiddleware creates a middleware from the given argument. The allowed types for the -// argument are: -// -// - a goa middleware: goa.Middleware or func(goa.Handler) goa.Handler -// -// - a goa handler: goa.Handler or func(context.Context, http.ResponseWriter, *http.Request) error -// -// - an http middleware: func(http.Handler) http.Handler -// -// - or an http handler: http.Handler or func(http.ResponseWriter, *http.Request) -// -// An error is returned if the given argument is not one of the types above. -func NewMiddleware(m interface{}) (mw Middleware, err error) { - switch m := m.(type) { - case Middleware: - mw = m - case func(Handler) Handler: - mw = m - case Handler: - mw = handlerToMiddleware(m) - case func(context.Context, http.ResponseWriter, *http.Request) error: - mw = handlerToMiddleware(m) - case func(http.Handler) http.Handler: - mw = func(h Handler) Handler { - return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) (err error) { - m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - err = h(ctx, w, r) - })).ServeHTTP(rw, req) - return - } - } - case http.Handler: - mw = httpHandlerToMiddleware(m.ServeHTTP) - case func(http.ResponseWriter, *http.Request): - mw = httpHandlerToMiddleware(m) - default: - err = fmt.Errorf("invalid middleware %#v", m) - } - return -} - -// handlerToMiddleware creates a middleware from a raw handler. -// The middleware calls the handler and either breaks the middleware chain if the handler returns -// an error by also returning the error or calls the next handler in the chain otherwise. -func handlerToMiddleware(m Handler) Middleware { - return func(h Handler) Handler { - return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { - if err := m(ctx, rw, req); err != nil { - return err - } - return h(ctx, rw, req) - } - } -} - -// httpHandlerToMiddleware creates a middleware from a http.HandlerFunc. -// The middleware calls the ServerHTTP method exposed by the http handler and then calls the next -// middleware in the chain. -func httpHandlerToMiddleware(m http.HandlerFunc) Middleware { - return func(h Handler) Handler { - return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { - m.ServeHTTP(rw, req) - return h(ctx, rw, req) - } - } -} diff --git a/vendor/github.com/goadesign/goa/mux.go b/vendor/github.com/goadesign/goa/mux.go deleted file mode 100644 index e8b6c2eae71..00000000000 --- a/vendor/github.com/goadesign/goa/mux.go +++ /dev/null @@ -1,101 +0,0 @@ -package goa - -import ( - "net/http" - "net/url" - - "github.com/dimfeld/httptreemux" -) - -type ( - // MuxHandler provides the low level implementation for an API endpoint. - // The values argument includes both the querystring and path parameter values. - MuxHandler func(http.ResponseWriter, *http.Request, url.Values) - - // MethodNotAllowedHandler provides the implementation for an MethodNotAllowed - // handler. The values argument includes both the querystring and path parameter - // values. The methods argument includes both the allowed method identifier - // and the registered handler. - MethodNotAllowedHandler func(http.ResponseWriter, *http.Request, url.Values, map[string]httptreemux.HandlerFunc) - - // ServeMux is the interface implemented by the service request muxes. - // It implements http.Handler and makes it possible to register request handlers for - // specific HTTP methods and request path via the Handle method. - ServeMux interface { - http.Handler - // Handle sets the MuxHandler for a given HTTP method and path. - Handle(method, path string, handle MuxHandler) - // HandleNotFound sets the MuxHandler invoked for requests that don't match any - // handler registered with Handle. The values argument given to the handler is - // always nil. - HandleNotFound(handle MuxHandler) - // HandleMethodNotAllowed sets the MethodNotAllowedHandler invoked for requests - // that match the path of a handler but not its HTTP method. The values argument - // given to the Handler is always nil. - HandleMethodNotAllowed(handle MethodNotAllowedHandler) - // Lookup returns the MuxHandler associated with the given HTTP method and path. - Lookup(method, path string) MuxHandler - } - - // Muxer implements an adapter that given a request handler can produce a mux handler. - Muxer interface { - MuxHandler(string, Handler, Unmarshaler) MuxHandler - } - - // mux is the default ServeMux implementation. - mux struct { - router *httptreemux.TreeMux - handles map[string]MuxHandler - } -) - -// NewMux returns a Mux. -func NewMux() ServeMux { - r := httptreemux.New() - r.EscapeAddedRoutes = true - return &mux{ - router: r, - handles: make(map[string]MuxHandler), - } -} - -// Handle sets the handler for the given verb and path. -func (m *mux) Handle(method, path string, handle MuxHandler) { - hthandle := func(rw http.ResponseWriter, req *http.Request, htparams map[string]string) { - params := req.URL.Query() - for n, p := range htparams { - params.Set(n, p) - } - handle(rw, req, params) - } - m.handles[method+path] = handle - m.router.Handle(method, path, hthandle) -} - -// HandleNotFound sets the MuxHandler invoked for requests that don't match any -// handler registered with Handle. -func (m *mux) HandleNotFound(handle MuxHandler) { - nfh := func(rw http.ResponseWriter, req *http.Request) { - handle(rw, req, nil) - } - m.router.NotFoundHandler = nfh -} - -// HandleMethodNotAllowed sets the MuxHandler invoked for requests that match -// the path of a handler but not its HTTP method. -func (m *mux) HandleMethodNotAllowed(handle MethodNotAllowedHandler) { - mna := func(rw http.ResponseWriter, req *http.Request, methods map[string]httptreemux.HandlerFunc) { - handle(rw, req, nil, methods) - } - m.router.MethodNotAllowedHandler = mna -} - -// Lookup returns the MuxHandler associated with the given method and path. -func (m *mux) Lookup(method, path string) MuxHandler { - return m.handles[method+path] -} - -// ServeHTTP is the function called back by the underlying HTTP server to handle incoming requests. -func (m *mux) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - m.router.ServeHTTP(rw, req) -} diff --git a/vendor/github.com/goadesign/goa/roadmap.md b/vendor/github.com/goadesign/goa/roadmap.md deleted file mode 100644 index eaf575fb0b7..00000000000 --- a/vendor/github.com/goadesign/goa/roadmap.md +++ /dev/null @@ -1,153 +0,0 @@ -# goa Roadmap - -This document summarizes the areas of focus for the next release (v2). These cover improvements and -new features that introduce non-backwards compatible changes. - -## Breakout the Context - -The generated context data structure contains both the request and response state. While this makes -it convenient to write controller code it does not make sense to pass these objects all the way down -in all layers. It also creates hidden dependencies. - -The proposal is to break up the generated context into two data structures, one that contains the -request state and the other the response state. Concretely today the following design: - -```go -Action("update", func() { - Routing( - PATCH("/:bottleID"), - ) - Params(func() { - Param("bottleID", Integer) - }) - Payload(BottlePayload) - Response(NoContent) - Response(NotFound) -}) -``` - -produces the following context data structure: - -```go -// UpdateBottleContext provides the bottle update action context. -type UpdateBottleContext struct { - context.Context - *goa.ResponseData - *goa.RequestData - AccountID int - BottleID int - Payload *UpdateBottlePayload - service *goa.Service -} -``` - -This proposal would break it down into: - -```go -// UpdateBottleRequest provides the bottle update action request context. -type UpdateBottleContext struct { - *goa.RequestData - AccountID int - BottleID int - Payload *UpdateBottlePayload -} - -// UpdateBottleResponse provides the bottle update action response context. -type UpdateBottleResponse struct { - *goa.ResponseData - service *goa.Service -} -``` - -The response functions would move from the `UpdateBottleContext` struct to the -`UpdateBottleResponse` struct. - -Both the response and request state structs would be given to the controller action function. Today -the design above generates: - -```go -Update(*UpdateBottleContext) error -``` - -Under this proposal the generated code would be: - -```go -Update(ctx context.Context, resp *UpdateBottleResponse, req *UpdateBottleRequest) error -``` - -### Error Handling Improvements - -Move from a model using structs to implement goa errors and check for them to a model using checking -for behavior. - -Consider changing the goa request handler signature from: - -```go -func (context.Context, http.ResponseWriter, *http.Request) error -``` - -to the standard: - -```go -func (context.Context, http.ResponseWriter, *http.Request) -``` - -And keep the error in the response struct instead. This means tweaking how error handling is done so -that the error handler middleware knows where to look for errors. - -## Code Generation Improvements - -### Generator Hooks - -The first planned improvement made to code generation is the ability for arbitrary plugins to hook -into the generated code of another generator. The main scenario that this should enable is the -ability to inject code in the built-in generator outputs (in particular `gen_app`). This would make -it possible to move the security and CORS generation in plugins and help keep the main generator -streamlined. Details on how this is enabled TBD. One possibility is to cater specifically to the use -case above and have the `gen_app` generator expose explicit hooks. Would be nice to come up with a -more generic approach though. - -### Easier Plugin Use - -Make it easier to invoke plugins on the command line. One possibility could be to have a hosted plugin -registry that goagen could look up where plugins could register with a simple moniker. This registry -could also provide discoverability of plugins (via something like `goagen plugins`). The registry -would only contain metadata (moniker, description, author, last update data etc.) and point to the -actual plugin package. - -### Intermediary Representation - -Generators start from the design data structures then massage that data into a shape suitable for -code generation. Today this is done in a ad-hoc way - each generator having its own strategy. For -example the `gen_app` generator uses `Template` data structures except for test code generation that -use a different kind of structs. Other generators rely on functions called at generation time to -perform the transformations which makes it hard to follow. - -The proposal is to implement a standard strategy of first creating explicit structs representing the -intermediary representation used by the code generation templates. This would help clarify what the -templates expect and keep that up-to-date as the definitions evolve. This should be done in a way -that doesn't force generators to use it (some simple generators may not have a need for such a IR) -but it should encourage it. For example there could be an additional optional interface that -generators could implement that would get called by the generation engine. - -## Cleanup Type System - -Move `DateTime` and `UUID` to formats on the `String` type. This is to keep the set of basic types -small and remain consistent with how `Integer` support formats for various underlying Go data types -(see below). This also will allow removing a lot of cruft that supporting these types introduced. -From the need to "alias" them to string in code generators to the special cases they introduce with -gopherjs support. - -## Protobuf / gRPC - -Look into generating .proto files from the design and invoke `protoc` on them during code -generation. Integrate the generated code with the generated data structures. - -This also requires the ability to specify the bit length of numerical values. The proposal here -would be to add support for the `Format` DSL to the `Integer` and `Number` primitive types. The -format would indicate bitness and whether the generated integer should be signed. - -## Client Improvements - -Try to remove the signers from the client package and instead make it possible to integrate with 3rd -party client packages. Make the client function generate http.Request to enable that integration. diff --git a/vendor/github.com/goadesign/goa/security.go b/vendor/github.com/goadesign/goa/security.go deleted file mode 100644 index 9d99bb7afda..00000000000 --- a/vendor/github.com/goadesign/goa/security.go +++ /dev/null @@ -1,77 +0,0 @@ -package goa - -import "context" - -// Location is the enum defining where the value of key based security schemes should be read: -// either a HTTP request header or a URL querystring value -type Location string - -// LocHeader indicates the secret value should be loaded from the request headers. -const LocHeader Location = "header" - -// LocQuery indicates the secret value should be loaded from the request URL querystring. -const LocQuery Location = "query" - -// ContextRequiredScopes extracts the security scopes from the given context. -// This should be used in auth handlers to validate that the required scopes are present in the -// JWT or OAuth2 token. -func ContextRequiredScopes(ctx context.Context) []string { - if s := ctx.Value(securityScopesKey); s != nil { - return s.([]string) - } - return nil -} - -// WithRequiredScopes builds a context containing the given required scopes. -func WithRequiredScopes(ctx context.Context, scopes []string) context.Context { - return context.WithValue(ctx, securityScopesKey, scopes) -} - -// OAuth2Security represents the `oauth2` security scheme. It is instantiated by the generated code -// accordingly to the use of the different `*Security()` DSL functions and `Security()` in the -// design. -type OAuth2Security struct { - // Description of the security scheme - Description string - // Flow defines the OAuth2 flow type. See http://swagger.io/specification/#securitySchemeObject - Flow string - // TokenURL defines the OAuth2 tokenUrl. See http://swagger.io/specification/#securitySchemeObject - TokenURL string - // AuthorizationURL defines the OAuth2 authorizationUrl. See http://swagger.io/specification/#securitySchemeObject - AuthorizationURL string - // Scopes defines a list of scopes for the security scheme, along with their description. - Scopes map[string]string -} - -// BasicAuthSecurity represents the `Basic` security scheme, which consists of a simple login/pass, -// accessible through Request.BasicAuth(). -type BasicAuthSecurity struct { - // Description of the security scheme - Description string -} - -// APIKeySecurity represents the `apiKey` security scheme. It handles a key that can be in the -// headers or in the query parameters, and does authentication based on that. The Name field -// represents the key of either the query string parameter or the header, depending on the In field. -type APIKeySecurity struct { - // Description of the security scheme - Description string - // In represents where to check for some data, `query` or `header` - In Location - // Name is the name of the `header` or `query` parameter to check for data. - Name string -} - -// JWTSecurity represents an api key based scheme, with support for scopes and a token URL. -type JWTSecurity struct { - // Description of the security scheme - Description string - // In represents where to check for the JWT, `query` or `header` - In Location - // Name is the name of the `header` or `query` parameter to check for data. - Name string - // TokenURL defines the URL where you'd get the JWT tokens. - TokenURL string - // Scopes defines a list of scopes for the security scheme, along with their description. - Scopes map[string]string -} diff --git a/vendor/github.com/goadesign/goa/service.go b/vendor/github.com/goadesign/goa/service.go deleted file mode 100644 index fd06f49f44c..00000000000 --- a/vendor/github.com/goadesign/goa/service.go +++ /dev/null @@ -1,455 +0,0 @@ -package goa - -import ( - "context" - "fmt" - "io" - "log" - "net" - "net/http" - "net/url" - "os" - "path/filepath" - "sort" - "strings" - "sync" - - "github.com/dimfeld/httptreemux" -) - -type ( - // Service is the data structure supporting goa services. - // It provides methods for configuring a service and running it. - // At the basic level a service consists of a set of controllers, each implementing a given - // resource actions. goagen generates global functions - one per resource - that make it - // possible to mount the corresponding controller onto a service. A service contains the - // middleware, not found handler, encoders and muxes shared by all its controllers. - Service struct { - // Name of service used for logging, tracing etc. - Name string - // Mux is the service request mux - Mux ServeMux - // Server is the service HTTP server. - Server *http.Server - // Context is the root context from which all request contexts are derived. - // Set values in the root context prior to starting the server to make these values - // available to all request handlers. - Context context.Context - // Request body decoder - Decoder *HTTPDecoder - // Response body encoder - Encoder *HTTPEncoder - - middleware []Middleware // Middleware chain - cancel context.CancelFunc // Service context cancel signal trigger - } - - // Controller defines the common fields and behavior of generated controllers. - Controller struct { - // Controller resource name - Name string - // Service that exposes the controller - Service *Service - // Controller root context - Context context.Context - // MaxRequestBodyLength is the maximum length read from request bodies. - // Set to 0 to remove the limit altogether. Defaults to 1GB. - MaxRequestBodyLength int64 - // FileSystem is used in FileHandler to open files. By default it returns - // http.Dir but you can override it with another one that implements http.FileSystem. - // For example using github.com/elazarl/go-bindata-assetfs is like below. - // - // ctrl.FileSystem = func(dir string) http.FileSystem { - // return &assetfs.AssetFS{ - // Asset: Asset, - // AssetDir: AssetDir, - // AssetInfo: AssetInfo, - // Prefix: dir, - // } - // } - FileSystem func(string) http.FileSystem - - middleware []Middleware // Controller specific middleware if any - } - - // FileServer is the interface implemented by controllers that can serve static files. - FileServer interface { - // FileHandler returns a handler that serves files under the given request path. - FileHandler(path, filename string) Handler - } - - // Handler defines the request handler signatures. - Handler func(context.Context, http.ResponseWriter, *http.Request) error - - // Unmarshaler defines the request payload unmarshaler signatures. - Unmarshaler func(context.Context, *Service, *http.Request) error - - // DecodeFunc is the function that initialize the unmarshaled payload from the request body. - DecodeFunc func(context.Context, io.ReadCloser, interface{}) error -) - -// New instantiates a service with the given name. -func New(name string) *Service { - var ( - stdlog = log.New(os.Stderr, "", log.LstdFlags) - ctx = WithLogger(context.Background(), NewLogger(stdlog)) - cctx, cancel = context.WithCancel(ctx) - mux = NewMux() - service = &Service{ - Name: name, - Context: cctx, - Mux: mux, - Server: &http.Server{ - Handler: mux, - }, - Decoder: NewHTTPDecoder(), - Encoder: NewHTTPEncoder(), - - cancel: cancel, - } - notFoundHandler Handler - methodNotAllowedHandler Handler - ) - - // Setup default NotFound handler - mux.HandleNotFound(func(rw http.ResponseWriter, req *http.Request, params url.Values) { - if resp := ContextResponse(ctx); resp != nil && resp.Written() { - return - } - // Use closure to do lazy computation of middleware chain so all middlewares are - // registered. - if notFoundHandler == nil { - notFoundHandler = func(_ context.Context, _ http.ResponseWriter, req *http.Request) error { - return ErrNotFound(req.URL.Path) - } - chain := service.middleware - ml := len(chain) - for i := range chain { - notFoundHandler = chain[ml-i-1](notFoundHandler) - } - } - ctx := NewContext(service.Context, rw, req, params) - err := notFoundHandler(ctx, ContextResponse(ctx), req) - if !ContextResponse(ctx).Written() { - service.Send(ctx, 404, err) - } - }) - - // Setup default MethodNotAllowed handler - mux.HandleMethodNotAllowed(func(rw http.ResponseWriter, req *http.Request, params url.Values, methods map[string]httptreemux.HandlerFunc) { - if resp := ContextResponse(ctx); resp != nil && resp.Written() { - return - } - // Use closure to do lazy computation of middleware chain so all middlewares are - // registered. - if methodNotAllowedHandler == nil { - methodNotAllowedHandler = func(_ context.Context, rw http.ResponseWriter, req *http.Request) error { - allowedMethods := make([]string, len(methods)) - i := 0 - for k := range methods { - allowedMethods[i] = k - i++ - } - rw.Header().Set("Allow", strings.Join(allowedMethods, ", ")) - return MethodNotAllowedError(req.Method, allowedMethods) - } - chain := service.middleware - ml := len(chain) - for i := range chain { - methodNotAllowedHandler = chain[ml-i-1](methodNotAllowedHandler) - } - } - ctx := NewContext(service.Context, rw, req, params) - err := methodNotAllowedHandler(ctx, ContextResponse(ctx), req) - if !ContextResponse(ctx).Written() { - service.Send(ctx, 405, err) - } - }) - - return service -} - -// CancelAll sends a cancel signals to all request handlers via the context. -// See https://golang.org/pkg/context/ for details on how to handle the signal. -func (service *Service) CancelAll() { - service.cancel() -} - -// Use adds a middleware to the service wide middleware chain. -// goa comes with a set of commonly used middleware, see the middleware package. -// Controller specific middleware should be mounted using the Controller struct Use method instead. -func (service *Service) Use(m Middleware) { - service.middleware = append(service.middleware, m) -} - -// WithLogger sets the logger used internally by the service and by Log. -func (service *Service) WithLogger(logger LogAdapter) { - service.Context = WithLogger(service.Context, logger) -} - -// LogInfo logs the message and values at odd indeces using the keys at even indeces of the keyvals slice. -func (service *Service) LogInfo(msg string, keyvals ...interface{}) { - LogInfo(service.Context, msg, keyvals...) -} - -// LogError logs the error and values at odd indeces using the keys at even indeces of the keyvals slice. -func (service *Service) LogError(msg string, keyvals ...interface{}) { - LogError(service.Context, msg, keyvals...) -} - -// ListenAndServe starts a HTTP server and sets up a listener on the given host/port. -func (service *Service) ListenAndServe(addr string) error { - service.LogInfo("listen", "transport", "http", "addr", addr) - service.Server.Addr = addr - return service.Server.ListenAndServe() -} - -// ListenAndServeTLS starts a HTTPS server and sets up a listener on the given host/port. -func (service *Service) ListenAndServeTLS(addr, certFile, keyFile string) error { - service.LogInfo("listen", "transport", "https", "addr", addr) - service.Server.Addr = addr - return service.Server.ListenAndServeTLS(certFile, keyFile) -} - -// Serve accepts incoming HTTP connections on the listener l, invoking the service mux handler for each. -func (service *Service) Serve(l net.Listener) error { - return service.Server.Serve(l) -} - -// NewController returns a controller for the given resource. This method is mainly intended for -// use by the generated code. User code shouldn't have to call it directly. -func (service *Service) NewController(name string) *Controller { - return &Controller{ - Name: name, - Service: service, - Context: context.WithValue(service.Context, ctrlKey, name), - MaxRequestBodyLength: 1073741824, // 1 GB - FileSystem: func(dir string) http.FileSystem { - return http.Dir(dir) - }, - } -} - -// Send serializes the given body matching the request Accept header against the service -// encoders. It uses the default service encoder if no match is found. -func (service *Service) Send(ctx context.Context, code int, body interface{}) error { - r := ContextResponse(ctx) - if r == nil { - return fmt.Errorf("no response data in context") - } - r.WriteHeader(code) - return service.EncodeResponse(ctx, body) -} - -// ServeFiles create a "FileServer" controller and calls ServerFiles on it. -func (service *Service) ServeFiles(path, filename string) error { - ctrl := service.NewController("FileServer") - return ctrl.ServeFiles(path, filename) -} - -// DecodeRequest uses the HTTP decoder to unmarshal the request body into the provided value based -// on the request Content-Type header. -func (service *Service) DecodeRequest(req *http.Request, v interface{}) error { - body, contentType := req.Body, req.Header.Get("Content-Type") - defer body.Close() - - if err := service.Decoder.Decode(v, body, contentType); err != nil { - return fmt.Errorf("failed to decode request body with content type %#v: %s", contentType, err) - } - - return nil -} - -// EncodeResponse uses the HTTP encoder to marshal and write the response body based on the request -// Accept header. -func (service *Service) EncodeResponse(ctx context.Context, v interface{}) error { - accept := ContextRequest(ctx).Header.Get("Accept") - return service.Encoder.Encode(v, ContextResponse(ctx), accept) -} - -// ServeFiles replies to the request with the contents of the named file or directory. See -// FileHandler for details. -func (ctrl *Controller) ServeFiles(path, filename string) error { - if strings.Contains(path, ":") { - return fmt.Errorf("path may only include wildcards that match the entire end of the URL (e.g. *filepath)") - } - LogInfo(ctrl.Context, "mount file", "name", filename, "route", fmt.Sprintf("GET %s", path)) - handler := func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { - if !ContextResponse(ctx).Written() { - return ctrl.FileHandler(path, filename)(ctx, rw, req) - } - return nil - } - ctrl.Service.Mux.Handle("GET", path, ctrl.MuxHandler("serve", handler, nil)) - return nil -} - -// Use adds a middleware to the controller. -// Service-wide middleware should be added via the Service Use method instead. -func (ctrl *Controller) Use(m Middleware) { - ctrl.middleware = append(ctrl.middleware, m) -} - -// MuxHandler wraps a request handler into a MuxHandler. The MuxHandler initializes the request -// context by loading the request state, invokes the handler and in case of error invokes the -// controller (if there is one) or Service error handler. -// This function is intended for the controller generated code. User code should not need to call -// it directly. -func (ctrl *Controller) MuxHandler(name string, hdlr Handler, unm Unmarshaler) MuxHandler { - // Use closure to enable late computation of handlers to ensure all middleware has been - // registered. - var handler Handler - var initHandler sync.Once - - return func(rw http.ResponseWriter, req *http.Request, params url.Values) { - // Build handler middleware chains on first invocation - initHandler.Do(func() { - handler = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { - if !ContextResponse(ctx).Written() { - return hdlr(ctx, rw, req) - } - return nil - } - chain := append(ctrl.Service.middleware, ctrl.middleware...) - ml := len(chain) - for i := range chain { - handler = chain[ml-i-1](handler) - } - }) - - // Build context - ctx := NewContext(WithAction(ctrl.Context, name), rw, req, params) - - // Protect against request bodies with unreasonable length - if ctrl.MaxRequestBodyLength > 0 { - req.Body = http.MaxBytesReader(rw, req.Body, ctrl.MaxRequestBodyLength) - } - - // Load body if any - if req.ContentLength > 0 && unm != nil { - if err := unm(ctx, ctrl.Service, req); err != nil { - if err.Error() == "http: request body too large" { - msg := fmt.Sprintf("request body length exceeds %d bytes", ctrl.MaxRequestBodyLength) - err = ErrRequestBodyTooLarge(msg) - } else { - err = ErrBadRequest(err) - } - ctx = WithError(ctx, err) - } - } - - // Invoke handler - if err := handler(ctx, ContextResponse(ctx), req); err != nil { - LogError(ctx, "uncaught error", "err", err) - respBody := fmt.Sprintf("Internal error: %s", err) // Sprintf catches panics - ctrl.Service.Send(ctx, 500, respBody) - } - } -} - -// FileHandler returns a handler that serves files under the given filename for the given route path. -// The logic for what to do when the filename points to a file vs. a directory is the same as the -// standard http package ServeFile function. The path may end with a wildcard that matches the rest -// of the URL (e.g. *filepath). If it does the matching path is appended to filename to form the -// full file path, so: -// -// c.FileHandler("/index.html", "/www/data/index.html") -// -// Returns the content of the file "/www/data/index.html" when requests are sent to "/index.html" -// and: -// -// c.FileHandler("/assets/*filepath", "/www/data/assets") -// -// returns the content of the file "/www/data/assets/x/y/z" when requests are sent to -// "/assets/x/y/z". -func (ctrl *Controller) FileHandler(path, filename string) Handler { - var wc string - if idx := strings.LastIndex(path, "/*"); idx > -1 && idx < len(path)-1 { - wc = path[idx+2:] - if strings.Contains(wc, "/") { - wc = "" - } - } - return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { - fname := filename - if len(wc) > 0 { - if m, ok := ContextRequest(ctx).Params[wc]; ok { - fname = filepath.Join(filename, m[0]) - } - } - LogInfo(ctx, "serve file", "name", fname, "route", req.URL.Path) - dir, name := filepath.Split(fname) - fs := ctrl.FileSystem(dir) - f, err := fs.Open(name) - if err != nil { - return ErrInvalidFile(err) - } - defer f.Close() - d, err := f.Stat() - if err != nil { - return ErrInvalidFile(err) - } - // use contents of index.html for directory, if present - if d.IsDir() { - index := strings.TrimSuffix(name, "/") + "/index.html" - ff, err := fs.Open(index) - if err == nil { - defer ff.Close() - dd, err := ff.Stat() - if err == nil { - name = index - d = dd - f = ff - } - } - } - - // serveContent will check modification time - // Still a directory? (we didn't find an index.html file) - if d.IsDir() { - return dirList(rw, f) - } - http.ServeContent(rw, req, d.Name(), d.ModTime(), f) - return nil - } -} - -var replacer = strings.NewReplacer( - "&", "&", - "<", "<", - ">", ">", - // """ is shorter than """. - `"`, """, - // "'" is shorter than "'" and apos was not in HTML until HTML5. - "'", "'", -) - -func dirList(w http.ResponseWriter, f http.File) error { - dirs, err := f.Readdir(-1) - if err != nil { - return err - } - sort.Sort(byName(dirs)) - - w.Header().Set("Content-Type", "text/html; charset=utf-8") - fmt.Fprintf(w, "
\n")
-	for _, d := range dirs {
-		name := d.Name()
-		if d.IsDir() {
-			name += "/"
-		}
-		// name may contain '?' or '#', which must be escaped to remain
-		// part of the URL path, and not indicate the start of a query
-		// string or fragment.
-		url := url.URL{Path: name}
-		fmt.Fprintf(w, "%s\n", url.String(), replacer.Replace(name))
-	}
-	fmt.Fprintf(w, "
\n") - return nil -} - -type byName []os.FileInfo - -func (s byName) Len() int { return len(s) } -func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } -func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } diff --git a/vendor/github.com/goadesign/goa/uuid/common.go b/vendor/github.com/goadesign/goa/uuid/common.go deleted file mode 100644 index a8967368b5b..00000000000 --- a/vendor/github.com/goadesign/goa/uuid/common.go +++ /dev/null @@ -1,4 +0,0 @@ -package uuid - -// UUID This is needed to build with gopherjs -type UUID [16]byte diff --git a/vendor/github.com/goadesign/goa/uuid/uuid.go b/vendor/github.com/goadesign/goa/uuid/uuid.go deleted file mode 100644 index 5117e4c7c35..00000000000 --- a/vendor/github.com/goadesign/goa/uuid/uuid.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build !js - -//This is just a declaration of the uuid.UUID which doesn't work with gopherjs -//See uuid_js.go for the JS implementation - -package uuid - -import "github.com/satori/go.uuid" - -// FromString Wrapper around the real FromString -func FromString(input string) (UUID, error) { - u, err := uuid.FromString(input) - return UUID(u), err -} - -// NewV4 Wrapper over the real NewV4 method -func NewV4() UUID { - return UUID(uuid.Must(uuid.NewV4())) -} - -// String Wrapper over the real String method -func (u UUID) String() string { - return uuid.UUID(u).String() -} - -// MarshalText Wrapper over the real MarshalText method -func (u UUID) MarshalText() (text []byte, err error) { - return uuid.UUID(u).MarshalText() -} - -// MarshalBinary Wrapper over the real MarshalBinary method -func (u UUID) MarshalBinary() ([]byte, error) { - return uuid.UUID(u).MarshalBinary() -} - -// UnmarshalBinary Wrapper over the real UnmarshalBinary method -func (u *UUID) UnmarshalBinary(data []byte) error { - t := uuid.UUID{} - err := t.UnmarshalBinary(data) - for i, b := range t.Bytes() { - u[i] = b - } - return err -} - -// UnmarshalText Wrapper over the real UnmarshalText method -func (u *UUID) UnmarshalText(text []byte) error { - t := uuid.UUID{} - err := t.UnmarshalText(text) - for i, b := range t.Bytes() { - u[i] = b - } - return err -} diff --git a/vendor/github.com/goadesign/goa/uuid/uuid_js.go b/vendor/github.com/goadesign/goa/uuid/uuid_js.go deleted file mode 100644 index 12d0cc78c26..00000000000 --- a/vendor/github.com/goadesign/goa/uuid/uuid_js.go +++ /dev/null @@ -1,90 +0,0 @@ -// +build js - -//This part is copied from github.com/satori/go.uuid but some feature uses non gopherjs compliants calls -//Since goa only needs a subset of the features the js copies them in here - -package uuid - -import ( - "bytes" - "encoding/hex" - "fmt" -) - -// String parse helpers. -var ( - urnPrefix = []byte("urn:uuid:") - byteGroups = []int{8, 4, 4, 4, 12} -) - -// FromString returns UUID parsed from string input. -// Input is expected in a form accepted by UnmarshalText. -func FromString(input string) (u UUID, err error) { - err = u.UnmarshalText([]byte(input)) - return -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -// Following formats are supported: -// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", -// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", -// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" -func (u *UUID) UnmarshalText(text []byte) (err error) { - if len(text) < 32 { - err = fmt.Errorf("uuid: UUID string too short: %s", text) - return - } - - t := text[:] - - if bytes.Equal(t[:9], urnPrefix) { - t = t[9:] - } else if t[0] == '{' { - t = t[1:] - } - - b := u[:] - - for _, byteGroup := range byteGroups { - if t[0] == '-' { - t = t[1:] - } - - if len(t) < byteGroup { - err = fmt.Errorf("uuid: UUID string too short: %s", text) - return - } - - _, err = hex.Decode(b[:byteGroup/2], t[:byteGroup]) - - if err != nil { - return - } - - t = t[byteGroup:] - b = b[byteGroup/2:] - } - - return -} - -// Used in string method conversion -const dash byte = '-' - -// Returns canonical string representation of UUID: -// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. -func (u UUID) String() string { - buf := make([]byte, 36) - - hex.Encode(buf[0:8], u[0:4]) - buf[8] = dash - hex.Encode(buf[9:13], u[4:6]) - buf[13] = dash - hex.Encode(buf[14:18], u[6:8]) - buf[18] = dash - hex.Encode(buf[19:23], u[8:10]) - buf[23] = dash - hex.Encode(buf[24:], u[10:]) - - return string(buf) -} diff --git a/vendor/github.com/goadesign/goa/validation.go b/vendor/github.com/goadesign/goa/validation.go deleted file mode 100644 index ea08a061850..00000000000 --- a/vendor/github.com/goadesign/goa/validation.go +++ /dev/null @@ -1,149 +0,0 @@ -package goa - -import ( - "fmt" - "net" - "net/mail" - "net/url" - "regexp" - "sync" - "time" - - "github.com/goadesign/goa/uuid" -) - -// Format defines a validation format. -type Format string - -const ( - // FormatDateTime defines RFC3339 date time values. - FormatDateTime Format = "date-time" - - // FormatUUID defines RFC4122 uuid values. - FormatUUID Format = "uuid" - - // FormatEmail defines RFC5322 email addresses. - FormatEmail = "email" - - // FormatHostname defines RFC1035 Internet host names. - FormatHostname = "hostname" - - // FormatIPv4 defines RFC2373 IPv4 address values. - FormatIPv4 = "ipv4" - - // FormatIPv6 defines RFC2373 IPv6 address values. - FormatIPv6 = "ipv6" - - // FormatIP defines RFC2373 IPv4 or IPv6 address values. - FormatIP = "ip" - - // FormatURI defines RFC3986 URI values. - FormatURI = "uri" - - // FormatMAC defines IEEE 802 MAC-48, EUI-48 or EUI-64 MAC address values. - FormatMAC = "mac" - - // FormatCIDR defines RFC4632 and RFC4291 CIDR notation IP address values. - FormatCIDR = "cidr" - - // FormatRegexp Regexp defines regular expression syntax accepted by RE2. - FormatRegexp = "regexp" - - // FormatRFC1123 defines RFC1123 date time values. - FormatRFC1123 = "rfc1123" -) - -var ( - // Regular expression used to validate RFC1035 hostnames*/ - hostnameRegex = regexp.MustCompile(`^[[:alnum:]][[:alnum:]\-]{0,61}[[:alnum:]]|[[:alpha:]]$`) - - // Simple regular expression for IPv4 values, more rigorous checking is done via net.ParseIP - ipv4Regex = regexp.MustCompile(`^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$`) -) - -// ValidateFormat validates a string against a standard format. -// It returns nil if the string conforms to the format, an error otherwise. -// The format specification follows the json schema draft 4 validation extension. -// see http://json-schema.org/latest/json-schema-validation.html#anchor105 -// Supported formats are: -// -// - "date-time": RFC3339 date time value -// - "email": RFC5322 email address -// - "hostname": RFC1035 Internet host name -// - "ipv4", "ipv6", "ip": RFC2673 and RFC2373 IP address values -// - "uri": RFC3986 URI value -// - "mac": IEEE 802 MAC-48, EUI-48 or EUI-64 MAC address value -// - "cidr": RFC4632 and RFC4291 CIDR notation IP address value -// - "regexp": Regular expression syntax accepted by RE2 -// - "rfc1123": RFC1123 date time value -func ValidateFormat(f Format, val string) error { - var err error - switch f { - case FormatDateTime: - _, err = time.Parse(time.RFC3339, val) - case FormatUUID: - _, err = uuid.FromString(val) - case FormatEmail: - _, err = mail.ParseAddress(val) - case FormatHostname: - if !hostnameRegex.MatchString(val) { - err = fmt.Errorf("hostname value '%s' does not match %s", - val, hostnameRegex.String()) - } - case FormatIPv4, FormatIPv6, FormatIP: - ip := net.ParseIP(val) - if ip == nil { - err = fmt.Errorf("\"%s\" is an invalid %s value", val, f) - } - if f == FormatIPv4 { - if !ipv4Regex.MatchString(val) { - err = fmt.Errorf("\"%s\" is an invalid ipv4 value", val) - } - } - if f == FormatIPv6 { - if ipv4Regex.MatchString(val) { - err = fmt.Errorf("\"%s\" is an invalid ipv6 value", val) - } - } - case FormatURI: - _, err = url.ParseRequestURI(val) - case FormatMAC: - _, err = net.ParseMAC(val) - case FormatCIDR: - _, _, err = net.ParseCIDR(val) - case FormatRegexp: - _, err = regexp.Compile(val) - case FormatRFC1123: - _, err = time.Parse(time.RFC1123, val) - default: - return fmt.Errorf("unknown format %#v", f) - } - if err != nil { - go IncrCounter([]string{"goa", "validation", "error", string(f)}, 1.0) - return fmt.Errorf("invalid %s value, %s", f, err) - } - return nil -} - -// knownPatterns records the compiled patterns. -// TBD: refactor all this so that the generated code initializes the map on start to get rid of the -// need for a RW mutex. -var knownPatterns = make(map[string]*regexp.Regexp) - -// knownPatternsLock is the mutex used to access knownPatterns -var knownPatternsLock = &sync.RWMutex{} - -// ValidatePattern returns an error if val does not match the regular expression p. -// It makes an effort to minimize the number of times the regular expression needs to be compiled. -func ValidatePattern(p string, val string) bool { - knownPatternsLock.RLock() - r, ok := knownPatterns[p] - knownPatternsLock.RUnlock() - if !ok { - r = regexp.MustCompile(p) // DSL validation makes sure regexp is valid - knownPatternsLock.Lock() - knownPatterns[p] = r - knownPatternsLock.Unlock() - } - return r.MatchString(val) -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/.gitignore b/vendor/github.com/hashicorp/go-immutable-radix/.gitignore deleted file mode 100644 index daf913b1b34..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/hashicorp/go-immutable-radix/.travis.yml b/vendor/github.com/hashicorp/go-immutable-radix/.travis.yml deleted file mode 100644 index 1a0bbea6c77..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: go -go: - - tip diff --git a/vendor/github.com/hashicorp/go-immutable-radix/LICENSE b/vendor/github.com/hashicorp/go-immutable-radix/LICENSE deleted file mode 100644 index e87a115e462..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/LICENSE +++ /dev/null @@ -1,363 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/go-immutable-radix/README.md b/vendor/github.com/hashicorp/go-immutable-radix/README.md deleted file mode 100644 index 8910fcc035a..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/README.md +++ /dev/null @@ -1,41 +0,0 @@ -go-immutable-radix [![Build Status](https://travis-ci.org/hashicorp/go-immutable-radix.png)](https://travis-ci.org/hashicorp/go-immutable-radix) -========= - -Provides the `iradix` package that implements an immutable [radix tree](http://en.wikipedia.org/wiki/Radix_tree). -The package only provides a single `Tree` implementation, optimized for sparse nodes. - -As a radix tree, it provides the following: - * O(k) operations. In many cases, this can be faster than a hash table since - the hash function is an O(k) operation, and hash tables have very poor cache locality. - * Minimum / Maximum value lookups - * Ordered iteration - -A tree supports using a transaction to batch multiple updates (insert, delete) -in a more efficient manner than performing each operation one at a time. - -For a mutable variant, see [go-radix](https://github.com/armon/go-radix). - -Documentation -============= - -The full documentation is available on [Godoc](http://godoc.org/github.com/hashicorp/go-immutable-radix). - -Example -======= - -Below is a simple example of usage - -```go -// Create a tree -r := iradix.New() -r, _, _ = r.Insert([]byte("foo"), 1) -r, _, _ = r.Insert([]byte("bar"), 2) -r, _, _ = r.Insert([]byte("foobar"), 2) - -// Find the longest prefix match -m, _, _ := r.Root().LongestPrefix([]byte("foozip")) -if string(m) != "foo" { - panic("should be foo") -} -``` - diff --git a/vendor/github.com/hashicorp/go-immutable-radix/edges.go b/vendor/github.com/hashicorp/go-immutable-radix/edges.go deleted file mode 100644 index a63674775f2..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/edges.go +++ /dev/null @@ -1,21 +0,0 @@ -package iradix - -import "sort" - -type edges []edge - -func (e edges) Len() int { - return len(e) -} - -func (e edges) Less(i, j int) bool { - return e[i].label < e[j].label -} - -func (e edges) Swap(i, j int) { - e[i], e[j] = e[j], e[i] -} - -func (e edges) Sort() { - sort.Sort(e) -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/iradix.go b/vendor/github.com/hashicorp/go-immutable-radix/iradix.go deleted file mode 100644 index e5e6e57f262..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/iradix.go +++ /dev/null @@ -1,662 +0,0 @@ -package iradix - -import ( - "bytes" - "strings" - - "github.com/hashicorp/golang-lru/simplelru" -) - -const ( - // defaultModifiedCache is the default size of the modified node - // cache used per transaction. This is used to cache the updates - // to the nodes near the root, while the leaves do not need to be - // cached. This is important for very large transactions to prevent - // the modified cache from growing to be enormous. This is also used - // to set the max size of the mutation notify maps since those should - // also be bounded in a similar way. - defaultModifiedCache = 8192 -) - -// Tree implements an immutable radix tree. This can be treated as a -// Dictionary abstract data type. The main advantage over a standard -// hash map is prefix-based lookups and ordered iteration. The immutability -// means that it is safe to concurrently read from a Tree without any -// coordination. -type Tree struct { - root *Node - size int -} - -// New returns an empty Tree -func New() *Tree { - t := &Tree{ - root: &Node{ - mutateCh: make(chan struct{}), - }, - } - return t -} - -// Len is used to return the number of elements in the tree -func (t *Tree) Len() int { - return t.size -} - -// Txn is a transaction on the tree. This transaction is applied -// atomically and returns a new tree when committed. A transaction -// is not thread safe, and should only be used by a single goroutine. -type Txn struct { - // root is the modified root for the transaction. - root *Node - - // snap is a snapshot of the root node for use if we have to run the - // slow notify algorithm. - snap *Node - - // size tracks the size of the tree as it is modified during the - // transaction. - size int - - // writable is a cache of writable nodes that have been created during - // the course of the transaction. This allows us to re-use the same - // nodes for further writes and avoid unnecessary copies of nodes that - // have never been exposed outside the transaction. This will only hold - // up to defaultModifiedCache number of entries. - writable *simplelru.LRU - - // trackChannels is used to hold channels that need to be notified to - // signal mutation of the tree. This will only hold up to - // defaultModifiedCache number of entries, after which we will set the - // trackOverflow flag, which will cause us to use a more expensive - // algorithm to perform the notifications. Mutation tracking is only - // performed if trackMutate is true. - trackChannels map[chan struct{}]struct{} - trackOverflow bool - trackMutate bool -} - -// Txn starts a new transaction that can be used to mutate the tree -func (t *Tree) Txn() *Txn { - txn := &Txn{ - root: t.root, - snap: t.root, - size: t.size, - } - return txn -} - -// TrackMutate can be used to toggle if mutations are tracked. If this is enabled -// then notifications will be issued for affected internal nodes and leaves when -// the transaction is committed. -func (t *Txn) TrackMutate(track bool) { - t.trackMutate = track -} - -// trackChannel safely attempts to track the given mutation channel, setting the -// overflow flag if we can no longer track any more. This limits the amount of -// state that will accumulate during a transaction and we have a slower algorithm -// to switch to if we overflow. -func (t *Txn) trackChannel(ch chan struct{}) { - // In overflow, make sure we don't store any more objects. - if t.trackOverflow { - return - } - - // If this would overflow the state we reject it and set the flag (since - // we aren't tracking everything that's required any longer). - if len(t.trackChannels) >= defaultModifiedCache { - // Mark that we are in the overflow state - t.trackOverflow = true - - // Clear the map so that the channels can be garbage collected. It is - // safe to do this since we have already overflowed and will be using - // the slow notify algorithm. - t.trackChannels = nil - return - } - - // Create the map on the fly when we need it. - if t.trackChannels == nil { - t.trackChannels = make(map[chan struct{}]struct{}) - } - - // Otherwise we are good to track it. - t.trackChannels[ch] = struct{}{} -} - -// writeNode returns a node to be modified, if the current node has already been -// modified during the course of the transaction, it is used in-place. Set -// forLeafUpdate to true if you are getting a write node to update the leaf, -// which will set leaf mutation tracking appropriately as well. -func (t *Txn) writeNode(n *Node, forLeafUpdate bool) *Node { - // Ensure the writable set exists. - if t.writable == nil { - lru, err := simplelru.NewLRU(defaultModifiedCache, nil) - if err != nil { - panic(err) - } - t.writable = lru - } - - // If this node has already been modified, we can continue to use it - // during this transaction. We know that we don't need to track it for - // a node update since the node is writable, but if this is for a leaf - // update we track it, in case the initial write to this node didn't - // update the leaf. - if _, ok := t.writable.Get(n); ok { - if t.trackMutate && forLeafUpdate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - return n - } - - // Mark this node as being mutated. - if t.trackMutate { - t.trackChannel(n.mutateCh) - } - - // Mark its leaf as being mutated, if appropriate. - if t.trackMutate && forLeafUpdate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - - // Copy the existing node. If you have set forLeafUpdate it will be - // safe to replace this leaf with another after you get your node for - // writing. You MUST replace it, because the channel associated with - // this leaf will be closed when this transaction is committed. - nc := &Node{ - mutateCh: make(chan struct{}), - leaf: n.leaf, - } - if n.prefix != nil { - nc.prefix = make([]byte, len(n.prefix)) - copy(nc.prefix, n.prefix) - } - if len(n.edges) != 0 { - nc.edges = make([]edge, len(n.edges)) - copy(nc.edges, n.edges) - } - - // Mark this node as writable. - t.writable.Add(nc, nil) - return nc -} - -// Visit all the nodes in the tree under n, and add their mutateChannels to the transaction -// Returns the size of the subtree visited -func (t *Txn) trackChannelsAndCount(n *Node) int { - // Count only leaf nodes - leaves := 0 - if n.leaf != nil { - leaves = 1 - } - // Mark this node as being mutated. - if t.trackMutate { - t.trackChannel(n.mutateCh) - } - - // Mark its leaf as being mutated, if appropriate. - if t.trackMutate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - - // Recurse on the children - for _, e := range n.edges { - leaves += t.trackChannelsAndCount(e.node) - } - return leaves -} - -// mergeChild is called to collapse the given node with its child. This is only -// called when the given node is not a leaf and has a single edge. -func (t *Txn) mergeChild(n *Node) { - // Mark the child node as being mutated since we are about to abandon - // it. We don't need to mark the leaf since we are retaining it if it - // is there. - e := n.edges[0] - child := e.node - if t.trackMutate { - t.trackChannel(child.mutateCh) - } - - // Merge the nodes. - n.prefix = concat(n.prefix, child.prefix) - n.leaf = child.leaf - if len(child.edges) != 0 { - n.edges = make([]edge, len(child.edges)) - copy(n.edges, child.edges) - } else { - n.edges = nil - } -} - -// insert does a recursive insertion -func (t *Txn) insert(n *Node, k, search []byte, v interface{}) (*Node, interface{}, bool) { - // Handle key exhaustion - if len(search) == 0 { - var oldVal interface{} - didUpdate := false - if n.isLeaf() { - oldVal = n.leaf.val - didUpdate = true - } - - nc := t.writeNode(n, true) - nc.leaf = &leafNode{ - mutateCh: make(chan struct{}), - key: k, - val: v, - } - return nc, oldVal, didUpdate - } - - // Look for the edge - idx, child := n.getEdge(search[0]) - - // No edge, create one - if child == nil { - e := edge{ - label: search[0], - node: &Node{ - mutateCh: make(chan struct{}), - leaf: &leafNode{ - mutateCh: make(chan struct{}), - key: k, - val: v, - }, - prefix: search, - }, - } - nc := t.writeNode(n, false) - nc.addEdge(e) - return nc, nil, false - } - - // Determine longest prefix of the search key on match - commonPrefix := longestPrefix(search, child.prefix) - if commonPrefix == len(child.prefix) { - search = search[commonPrefix:] - newChild, oldVal, didUpdate := t.insert(child, k, search, v) - if newChild != nil { - nc := t.writeNode(n, false) - nc.edges[idx].node = newChild - return nc, oldVal, didUpdate - } - return nil, oldVal, didUpdate - } - - // Split the node - nc := t.writeNode(n, false) - splitNode := &Node{ - mutateCh: make(chan struct{}), - prefix: search[:commonPrefix], - } - nc.replaceEdge(edge{ - label: search[0], - node: splitNode, - }) - - // Restore the existing child node - modChild := t.writeNode(child, false) - splitNode.addEdge(edge{ - label: modChild.prefix[commonPrefix], - node: modChild, - }) - modChild.prefix = modChild.prefix[commonPrefix:] - - // Create a new leaf node - leaf := &leafNode{ - mutateCh: make(chan struct{}), - key: k, - val: v, - } - - // If the new key is a subset, add to to this node - search = search[commonPrefix:] - if len(search) == 0 { - splitNode.leaf = leaf - return nc, nil, false - } - - // Create a new edge for the node - splitNode.addEdge(edge{ - label: search[0], - node: &Node{ - mutateCh: make(chan struct{}), - leaf: leaf, - prefix: search, - }, - }) - return nc, nil, false -} - -// delete does a recursive deletion -func (t *Txn) delete(parent, n *Node, search []byte) (*Node, *leafNode) { - // Check for key exhaustion - if len(search) == 0 { - if !n.isLeaf() { - return nil, nil - } - // Copy the pointer in case we are in a transaction that already - // modified this node since the node will be reused. Any changes - // made to the node will not affect returning the original leaf - // value. - oldLeaf := n.leaf - - // Remove the leaf node - nc := t.writeNode(n, true) - nc.leaf = nil - - // Check if this node should be merged - if n != t.root && len(nc.edges) == 1 { - t.mergeChild(nc) - } - return nc, oldLeaf - } - - // Look for an edge - label := search[0] - idx, child := n.getEdge(label) - if child == nil || !bytes.HasPrefix(search, child.prefix) { - return nil, nil - } - - // Consume the search prefix - search = search[len(child.prefix):] - newChild, leaf := t.delete(n, child, search) - if newChild == nil { - return nil, nil - } - - // Copy this node. WATCH OUT - it's safe to pass "false" here because we - // will only ADD a leaf via nc.mergeChild() if there isn't one due to - // the !nc.isLeaf() check in the logic just below. This is pretty subtle, - // so be careful if you change any of the logic here. - nc := t.writeNode(n, false) - - // Delete the edge if the node has no edges - if newChild.leaf == nil && len(newChild.edges) == 0 { - nc.delEdge(label) - if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() { - t.mergeChild(nc) - } - } else { - nc.edges[idx].node = newChild - } - return nc, leaf -} - -// delete does a recursive deletion -func (t *Txn) deletePrefix(parent, n *Node, search []byte) (*Node, int) { - // Check for key exhaustion - if len(search) == 0 { - nc := t.writeNode(n, true) - if n.isLeaf() { - nc.leaf = nil - } - nc.edges = nil - return nc, t.trackChannelsAndCount(n) - } - - // Look for an edge - label := search[0] - idx, child := n.getEdge(label) - // We make sure that either the child node's prefix starts with the search term, or the search term starts with the child node's prefix - // Need to do both so that we can delete prefixes that don't correspond to any node in the tree - if child == nil || (!bytes.HasPrefix(child.prefix, search) && !bytes.HasPrefix(search, child.prefix)) { - return nil, 0 - } - - // Consume the search prefix - if len(child.prefix) > len(search) { - search = []byte("") - } else { - search = search[len(child.prefix):] - } - newChild, numDeletions := t.deletePrefix(n, child, search) - if newChild == nil { - return nil, 0 - } - // Copy this node. WATCH OUT - it's safe to pass "false" here because we - // will only ADD a leaf via nc.mergeChild() if there isn't one due to - // the !nc.isLeaf() check in the logic just below. This is pretty subtle, - // so be careful if you change any of the logic here. - - nc := t.writeNode(n, false) - - // Delete the edge if the node has no edges - if newChild.leaf == nil && len(newChild.edges) == 0 { - nc.delEdge(label) - if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() { - t.mergeChild(nc) - } - } else { - nc.edges[idx].node = newChild - } - return nc, numDeletions -} - -// Insert is used to add or update a given key. The return provides -// the previous value and a bool indicating if any was set. -func (t *Txn) Insert(k []byte, v interface{}) (interface{}, bool) { - newRoot, oldVal, didUpdate := t.insert(t.root, k, k, v) - if newRoot != nil { - t.root = newRoot - } - if !didUpdate { - t.size++ - } - return oldVal, didUpdate -} - -// Delete is used to delete a given key. Returns the old value if any, -// and a bool indicating if the key was set. -func (t *Txn) Delete(k []byte) (interface{}, bool) { - newRoot, leaf := t.delete(nil, t.root, k) - if newRoot != nil { - t.root = newRoot - } - if leaf != nil { - t.size-- - return leaf.val, true - } - return nil, false -} - -// DeletePrefix is used to delete an entire subtree that matches the prefix -// This will delete all nodes under that prefix -func (t *Txn) DeletePrefix(prefix []byte) bool { - newRoot, numDeletions := t.deletePrefix(nil, t.root, prefix) - if newRoot != nil { - t.root = newRoot - t.size = t.size - numDeletions - return true - } - return false - -} - -// Root returns the current root of the radix tree within this -// transaction. The root is not safe across insert and delete operations, -// but can be used to read the current state during a transaction. -func (t *Txn) Root() *Node { - return t.root -} - -// Get is used to lookup a specific key, returning -// the value and if it was found -func (t *Txn) Get(k []byte) (interface{}, bool) { - return t.root.Get(k) -} - -// GetWatch is used to lookup a specific key, returning -// the watch channel, value and if it was found -func (t *Txn) GetWatch(k []byte) (<-chan struct{}, interface{}, bool) { - return t.root.GetWatch(k) -} - -// Commit is used to finalize the transaction and return a new tree. If mutation -// tracking is turned on then notifications will also be issued. -func (t *Txn) Commit() *Tree { - nt := t.CommitOnly() - if t.trackMutate { - t.Notify() - } - return nt -} - -// CommitOnly is used to finalize the transaction and return a new tree, but -// does not issue any notifications until Notify is called. -func (t *Txn) CommitOnly() *Tree { - nt := &Tree{t.root, t.size} - t.writable = nil - return nt -} - -// slowNotify does a complete comparison of the before and after trees in order -// to trigger notifications. This doesn't require any additional state but it -// is very expensive to compute. -func (t *Txn) slowNotify() { - snapIter := t.snap.rawIterator() - rootIter := t.root.rawIterator() - for snapIter.Front() != nil || rootIter.Front() != nil { - // If we've exhausted the nodes in the old snapshot, we know - // there's nothing remaining to notify. - if snapIter.Front() == nil { - return - } - snapElem := snapIter.Front() - - // If we've exhausted the nodes in the new root, we know we need - // to invalidate everything that remains in the old snapshot. We - // know from the loop condition there's something in the old - // snapshot. - if rootIter.Front() == nil { - close(snapElem.mutateCh) - if snapElem.isLeaf() { - close(snapElem.leaf.mutateCh) - } - snapIter.Next() - continue - } - - // Do one string compare so we can check the various conditions - // below without repeating the compare. - cmp := strings.Compare(snapIter.Path(), rootIter.Path()) - - // If the snapshot is behind the root, then we must have deleted - // this node during the transaction. - if cmp < 0 { - close(snapElem.mutateCh) - if snapElem.isLeaf() { - close(snapElem.leaf.mutateCh) - } - snapIter.Next() - continue - } - - // If the snapshot is ahead of the root, then we must have added - // this node during the transaction. - if cmp > 0 { - rootIter.Next() - continue - } - - // If we have the same path, then we need to see if we mutated a - // node and possibly the leaf. - rootElem := rootIter.Front() - if snapElem != rootElem { - close(snapElem.mutateCh) - if snapElem.leaf != nil && (snapElem.leaf != rootElem.leaf) { - close(snapElem.leaf.mutateCh) - } - } - snapIter.Next() - rootIter.Next() - } -} - -// Notify is used along with TrackMutate to trigger notifications. This must -// only be done once a transaction is committed via CommitOnly, and it is called -// automatically by Commit. -func (t *Txn) Notify() { - if !t.trackMutate { - return - } - - // If we've overflowed the tracking state we can't use it in any way and - // need to do a full tree compare. - if t.trackOverflow { - t.slowNotify() - } else { - for ch := range t.trackChannels { - close(ch) - } - } - - // Clean up the tracking state so that a re-notify is safe (will trigger - // the else clause above which will be a no-op). - t.trackChannels = nil - t.trackOverflow = false -} - -// Insert is used to add or update a given key. The return provides -// the new tree, previous value and a bool indicating if any was set. -func (t *Tree) Insert(k []byte, v interface{}) (*Tree, interface{}, bool) { - txn := t.Txn() - old, ok := txn.Insert(k, v) - return txn.Commit(), old, ok -} - -// Delete is used to delete a given key. Returns the new tree, -// old value if any, and a bool indicating if the key was set. -func (t *Tree) Delete(k []byte) (*Tree, interface{}, bool) { - txn := t.Txn() - old, ok := txn.Delete(k) - return txn.Commit(), old, ok -} - -// DeletePrefix is used to delete all nodes starting with a given prefix. Returns the new tree, -// and a bool indicating if the prefix matched any nodes -func (t *Tree) DeletePrefix(k []byte) (*Tree, bool) { - txn := t.Txn() - ok := txn.DeletePrefix(k) - return txn.Commit(), ok -} - -// Root returns the root node of the tree which can be used for richer -// query operations. -func (t *Tree) Root() *Node { - return t.root -} - -// Get is used to lookup a specific key, returning -// the value and if it was found -func (t *Tree) Get(k []byte) (interface{}, bool) { - return t.root.Get(k) -} - -// longestPrefix finds the length of the shared prefix -// of two strings -func longestPrefix(k1, k2 []byte) int { - max := len(k1) - if l := len(k2); l < max { - max = l - } - var i int - for i = 0; i < max; i++ { - if k1[i] != k2[i] { - break - } - } - return i -} - -// concat two byte slices, returning a third new copy -func concat(a, b []byte) []byte { - c := make([]byte, len(a)+len(b)) - copy(c, a) - copy(c[len(a):], b) - return c -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/iter.go b/vendor/github.com/hashicorp/go-immutable-radix/iter.go deleted file mode 100644 index 9815e02538e..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/iter.go +++ /dev/null @@ -1,91 +0,0 @@ -package iradix - -import "bytes" - -// Iterator is used to iterate over a set of nodes -// in pre-order -type Iterator struct { - node *Node - stack []edges -} - -// SeekPrefixWatch is used to seek the iterator to a given prefix -// and returns the watch channel of the finest granularity -func (i *Iterator) SeekPrefixWatch(prefix []byte) (watch <-chan struct{}) { - // Wipe the stack - i.stack = nil - n := i.node - watch = n.mutateCh - search := prefix - for { - // Check for key exhaution - if len(search) == 0 { - i.node = n - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - i.node = nil - return - } - - // Update to the finest granularity as the search makes progress - watch = n.mutateCh - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - - } else if bytes.HasPrefix(n.prefix, search) { - i.node = n - return - } else { - i.node = nil - return - } - } -} - -// SeekPrefix is used to seek the iterator to a given prefix -func (i *Iterator) SeekPrefix(prefix []byte) { - i.SeekPrefixWatch(prefix) -} - -// Next returns the next node in order -func (i *Iterator) Next() ([]byte, interface{}, bool) { - // Initialize our stack if needed - if i.stack == nil && i.node != nil { - i.stack = []edges{ - edges{ - edge{node: i.node}, - }, - } - } - - for len(i.stack) > 0 { - // Inspect the last element of the stack - n := len(i.stack) - last := i.stack[n-1] - elem := last[0].node - - // Update the stack - if len(last) > 1 { - i.stack[n-1] = last[1:] - } else { - i.stack = i.stack[:n-1] - } - - // Push the edges onto the frontier - if len(elem.edges) > 0 { - i.stack = append(i.stack, elem.edges) - } - - // Return the leaf values if any - if elem.leaf != nil { - return elem.leaf.key, elem.leaf.val, true - } - } - return nil, nil, false -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/node.go b/vendor/github.com/hashicorp/go-immutable-radix/node.go deleted file mode 100644 index 7a065e7a09e..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/node.go +++ /dev/null @@ -1,292 +0,0 @@ -package iradix - -import ( - "bytes" - "sort" -) - -// WalkFn is used when walking the tree. Takes a -// key and value, returning if iteration should -// be terminated. -type WalkFn func(k []byte, v interface{}) bool - -// leafNode is used to represent a value -type leafNode struct { - mutateCh chan struct{} - key []byte - val interface{} -} - -// edge is used to represent an edge node -type edge struct { - label byte - node *Node -} - -// Node is an immutable node in the radix tree -type Node struct { - // mutateCh is closed if this node is modified - mutateCh chan struct{} - - // leaf is used to store possible leaf - leaf *leafNode - - // prefix is the common prefix we ignore - prefix []byte - - // Edges should be stored in-order for iteration. - // We avoid a fully materialized slice to save memory, - // since in most cases we expect to be sparse - edges edges -} - -func (n *Node) isLeaf() bool { - return n.leaf != nil -} - -func (n *Node) addEdge(e edge) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= e.label - }) - n.edges = append(n.edges, e) - if idx != num { - copy(n.edges[idx+1:], n.edges[idx:num]) - n.edges[idx] = e - } -} - -func (n *Node) replaceEdge(e edge) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= e.label - }) - if idx < num && n.edges[idx].label == e.label { - n.edges[idx].node = e.node - return - } - panic("replacing missing edge") -} - -func (n *Node) getEdge(label byte) (int, *Node) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - if idx < num && n.edges[idx].label == label { - return idx, n.edges[idx].node - } - return -1, nil -} - -func (n *Node) delEdge(label byte) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - if idx < num && n.edges[idx].label == label { - copy(n.edges[idx:], n.edges[idx+1:]) - n.edges[len(n.edges)-1] = edge{} - n.edges = n.edges[:len(n.edges)-1] - } -} - -func (n *Node) GetWatch(k []byte) (<-chan struct{}, interface{}, bool) { - search := k - watch := n.mutateCh - for { - // Check for key exhaustion - if len(search) == 0 { - if n.isLeaf() { - return n.leaf.mutateCh, n.leaf.val, true - } - break - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Update to the finest granularity as the search makes progress - watch = n.mutateCh - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } - return watch, nil, false -} - -func (n *Node) Get(k []byte) (interface{}, bool) { - _, val, ok := n.GetWatch(k) - return val, ok -} - -// LongestPrefix is like Get, but instead of an -// exact match, it will return the longest prefix match. -func (n *Node) LongestPrefix(k []byte) ([]byte, interface{}, bool) { - var last *leafNode - search := k - for { - // Look for a leaf node - if n.isLeaf() { - last = n.leaf - } - - // Check for key exhaution - if len(search) == 0 { - break - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } - if last != nil { - return last.key, last.val, true - } - return nil, nil, false -} - -// Minimum is used to return the minimum value in the tree -func (n *Node) Minimum() ([]byte, interface{}, bool) { - for { - if n.isLeaf() { - return n.leaf.key, n.leaf.val, true - } - if len(n.edges) > 0 { - n = n.edges[0].node - } else { - break - } - } - return nil, nil, false -} - -// Maximum is used to return the maximum value in the tree -func (n *Node) Maximum() ([]byte, interface{}, bool) { - for { - if num := len(n.edges); num > 0 { - n = n.edges[num-1].node - continue - } - if n.isLeaf() { - return n.leaf.key, n.leaf.val, true - } else { - break - } - } - return nil, nil, false -} - -// Iterator is used to return an iterator at -// the given node to walk the tree -func (n *Node) Iterator() *Iterator { - return &Iterator{node: n} -} - -// rawIterator is used to return a raw iterator at the given node to walk the -// tree. -func (n *Node) rawIterator() *rawIterator { - iter := &rawIterator{node: n} - iter.Next() - return iter -} - -// Walk is used to walk the tree -func (n *Node) Walk(fn WalkFn) { - recursiveWalk(n, fn) -} - -// WalkPrefix is used to walk the tree under a prefix -func (n *Node) WalkPrefix(prefix []byte, fn WalkFn) { - search := prefix - for { - // Check for key exhaution - if len(search) == 0 { - recursiveWalk(n, fn) - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - - } else if bytes.HasPrefix(n.prefix, search) { - // Child may be under our search prefix - recursiveWalk(n, fn) - return - } else { - break - } - } -} - -// WalkPath is used to walk the tree, but only visiting nodes -// from the root down to a given leaf. Where WalkPrefix walks -// all the entries *under* the given prefix, this walks the -// entries *above* the given prefix. -func (n *Node) WalkPath(path []byte, fn WalkFn) { - search := path - for { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return - } - - // Check for key exhaution - if len(search) == 0 { - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - return - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } -} - -// recursiveWalk is used to do a pre-order walk of a node -// recursively. Returns true if the walk should be aborted -func recursiveWalk(n *Node, fn WalkFn) bool { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return true - } - - // Recurse on the children - for _, e := range n.edges { - if recursiveWalk(e.node, fn) { - return true - } - } - return false -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go b/vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go deleted file mode 100644 index 04814c1323f..00000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/raw_iter.go +++ /dev/null @@ -1,78 +0,0 @@ -package iradix - -// rawIterator visits each of the nodes in the tree, even the ones that are not -// leaves. It keeps track of the effective path (what a leaf at a given node -// would be called), which is useful for comparing trees. -type rawIterator struct { - // node is the starting node in the tree for the iterator. - node *Node - - // stack keeps track of edges in the frontier. - stack []rawStackEntry - - // pos is the current position of the iterator. - pos *Node - - // path is the effective path of the current iterator position, - // regardless of whether the current node is a leaf. - path string -} - -// rawStackEntry is used to keep track of the cumulative common path as well as -// its associated edges in the frontier. -type rawStackEntry struct { - path string - edges edges -} - -// Front returns the current node that has been iterated to. -func (i *rawIterator) Front() *Node { - return i.pos -} - -// Path returns the effective path of the current node, even if it's not actually -// a leaf. -func (i *rawIterator) Path() string { - return i.path -} - -// Next advances the iterator to the next node. -func (i *rawIterator) Next() { - // Initialize our stack if needed. - if i.stack == nil && i.node != nil { - i.stack = []rawStackEntry{ - rawStackEntry{ - edges: edges{ - edge{node: i.node}, - }, - }, - } - } - - for len(i.stack) > 0 { - // Inspect the last element of the stack. - n := len(i.stack) - last := i.stack[n-1] - elem := last.edges[0].node - - // Update the stack. - if len(last.edges) > 1 { - i.stack[n-1].edges = last.edges[1:] - } else { - i.stack = i.stack[:n-1] - } - - // Push the edges onto the frontier. - if len(elem.edges) > 0 { - path := last.path + string(elem.prefix) - i.stack = append(i.stack, rawStackEntry{path, elem.edges}) - } - - i.pos = elem - i.path = last.path + string(elem.prefix) - return - } - - i.pos = nil - i.path = "" -} diff --git a/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/LICENSE deleted file mode 100644 index be2cc4dfb60..00000000000 --- a/vendor/github.com/hashicorp/golang-lru/LICENSE +++ /dev/null @@ -1,362 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go deleted file mode 100644 index 5673773b22b..00000000000 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ /dev/null @@ -1,161 +0,0 @@ -package simplelru - -import ( - "container/list" - "errors" -) - -// EvictCallback is used to get a callback when a cache entry is evicted -type EvictCallback func(key interface{}, value interface{}) - -// LRU implements a non-thread safe fixed size LRU cache -type LRU struct { - size int - evictList *list.List - items map[interface{}]*list.Element - onEvict EvictCallback -} - -// entry is used to hold a value in the evictList -type entry struct { - key interface{} - value interface{} -} - -// NewLRU constructs an LRU of the given size -func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { - if size <= 0 { - return nil, errors.New("Must provide a positive size") - } - c := &LRU{ - size: size, - evictList: list.New(), - items: make(map[interface{}]*list.Element), - onEvict: onEvict, - } - return c, nil -} - -// Purge is used to completely clear the cache. -func (c *LRU) Purge() { - for k, v := range c.items { - if c.onEvict != nil { - c.onEvict(k, v.Value.(*entry).value) - } - delete(c.items, k) - } - c.evictList.Init() -} - -// Add adds a value to the cache. Returns true if an eviction occurred. -func (c *LRU) Add(key, value interface{}) (evicted bool) { - // Check for existing item - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - ent.Value.(*entry).value = value - return false - } - - // Add new item - ent := &entry{key, value} - entry := c.evictList.PushFront(ent) - c.items[key] = entry - - evict := c.evictList.Len() > c.size - // Verify size not exceeded - if evict { - c.removeOldest() - } - return evict -} - -// Get looks up a key's value from the cache. -func (c *LRU) Get(key interface{}) (value interface{}, ok bool) { - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - return ent.Value.(*entry).value, true - } - return -} - -// Contains checks if a key is in the cache, without updating the recent-ness -// or deleting it for being stale. -func (c *LRU) Contains(key interface{}) (ok bool) { - _, ok = c.items[key] - return ok -} - -// Peek returns the key value (or undefined if not found) without updating -// the "recently used"-ness of the key. -func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) { - var ent *list.Element - if ent, ok = c.items[key]; ok { - return ent.Value.(*entry).value, true - } - return nil, ok -} - -// Remove removes the provided key from the cache, returning if the -// key was contained. -func (c *LRU) Remove(key interface{}) (present bool) { - if ent, ok := c.items[key]; ok { - c.removeElement(ent) - return true - } - return false -} - -// RemoveOldest removes the oldest item from the cache. -func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { - ent := c.evictList.Back() - if ent != nil { - c.removeElement(ent) - kv := ent.Value.(*entry) - return kv.key, kv.value, true - } - return nil, nil, false -} - -// GetOldest returns the oldest entry -func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { - ent := c.evictList.Back() - if ent != nil { - kv := ent.Value.(*entry) - return kv.key, kv.value, true - } - return nil, nil, false -} - -// Keys returns a slice of the keys in the cache, from oldest to newest. -func (c *LRU) Keys() []interface{} { - keys := make([]interface{}, len(c.items)) - i := 0 - for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() { - keys[i] = ent.Value.(*entry).key - i++ - } - return keys -} - -// Len returns the number of items in the cache. -func (c *LRU) Len() int { - return c.evictList.Len() -} - -// removeOldest removes the oldest item from the cache. -func (c *LRU) removeOldest() { - ent := c.evictList.Back() - if ent != nil { - c.removeElement(ent) - } -} - -// removeElement is used to remove a given list element from the cache -func (c *LRU) removeElement(e *list.Element) { - c.evictList.Remove(e) - kv := e.Value.(*entry) - delete(c.items, kv.key) - if c.onEvict != nil { - c.onEvict(kv.key, kv.value) - } -} diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go deleted file mode 100644 index 744cac01c63..00000000000 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go +++ /dev/null @@ -1,37 +0,0 @@ -package simplelru - - -// LRUCache is the interface for simple LRU cache. -type LRUCache interface { - // Adds a value to the cache, returns true if an eviction occurred and - // updates the "recently used"-ness of the key. - Add(key, value interface{}) bool - - // Returns key's value from the cache and - // updates the "recently used"-ness of the key. #value, isFound - Get(key interface{}) (value interface{}, ok bool) - - // Check if a key exsists in cache without updating the recent-ness. - Contains(key interface{}) (ok bool) - - // Returns key's value without updating the "recently used"-ness of the key. - Peek(key interface{}) (value interface{}, ok bool) - - // Removes a key from the cache. - Remove(key interface{}) bool - - // Removes the oldest entry from cache. - RemoveOldest() (interface{}, interface{}, bool) - - // Returns the oldest entry from the cache. #key, value, isFound - GetOldest() (interface{}, interface{}, bool) - - // Returns a slice of the keys in the cache, from oldest to newest. - Keys() []interface{} - - // Returns the number of items in the cache. - Len() int - - // Clear all cache entries - Purge() -} diff --git a/vendor/golang.org/x/net/websocket/client.go b/vendor/golang.org/x/net/websocket/client.go deleted file mode 100644 index 69a4ac7eefe..00000000000 --- a/vendor/golang.org/x/net/websocket/client.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "io" - "net" - "net/http" - "net/url" -) - -// DialError is an error that occurs while dialling a websocket server. -type DialError struct { - *Config - Err error -} - -func (e *DialError) Error() string { - return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error() -} - -// NewConfig creates a new WebSocket config for client connection. -func NewConfig(server, origin string) (config *Config, err error) { - config = new(Config) - config.Version = ProtocolVersionHybi13 - config.Location, err = url.ParseRequestURI(server) - if err != nil { - return - } - config.Origin, err = url.ParseRequestURI(origin) - if err != nil { - return - } - config.Header = http.Header(make(map[string][]string)) - return -} - -// NewClient creates a new WebSocket client connection over rwc. -func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) { - br := bufio.NewReader(rwc) - bw := bufio.NewWriter(rwc) - err = hybiClientHandshake(config, br, bw) - if err != nil { - return - } - buf := bufio.NewReadWriter(br, bw) - ws = newHybiClientConn(config, buf, rwc) - return -} - -// Dial opens a new client connection to a WebSocket. -func Dial(url_, protocol, origin string) (ws *Conn, err error) { - config, err := NewConfig(url_, origin) - if err != nil { - return nil, err - } - if protocol != "" { - config.Protocol = []string{protocol} - } - return DialConfig(config) -} - -var portMap = map[string]string{ - "ws": "80", - "wss": "443", -} - -func parseAuthority(location *url.URL) string { - if _, ok := portMap[location.Scheme]; ok { - if _, _, err := net.SplitHostPort(location.Host); err != nil { - return net.JoinHostPort(location.Host, portMap[location.Scheme]) - } - } - return location.Host -} - -// DialConfig opens a new client connection to a WebSocket with a config. -func DialConfig(config *Config) (ws *Conn, err error) { - var client net.Conn - if config.Location == nil { - return nil, &DialError{config, ErrBadWebSocketLocation} - } - if config.Origin == nil { - return nil, &DialError{config, ErrBadWebSocketOrigin} - } - dialer := config.Dialer - if dialer == nil { - dialer = &net.Dialer{} - } - client, err = dialWithDialer(dialer, config) - if err != nil { - goto Error - } - ws, err = NewClient(config, client) - if err != nil { - client.Close() - goto Error - } - return - -Error: - return nil, &DialError{config, err} -} diff --git a/vendor/golang.org/x/net/websocket/dial.go b/vendor/golang.org/x/net/websocket/dial.go deleted file mode 100644 index 2dab943a489..00000000000 --- a/vendor/golang.org/x/net/websocket/dial.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "crypto/tls" - "net" -) - -func dialWithDialer(dialer *net.Dialer, config *Config) (conn net.Conn, err error) { - switch config.Location.Scheme { - case "ws": - conn, err = dialer.Dial("tcp", parseAuthority(config.Location)) - - case "wss": - conn, err = tls.DialWithDialer(dialer, "tcp", parseAuthority(config.Location), config.TlsConfig) - - default: - err = ErrBadScheme - } - return -} diff --git a/vendor/golang.org/x/net/websocket/hybi.go b/vendor/golang.org/x/net/websocket/hybi.go deleted file mode 100644 index 8cffdd16c91..00000000000 --- a/vendor/golang.org/x/net/websocket/hybi.go +++ /dev/null @@ -1,583 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -// This file implements a protocol of hybi draft. -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 - -import ( - "bufio" - "bytes" - "crypto/rand" - "crypto/sha1" - "encoding/base64" - "encoding/binary" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strings" -) - -const ( - websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - - closeStatusNormal = 1000 - closeStatusGoingAway = 1001 - closeStatusProtocolError = 1002 - closeStatusUnsupportedData = 1003 - closeStatusFrameTooLarge = 1004 - closeStatusNoStatusRcvd = 1005 - closeStatusAbnormalClosure = 1006 - closeStatusBadMessageData = 1007 - closeStatusPolicyViolation = 1008 - closeStatusTooBigData = 1009 - closeStatusExtensionMismatch = 1010 - - maxControlFramePayloadLength = 125 -) - -var ( - ErrBadMaskingKey = &ProtocolError{"bad masking key"} - ErrBadPongMessage = &ProtocolError{"bad pong message"} - ErrBadClosingStatus = &ProtocolError{"bad closing status"} - ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"} - ErrNotImplemented = &ProtocolError{"not implemented"} - - handshakeHeader = map[string]bool{ - "Host": true, - "Upgrade": true, - "Connection": true, - "Sec-Websocket-Key": true, - "Sec-Websocket-Origin": true, - "Sec-Websocket-Version": true, - "Sec-Websocket-Protocol": true, - "Sec-Websocket-Accept": true, - } -) - -// A hybiFrameHeader is a frame header as defined in hybi draft. -type hybiFrameHeader struct { - Fin bool - Rsv [3]bool - OpCode byte - Length int64 - MaskingKey []byte - - data *bytes.Buffer -} - -// A hybiFrameReader is a reader for hybi frame. -type hybiFrameReader struct { - reader io.Reader - - header hybiFrameHeader - pos int64 - length int -} - -func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) { - n, err = frame.reader.Read(msg) - if frame.header.MaskingKey != nil { - for i := 0; i < n; i++ { - msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4] - frame.pos++ - } - } - return n, err -} - -func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode } - -func (frame *hybiFrameReader) HeaderReader() io.Reader { - if frame.header.data == nil { - return nil - } - if frame.header.data.Len() == 0 { - return nil - } - return frame.header.data -} - -func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil } - -func (frame *hybiFrameReader) Len() (n int) { return frame.length } - -// A hybiFrameReaderFactory creates new frame reader based on its frame type. -type hybiFrameReaderFactory struct { - *bufio.Reader -} - -// NewFrameReader reads a frame header from the connection, and creates new reader for the frame. -// See Section 5.2 Base Framing protocol for detail. -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2 -func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) { - hybiFrame := new(hybiFrameReader) - frame = hybiFrame - var header []byte - var b byte - // First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits) - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0 - for i := 0; i < 3; i++ { - j := uint(6 - i) - hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0 - } - hybiFrame.header.OpCode = header[0] & 0x0f - - // Second byte. Mask/Payload len(7bits) - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - mask := (b & 0x80) != 0 - b &= 0x7f - lengthFields := 0 - switch { - case b <= 125: // Payload length 7bits. - hybiFrame.header.Length = int64(b) - case b == 126: // Payload length 7+16bits - lengthFields = 2 - case b == 127: // Payload length 7+64bits - lengthFields = 8 - } - for i := 0; i < lengthFields; i++ { - b, err = buf.ReadByte() - if err != nil { - return - } - if lengthFields == 8 && i == 0 { // MSB must be zero when 7+64 bits - b &= 0x7f - } - header = append(header, b) - hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b) - } - if mask { - // Masking key. 4 bytes. - for i := 0; i < 4; i++ { - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b) - } - } - hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length) - hybiFrame.header.data = bytes.NewBuffer(header) - hybiFrame.length = len(header) + int(hybiFrame.header.Length) - return -} - -// A HybiFrameWriter is a writer for hybi frame. -type hybiFrameWriter struct { - writer *bufio.Writer - - header *hybiFrameHeader -} - -func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) { - var header []byte - var b byte - if frame.header.Fin { - b |= 0x80 - } - for i := 0; i < 3; i++ { - if frame.header.Rsv[i] { - j := uint(6 - i) - b |= 1 << j - } - } - b |= frame.header.OpCode - header = append(header, b) - if frame.header.MaskingKey != nil { - b = 0x80 - } else { - b = 0 - } - lengthFields := 0 - length := len(msg) - switch { - case length <= 125: - b |= byte(length) - case length < 65536: - b |= 126 - lengthFields = 2 - default: - b |= 127 - lengthFields = 8 - } - header = append(header, b) - for i := 0; i < lengthFields; i++ { - j := uint((lengthFields - i - 1) * 8) - b = byte((length >> j) & 0xff) - header = append(header, b) - } - if frame.header.MaskingKey != nil { - if len(frame.header.MaskingKey) != 4 { - return 0, ErrBadMaskingKey - } - header = append(header, frame.header.MaskingKey...) - frame.writer.Write(header) - data := make([]byte, length) - for i := range data { - data[i] = msg[i] ^ frame.header.MaskingKey[i%4] - } - frame.writer.Write(data) - err = frame.writer.Flush() - return length, err - } - frame.writer.Write(header) - frame.writer.Write(msg) - err = frame.writer.Flush() - return length, err -} - -func (frame *hybiFrameWriter) Close() error { return nil } - -type hybiFrameWriterFactory struct { - *bufio.Writer - needMaskingKey bool -} - -func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType} - if buf.needMaskingKey { - frameHeader.MaskingKey, err = generateMaskingKey() - if err != nil { - return nil, err - } - } - return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil -} - -type hybiFrameHandler struct { - conn *Conn - payloadType byte -} - -func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (frameReader, error) { - if handler.conn.IsServerConn() { - // The client MUST mask all frames sent to the server. - if frame.(*hybiFrameReader).header.MaskingKey == nil { - handler.WriteClose(closeStatusProtocolError) - return nil, io.EOF - } - } else { - // The server MUST NOT mask all frames. - if frame.(*hybiFrameReader).header.MaskingKey != nil { - handler.WriteClose(closeStatusProtocolError) - return nil, io.EOF - } - } - if header := frame.HeaderReader(); header != nil { - io.Copy(ioutil.Discard, header) - } - switch frame.PayloadType() { - case ContinuationFrame: - frame.(*hybiFrameReader).header.OpCode = handler.payloadType - case TextFrame, BinaryFrame: - handler.payloadType = frame.PayloadType() - case CloseFrame: - return nil, io.EOF - case PingFrame, PongFrame: - b := make([]byte, maxControlFramePayloadLength) - n, err := io.ReadFull(frame, b) - if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { - return nil, err - } - io.Copy(ioutil.Discard, frame) - if frame.PayloadType() == PingFrame { - if _, err := handler.WritePong(b[:n]); err != nil { - return nil, err - } - } - return nil, nil - } - return frame, nil -} - -func (handler *hybiFrameHandler) WriteClose(status int) (err error) { - handler.conn.wio.Lock() - defer handler.conn.wio.Unlock() - w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame) - if err != nil { - return err - } - msg := make([]byte, 2) - binary.BigEndian.PutUint16(msg, uint16(status)) - _, err = w.Write(msg) - w.Close() - return err -} - -func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) { - handler.conn.wio.Lock() - defer handler.conn.wio.Unlock() - w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame) - if err != nil { - return 0, err - } - n, err = w.Write(msg) - w.Close() - return n, err -} - -// newHybiConn creates a new WebSocket connection speaking hybi draft protocol. -func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - if buf == nil { - br := bufio.NewReader(rwc) - bw := bufio.NewWriter(rwc) - buf = bufio.NewReadWriter(br, bw) - } - ws := &Conn{config: config, request: request, buf: buf, rwc: rwc, - frameReaderFactory: hybiFrameReaderFactory{buf.Reader}, - frameWriterFactory: hybiFrameWriterFactory{ - buf.Writer, request == nil}, - PayloadType: TextFrame, - defaultCloseStatus: closeStatusNormal} - ws.frameHandler = &hybiFrameHandler{conn: ws} - return ws -} - -// generateMaskingKey generates a masking key for a frame. -func generateMaskingKey() (maskingKey []byte, err error) { - maskingKey = make([]byte, 4) - if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil { - return - } - return -} - -// generateNonce generates a nonce consisting of a randomly selected 16-byte -// value that has been base64-encoded. -func generateNonce() (nonce []byte) { - key := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - panic(err) - } - nonce = make([]byte, 24) - base64.StdEncoding.Encode(nonce, key) - return -} - -// removeZone removes IPv6 zone identifer from host. -// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080" -func removeZone(host string) string { - if !strings.HasPrefix(host, "[") { - return host - } - i := strings.LastIndex(host, "]") - if i < 0 { - return host - } - j := strings.LastIndex(host[:i], "%") - if j < 0 { - return host - } - return host[:j] + host[i:] -} - -// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of -// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string. -func getNonceAccept(nonce []byte) (expected []byte, err error) { - h := sha1.New() - if _, err = h.Write(nonce); err != nil { - return - } - if _, err = h.Write([]byte(websocketGUID)); err != nil { - return - } - expected = make([]byte, 28) - base64.StdEncoding.Encode(expected, h.Sum(nil)) - return -} - -// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17 -func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) { - bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n") - - // According to RFC 6874, an HTTP client, proxy, or other - // intermediary must remove any IPv6 zone identifier attached - // to an outgoing URI. - bw.WriteString("Host: " + removeZone(config.Location.Host) + "\r\n") - bw.WriteString("Upgrade: websocket\r\n") - bw.WriteString("Connection: Upgrade\r\n") - nonce := generateNonce() - if config.handshakeData != nil { - nonce = []byte(config.handshakeData["key"]) - } - bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n") - bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n") - - if config.Version != ProtocolVersionHybi13 { - return ErrBadProtocolVersion - } - - bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n") - if len(config.Protocol) > 0 { - bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n") - } - // TODO(ukai): send Sec-WebSocket-Extensions. - err = config.Header.WriteSubset(bw, handshakeHeader) - if err != nil { - return err - } - - bw.WriteString("\r\n") - if err = bw.Flush(); err != nil { - return err - } - - resp, err := http.ReadResponse(br, &http.Request{Method: "GET"}) - if err != nil { - return err - } - if resp.StatusCode != 101 { - return ErrBadStatus - } - if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" || - strings.ToLower(resp.Header.Get("Connection")) != "upgrade" { - return ErrBadUpgrade - } - expectedAccept, err := getNonceAccept(nonce) - if err != nil { - return err - } - if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) { - return ErrChallengeResponse - } - if resp.Header.Get("Sec-WebSocket-Extensions") != "" { - return ErrUnsupportedExtensions - } - offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol") - if offeredProtocol != "" { - protocolMatched := false - for i := 0; i < len(config.Protocol); i++ { - if config.Protocol[i] == offeredProtocol { - protocolMatched = true - break - } - } - if !protocolMatched { - return ErrBadWebSocketProtocol - } - config.Protocol = []string{offeredProtocol} - } - - return nil -} - -// newHybiClientConn creates a client WebSocket connection after handshake. -func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn { - return newHybiConn(config, buf, rwc, nil) -} - -// A HybiServerHandshaker performs a server handshake using hybi draft protocol. -type hybiServerHandshaker struct { - *Config - accept []byte -} - -func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) { - c.Version = ProtocolVersionHybi13 - if req.Method != "GET" { - return http.StatusMethodNotAllowed, ErrBadRequestMethod - } - // HTTP version can be safely ignored. - - if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" || - !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { - return http.StatusBadRequest, ErrNotWebSocket - } - - key := req.Header.Get("Sec-Websocket-Key") - if key == "" { - return http.StatusBadRequest, ErrChallengeResponse - } - version := req.Header.Get("Sec-Websocket-Version") - switch version { - case "13": - c.Version = ProtocolVersionHybi13 - default: - return http.StatusBadRequest, ErrBadWebSocketVersion - } - var scheme string - if req.TLS != nil { - scheme = "wss" - } else { - scheme = "ws" - } - c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI()) - if err != nil { - return http.StatusBadRequest, err - } - protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol")) - if protocol != "" { - protocols := strings.Split(protocol, ",") - for i := 0; i < len(protocols); i++ { - c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) - } - } - c.accept, err = getNonceAccept([]byte(key)) - if err != nil { - return http.StatusInternalServerError, err - } - return http.StatusSwitchingProtocols, nil -} - -// Origin parses the Origin header in req. -// If the Origin header is not set, it returns nil and nil. -func Origin(config *Config, req *http.Request) (*url.URL, error) { - var origin string - switch config.Version { - case ProtocolVersionHybi13: - origin = req.Header.Get("Origin") - } - if origin == "" { - return nil, nil - } - return url.ParseRequestURI(origin) -} - -func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) { - if len(c.Protocol) > 0 { - if len(c.Protocol) != 1 { - // You need choose a Protocol in Handshake func in Server. - return ErrBadWebSocketProtocol - } - } - buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n") - buf.WriteString("Upgrade: websocket\r\n") - buf.WriteString("Connection: Upgrade\r\n") - buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n") - if len(c.Protocol) > 0 { - buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n") - } - // TODO(ukai): send Sec-WebSocket-Extensions. - if c.Header != nil { - err := c.Header.WriteSubset(buf, handshakeHeader) - if err != nil { - return err - } - } - buf.WriteString("\r\n") - return buf.Flush() -} - -func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - return newHybiServerConn(c.Config, buf, rwc, request) -} - -// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol. -func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - return newHybiConn(config, buf, rwc, request) -} diff --git a/vendor/golang.org/x/net/websocket/server.go b/vendor/golang.org/x/net/websocket/server.go deleted file mode 100644 index 0895dea1905..00000000000 --- a/vendor/golang.org/x/net/websocket/server.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "fmt" - "io" - "net/http" -) - -func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) { - var hs serverHandshaker = &hybiServerHandshaker{Config: config} - code, err := hs.ReadHandshake(buf.Reader, req) - if err == ErrBadWebSocketVersion { - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion) - buf.WriteString("\r\n") - buf.WriteString(err.Error()) - buf.Flush() - return - } - if err != nil { - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.WriteString(err.Error()) - buf.Flush() - return - } - if handshake != nil { - err = handshake(config, req) - if err != nil { - code = http.StatusForbidden - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.Flush() - return - } - } - err = hs.AcceptHandshake(buf.Writer) - if err != nil { - code = http.StatusBadRequest - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.Flush() - return - } - conn = hs.NewServerConn(buf, rwc, req) - return -} - -// Server represents a server of a WebSocket. -type Server struct { - // Config is a WebSocket configuration for new WebSocket connection. - Config - - // Handshake is an optional function in WebSocket handshake. - // For example, you can check, or don't check Origin header. - // Another example, you can select config.Protocol. - Handshake func(*Config, *http.Request) error - - // Handler handles a WebSocket connection. - Handler -} - -// ServeHTTP implements the http.Handler interface for a WebSocket -func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s.serveWebSocket(w, req) -} - -func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) { - rwc, buf, err := w.(http.Hijacker).Hijack() - if err != nil { - panic("Hijack failed: " + err.Error()) - } - // The server should abort the WebSocket connection if it finds - // the client did not send a handshake that matches with protocol - // specification. - defer rwc.Close() - conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake) - if err != nil { - return - } - if conn == nil { - panic("unexpected nil conn") - } - s.Handler(conn) -} - -// Handler is a simple interface to a WebSocket browser client. -// It checks if Origin header is valid URL by default. -// You might want to verify websocket.Conn.Config().Origin in the func. -// If you use Server instead of Handler, you could call websocket.Origin and -// check the origin in your Handshake func. So, if you want to accept -// non-browser clients, which do not send an Origin header, set a -// Server.Handshake that does not check the origin. -type Handler func(*Conn) - -func checkOrigin(config *Config, req *http.Request) (err error) { - config.Origin, err = Origin(config, req) - if err == nil && config.Origin == nil { - return fmt.Errorf("null origin") - } - return err -} - -// ServeHTTP implements the http.Handler interface for a WebSocket -func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s := Server{Handler: h, Handshake: checkOrigin} - s.serveWebSocket(w, req) -} diff --git a/vendor/golang.org/x/net/websocket/websocket.go b/vendor/golang.org/x/net/websocket/websocket.go deleted file mode 100644 index e242c89a7a1..00000000000 --- a/vendor/golang.org/x/net/websocket/websocket.go +++ /dev/null @@ -1,448 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package websocket implements a client and server for the WebSocket protocol -// as specified in RFC 6455. -// -// This package currently lacks some features found in an alternative -// and more actively maintained WebSocket package: -// -// https://godoc.org/github.com/gorilla/websocket -// -package websocket // import "golang.org/x/net/websocket" - -import ( - "bufio" - "crypto/tls" - "encoding/json" - "errors" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "sync" - "time" -) - -const ( - ProtocolVersionHybi13 = 13 - ProtocolVersionHybi = ProtocolVersionHybi13 - SupportedProtocolVersion = "13" - - ContinuationFrame = 0 - TextFrame = 1 - BinaryFrame = 2 - CloseFrame = 8 - PingFrame = 9 - PongFrame = 10 - UnknownFrame = 255 - - DefaultMaxPayloadBytes = 32 << 20 // 32MB -) - -// ProtocolError represents WebSocket protocol errors. -type ProtocolError struct { - ErrorString string -} - -func (err *ProtocolError) Error() string { return err.ErrorString } - -var ( - ErrBadProtocolVersion = &ProtocolError{"bad protocol version"} - ErrBadScheme = &ProtocolError{"bad scheme"} - ErrBadStatus = &ProtocolError{"bad status"} - ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"} - ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"} - ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"} - ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"} - ErrBadWebSocketVersion = &ProtocolError{"missing or bad WebSocket Version"} - ErrChallengeResponse = &ProtocolError{"mismatch challenge/response"} - ErrBadFrame = &ProtocolError{"bad frame"} - ErrBadFrameBoundary = &ProtocolError{"not on frame boundary"} - ErrNotWebSocket = &ProtocolError{"not websocket protocol"} - ErrBadRequestMethod = &ProtocolError{"bad method"} - ErrNotSupported = &ProtocolError{"not supported"} -) - -// ErrFrameTooLarge is returned by Codec's Receive method if payload size -// exceeds limit set by Conn.MaxPayloadBytes -var ErrFrameTooLarge = errors.New("websocket: frame payload size exceeds limit") - -// Addr is an implementation of net.Addr for WebSocket. -type Addr struct { - *url.URL -} - -// Network returns the network type for a WebSocket, "websocket". -func (addr *Addr) Network() string { return "websocket" } - -// Config is a WebSocket configuration -type Config struct { - // A WebSocket server address. - Location *url.URL - - // A Websocket client origin. - Origin *url.URL - - // WebSocket subprotocols. - Protocol []string - - // WebSocket protocol version. - Version int - - // TLS config for secure WebSocket (wss). - TlsConfig *tls.Config - - // Additional header fields to be sent in WebSocket opening handshake. - Header http.Header - - // Dialer used when opening websocket connections. - Dialer *net.Dialer - - handshakeData map[string]string -} - -// serverHandshaker is an interface to handle WebSocket server side handshake. -type serverHandshaker interface { - // ReadHandshake reads handshake request message from client. - // Returns http response code and error if any. - ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) - - // AcceptHandshake accepts the client handshake request and sends - // handshake response back to client. - AcceptHandshake(buf *bufio.Writer) (err error) - - // NewServerConn creates a new WebSocket connection. - NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn) -} - -// frameReader is an interface to read a WebSocket frame. -type frameReader interface { - // Reader is to read payload of the frame. - io.Reader - - // PayloadType returns payload type. - PayloadType() byte - - // HeaderReader returns a reader to read header of the frame. - HeaderReader() io.Reader - - // TrailerReader returns a reader to read trailer of the frame. - // If it returns nil, there is no trailer in the frame. - TrailerReader() io.Reader - - // Len returns total length of the frame, including header and trailer. - Len() int -} - -// frameReaderFactory is an interface to creates new frame reader. -type frameReaderFactory interface { - NewFrameReader() (r frameReader, err error) -} - -// frameWriter is an interface to write a WebSocket frame. -type frameWriter interface { - // Writer is to write payload of the frame. - io.WriteCloser -} - -// frameWriterFactory is an interface to create new frame writer. -type frameWriterFactory interface { - NewFrameWriter(payloadType byte) (w frameWriter, err error) -} - -type frameHandler interface { - HandleFrame(frame frameReader) (r frameReader, err error) - WriteClose(status int) (err error) -} - -// Conn represents a WebSocket connection. -// -// Multiple goroutines may invoke methods on a Conn simultaneously. -type Conn struct { - config *Config - request *http.Request - - buf *bufio.ReadWriter - rwc io.ReadWriteCloser - - rio sync.Mutex - frameReaderFactory - frameReader - - wio sync.Mutex - frameWriterFactory - - frameHandler - PayloadType byte - defaultCloseStatus int - - // MaxPayloadBytes limits the size of frame payload received over Conn - // by Codec's Receive method. If zero, DefaultMaxPayloadBytes is used. - MaxPayloadBytes int -} - -// Read implements the io.Reader interface: -// it reads data of a frame from the WebSocket connection. -// if msg is not large enough for the frame data, it fills the msg and next Read -// will read the rest of the frame data. -// it reads Text frame or Binary frame. -func (ws *Conn) Read(msg []byte) (n int, err error) { - ws.rio.Lock() - defer ws.rio.Unlock() -again: - if ws.frameReader == nil { - frame, err := ws.frameReaderFactory.NewFrameReader() - if err != nil { - return 0, err - } - ws.frameReader, err = ws.frameHandler.HandleFrame(frame) - if err != nil { - return 0, err - } - if ws.frameReader == nil { - goto again - } - } - n, err = ws.frameReader.Read(msg) - if err == io.EOF { - if trailer := ws.frameReader.TrailerReader(); trailer != nil { - io.Copy(ioutil.Discard, trailer) - } - ws.frameReader = nil - goto again - } - return n, err -} - -// Write implements the io.Writer interface: -// it writes data as a frame to the WebSocket connection. -func (ws *Conn) Write(msg []byte) (n int, err error) { - ws.wio.Lock() - defer ws.wio.Unlock() - w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType) - if err != nil { - return 0, err - } - n, err = w.Write(msg) - w.Close() - return n, err -} - -// Close implements the io.Closer interface. -func (ws *Conn) Close() error { - err := ws.frameHandler.WriteClose(ws.defaultCloseStatus) - err1 := ws.rwc.Close() - if err != nil { - return err - } - return err1 -} - -func (ws *Conn) IsClientConn() bool { return ws.request == nil } -func (ws *Conn) IsServerConn() bool { return ws.request != nil } - -// LocalAddr returns the WebSocket Origin for the connection for client, or -// the WebSocket location for server. -func (ws *Conn) LocalAddr() net.Addr { - if ws.IsClientConn() { - return &Addr{ws.config.Origin} - } - return &Addr{ws.config.Location} -} - -// RemoteAddr returns the WebSocket location for the connection for client, or -// the Websocket Origin for server. -func (ws *Conn) RemoteAddr() net.Addr { - if ws.IsClientConn() { - return &Addr{ws.config.Location} - } - return &Addr{ws.config.Origin} -} - -var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn") - -// SetDeadline sets the connection's network read & write deadlines. -func (ws *Conn) SetDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetDeadline(t) - } - return errSetDeadline -} - -// SetReadDeadline sets the connection's network read deadline. -func (ws *Conn) SetReadDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetReadDeadline(t) - } - return errSetDeadline -} - -// SetWriteDeadline sets the connection's network write deadline. -func (ws *Conn) SetWriteDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetWriteDeadline(t) - } - return errSetDeadline -} - -// Config returns the WebSocket config. -func (ws *Conn) Config() *Config { return ws.config } - -// Request returns the http request upgraded to the WebSocket. -// It is nil for client side. -func (ws *Conn) Request() *http.Request { return ws.request } - -// Codec represents a symmetric pair of functions that implement a codec. -type Codec struct { - Marshal func(v interface{}) (data []byte, payloadType byte, err error) - Unmarshal func(data []byte, payloadType byte, v interface{}) (err error) -} - -// Send sends v marshaled by cd.Marshal as single frame to ws. -func (cd Codec) Send(ws *Conn, v interface{}) (err error) { - data, payloadType, err := cd.Marshal(v) - if err != nil { - return err - } - ws.wio.Lock() - defer ws.wio.Unlock() - w, err := ws.frameWriterFactory.NewFrameWriter(payloadType) - if err != nil { - return err - } - _, err = w.Write(data) - w.Close() - return err -} - -// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores -// in v. The whole frame payload is read to an in-memory buffer; max size of -// payload is defined by ws.MaxPayloadBytes. If frame payload size exceeds -// limit, ErrFrameTooLarge is returned; in this case frame is not read off wire -// completely. The next call to Receive would read and discard leftover data of -// previous oversized frame before processing next frame. -func (cd Codec) Receive(ws *Conn, v interface{}) (err error) { - ws.rio.Lock() - defer ws.rio.Unlock() - if ws.frameReader != nil { - _, err = io.Copy(ioutil.Discard, ws.frameReader) - if err != nil { - return err - } - ws.frameReader = nil - } -again: - frame, err := ws.frameReaderFactory.NewFrameReader() - if err != nil { - return err - } - frame, err = ws.frameHandler.HandleFrame(frame) - if err != nil { - return err - } - if frame == nil { - goto again - } - maxPayloadBytes := ws.MaxPayloadBytes - if maxPayloadBytes == 0 { - maxPayloadBytes = DefaultMaxPayloadBytes - } - if hf, ok := frame.(*hybiFrameReader); ok && hf.header.Length > int64(maxPayloadBytes) { - // payload size exceeds limit, no need to call Unmarshal - // - // set frameReader to current oversized frame so that - // the next call to this function can drain leftover - // data before processing the next frame - ws.frameReader = frame - return ErrFrameTooLarge - } - payloadType := frame.PayloadType() - data, err := ioutil.ReadAll(frame) - if err != nil { - return err - } - return cd.Unmarshal(data, payloadType, v) -} - -func marshal(v interface{}) (msg []byte, payloadType byte, err error) { - switch data := v.(type) { - case string: - return []byte(data), TextFrame, nil - case []byte: - return data, BinaryFrame, nil - } - return nil, UnknownFrame, ErrNotSupported -} - -func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) { - switch data := v.(type) { - case *string: - *data = string(msg) - return nil - case *[]byte: - *data = msg - return nil - } - return ErrNotSupported -} - -/* -Message is a codec to send/receive text/binary data in a frame on WebSocket connection. -To send/receive text frame, use string type. -To send/receive binary frame, use []byte type. - -Trivial usage: - - import "websocket" - - // receive text frame - var message string - websocket.Message.Receive(ws, &message) - - // send text frame - message = "hello" - websocket.Message.Send(ws, message) - - // receive binary frame - var data []byte - websocket.Message.Receive(ws, &data) - - // send binary frame - data = []byte{0, 1, 2} - websocket.Message.Send(ws, data) - -*/ -var Message = Codec{marshal, unmarshal} - -func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) { - msg, err = json.Marshal(v) - return msg, TextFrame, err -} - -func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) { - return json.Unmarshal(msg, v) -} - -/* -JSON is a codec to send/receive JSON data in a frame from a WebSocket connection. - -Trivial usage: - - import "websocket" - - type T struct { - Msg string - Count int - } - - // receive JSON type T - var data T - websocket.JSON.Receive(ws, &data) - - // send JSON type T - websocket.JSON.Send(ws, data) -*/ -var JSON = Codec{jsonMarshal, jsonUnmarshal}