diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..f681036 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,53 @@ +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-aws-SNS + 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 + - varcheck diff --git a/Makefile b/Makefile index 7165e4e..fc3b2d2 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,11 @@ 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 # You can include assets this directory into the bundle. This can be e.g. used to include profile pictures. @@ -12,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 @@ -20,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. @@ -85,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: @@ -114,56 +111,63 @@ 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 --post301 --location $(MM_SERVICESETTINGS_SITEURL) -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 --post301 --location $(MM_SERVICESETTINGS_SITEURL) -H "Authorization: Bearer $(TOKEN)" -X POST $(MM_SERVICESETTINGS_SITEURL)/api/v4/plugins -F "plugin=@dist/$(BUNDLE_NAME)" -F "force=true" > /dev/null && \ - curl -s --post301 --location $(MM_SERVICESETTINGS_SITEURL) -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: +ifneq ($(HAS_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. .PHONY: clean 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 527ff68..1bff1cb 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.12 require ( github.com/google/go-github/v25 v25.1.1 github.com/mattermost/mattermost-server/v5 v5.18.0 + github.com/mholt/archiver/v3 v3.3.0 github.com/pkg/errors v0.8.1 github.com/stretchr/testify v1.4.0 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 diff --git a/go.sum b/go.sum index 0d1dee2..d5d6997 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 h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= @@ -173,6 +183,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= @@ -232,6 +250,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= @@ -253,6 +273,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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -326,6 +347,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/changelog.go b/server/changelog.go index 64fe42f..2a0e588 100644 --- a/server/changelog.go +++ b/server/changelog.go @@ -94,12 +94,7 @@ func (p *Plugin) updateChangelogPost(post *model.Post, userID, org, repo string, if err != nil { p.API.LogError("Failed to fetch data", "err", err.Error()) - var message string - if _, ok := err.(*github.RateLimitError); ok { - message = "Hit rate limit. Please try again later." - } else { - message = "Failed to fetch data. Please try again later. Error: " + err.Error() - } + message := githubErrorHandle(err) post.Props["attachments"].([]*model.SlackAttachment)[0].Text = message } else { var commiter []string @@ -163,3 +158,13 @@ func (p *Plugin) updateChangelogPost(post *model.Post, userID, org, repo string, return } } + +func githubErrorHandle(err error) string { + var message string + if _, ok := err.(*github.RateLimitError); ok { + message = "Hit rate limit. Please try again later." + } else { + message = "Failed to fetch data:" + err.Error() + } + return message +} diff --git a/server/command.go b/server/command.go index 3800041..3c49d2f 100644 --- a/server/command.go +++ b/server/command.go @@ -31,7 +31,7 @@ func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*mo appErr = p.executeHackfestCommand(commandArgs, args) default: return nil, &model.AppError{ - Id: fmt.Sprintf("Unkown command %v", command), + Id: fmt.Sprintf("Unknown command %v", command), StatusCode: http.StatusBadRequest, Where: "p.ExecuteCommand", } diff --git a/server/commiter.go b/server/commiter.go index 93e3c11..4956934 100644 --- a/server/commiter.go +++ b/server/commiter.go @@ -114,12 +114,7 @@ func (p *Plugin) updateCommitersPost(post *model.Post, userID, org, repo string, if err != nil { p.API.LogError("failed to fetch data", "err", err.Error()) - var message string - if _, ok := err.(*github.RateLimitError); ok { - message = "Hit rate limit. Please try again later." - } else { - message = "Failed to fetch data:" + err.Error() - } + message := githubErrorHandle(err) post.Props["attachments"].([]*model.SlackAttachment)[0].Text = message } else { commiter := map[string]int{} diff --git a/server/fetcher.go b/server/fetcher.go index 02af91b..0c66af3 100644 --- a/server/fetcher.go +++ b/server/fetcher.go @@ -140,23 +140,6 @@ func (p *Plugin) fetchCommitsFromRepo(org, repo string, since, until time.Time) return result, nil } -func (p *Plugin) fetchOrgMember(org string) ([]*github.User, error) { - teams, err := p.fetchTeams(org) - if err != nil { - return nil, err - } - - var orgMember []*github.User - for _, team := range teams { - teamMember, err := p.fetchTeamMemberFromTeam(team.GetID()) - if err != nil { - return nil, err - } - orgMember = append(orgMember, teamMember...) - } - return orgMember, nil -} - func (p *Plugin) fetchTeamMemberFromTeam(id int64) ([]*github.User, error) { var result []*github.User opts := &github.TeamListTeamMembersOptions{ diff --git a/server/hackfest.go b/server/hackfest.go index fb373c1..e1ad576 100644 --- a/server/hackfest.go +++ b/server/hackfest.go @@ -108,7 +108,7 @@ func (p *Plugin) listHackfestContributors(args *model.CommandArgs) *model.AppErr org := config.HackfestOrg if org == "" { return &model.AppError{ - Id: "Hackfest organisation not configured. Please contact you system administrator", + Id: "Hackfest organization not configured. Please contact you system administrator", StatusCode: http.StatusBadRequest, Where: "p.ExecuteCommand", } @@ -188,12 +188,7 @@ func (p *Plugin) updateHackfestContributorsPost(post *model.Post, userID, org, r if err != nil { p.API.LogWarn("failed to fetch data", "err", err.Error()) - var message string - if _, ok := err.(*github.RateLimitError); ok { - message = "Hit rate limit. Please try again later." - } else { - message = "Failed to fetch data:" + err.Error() - } + message := githubErrorHandle(err) post.Props["attachments"].([]*model.SlackAttachment)[0].Text = message } else { contributors := map[string]int{} diff --git a/server/manifest.go b/server/manifest.go index 9c56b7a..37fa60a 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.community", + ID: "com.mattermost.community", Version: "0.1.2", }