diff --git a/.gitignore b/.gitignore index 68d2443..a320d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /*.pem /vendor/ .env +.idea diff --git a/.travis.yml b/.travis.yml index 54eb1fe..582525f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,19 @@ language: go go: - - 1.x +- 1.x # sudo for docker service # https://docs.travis-ci.com/user/docker/ sudo: required services: - - docker +- docker env: - - GOOGLE_APPLICATION_CREDENTIALS=/tmp/gcloud-GopherCI-dev.json +- GOOGLE_APPLICATION_CREDENTIALS=/tmp/gcloud-GopherCI-dev.json before_install: - - openssl aes-256-cbc -K $encrypted_870f8d7239ea_key -iv $encrypted_870f8d7239ea_iv -in GopherCI-dev-81e88eb7fa6e.json.enc -out /tmp/gcloud-GopherCI-dev.json -d - - docker pull gopherci/gopherci-env:latest - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover - - go get github.com/golang/dep/cmd/dep - - make deps +- openssl aes-256-cbc -K $encrypted_870f8d7239ea_key -iv $encrypted_870f8d7239ea_iv -in GopherCI-dev-81e88eb7fa6e.json.enc -out /tmp/gcloud-GopherCI-dev.json -d +- docker pull gopherci/gopherci-env:latest +- go get github.com/mattn/goveralls +- go get golang.org/x/tools/cmd/cover +- go get github.com/golang/dep/cmd/dep +- make deps script: - - $HOME/gopath/bin/goveralls -service=travis-ci +- $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index 2d10377..0000000 --- a/Gopkg.lock +++ /dev/null @@ -1,272 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "cloud.google.com/go" - packages = ["compute/metadata","iam","internal/version","pubsub","pubsub/apiv1"] - revision = "a5913b3f7deecba45e98ff33cefbac4fd204ddd7" - version = "v0.10.0" - -[[projects]] - branch = "master" - name = "github.com/Azure/go-ansiterm" - packages = [".","winterm"] - revision = "19f72df4d05d31cbe1c56bfc8045c96babff6c7e" - -[[projects]] - name = "github.com/Microsoft/go-winio" - packages = ["."] - revision = "7ff89941bcb93df2e962467fb073c6e997b13cf0" - version = "v0.4.4" - -[[projects]] - branch = "master" - name = "github.com/Nvveen/Gotty" - packages = ["."] - revision = "cd527374f1e5bff4938207604a14f2e38a9cf512" - -[[projects]] - name = "github.com/Sirupsen/logrus" - packages = ["."] - revision = "a3f95b5c423586578a4e099b11a46c2479628cac" - version = "1.0.2" - -[[projects]] - name = "github.com/bradleyfalzon/ghinstallation" - packages = ["."] - revision = "14854a3ebfc8004781bd05b3ed37094ea8beb922" - version = "v0.1.0" - -[[projects]] - name = "github.com/bradleyfalzon/revgrep" - packages = ["."] - revision = "08df62e795d7d6c43b15253e1c40973a33eb38e8" - version = "v0.2" - -[[projects]] - name = "github.com/certifi/gocertifi" - packages = ["."] - revision = "3fd9e1adb12b72d2f3f82191d49be9b93c69f67c" - version = "2017.07.27" - -[[projects]] - name = "github.com/dgrijalva/jwt-go" - packages = ["."] - revision = "d2709f9f1f31ebcda9651b03077758c1f3a0018c" - version = "v3.0.0" - -[[projects]] - name = "github.com/docker/docker" - packages = ["api/types","api/types/blkiodev","api/types/container","api/types/filters","api/types/mount","api/types/network","api/types/registry","api/types/strslice","api/types/swarm","api/types/versions","opts","pkg/archive","pkg/fileutils","pkg/homedir","pkg/idtools","pkg/ioutils","pkg/jsonlog","pkg/jsonmessage","pkg/longpath","pkg/pools","pkg/promise","pkg/stdcopy","pkg/system","pkg/term","pkg/term/windows"] - revision = "v17.05.0-ce" - -[[projects]] - name = "github.com/docker/go-connections" - packages = ["nat"] - revision = "990a1a1a70b0da4c4cb70e117971a4f0babfbf1a" - version = "v0.2.1" - -[[projects]] - name = "github.com/docker/go-units" - packages = ["."] - revision = "f2d77a61e3c169b43402a0a1e84f06daf29b8190" - version = "v0.3.1" - -[[projects]] - name = "github.com/evalphobia/logrus_sentry" - packages = ["."] - revision = "9f8f2d05a621e616d9341ac75374eb8402ae0630" - version = "v0.4.1" - -[[projects]] - branch = "master" - name = "github.com/fsouza/go-dockerclient" - packages = ["."] - revision = "8462902e31da1644862169cd142c126223ecb38e" - -[[projects]] - branch = "master" - name = "github.com/getsentry/raven-go" - packages = ["."] - revision = "d175f85701dfbf44cb0510114c9943e665e60907" - -[[projects]] - name = "github.com/go-chi/chi" - packages = [".","middleware"] - revision = "524a020446146841512dd1639e736422e7af53a4" - version = "v3.1.3" - -[[projects]] - name = "github.com/go-sql-driver/mysql" - packages = ["."] - revision = "a0583e0143b1624142adab07e0e97fe106d99561" - version = "v1.3" - -[[projects]] - name = "github.com/gogo/protobuf" - packages = ["proto"] - revision = "100ba4e885062801d56799d78530b73b178a78f3" - version = "v0.4" - -[[projects]] - branch = "master" - name = "github.com/golang/protobuf" - packages = ["proto","protoc-gen-go/descriptor","ptypes","ptypes/any","ptypes/duration","ptypes/empty","ptypes/timestamp"] - revision = "748d386b5c1ea99658fd69fe9f03991ce86a90c1" - -[[projects]] - name = "github.com/google/go-cmp" - packages = ["cmp","cmp/internal/diff","cmp/internal/function","cmp/internal/value"] - revision = "8099a9787ce5dc5984ed879a3bda47dc730a8e97" - version = "v0.1.0" - -[[projects]] - branch = "master" - name = "github.com/google/go-github" - packages = ["github"] - revision = "6afafa88c26eb51b33a8307c944bd2f0ef227af7" - -[[projects]] - branch = "master" - name = "github.com/google/go-querystring" - packages = ["query"] - revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a" - -[[projects]] - branch = "master" - name = "github.com/googleapis/gax-go" - packages = ["."] - revision = "84ed26760e7f6f80887a2fbfb50db3cc415d2cea" - -[[projects]] - branch = "master" - name = "github.com/hashicorp/go-cleanhttp" - packages = ["."] - revision = "3573b8b52aa7b37b9358d966a898feb387f62437" - -[[projects]] - branch = "master" - name = "github.com/jmoiron/sqlx" - packages = [".","reflectx"] - revision = "d9bd385d68c068f1fabb5057e3dedcbcbb039d0f" - -[[projects]] - name = "github.com/joho/godotenv" - packages = ["."] - revision = "726cc8b906e3d31c70a9671c90a13716a8d3f50d" - version = "v1.1" - -[[projects]] - name = "github.com/opencontainers/runc" - packages = ["libcontainer/system","libcontainer/user"] - revision = "baf6536d6259209c3edfa2b22237af82942d3dfa" - version = "v0.1.1" - -[[projects]] - name = "github.com/pkg/errors" - packages = ["."] - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - branch = "master" - name = "github.com/rubenv/sql-migrate" - packages = [".","sqlparse"] - revision = "72a5478faa469f9023cc1802367cddfc5270acbb" - -[[projects]] - branch = "master" - name = "github.com/sethgrid/pester" - packages = ["."] - revision = "99271bb5a99e5769f688c483eabb3c22d71ebf93" - -[[projects]] - name = "github.com/sirupsen/logrus" - packages = ["."] - revision = "a3f95b5c423586578a4e099b11a46c2479628cac" - version = "1.0.2" - -[[projects]] - branch = "master" - name = "golang.org/x/net" - packages = ["context","context/ctxhttp","http2","http2/hpack","idna","internal/timeseries","lex/httplex","trace"] - revision = "f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f" - -[[projects]] - branch = "master" - name = "golang.org/x/oauth2" - packages = [".","google","internal","jws","jwt"] - revision = "b53b38ad8a6435bd399ea76d0fa74f23149cca4e" - -[[projects]] - branch = "master" - name = "golang.org/x/sync" - packages = ["errgroup","semaphore"] - revision = "f52d1811a62927559de87708c8913c1650ce4f26" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix","windows"] - revision = "02a66801d979d706a4b445e24e03916eeaa2a404" - -[[projects]] - branch = "master" - name = "golang.org/x/text" - packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"] - revision = "836efe42bb4aa16aaa17b9c155d8813d336ed720" - -[[projects]] - branch = "master" - name = "google.golang.org/api" - packages = ["googleapi/transport","internal","iterator","option","support/bundler","transport","transport/grpc","transport/http"] - revision = "66dba45b06824cbfe030e696b156d562994531e1" - -[[projects]] - name = "google.golang.org/appengine" - packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/socket","internal/urlfetch","socket","urlfetch"] - revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" - version = "v1.0.0" - -[[projects]] - branch = "master" - name = "google.golang.org/genproto" - packages = ["googleapis/api/annotations","googleapis/iam/v1","googleapis/pubsub/v1","googleapis/rpc/status","protobuf/field_mask"] - revision = "b0a3dcfcd1a9bd48e63634bd8802960804cf8315" - -[[projects]] - name = "google.golang.org/grpc" - packages = [".","codes","credentials","credentials/oauth","grpclb/grpc_lb_v1","grpclog","internal","keepalive","metadata","naming","peer","stats","status","tap","transport"] - revision = "172ccacff3cfbddedcf1ba5ea06cda943bc976c1" - version = "v1.5.0" - -[[projects]] - name = "gopkg.in/gorp.v1" - packages = ["."] - revision = "c87af80f3cc5036b55b83d77171e156791085e2e" - version = "v1.7.1" - -[[projects]] - branch = "v1" - name = "gopkg.in/yaml.v1" - packages = ["."] - revision = "9f9df34309c04878acc86042b16630b0f696e1de" - -[[projects]] - branch = "master" - name = "sourcegraph.com/sourcegraph/go-diff" - packages = ["diff"] - revision = "748a069ce7626ea59d76c3b5786b4281b7cfc98d" - -[[projects]] - branch = "master" - name = "sourcegraph.com/sqs/pbtypes" - packages = ["."] - revision = "4d1b9dc7ffc3f7b555de9b02055fa616f0ebcd18" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "9f895e48b0f7c281dd14a0bca17d8427e5535ccbbd72f018272fb0c4186093db" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index cb06cf8..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,98 +0,0 @@ - -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - - -[[constraint]] - name = "cloud.google.com/go" - version = "0.10.0" - -[[constraint]] - name = "github.com/bradleyfalzon/ghinstallation" - version = "0.1.0" - -[[constraint]] - name = "github.com/bradleyfalzon/revgrep" - version = "0.2.0" - -[[override]] - revision = "v17.05.0-ce" - name = "github.com/docker/docker" - -[[constraint]] - branch = "master" - name = "github.com/fsouza/go-dockerclient" - -[[constraint]] - name = "github.com/go-chi/chi" - version = "3.1.3" - -[[constraint]] - name = "github.com/go-sql-driver/mysql" - version = "1.3.0" - -[[constraint]] - branch = "master" - name = "github.com/google/go-github" - -[[constraint]] - branch = "master" - name = "github.com/jmoiron/sqlx" - -[[constraint]] - name = "github.com/joho/godotenv" - version = "1.1.0" - -[[constraint]] - name = "github.com/pkg/errors" - version = "0.8.0" - -[[constraint]] - branch = "master" - name = "github.com/rubenv/sql-migrate" - -[[constraint]] - branch = "master" - name = "github.com/sethgrid/pester" - -[[constraint]] - branch = "master" - name = "golang.org/x/net" - -[[constraint]] - branch = "master" - name = "golang.org/x/oauth2" - -[[constraint]] - branch = "master" - name = "golang.org/x/sys" - -[[constraint]] - name = "google.golang.org/grpc" - version = "1.5.0" - -[[constraint]] - branch = "v1" - name = "gopkg.in/yaml.v1" - -[[constraint]] - branch = "master" - name = "sourcegraph.com/sourcegraph/go-diff" diff --git a/Makefile b/Makefile index 1f7c6f9..3a52dae 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ deps: - dep ensure + glide install mkdir -p ${GOPATH}/src/github.com/Sirupsen mv vendor/github.com/Sirupsen/logrus ${GOPATH}/src/github.com/Sirupsen diff --git a/glide.lock b/glide.lock new file mode 100644 index 0000000..33bcd0d --- /dev/null +++ b/glide.lock @@ -0,0 +1,275 @@ +hash: 50be5d41f30848267b9e3378822f3fbfe382dcf5189bfe83d2446b2128194004 +updated: 2018-10-11T12:23:49.672724+11:00 +imports: +- name: cloud.google.com/go + version: dfffe386c33fb24c34ee501e5723df5b97b98514 + subpackages: + - compute/metadata + - iam + - internal/optional + - internal/version + - pubsub + - pubsub/apiv1 + - pubsub/internal/distribution +- name: github.com/Azure/go-ansiterm + version: d6e3b3328b783f23731bc4d058875b0371ff8109 + subpackages: + - winterm +- name: github.com/bradleyfalzon/ghinstallation + version: 3f4e9b1898e6b65e31827d5dccb97d91d59feaa3 +- name: github.com/bradleyfalzon/revgrep + version: c04006dc3307c8768bda7a33c7c15d1c6f664e14 +- name: github.com/certifi/gocertifi + version: ee1a9a0726d2ae45f54118cac878c990d4016ded +- name: github.com/containerd/continuity + version: be9bd761db19d4fc551d40be908f02e00487511d + subpackages: + - pathdriver +- name: github.com/dgrijalva/jwt-go + version: 3af4c746e1c248ee8491a3e0c6f7a9cd831e95f8 +- name: github.com/docker/docker + version: 5d82d77a6df0c95bb5986ace1255de424c700b33 + subpackages: + - api/types + - api/types/blkiodev + - api/types/container + - api/types/filters + - api/types/mount + - api/types/network + - api/types/registry + - api/types/strslice + - api/types/swarm + - api/types/swarm/runtime + - api/types/versions + - errdefs + - opts + - pkg/fileutils + - pkg/homedir + - pkg/idtools + - pkg/ioutils + - pkg/longpath + - pkg/mount + - pkg/pools + - pkg/stdcopy + - pkg/system +- name: github.com/docker/go-connections + version: 97c2040d34dfae1d1b1275fa3a78dbdd2f41cf7e + subpackages: + - nat +- name: github.com/docker/go-units + version: 47565b4f722fb6ceae66b95f853feed578a4a51c +- name: github.com/docker/libnetwork + version: 87fe5db676712bf4bd772f4d9913822e8c704cb9 + subpackages: + - ipamutils +- name: github.com/evalphobia/logrus_sentry + version: b78b27461c8163c45abf4ab3a8330d2b1ee9456a +- name: github.com/fsouza/go-dockerclient + version: f3bdb27a96799b10006a884ef2fed89284466276 + subpackages: + - internal/archive + - internal/jsonmessage + - internal/term +- name: github.com/getsentry/raven-go + version: 084a9de9eb0361fbd5ded14b55c84e5493a5d7f6 +- name: github.com/go-chi/chi + version: b5294d10673813fac8558e7f47242bc9e61b4c25 + subpackages: + - middleware +- name: github.com/go-sql-driver/mysql + version: d523deb1b23d913de5bdada721a6071e71283618 +- name: github.com/gogo/protobuf + version: fd322a3c49630fe6d05737e2b7d9426e6680e28d + subpackages: + - proto +- name: github.com/golang/protobuf + version: ddf22928ea3c56eb4292a0adbbf5001b1e8e7d0d + subpackages: + - proto + - protoc-gen-go/descriptor + - ptypes + - ptypes/any + - ptypes/duration + - ptypes/empty + - ptypes/timestamp +- name: github.com/google/go-github + version: f55b50f38167644bb7e4be03d9a2bde71d435239 + subpackages: + - github +- name: github.com/google/go-querystring + version: 44c6ddd0a2342c386950e880b658017258da92fc + subpackages: + - query +- name: github.com/googleapis/gax-go + version: 1ef592c90f479e3ab30c6c2312e20e13881b7ea6 +- name: github.com/jmoiron/sqlx + version: 0dae4fefe7c0e190f7b5a78dac28a1c82cc8d849 + subpackages: + - reflectx +- name: github.com/joho/godotenv + version: 23d116af351c84513e1946b527c88823e476be13 +- name: github.com/konsorten/go-windows-terminal-sequences + version: 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 +- name: github.com/Microsoft/go-winio + version: 97e4973ce50b2ff5f09635a57e2b88a037aae829 +- name: github.com/Nvveen/Gotty + version: cd527374f1e5bff4938207604a14f2e38a9cf512 +- name: github.com/opencontainers/go-digest + version: c9281466c8b2f606084ac71339773efd177436e7 +- name: github.com/opencontainers/image-spec + version: 7b1e489870acb042978a3935d2fb76f8a79aff81 + subpackages: + - specs-go + - specs-go/v1 +- name: github.com/opencontainers/runc + version: e40d4635c441b9b9ed3deb6fb2cfb8ff3605096b + subpackages: + - libcontainer/user +- name: github.com/pkg/errors + version: 645ef00459ed84a119197bfb8d8205042c6df63d +- name: github.com/rubenv/sql-migrate + version: 3f452fc0ebebbb784fdab91f7bc79a31dcacab5c + subpackages: + - sqlparse +- name: github.com/sethgrid/pester + version: 03e26c9abbbf5accb8349790bf9f41bde09d72c3 +- name: github.com/sirupsen/logrus + version: ad15b42461921f1fb3529b058c6786c6a45d5162 +- name: go.opencensus.io + version: ae36bd8445ff9cde752c94cf0d4f3f9dced1facc + subpackages: + - exemplar + - internal + - internal/tagencoding + - plugin/ocgrpc + - plugin/ochttp + - plugin/ochttp/propagation/b3 + - stats + - stats/internal + - stats/view + - tag + - trace + - trace/internal + - trace/propagation + - trace/tracestate +- name: golang.org/x/crypto + version: 7c1a557ab941a71c619514f229f0b27ccb0c27cf + subpackages: + - ssh/terminal +- name: golang.org/x/net + version: 146acd28ed5894421fb5aac80ca93bc1b1f46f87 + subpackages: + - context + - context/ctxhttp + - http/httpguts + - http2 + - http2/hpack + - idna + - internal/timeseries + - trace +- name: golang.org/x/oauth2 + version: c57b0facaced709681d9f90397429b9430a74754 + subpackages: + - google + - internal + - jws + - jwt +- name: golang.org/x/sync + version: 1d60e4601c6fd243af51cc01ddf169918a5407ca + subpackages: + - errgroup + - semaphore +- name: golang.org/x/sys + version: 4497e2df6f9e69048a54498c7affbbec3294ad47 + subpackages: + - unix + - windows +- name: golang.org/x/text + version: 4d1c5fb19474adfe9562c9847ba425e7da817e81 + subpackages: + - secure/bidirule + - transform + - unicode/bidi + - unicode/norm +- name: google.golang.org/api + version: ce4acf611b3920b111e21272a15ddaea10c1fd2e + subpackages: + - googleapi/transport + - internal + - iterator + - option + - support/bundler + - transport + - transport/grpc + - transport/http + - transport/http/internal/propagation +- name: google.golang.org/appengine + version: ae0ab99deb4dc413a2b4bd6c8bdd0eb67f1e4d06 + subpackages: + - cloudsql + - internal + - internal/app_identity + - internal/base + - internal/datastore + - internal/log + - internal/modules + - internal/remote_api + - internal/socket + - internal/urlfetch + - socket + - urlfetch +- name: google.golang.org/genproto + version: af9cb2a35e7f169ec875002c1829c9b315cddc04 + subpackages: + - googleapis/api/annotations + - googleapis/iam/v1 + - googleapis/pubsub/v1 + - googleapis/rpc/status + - protobuf/field_mask +- name: google.golang.org/grpc + version: 8dea3dc473e90c8179e519d91302d0597c0ca1d1 + subpackages: + - balancer + - balancer/base + - balancer/roundrobin + - codes + - connectivity + - credentials + - credentials/oauth + - encoding + - encoding/proto + - grpclog + - internal + - internal/backoff + - internal/channelz + - internal/envconfig + - internal/grpcrand + - internal/transport + - keepalive + - metadata + - naming + - peer + - resolver + - resolver/dns + - resolver/passthrough + - stats + - status + - tap +- name: gopkg.in/gorp.v1 + version: c87af80f3cc5036b55b83d77171e156791085e2e +- name: gopkg.in/yaml.v1 + version: 5420a8b6744d3b0345ab293f6fcba19c978f1183 +- name: sourcegraph.com/sourcegraph/go-diff + version: c613306ac97fb4807862c088149199f0dab8685a + subpackages: + - diff +- name: sourcegraph.com/sqs/pbtypes + version: 688c2c2cb411327a50aae0f89119af9f38b0fc03 +testImports: +- name: github.com/google/go-cmp + version: 3af367b6b30c263d47e8895973edcca9a49cf029 + subpackages: + - cmp + - cmp/internal/diff + - cmp/internal/function + - cmp/internal/value diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 0000000..e3a7dff --- /dev/null +++ b/glide.yaml @@ -0,0 +1,56 @@ +package: github.com/bradleyfalzon/gopherci +import: +- package: cloud.google.com/go + version: ^0.30.0 + subpackages: + - pubsub +- package: github.com/bradleyfalzon/ghinstallation + version: ^0.1.2 +- package: github.com/bradleyfalzon/revgrep + version: ^0.3.0 +- package: github.com/evalphobia/logrus_sentry + version: ^0.4.6 +- package: github.com/fsouza/go-dockerclient + version: ^1.3.1 +- package: github.com/go-chi/chi + version: ^3.3.3 + subpackages: + - middleware +- package: github.com/go-sql-driver/mysql + version: ^1.4.0 +- package: github.com/google/go-github + version: ^18.2.0 + subpackages: + - github +- package: github.com/jmoiron/sqlx +- package: github.com/joho/godotenv + version: ^1.3.0 +- package: github.com/pkg/errors + version: ^0.8.0 +- package: github.com/rubenv/sql-migrate +- package: github.com/sethgrid/pester + version: ^1.0.0 +- package: github.com/sirupsen/logrus + version: ^1.1.1 +- package: golang.org/x/net + subpackages: + - context +- package: golang.org/x/sys + subpackages: + - unix +- package: google.golang.org/grpc + version: ^1.15.0 + subpackages: + - codes +- package: gopkg.in/yaml.v1 + version: ^2.2.1 +- package: sourcegraph.com/sourcegraph/go-diff + version: ^0.5.0 + subpackages: + - diff +testImport: +- package: github.com/google/go-cmp + version: ^0.2.0 + subpackages: + - cmp +- package: golang.org/x/oauth2 diff --git a/health-check.go b/health-check.go index 558d6af..80a73be 100644 --- a/health-check.go +++ b/health-check.go @@ -39,7 +39,7 @@ func SignalHandler(logger logger.Logger, cancel context.CancelFunc, srv *http.Se // HealthCheckHandler checks whether the instance is shutting down, and if so, // responds with 503 Service Unavailable. -func HealthCheckHandler(w http.ResponseWriter, r *http.Request) { +func HealthCheckHandler(w http.ResponseWriter, _ *http.Request) { if shuttingDown { http.Error(w, "Service shutting down", http.StatusServiceUnavailable) } diff --git a/internal/analyser/analyser.go b/internal/analyser/analyser.go index 25cc0d5..4089de6 100644 --- a/internal/analyser/analyser.go +++ b/internal/analyser/analyser.go @@ -165,7 +165,7 @@ func Analyse(ctx context.Context, logger logger.Logger, exec Executer, cloner Cl var issues []db.Issue for _, issue := range revIssues { - // Remove issues in generated files, isFileGenereated will return + // Remove issues in generated files, isFileGenerated will return // 0 for file is generated or 1 for file is not generated. args = []string{"isFileGenerated", pwd, issue.File} out, err := exec.Execute(ctx, args) diff --git a/internal/analyser/analyser_test.go b/internal/analyser/analyser_test.go index 4398b92..f9a4d24 100644 --- a/internal/analyser/analyser_test.go +++ b/internal/analyser/analyser_test.go @@ -114,8 +114,8 @@ index 0000000..6362395 } want := map[db.ToolID][]db.Issue{ - 1: []db.Issue{{Path: "main.go", Line: 1, HunkPos: 1, Issue: "Name1: error1"}}, - 2: []db.Issue{{Path: "main.go", Line: 1, HunkPos: 1, Issue: "Name2: error2"}}, + 1: {{Path: "main.go", Line: 1, HunkPos: 1, Issue: "Name1: error1"}}, + 2: {{Path: "main.go", Line: 1, HunkPos: 1, Issue: "Name2: error2"}}, 3: nil, } for toolID, issues := range want { diff --git a/internal/analyser/configReader.go b/internal/analyser/configReader.go index dbaf8cf..5582b15 100644 --- a/internal/analyser/configReader.go +++ b/internal/analyser/configReader.go @@ -3,7 +3,7 @@ package analyser import ( "context" - yaml "gopkg.in/yaml.v1" + "gopkg.in/yaml.v1" "github.com/bradleyfalzon/gopherci/internal/db" "github.com/pkg/errors" diff --git a/internal/analyser/docker.go b/internal/analyser/docker.go index 5558621..b40dd2e 100644 --- a/internal/analyser/docker.go +++ b/internal/analyser/docker.go @@ -9,7 +9,7 @@ import ( "time" "github.com/bradleyfalzon/gopherci/internal/logger" - docker "github.com/fsouza/go-dockerclient" + "github.com/fsouza/go-dockerclient" "github.com/pkg/errors" ) diff --git a/internal/db/db.go b/internal/db/db.go index 48388b2..96ae138 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -10,19 +10,19 @@ import ( // DB interface provides access to a persistent database. type DB interface { // AddGHInstallation records a new installation. - AddGHInstallation(installationID, accountID, senderID int) error + AddGHInstallation(installationID, accountID, senderID int64) error // RemoveGHInstallation removes an installation. - RemoveGHInstallation(installationID int) error + RemoveGHInstallation(installationID int64) error // GetGHInstallation returns an installation for a given installationID, returns // nil if no installation was found, or an error occurs. - GetGHInstallation(installationID int) (*GHInstallation, error) + GetGHInstallation(installationID int64) (*GHInstallation, error) // ListTools returns all tools. Returns nil if no tools were found, error will // be non-nil if an error occurs. ListTools() ([]Tool, error) // StartAnalysis records a new analysis. RequestNumber is a GitHub Pull Request // ID (or Merge Request) and may be 0 for none, if 0 commitTo must be set, // but commitFrom may be blank if this is the first push. - StartAnalysis(ghInstallationID, repositoryID int, commitFrom, commitTo string, requestNumber int) (*Analysis, error) + StartAnalysis(ghInstallationID, repositoryID int64, commitFrom, commitTo string, requestNumber int) (*Analysis, error) // FinishAnalysis marks a status as finished. FinishAnalysis(analysisID int, status AnalysisStatus, analysis *Analysis) error // GetAnalysis returns an analysis for a given analysisID, returns nil if no @@ -70,10 +70,10 @@ func (s *AnalysisStatus) Scan(value interface{}) error { // GHInstallation represents a row from the gh_installations table. type GHInstallation struct { - ID int - InstallationID int - AccountID int - SenderID int + ID int64 + InstallationID int64 + AccountID int64 + SenderID int64 enabledAt time.Time } @@ -134,7 +134,7 @@ type Output struct { // Analysis represents a single analysis of a repository at a point in time. type Analysis struct { ID int `db:"id"` - InstallationID int `db:"installation_id"` + InstallationID int64 `db:"installation_id"` RepositoryID int `db:"repository_id"` CommitFrom string `db:"commit_from"` CommitTo string `db:"commit_to"` diff --git a/internal/db/mockdb.go b/internal/db/mockdb.go index 2e269d0..ce6df0d 100644 --- a/internal/db/mockdb.go +++ b/internal/db/mockdb.go @@ -5,7 +5,7 @@ import "time" // MockDB is an in-memory database repository implementing the DB interface // used for testing type MockDB struct { - installations map[int]GHInstallation // installationID -> exists + installations map[int64]GHInstallation // installationID -> exists err error Tools []Tool } @@ -16,7 +16,7 @@ var _ DB = (*MockDB)(nil) // NewMockDB returns an MockDB func NewMockDB() *MockDB { return &MockDB{ - installations: make(map[int]GHInstallation), + installations: make(map[int64]GHInstallation), } } @@ -26,7 +26,7 @@ func (db *MockDB) ForceError(err error) { } // AddGHInstallation implements DB interface -func (db *MockDB) AddGHInstallation(installationID, accountID, senderID int) error { +func (db *MockDB) AddGHInstallation(installationID, accountID, senderID int64) error { db.installations[installationID] = GHInstallation{ InstallationID: installationID, AccountID: accountID, @@ -36,13 +36,13 @@ func (db *MockDB) AddGHInstallation(installationID, accountID, senderID int) err } // RemoveGHInstallation implements DB interface -func (db *MockDB) RemoveGHInstallation(installationID int) error { +func (db *MockDB) RemoveGHInstallation(installationID int64) error { delete(db.installations, installationID) return db.err } // EnableGHInstallation enables a gh installation -func (db *MockDB) EnableGHInstallation(installationID int) error { +func (db *MockDB) EnableGHInstallation(installationID int64) error { install := db.installations[installationID] install.enabledAt = time.Unix(1, 0) db.installations[installationID] = install @@ -50,7 +50,7 @@ func (db *MockDB) EnableGHInstallation(installationID int) error { } // GetGHInstallation implements DB interface -func (db *MockDB) GetGHInstallation(installationID int) (*GHInstallation, error) { +func (db *MockDB) GetGHInstallation(installationID int64) (*GHInstallation, error) { if installation, ok := db.installations[installationID]; ok { return &installation, db.err } @@ -63,7 +63,7 @@ func (db *MockDB) ListTools() ([]Tool, error) { } // StartAnalysis implements the DB interface. -func (db *MockDB) StartAnalysis(ghInstallationID, repositoryID int, commitFrom, commitTo string, requestNumber int) (*Analysis, error) { +func (db *MockDB) StartAnalysis(ghInstallationID, repositoryID int64, commitFrom, commitTo string, requestNumber int) (*Analysis, error) { analysis := NewAnalysis() analysis.ID = 99 analysis.CommitFrom = commitFrom diff --git a/internal/db/sqldb.go b/internal/db/sqldb.go index 4772bfd..1bdc54e 100644 --- a/internal/db/sqldb.go +++ b/internal/db/sqldb.go @@ -52,7 +52,7 @@ func (db *SQLDB) Cleanup(ctx context.Context, logger logger.Logger) { } // AddGHInstallation implements the DB interface. -func (db *SQLDB) AddGHInstallation(installationID, accountID, senderID int) error { +func (db *SQLDB) AddGHInstallation(installationID, accountID, senderID int64) error { // INSERT IGNORE so any duplicates are ignored _, err := db.sqlx.Exec("INSERT IGNORE INTO gh_installations (installation_id, account_id, sender_id) VALUES (?, ?, ?)", installationID, accountID, senderID, @@ -61,18 +61,18 @@ func (db *SQLDB) AddGHInstallation(installationID, accountID, senderID int) erro } // RemoveGHInstallation implements the DB interface. -func (db *SQLDB) RemoveGHInstallation(installationID int) error { +func (db *SQLDB) RemoveGHInstallation(installationID int64) error { _, err := db.sqlx.Exec("DELETE FROM gh_installations WHERE installation_id = ?", installationID) return err } // GetGHInstallation implements the DB interface. -func (db *SQLDB) GetGHInstallation(installationID int) (*GHInstallation, error) { +func (db *SQLDB) GetGHInstallation(installationID int64) (*GHInstallation, error) { var row struct { - ID int `db:"id"` - InstallationID int `db:"installation_id"` - AccountID int `db:"account_id"` - SenderID int `db:"sender_id"` + ID int64 `db:"id"` + InstallationID int64 `db:"installation_id"` + AccountID int64 `db:"account_id"` + SenderID int64 `db:"sender_id"` EnabledAt mysql.NullTime `db:"enabled_at"` } err := db.sqlx.Get(&row, "SELECT id, installation_id, account_id, sender_id, enabled_at FROM gh_installations WHERE installation_id = ?", installationID) @@ -102,7 +102,7 @@ func (db *SQLDB) ListTools() ([]Tool, error) { } // StartAnalysis implements the DB interface. -func (db *SQLDB) StartAnalysis(ghInstallationID, repositoryID int, commitFrom, commitTo string, requestNumber int) (*Analysis, error) { +func (db *SQLDB) StartAnalysis(ghInstallationID, repositoryID int64, commitFrom, commitTo string, requestNumber int) (*Analysis, error) { analysis := NewAnalysis() result, err := db.sqlx.Exec("INSERT INTO analysis (gh_installation_id, repository_id) VALUES (?, ?)", ghInstallationID, repositoryID) if err != nil { diff --git a/internal/github/github.go b/internal/github/github.go index 26b8337..68bcc4b 100644 --- a/internal/github/github.go +++ b/internal/github/github.go @@ -10,14 +10,14 @@ import ( "github.com/sethgrid/pester" ) -// GitHub is the type gopherci uses to interract with github.com. +// GitHub is the type gopherci uses to interact with github.com. type GitHub struct { logger logger.Logger db db.DB analyser analyser.Analyser queuePush chan<- interface{} webhookSecret []byte // shared webhook secret configured for the integration - integrationID int // id is the integration id + integrationID int64 // id is the integration id integrationKey []byte // integrationKey is the private key for the installationID tr http.RoundTripper // tr is a transport shared by all installations to reuse http connections baseURL string // baseURL for GitHub API @@ -29,7 +29,7 @@ type GitHub struct { // integrationID is the GitHub Integration ID (not installation ID). // integrationKey is the key for the integrationID provided to you by GitHub // during the integration registration. -func New(logger logger.Logger, analyser analyser.Analyser, db db.DB, queuePush chan<- interface{}, integrationID int, integrationKey []byte, webhookSecret, gciBaseURL string) (*GitHub, error) { +func New(logger logger.Logger, analyser analyser.Analyser, db db.DB, queuePush chan<- interface{}, integrationID int64, integrationKey []byte, webhookSecret, gciBaseURL string) (*GitHub, error) { g := &GitHub{ logger: logger, analyser: analyser, @@ -48,8 +48,8 @@ func New(logger logger.Logger, analyser analyser.Analyser, db db.DB, queuePush c return g, nil } -func (g *GitHub) newInstallationTransport(installationID int) (*ghinstallation.Transport, error) { - tr, err := ghinstallation.New(g.tr, g.integrationID, installationID, g.integrationKey) +func (g *GitHub) newInstallationTransport(installationID int64) (*ghinstallation.Transport, error) { + tr, err := ghinstallation.New(g.tr, int(g.integrationID), int(installationID), g.integrationKey) if err != nil { return nil, err } diff --git a/internal/github/handlers.go b/internal/github/handlers.go index cc0bb8e..41fbc3a 100644 --- a/internal/github/handlers.go +++ b/internal/github/handlers.go @@ -325,8 +325,8 @@ func PullRequestConfig(e *github.PullRequestEvent) AnalyseConfig { type AnalyseConfig struct { cloner analyser.Cloner refReader analyser.RefReader - installationID int - repositoryID int + installationID int64 + repositoryID int64 statusesContext string statusesURL string @@ -376,7 +376,7 @@ func (g *GitHub) Analyse(cfg AnalyseConfig) (err error) { } // Record start of analysis - analysis, err := g.db.StartAnalysis(install.ID, cfg.repositoryID, cfg.commitFrom, cfg.commitTo, cfg.pr) + analysis, err := g.db.StartAnalysis(int64(install.ID), cfg.repositoryID, cfg.commitFrom, cfg.commitTo, cfg.pr) if err != nil { return errors.Wrap(err, "error starting analysis") } diff --git a/internal/github/handlers_test.go b/internal/github/handlers_test.go index 6a2a60f..001e263 100644 --- a/internal/github/handlers_test.go +++ b/internal/github/handlers_test.go @@ -87,8 +87,8 @@ func setup(t *testing.T) (*GitHub, *mockAnalyser, *db.MockDB) { wg sync.WaitGroup c = make(chan interface{}) ) - queue := queue.NewMemoryQueue(logger.Testing()) - queue.Wait(context.Background(), &wg, c, func(job interface{}) {}) + q := queue.NewMemoryQueue(logger.Testing()) + q.Wait(context.Background(), &wg, c, func(job interface{}) {}) // New GitHub g, err := New(logger.Testing(), mockAnalyser, memDB, c, 1, integrationKey, webhookSecret, "https://example.com") @@ -155,10 +155,10 @@ func TestWebhookHandler(t *testing.T) { goodPush := func() *github.PushEvent { return &github.PushEvent{ Installation: &github.Installation{ - ID: github.Int(1), + ID: github.Int64(1), }, Repo: &github.PushEventRepository{ - ID: github.Int(2), + ID: github.Int64(2), StatusesURL: github.String("https://github.com/owner/repo/status/{sha}"), CloneURL: github.String("https://github.com/owner/repo.git"), HTMLURL: github.String("https://github.com/owner/repo"), @@ -197,14 +197,14 @@ func TestWebhookHandler(t *testing.T) { }, }, Installation: &github.Installation{ - ID: github.Int(1), + ID: github.Int64(1), }, Repo: &github.Repository{ Owner: &github.User{ Login: github.String("owner"), }, Name: github.String("repo"), - ID: github.Int(2), + ID: github.Int64(2), Private: github.Bool(false), }, } @@ -223,7 +223,7 @@ func TestWebhookHandler(t *testing.T) { // No valid installation pushNoInstall := goodPush() - pushNoInstall.Installation.ID = github.Int(2) + pushNoInstall.Installation.ID = github.Int64(2) // Private repo pushPrivateRepo := goodPush() @@ -242,7 +242,7 @@ func TestWebhookHandler(t *testing.T) { // No install prNoInstall := goodPR() - prNoInstall.Installation.ID = github.Int(2) + prNoInstall.Installation.ID = github.Int64(2) // Invalid action prInvalidAction := goodPR() @@ -442,8 +442,8 @@ func TestCheckPRAffectsGo(t *testing.T) { t.Fatal("unexpected error:", err) } - if want := true; have != want { - t.Errorf("have: %v, want: %v", have, want) + if !have { + t.Errorf("have: %v, want: %v", have, true) } } @@ -504,14 +504,14 @@ func TestIntegrationInstallationEvent(t *testing.T) { event := &github.InstallationEvent{ Action: github.String("created"), Installation: &github.Installation{ - ID: github.Int(installationID), + ID: github.Int64(installationID), Account: &github.User{ - ID: github.Int(accountID), + ID: github.Int64(accountID), Login: github.String("accountlogin"), }, }, Sender: &github.User{ - ID: github.Int(senderID), + ID: github.Int64(senderID), Login: github.String("senderlogin"), }, } @@ -578,10 +578,10 @@ func TestPushConfig(t *testing.T) { func goodPush() *github.PushEvent { return &github.PushEvent{ Installation: &github.Installation{ - ID: github.Int(1), + ID: github.Int64(1), }, Repo: &github.PushEventRepository{ - ID: github.Int(2), + ID: github.Int64(2), Owner: &github.PushEventRepoOwner{ Name: github.String("owner"), }, @@ -651,10 +651,10 @@ func TestPullRequestConfig(t *testing.T) { }, }, Installation: &github.Installation{ - ID: github.Int(1), + ID: github.Int64(1), }, Repo: &github.Repository{ - ID: github.Int(2), + ID: github.Int64(2), }, } have := PullRequestConfig(e) diff --git a/internal/github/installation.go b/internal/github/installation.go index 8d0f9b2..e889dda 100644 --- a/internal/github/installation.go +++ b/internal/github/installation.go @@ -19,7 +19,7 @@ type Installation struct { client *github.Client } -func (g *GitHub) NewInstallation(installationID int) (*Installation, error) { +func (g *GitHub) NewInstallation(installationID int64) (*Installation, error) { // TODO reuse installations, so we maintain rate limit state between webhooks installation, err := g.db.GetGHInstallation(installationID) @@ -44,7 +44,7 @@ func (g *GitHub) NewInstallation(installationID int) (*Installation, error) { return nil, err } - return &Installation{ID: installation.ID, client: client}, nil + return &Installation{ID: int(installation.ID), client: client}, nil } // IsEnabled returns true if an installation is enabled. diff --git a/internal/github/installation_test.go b/internal/github/installation_test.go index 406b542..98a993c 100644 --- a/internal/github/installation_test.go +++ b/internal/github/installation_test.go @@ -15,12 +15,12 @@ import ( func TestInstallation_isEnabled(t *testing.T) { var i *Installation - if want := false; i.IsEnabled() != want { - t.Errorf("want: %v, have: %v", want, i.IsEnabled()) + if i.IsEnabled() { + t.Errorf("want: %v, have: %v", true, i.IsEnabled()) } i = &Installation{} - if want := true; i.IsEnabled() != want { - t.Errorf("want: %v, have: %v", want, i.IsEnabled()) + if !i.IsEnabled() { + t.Errorf("want: %v, have: %v", false, i.IsEnabled()) } } diff --git a/internal/github/reporters_test.go b/internal/github/reporters_test.go index 5723415..3fa3f8b 100644 --- a/internal/github/reporters_test.go +++ b/internal/github/reporters_test.go @@ -53,8 +53,8 @@ func TestDedupePRIssues(t *testing.T) { Position: github.Int(expectedCmtPos + 2), }, } - json, _ := json.Marshal(comments) - fmt.Fprint(w, string(json)) + bites, _ := json.Marshal(comments) + fmt.Fprint(w, string(bites)) } })) defer ts.Close() @@ -95,9 +95,9 @@ func TestPRCommentReporter_report(t *testing.T) { case fmt.Sprintf("/repos/%v/%v/pulls/%v/comments", expectedOwner, expectedRepo, expectedPR): if strings.ToLower(r.Method) == "get" { // Call to ListComments - comments := []*github.PullRequestComment{} - json, _ := json.Marshal(comments) - fmt.Fprint(w, string(json)) + var comments []*github.PullRequestComment + bites, _ := json.Marshal(comments) + fmt.Fprint(w, string(bites)) break } expected := github.PullRequestComment{ diff --git a/internal/queue/gcp-pubsub.go b/internal/queue/gcp-pubsub.go index e8f5be7..74af1c3 100644 --- a/internal/queue/gcp-pubsub.go +++ b/internal/queue/gcp-pubsub.go @@ -160,24 +160,24 @@ type container struct { // receive calls sub.Receive, which blocks forever waiting for new jobs. func (q *GCPPubSubQueue) receive(ctx context.Context, f func(interface{})) { err := q.subscription.Receive(ctx, func(ctx xContext.Context, msg *pubsub.Message) { - logger := q.logger.With("messageID", msg.ID) + log := q.logger.With("messageID", msg.ID) - logger.With("publishTime", msg.PublishTime).Info("processing job published") + log.With("publishTime", msg.PublishTime).Info("processing job published") // Acknowledge the job now, anything else that could fail by this instance // will probably fail for others. msg.Ack() - logger.Info("acknowledged job") + log.Info("acknowledged job") reader := bytes.NewReader(msg.Data) dec := gob.NewDecoder(reader) var job container if err := dec.Decode(&job); err != nil { - logger.With("error", err).Errorf("could not decode job") + log.With("error", err).Errorf("could not decode job") return } - logger.Info("processing") + log.Info("processing") f(job.Job) }) diff --git a/internal/web/static/site.css b/internal/web/static/site.css index 303f2b2..a0c7e25 100644 --- a/internal/web/static/site.css +++ b/internal/web/static/site.css @@ -1,33 +1,85 @@ +/* Base Tweaks */ +html { + background-color: #f5f5f5; +} + +h1, h2 { + margin-bottom: 1.2rem; +} -/* Base Tweaks */ -html { background-color: #f5f5f5; } -h1, h2 { margin-bottom: 1.2rem; } -footer { text-align: center; background-color: #f5f5f5; padding: 40px 20px; border-top: 1px solid #e6e6e6; } +footer { + text-align: center; + background-color: #f5f5f5; + padding: 40px 20px; + border-top: 1px solid #e6e6e6; +} /* Top Navigation / Logo */ .top-nav { - background-color: #3069b3; - color: rgba(255, 255, 255, 0.85); - border-bottom: 1px solid white; + background-color: #3069b3; + color: rgba(255, 255, 255, 0.85); + border-bottom: 1px solid white; +} + +.top-nav .logo { + color: inherit; + font-size: 26px; + line-height: 1.7em; +} + +.top-nav .logo .ci { + font-weight: bold; } -.top-nav .logo { color: inherit; font-size: 26px; line-height: 1.7em; } -.top-nav .logo .ci { font-weight: bold; } /* Analysis Summary */ -.asummary-cont { padding: 2rem 0; background: #fbfbfc; border-bottom: 1px solid #eceeef; } +.asummary-cont { + padding: 2rem 0; + background: #fbfbfc; + border-bottom: 1px solid #eceeef; +} + .asummary { border-left: 5px solid grey; margin-bottom: 2rem; background: white; } -.asummary.Success { border-left-color: #5cb85c; } -.asummary.Failure { border-left-color: #d9534f; } -.asummary.Error { border-left-color: #f0ad4e; } -.asummary .table { margin-bottom: 0; border-right: 1px solid #eceeef; border-bottom: 1px solid #eceeef; } -.asummary .durations { text-align: center; } -.asummary .duration { color: #757575; } -.asummary .duration-cont { border-right: 1px solid #eceeef; border-bottom: 1px solid #eceeef; padding-top: .75em; } -.asummary .badge-pending { color: #fff; background-color: grey; } + +.asummary.Success { + border-left-color: #5cb85c; +} + +.asummary.Failure { + border-left-color: #d9534f; +} + +.asummary.Error { + border-left-color: #f0ad4e; +} + +.asummary .table { + margin-bottom: 0; + border-right: 1px solid #eceeef; + border-bottom: 1px solid #eceeef; +} + +.asummary .durations { + text-align: center; +} + +.asummary .duration { + color: #757575; +} + +.asummary .duration-cont { + border-right: 1px solid #eceeef; + border-bottom: 1px solid #eceeef; + padding-top: .75em; +} + +.asummary .badge-pending { + color: #fff; + background-color: grey; +} /* Analysis Tools Summary */ .tools { @@ -35,65 +87,145 @@ footer { text-align: center; background-color: #f5f5f5; padding: 40px 20px; bord border-bottom: 1px solid #eceeef; background: white; } -.tools .name { width: 20%; } -.tools .tool { border-left: 5px solid grey; } -.tools .tool.tool-success { border-left-color: #5cb85c; } -.tools .tool.tool-warning { border-left-color: #f0ad4e; } -.tools .tool-warning .count { font-weight: bold; } -.tools .tool-issue { border-left: 1px solid #f0ad4e; } -.tools .tool-issue .line { text-align: right; } + +.tools .name { + width: 20%; +} + +.tools .tool { + border-left: 5px solid grey; +} + +.tools .tool.tool-success { + border-left-color: #5cb85c; +} + +.tools .tool.tool-warning { + border-left-color: #f0ad4e; +} + +.tools .tool-warning .count { + font-weight: bold; +} + +.tools .tool-issue { + border-left: 1px solid #f0ad4e; +} + +.tools .tool-issue .line { + text-align: right; +} + .tools .tool-issue td { padding: 0.4em 0.8em; font-family: monospace; background: #fff0da; } -/* extra-cont is a container for patches/output paadding */ -.extra-cont { padding-top: 2em; } -.extra-cont:last-child { padding-bottom: 2em; } +/* extra-cont is a container for patches/output padding */ +.extra-cont { + padding-top: 2em; +} + +.extra-cont:last-child { + padding-bottom: 2em; +} /* Analysis Hunk */ .patch { - width: 100%; - margin: 0 auto 2rem; - font-family: monospace; - font-size: 12px; - border: 1px solid #d7d7d7; -} -.patch thead th { background-color: #f2f2f2; font-weight: bold; } -.patch td, .patch th { padding: 7px 10px; white-space: pre-wrap; } -.patch .none { background-color: #fff; } -.patch .e { background-color: floralwhite; } -.patch .e td:nth-child(2) { text-align: right; font-weight: bold; } -.patch .add { background-color: #eaffea; } -.patch .remove { background-color: #ffecec; } -.patch .m { font-weight: bold; } -.patch .lno { text-align: right; background-color: rgba(250, 251, 252, 0.3); user-select: none; } -.patch .range { background-color: #f3f8ff; } -.patch tfoot tr:first-child { border-top: 1px solid #d7d7d7; } + width: 100%; + margin: 0 auto 2rem; + font-family: monospace; + font-size: 12px; + border: 1px solid #d7d7d7; +} + +.patch thead th { + background-color: #f2f2f2; + font-weight: bold; +} + +.patch td, .patch th { + padding: 7px 10px; + white-space: pre-wrap; +} + +.patch .none { + background-color: #fff; +} + +.patch .e { + background-color: floralwhite; +} + +.patch .e td:nth-child(2) { + text-align: right; + font-weight: bold; +} + +.patch .add { + background-color: #eaffea; +} + +.patch .remove { + background-color: #ffecec; +} + +.patch .m { + font-weight: bold; +} + +.patch .lno { + text-align: right; + background-color: rgba(250, 251, 252, 0.3); + user-select: none; +} + +.patch .range { + background-color: #f3f8ff; +} + +.patch tfoot tr:first-child { + border-top: 1px solid #d7d7d7; +} /* Analysis Outputs */ -.outputs-cont { padding-top: 2em; } +.outputs-cont { + padding-top: 2em; +} + .outputs { - font-family: Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; - font-size: 90%; - background-color: #292b2c; + font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-size: 90%; + background-color: #292b2c; padding: 1em 1em 0.5em; margin-bottom: 2rem; color: #a9a9a9; } -.output-cont { position: relative; padding-bottom: 0.5rem; margin-bottom: 0; } + +.output-cont { + position: relative; + padding-bottom: 0.5rem; + margin-bottom: 0; +} + .outputs .arg { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - color: #e8e8e8; + color: #e8e8e8; } + .outputs .duration { - text-align: right; + text-align: right; display: block; right: 0; position: absolute; top: 0; } -.outputs .output { white-space: pre; display: block; overflow-y: scroll; } + +.outputs .output { + white-space: pre; + display: block; + overflow-y: scroll; +} diff --git a/internal/web/vcsviewer.go b/internal/web/vcsviewer.go index 2c608d3..3d4d313 100644 --- a/internal/web/vcsviewer.go +++ b/internal/web/vcsviewer.go @@ -68,7 +68,7 @@ type Line struct { // DiffIssues reads a diff and adds the issues to the lines affected. Only // hunks with issues will be returned. -func DiffIssues(ctx context.Context, diffReader io.Reader, issues []db.Issue) ([]Patch, error) { +func DiffIssues(_ context.Context, diffReader io.Reader, issues []db.Issue) ([]Patch, error) { ghDiff, err := ioutil.ReadAll(&io.LimitedReader{R: diffReader, N: 1e9}) if err != nil { return nil, errors.Wrap(err, "could not read from diff reader") diff --git a/internal/web/web.go b/internal/web/web.go index 3362e11..a0b9f7b 100644 --- a/internal/web/web.go +++ b/internal/web/web.go @@ -70,11 +70,11 @@ func (web *Web) AnalysisHandler(w http.ResponseWriter, r *http.Request) { return } - logger := web.logger.With("analysisID", analysisID) + log := web.logger.With("analysisID", analysisID) analysis, err := web.db.GetAnalysis(int(analysisID)) if err != nil { - logger.With("error", err).Error("cannot get analysis") + log.With("error", err).Error("cannot get analysis") web.errorHandler(w, r, http.StatusInternalServerError, "Could not get analysis") return } @@ -86,14 +86,14 @@ func (web *Web) AnalysisHandler(w http.ResponseWriter, r *http.Request) { outputs, err := web.db.AnalysisOutputs(analysis.ID) if err != nil { - logger.With("error", err).Error("cannot get analysis output") + log.With("error", err).Error("cannot get analysis output") web.errorHandler(w, r, http.StatusInternalServerError, "Could not get analysis output") return } vcs, err := NewVCS(web.gh, analysis) if err != nil { - logger.With("error", err).Error("cannot get analysis VCS") + log.With("error", err).Error("cannot get analysis VCS") web.errorHandler(w, r, http.StatusInternalServerError, "Could not get VCS") return } @@ -112,13 +112,13 @@ func (web *Web) AnalysisHandler(w http.ResponseWriter, r *http.Request) { // when we receive the GitHub event, there's no indication that it's a // new tree. But we can't fetch the diff because there's no history for // this commit so GitHub sends a 404. - logger.With("error", err).Error("cannot get diff from VCS") + log.With("error", err).Error("cannot get diff from VCS") case diffReader != nil: defer diffReader.Close() patches, err = DiffIssues(r.Context(), diffReader, analysis.Issues()) if err != nil { - logger.With("error", err).Error("cannot diff issues from VCS diff") + log.With("error", err).Error("cannot diff issues from VCS diff") web.errorHandler(w, r, http.StatusInternalServerError, "Could not read VCS") return } @@ -140,6 +140,6 @@ func (web *Web) AnalysisHandler(w http.ResponseWriter, r *http.Request) { } if err := web.templates.ExecuteTemplate(w, "analysis.tmpl", page); err != nil { - logger.With("error", err).Error("cannot parse analysis template") + log.With("error", err).Error("cannot parse analysis template") } } diff --git a/main.go b/main.go index 47f2886..a150fb2 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,7 @@ import ( gh "github.com/google/go-github/github" "github.com/joho/godotenv" "github.com/pkg/errors" - migrate "github.com/rubenv/sql-migrate" + "github.com/rubenv/sql-migrate" ) // build tracks the build version of the binary. @@ -35,8 +35,8 @@ func main() { _ = godotenv.Load() rootLogger := logger.New(os.Stdout, build, os.Getenv("LOGGER_ENV"), os.Getenv("LOGGER_SENTRY_DSN")) - logger := rootLogger.With("area", "main") - logger.With("build", build).Info("starting gopherci") + log := rootLogger.With("area", "main") + log.With("build", build).Info("starting gopherci") r := chi.NewRouter() r.Use(middleware.RealIP) // Blindly accept XFF header, ensure LB overwrites it @@ -56,17 +56,17 @@ func main() { switch { case os.Getenv("GCI_BASE_URL") == "": - logger.Info("GCI_BASE_URL is blank, URLs linking back to GopherCI will not work") + log.Info("GCI_BASE_URL is blank, URLs linking back to GopherCI will not work") case os.Getenv("GITHUB_ID") == "": - logger.Error("GITHUB_ID is not set") + log.Error("GITHUB_ID is not set") case os.Getenv("GITHUB_PEM_FILE") == "": - logger.Fatal("GITHUB_PEM_FILE is not set") + log.Fatal("GITHUB_PEM_FILE is not set") case os.Getenv("GITHUB_WEBHOOK_SECRET") == "": - logger.Fatal("GITHUB_WEBHOOK_SECRET is not set") + log.Fatal("GITHUB_WEBHOOK_SECRET is not set") } // Database - logger.Infof("connecting to %q db name: %q, username: %q, host: %q, port: %q", + log.Infof("connecting to %q db name: %q, username: %q, host: %q, port: %q", os.Getenv("DB_DRIVER"), os.Getenv("DB_DATABASE"), os.Getenv("DB_USERNAME"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), ) @@ -76,7 +76,7 @@ func main() { sqlDB, err := sql.Open(os.Getenv("DB_DRIVER"), dsn) if err != nil { - logger.With("error", err).Fatal("could not open database") + log.With("error", err).Fatal("could not open database") } // Do DB migrations @@ -89,36 +89,36 @@ func main() { migrateMax = 1 } n, err := migrate.ExecMax(sqlDB, os.Getenv("DB_DRIVER"), migrations, direction, migrateMax) - logger.Infof("applied %d migrations to database", n) + log.Infof("applied %d migrations to database", n) if err != nil { - logger.With("error", err).Fatal("could not execute all migrations") + log.With("error", err).Fatal("could not execute all migrations") } - db, err := db.NewSQLDB(sqlDB, os.Getenv("DB_DRIVER")) + database, err := db.NewSQLDB(sqlDB, os.Getenv("DB_DRIVER")) if err != nil { - logger.With("error", err).Fatal("could not initialise database") + log.With("error", err).Fatal("could not initialise database") } - go db.Cleanup(ctx, rootLogger.With("area", "db")) + go database.Cleanup(ctx, rootLogger.With("area", "db")) var analyserMemoryLimit int64 if os.Getenv("ANALYSER_MEMORY_LIMIT") != "" { analyserMemoryLimit, err = strconv.ParseInt(os.Getenv("ANALYSER_MEMORY_LIMIT"), 10, 32) if err != nil { - logger.With("error", err).Fatal("could not parse ANALYSER_MEMORY_LIMIT") + log.With("error", err).Fatal("could not parse ANALYSER_MEMORY_LIMIT") } } // Analyser - logger.Infof("using analyser %q", os.Getenv("ANALYSER")) + log.Infof("using analyser %q", os.Getenv("ANALYSER")) var analyse analyser.Analyser switch os.Getenv("ANALYSER") { case "filesystem": if os.Getenv("ANALYSER_FILESYSTEM_PATH") == "" { - logger.Fatal("ANALYSER_FILESYSTEM_PATH is not set") + log.Fatal("ANALYSER_FILESYSTEM_PATH is not set") } analyse, err = analyser.NewFileSystem(os.Getenv("ANALYSER_FILESYSTEM_PATH"), int(analyserMemoryLimit)) if err != nil { - logger.Fatal("could not initialise file system analyser:", err) + log.Fatal("could not initialise file system analyser:", err) } case "docker": image := os.Getenv("ANALYSER_DOCKER_IMAGE") @@ -127,39 +127,39 @@ func main() { } analyse, err = analyser.NewDocker(rootLogger.With("area", "docker"), image, int(analyserMemoryLimit)) if err != nil { - logger.Fatal("could not initialise Docker analyser:", err) + log.Fatal("could not initialise Docker analyser:", err) } case "": - logger.Fatal("ANALYSER is not set") + log.Fatal("ANALYSER is not set") default: - logger.Fatalf("Unknown ANALYSER option %q", os.Getenv("ANALYSER")) + log.Fatalf("Unknown ANALYSER option %q", os.Getenv("ANALYSER")) } // GitHub - logger.Infof("github Integration ID: %q, GitHub Integration PEM File: %q", os.Getenv("GITHUB_ID"), os.Getenv("GITHUB_PEM_FILE")) + log.Infof("github Integration ID: %q, GitHub Integration PEM File: %q", os.Getenv("GITHUB_ID"), os.Getenv("GITHUB_PEM_FILE")) integrationID, err := strconv.ParseInt(os.Getenv("GITHUB_ID"), 10, 64) if err != nil { - logger.Fatalf("could not parse integrationID %q", os.Getenv("GITHUB_ID")) + log.Fatalf("could not parse integrationID %q", os.Getenv("GITHUB_ID")) } integrationKey, err := ioutil.ReadFile(os.Getenv("GITHUB_PEM_FILE")) if err != nil { - logger.Fatalf("could not read private key for GitHub integration: %s", err) + log.Fatalf("could not read private key for GitHub integration: %s", err) } // queuePush is used to add a job to the queue var queuePush = make(chan interface{}) - gh, err := github.New(rootLogger, analyse, db, queuePush, int(integrationID), integrationKey, os.Getenv("GITHUB_WEBHOOK_SECRET"), os.Getenv("GCI_BASE_URL")) + gith, err := github.New(rootLogger, analyse, database, queuePush, integrationID, integrationKey, os.Getenv("GITHUB_WEBHOOK_SECRET"), os.Getenv("GCI_BASE_URL")) if err != nil { - logger.Fatal("could not initialise GitHub:", err) + log.Fatal("could not initialise GitHub:", err) } - r.Post("/gh/webhook", gh.WebHookHandler) - r.Get("/gh/callback", gh.CallbackHandler) + r.Post("/gh/webhook", gith.WebHookHandler) + r.Get("/gh/callback", gith.CallbackHandler) var ( wg sync.WaitGroup // wait for queue to finish before exiting - qProcessor = queueProcessor{github: gh, logger: rootLogger.With("area", "queueProcessor")} + qProcessor = queueProcessor{github: gith, logger: rootLogger.With("area", "queueProcessor")} ) switch os.Getenv("QUEUER") { @@ -169,44 +169,44 @@ func main() { case "gcppubsub": switch { case os.Getenv("QUEUER_GCPPUBSUB_PROJECT_ID") == "": - logger.Fatalf("QUEUER_GCPPUBSUB_PROJECT_ID is not set") + log.Fatalf("QUEUER_GCPPUBSUB_PROJECT_ID is not set") } gcp, err := queue.NewGCPPubSubQueue(ctx, rootLogger.With("area", "gcpPubSubQueue"), os.Getenv("QUEUER_GCPPUBSUB_PROJECT_ID"), os.Getenv("QUEUER_GCPPUBSUB_TOPIC")) if err != nil { - logger.Fatal("Could not initialise GCPPubSubQueue:", err) + log.Fatal("Could not initialise GCPPubSubQueue:", err) } gcp.Wait(ctx, &wg, queuePush, qProcessor.Process) case "": - logger.Fatal("QUEUER is not set") + log.Fatal("QUEUER is not set") default: - logger.Fatalf("Unknown QUEUER option %q", os.Getenv("QUEUER")) + log.Fatalf("Unknown QUEUER option %q", os.Getenv("QUEUER")) } // Web routes - web, err := web.NewWeb(rootLogger.With("area", "web"), db, gh) + webr, err := web.NewWeb(rootLogger.With("area", "web"), database, gith) if err != nil { - logger.With("error", err).Fatal("could not instantiate web") + log.With("error", err).Fatal("could not instantiate web") } workDir, _ := os.Getwd() FileServer(r, "/static", http.Dir(filepath.Join(workDir, "internal", "web", "static"))) - r.NotFound(web.NotFoundHandler) - r.Get("/analysis/{analysisID}", web.AnalysisHandler) + r.NotFound(webr.NotFoundHandler) + r.Get("/analysis/{analysisID}", webr.AnalysisHandler) // Health checks r.Get("/health-check", HealthCheckHandler) // Listen - logger.Infof("listening on %s", srv.Addr) + log.Infof("listening on %s", srv.Addr) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - logger.With("error", err).Error("http server error") + log.With("error", err).Error("http server error") cancel() } // Wait for current item in queue to finish - logger.Info("waiting for queuer to finish") + log.Info("waiting for queuer to finish") wg.Wait() - logger.Info("exiting gracefully") + log.Info("exiting gracefully") } // FileServer conveniently sets up a http.FileServer handler to serve