From ee742699dd876066743ce4ae955b83f157063cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathana=C3=ABl?= Date: Tue, 11 Aug 2020 16:06:25 +0200 Subject: [PATCH] #45 - Integrate GolangCI-lint (#46) --- .golangci.yml | 62 +++++++++++++++++++++ Makefile | 112 ++++++++++++++++++------------------- build/custom.mk | 1 + build/deploy/main.go | 122 +++++++++++++++++++++++++++++++++++++++++ build/manifest/main.go | 24 ++++---- build/setup.mk | 9 +++ go.mod | 1 + go.sum | 25 +++++++++ server/manifest.go | 6 +- server/plugin.go | 5 +- webapp/.eslintrc.json | 5 +- webapp/src/manifest.js | 2 + 12 files changed, 301 insertions(+), 73 deletions(-) create mode 100644 .golangci.yml create mode 100644 build/custom.mk create mode 100644 build/deploy/main.go diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..b1cd892 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,62 @@ +run: + timeout: 5m + modules-download-mode: readonly + +linters-settings: + goconst: + min-len: 2 + min-occurrences: 2 + gofmt: + simplify: true + goimports: + local-prefixes: github.com/mattermost/mattermost-plugin-custom-attributes + golint: + min-confidence: 0 + govet: + check-shadowing: true + enable-all: true + misspell: + locale: US + +linters: + disable-all: true + enable: + - bodyclose + - deadcode + - errcheck + - goconst + - gocritic + - gofmt + - goimports + - golint + - gosec + - gosimple + - govet + - ineffassign + - interfacer + - misspell + - nakedret + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unused + - varcheck + - whitespace + +issues: + exclude-rules: + - path: server/manifest.go + linters: + - deadcode + - unused + - varcheck + - path: server/configuration.go + linters: + - unused + - path: _test\.go + linters: + - bodyclose + - goconst + - scopelint # https://github.com/kyoh86/scopelint/issues/4 \ No newline at end of file diff --git a/Makefile b/Makefile index 403385d..fc3b2d2 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ GO ?= $(shell command -v go 2> /dev/null) NPM ?= $(shell command -v npm 2> /dev/null) CURL ?= $(shell command -v curl 2> /dev/null) MANIFEST_FILE ?= plugin.json +GOPATH ?= $(shell go env GOPATH) +GO_TEST_FLAGS ?= -race +GO_BUILD_FLAGS ?= MM_UTILITIES_DIR ?= ../mattermost-utilities export GO111MODULE=on @@ -14,6 +17,11 @@ include build/setup.mk BUNDLE_NAME ?= $(PLUGIN_ID)-$(PLUGIN_VERSION).tar.gz +# Include custom makefile, if present +ifneq ($(wildcard build/custom.mk),) + include build/custom.mk +endif + ## Checks the code style, tests, builds and bundles the plugin. all: check-style test dist @@ -22,55 +30,34 @@ all: check-style test dist apply: ./build/bin/manifest apply -## Runs govet and gofmt against all packages. +## Runs golangci-lint and eslint. .PHONY: check-style -check-style: webapp/.npminstall gofmt govet +check-style: webapp/.npminstall golangci-lint @echo Checking for style guide compliance ifneq ($(HAS_WEBAPP),) cd webapp && npm run lint endif -## Runs gofmt against all packages. -.PHONY: gofmt -gofmt: -ifneq ($(HAS_SERVER),) - @echo Running gofmt - @for package in $$(go list ./server/...); do \ - echo "Checking "$$package; \ - files=$$(go list -f '{{range .GoFiles}}{{$$.Dir}}/{{.}} {{end}}' $$package); \ - if [ "$$files" ]; then \ - gofmt_output=$$(gofmt -d -s $$files 2>&1); \ - if [ "$$gofmt_output" ]; then \ - echo "$$gofmt_output"; \ - echo "Gofmt failure"; \ - exit 1; \ - fi; \ - fi; \ - done - @echo Gofmt success -endif - -## Runs govet against all packages. -.PHONY: govet -govet: -ifneq ($(HAS_SERVER),) - @echo Running govet - @# Workaroung because you can't install binaries without adding them to go.mod - env GO111MODULE=off $(GO) get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow - $(GO) vet ./server/... - $(GO) vet -vettool=$(GOPATH)/bin/shadow ./server/... - @echo Govet success -endif +## Run golangci-lint on codebase. +.PHONY: golangci-lint +golangci-lint: + @if ! [ -x "$$(command -v golangci-lint)" ]; then \ + echo "golangci-lint is not installed. Please see https://github.com/golangci/golangci-lint#install for installation instructions."; \ + exit 1; \ + fi; \ + + @echo Running golangci-lint + golangci-lint run ./... ## Builds the server, if it exists, including support for multiple architectures. .PHONY: server server: ifneq ($(HAS_SERVER),) mkdir -p server/dist; - cd server && env GOOS=linux GOARCH=amd64 $(GO) build -o dist/plugin-linux-amd64; - cd server && env GOOS=darwin GOARCH=amd64 $(GO) build -o dist/plugin-darwin-amd64; - cd server && env GOOS=windows GOARCH=amd64 $(GO) build -o dist/plugin-windows-amd64.exe; + cd server && env GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-linux-amd64; + cd server && env GOOS=darwin GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-darwin-amd64; + cd server && env GOOS=windows GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -o dist/plugin-windows-amd64.exe; endif ## Ensures NPM dependencies are installed without having to run this all the time. @@ -87,6 +74,14 @@ ifneq ($(HAS_WEBAPP),) cd webapp && $(NPM) run build; endif +## Builds the webapp in debug mode, if it exists. +.PHONY: webapp-debug +webapp-debug: webapp/.npminstall +ifneq ($(HAS_WEBAPP),) + cd webapp && \ + $(NPM) run debug; +endif + ## Generates a tar bundle of the plugin for install. .PHONY: bundle bundle: @@ -116,48 +111,45 @@ endif dist: apply server webapp bundle ## Installs the plugin to a (development) server. +## It uses the API if appropriate environment variables are defined, +## and otherwise falls back to trying to copy the plugin to a sibling mattermost-server directory. .PHONY: deploy deploy: dist -## It uses the API if appropriate environment variables are defined, -## or copying the files directly to a sibling mattermost-server directory. -ifneq ($(and $(MM_SERVICESETTINGS_SITEURL),$(MM_ADMIN_USERNAME),$(MM_ADMIN_PASSWORD),$(CURL)),) - @echo "Installing plugin via API" - $(eval TOKEN := $(shell curl -i -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/users/login -d '{"login_id": "$(MM_ADMIN_USERNAME)", "password": "$(MM_ADMIN_PASSWORD)"}' | grep Token | cut -f2 -d' ' 2> /dev/null)) - @curl -s -H "Authorization: Bearer $(TOKEN)" -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/plugins -F "plugin=@dist/$(BUNDLE_NAME)" -F "force=true" > /dev/null && \ - curl -s -H "Authorization: Bearer $(TOKEN)" -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/plugins/$(PLUGIN_ID)/enable > /dev/null && \ - echo "OK." || echo "Sorry, something went wrong." -else ifneq ($(wildcard ../mattermost-server/.*),) - @echo "Installing plugin via filesystem. Server restart and manual plugin enabling required" - mkdir -p ../mattermost-server/plugins - tar -C ../mattermost-server/plugins -zxvf dist/$(BUNDLE_NAME) -else - @echo "No supported deployment method available. Install plugin manually." -endif + ./build/bin/deploy $(PLUGIN_ID) dist/$(BUNDLE_NAME) + +.PHONY: debug-deploy +debug-deploy: debug-dist deploy + +.PHONY: debug-dist +debug-dist: apply server webapp-debug bundle ## Runs any lints and unit tests defined for the server and webapp, if they exist. .PHONY: test test: webapp/.npminstall ifneq ($(HAS_SERVER),) - $(GO) test -race -v ./server/... + $(GO) test -v $(GO_TEST_FLAGS) ./server/... endif ifneq ($(HAS_WEBAPP),) - cd webapp && $(NPM) run fix; + cd webapp && $(NPM) run fix && $(NPM) run test; endif ## Creates a coverage report for the server code. .PHONY: coverage coverage: webapp/.npminstall ifneq ($(HAS_SERVER),) - $(GO) test -race -coverprofile=server/coverage.txt ./server/... + $(GO) test $(GO_TEST_FLAGS) -coverprofile=server/coverage.txt ./server/... $(GO) tool cover -html=server/coverage.txt endif ## Extract strings for translation from the source code. .PHONY: i18n-extract -i18n-extract: +i18n-extract: ifneq ($(HAS_WEBAPP),) - @[[ -d $(MM_UTILITIES_DIR) ]] || echo "You must clone github.com/mattermost/mattermost-utilities repo in .. to use this command" - @[[ -d $(MM_UTILITIES_DIR) ]] && cd $(MM_UTILITIES_DIR) && npm install && npm run babel && node mmjstool/build/index.js i18n extract-webapp --webapp-dir ../mattermost-plugin-demo/webapp +ifeq ($(HAS_MM_UTILITIES),) + @echo "You must clone github.com/mattermost/mattermost-utilities repo in .. to use this command" +else + cd $(MM_UTILITIES_DIR) && npm install && npm run babel && node mmjstool/build/index.js i18n extract-webapp --webapp-dir $(PWD)/webapp +endif endif ## Clean removes all build artifacts. @@ -165,15 +157,17 @@ endif clean: rm -fr dist/ ifneq ($(HAS_SERVER),) + rm -fr server/coverage.txt rm -fr server/dist endif ifneq ($(HAS_WEBAPP),) rm -fr webapp/.npminstall + rm -fr webapp/junit.xml rm -fr webapp/dist rm -fr webapp/node_modules endif rm -fr build/bin/ -# Help documentatin à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html +# Help documentation à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html help: - @cat Makefile | grep -v '\.PHONY' | grep -v '\help:' | grep -B1 -E '^[a-zA-Z0-9_.-]+:.*' | sed -e "s/:.*//" | sed -e "s/^## //" | grep -v '\-\-' | sed '1!G;h;$$!d' | awk 'NR%2{printf "\033[36m%-30s\033[0m",$$0;next;}1' | sort + @cat Makefile | grep -v '\.PHONY' | grep -v '\help:' | grep -B1 -E '^[a-zA-Z0-9_.-]+:.*' | sed -e "s/:.*//" | sed -e "s/^## //" | grep -v '\-\-' | sed '1!G;h;$$!d' | awk 'NR%2{printf "\033[36m%-30s\033[0m",$$0;next;}1' | sort \ No newline at end of file diff --git a/build/custom.mk b/build/custom.mk new file mode 100644 index 0000000..efad4fb --- /dev/null +++ b/build/custom.mk @@ -0,0 +1 @@ +# Include custome targets and environment variables here diff --git a/build/deploy/main.go b/build/deploy/main.go new file mode 100644 index 0000000..186bb49 --- /dev/null +++ b/build/deploy/main.go @@ -0,0 +1,122 @@ +// main handles deployment of the plugin to a development server using either the Client4 API +// or by copying the plugin bundle into a sibling mattermost-server/plugin directory. +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + + "github.com/mattermost/mattermost-server/v5/model" + "github.com/mholt/archiver/v3" + "github.com/pkg/errors" +) + +func main() { + err := deploy() + if err != nil { + fmt.Printf("Failed to deploy: %s\n", err.Error()) + fmt.Println() + fmt.Println("Usage:") + fmt.Println(" deploy ") + os.Exit(1) + } +} + +// deploy handles deployment of the plugin to a development server. +func deploy() error { + if len(os.Args) < 3 { + return errors.New("invalid number of arguments") + } + + pluginID := os.Args[1] + bundlePath := os.Args[2] + + siteURL := os.Getenv("MM_SERVICESETTINGS_SITEURL") + adminToken := os.Getenv("MM_ADMIN_TOKEN") + adminUsername := os.Getenv("MM_ADMIN_USERNAME") + adminPassword := os.Getenv("MM_ADMIN_PASSWORD") + copyTargetDirectory, _ := filepath.Abs("../mattermost-server") + + if siteURL != "" { + client := model.NewAPIv4Client(siteURL) + + if adminToken != "" { + log.Printf("Authenticating using token against %s.", siteURL) + client.SetToken(adminToken) + + return uploadPlugin(client, pluginID, bundlePath) + } + + if adminUsername != "" && adminPassword != "" { + client := model.NewAPIv4Client(siteURL) + log.Printf("Authenticating as %s against %s.", adminUsername, siteURL) + _, resp := client.Login(adminUsername, adminPassword) + if resp.Error != nil { + return errors.Wrapf(resp.Error, "failed to login as %s", adminUsername) + } + + return uploadPlugin(client, pluginID, bundlePath) + } + } + + _, err := os.Stat(copyTargetDirectory) + if os.IsNotExist(err) { + return errors.New("no supported deployment method available, please install plugin manually") + } else if err != nil { + return errors.Wrapf(err, "failed to stat %s", copyTargetDirectory) + } + + log.Printf("Installing plugin to mattermost-server found in %s.", copyTargetDirectory) + log.Print("Server restart required to load updated plugin.") + return copyPlugin(pluginID, copyTargetDirectory, bundlePath) +} + +// uploadPlugin attempts to upload and enable a plugin via the Client4 API. +// It will fail if plugin uploads are disabled. +func uploadPlugin(client *model.Client4, pluginID, bundlePath string) error { + pluginBundle, err := os.Open(bundlePath) + if err != nil { + return errors.Wrapf(err, "failed to open %s", bundlePath) + } + defer pluginBundle.Close() + + log.Print("Uploading plugin via API.") + _, resp := client.UploadPluginForced(pluginBundle) + if resp.Error != nil { + return errors.Wrap(resp.Error, "failed to upload plugin bundle") + } + + log.Print("Enabling plugin.") + _, resp = client.EnablePlugin(pluginID) + if resp.Error != nil { + return errors.Wrap(resp.Error, "Failed to enable plugin") + } + + return nil +} + +// copyPlugin attempts to install a plugin by copying it to a sibling ../mattermost-server/plugin +// directory. A server restart is required before the plugin will start. +func copyPlugin(pluginID, targetPath, bundlePath string) error { + targetPath = filepath.Join(targetPath, "plugins") + + err := os.MkdirAll(targetPath, 0777) + if err != nil { + return errors.Wrapf(err, "failed to create %s", targetPath) + } + + existingPluginPath := filepath.Join(targetPath, pluginID) + err = os.RemoveAll(existingPluginPath) + if err != nil { + return errors.Wrapf(err, "failed to remove existing existing plugin directory %s", existingPluginPath) + } + + err = archiver.Unarchive(bundlePath, targetPath) + if err != nil { + return errors.Wrapf(err, "failed to unarchive %s into %s", bundlePath, targetPath) + } + + return nil +} diff --git a/build/manifest/main.go b/build/manifest/main.go index 4bf4e19..3227c2a 100644 --- a/build/manifest/main.go +++ b/build/manifest/main.go @@ -10,18 +10,22 @@ import ( "github.com/pkg/errors" ) -const pluginIdGoFileTemplate = `package main +const pluginIDGoFileTemplate = `// This file is automatically generated. Do not modify it manually. + +package main var manifest = struct { - Id string + ID string Version string }{ - Id: "%s", + ID: "%s", Version: "%s", } ` -const pluginIdJsFileTemplate = `export const id = '%s'; +const pluginIDJSFileTemplate = `// This file is automatically generated. Do not modify it manually. + +export const id = '%s'; export const version = '%s'; ` @@ -38,7 +42,7 @@ func main() { cmd := os.Args[1] switch cmd { case "id": - dumpPluginId(manifest) + dumpPluginID(manifest) case "version": dumpPluginVersion(manifest) @@ -87,7 +91,7 @@ func findManifest() (*model.Manifest, error) { } // dumpPluginId writes the plugin id from the given manifest to standard out -func dumpPluginId(manifest *model.Manifest) { +func dumpPluginID(manifest *model.Manifest) { fmt.Printf("%s", manifest.Id) } @@ -101,8 +105,8 @@ func applyManifest(manifest *model.Manifest) error { if manifest.HasServer() { if err := ioutil.WriteFile( "server/manifest.go", - []byte(fmt.Sprintf(pluginIdGoFileTemplate, manifest.Id, manifest.Version)), - 0644, + []byte(fmt.Sprintf(pluginIDGoFileTemplate, manifest.Id, manifest.Version)), + 0600, ); err != nil { return errors.Wrap(err, "failed to write server/manifest.go") } @@ -111,8 +115,8 @@ func applyManifest(manifest *model.Manifest) error { if manifest.HasWebapp() { if err := ioutil.WriteFile( "webapp/src/manifest.js", - []byte(fmt.Sprintf(pluginIdJsFileTemplate, manifest.Id, manifest.Version)), - 0644, + []byte(fmt.Sprintf(pluginIDJSFileTemplate, manifest.Id, manifest.Version)), + 0600, ); err != nil { return errors.Wrap(err, "failed to open webapp/src/manifest.js") } diff --git a/build/setup.mk b/build/setup.mk index 13ece2b..bc1fdc3 100644 --- a/build/setup.mk +++ b/build/setup.mk @@ -7,6 +7,9 @@ endif # Ensure that the build tools are compiled. Go's caching makes this quick. $(shell cd build/manifest && $(GO) build -o ../bin/manifest) +# Ensure that the deployment tools are compiled. Go's caching makes this quick. +$(shell cd build/deploy && $(GO) build -o ../bin/deploy) + # Extract the plugin id from the manifest. PLUGIN_ID ?= $(shell build/bin/manifest id) ifeq ($(PLUGIN_ID),) @@ -28,6 +31,12 @@ HAS_WEBAPP ?= $(shell build/bin/manifest has_webapp) # Determine if a /public folder is in use HAS_PUBLIC ?= $(wildcard public/.) +# Determine if the mattermost-utilities repo is present +HAS_MM_UTILITIES ?= $(wildcard $(MM_UTILITIES_DIR)/.) + +# Store the current path for later use +PWD ?= $(shell pwd) + # Ensure that npm (and thus node) is installed. ifneq ($(HAS_WEBAPP),) ifeq ($(NPM),) diff --git a/go.mod b/go.mod index 67467bd..229239f 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,6 @@ go 1.12 require ( github.com/mattermost/mattermost-server/v5 v5.18.0 + github.com/mholt/archiver/v3 v3.3.0 github.com/pkg/errors v0.8.1 ) diff --git a/go.sum b/go.sum index cd132c2..754d1c5 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6 h1:bZ28Hqta7TFAK3Q08CMvv8y3/8ATaEqv2nGoc6yff6c= +github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -59,6 +61,9 @@ github.com/die-net/lrucache v0.0.0-20181227122439-19a39ef22a11/go.mod h1:ew0MSjC github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= github.com/disintegration/imaging v1.6.1/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 h1:6muCmMJat6z7qptVrIf/+OWPxsjAfvhw5/6t+FwEkgg= github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYia/MIs9OyvXXYboPmNOj0gVWo97Wx0sde+ZuKkoM4= @@ -87,6 +92,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw= +github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= @@ -98,10 +105,13 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -171,6 +181,12 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY= +github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM= +github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -212,6 +228,8 @@ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mholt/archiver/v3 v3.3.0 h1:vWjhY8SQp5yzM9P6OJ/eZEkmi3UAbRrxCq48MxjAzig= +github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08Ebtr1Mqao= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.19/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/minio/minio-go/v6 v6.0.40/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= @@ -233,6 +251,8 @@ github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78Rwc github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= +github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs= +github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -255,6 +275,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/peterbourgon/diskv v0.0.0-20171120014656-2973218375c3/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -335,6 +356,10 @@ github.com/throttled/throttled v2.2.4+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLs github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= diff --git a/server/manifest.go b/server/manifest.go index e6df261..9330054 100644 --- a/server/manifest.go +++ b/server/manifest.go @@ -1,9 +1,11 @@ +// This file is automatically generated. Do not modify it manually. + package main var manifest = struct { - Id string + ID string Version string }{ - Id: "com.mattermost.custom-attributes", + ID: "com.mattermost.custom-attributes", Version: "1.2.0", } diff --git a/server/plugin.go b/server/plugin.go index dd07c8f..83cf889 100644 --- a/server/plugin.go +++ b/server/plugin.go @@ -74,7 +74,10 @@ func (p *Plugin) handleGetAttributes(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") - w.Write(b) + _, err := w.Write(b) + if err != nil { + p.API.LogError("failed to write http response", err.Error()) + } } func sliceContainsString(arr []string, str string) bool { diff --git a/webapp/.eslintrc.json b/webapp/.eslintrc.json index 2c1e0b6..7411fa3 100644 --- a/webapp/.eslintrc.json +++ b/webapp/.eslintrc.json @@ -32,7 +32,10 @@ "beforeEach": true }, "settings": { - "import/resolver": "webpack" + "import/resolver": "webpack", + "react": { + "version": "detect" + } }, "rules": { "array-bracket-spacing": [ diff --git a/webapp/src/manifest.js b/webapp/src/manifest.js index 95d6d87..303bfab 100644 --- a/webapp/src/manifest.js +++ b/webapp/src/manifest.js @@ -1,2 +1,4 @@ +// This file is automatically generated. Do not modify it manually. + export const id = 'com.mattermost.custom-attributes'; export const version = '1.2.0';