Switch to mage (#651)
Add comment about magefile compile Switch make to mage commands in drone Fix misspell Update docs Add general release command Add reprepro command Make sure the filename contains the proper version Add deb package building Add zip command Preserve file permissions when copying files Fix release:os-package Make sure to not create checksums of directories Cleanup Only compress what upx is able to compress Add check command Add release:os-package command Add copy command Add comments Add compress step Move releasing binaries to a more general function and add ones of linux + darwin Add release:windows command Add release:dir command Add namespaces for commands Reorder Add command to run all checks at once Add goconst-check Add gosec-check Add static-check Add gocyclo-check Add ineffasign-check Add misspell-check Add command to check for swagger docs regeneration Add comments Add command to generate swagger docs Reorder Add check for installing golint before running it Add fmt check command Add fmt command Use runAndStreamOutput everywhere Add aliases and comments Add todo Reorder Add test coverage command Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/api/pulls/651
This commit is contained in:
parent
05099e1784
commit
d359130bcf
10 changed files with 1073 additions and 559 deletions
128
.drone1.yml
128
.drone1.yml
|
@ -52,13 +52,26 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- git fetch --tags
|
- git fetch --tags
|
||||||
|
|
||||||
- name: build
|
# We're statically compiling the magefile to avoid race condition issues caused by multiple pipeline steps
|
||||||
|
# compiling the same magefile at the same time. It's also faster if each step does not need to compile it first.
|
||||||
|
- name: mage
|
||||||
image: vikunja/golang-build:latest
|
image: vikunja/golang-build:latest
|
||||||
pull: true
|
pull: true
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: 'https://goproxy.kolaente.de'
|
GOPROXY: 'https://goproxy.kolaente.de'
|
||||||
commands:
|
commands:
|
||||||
- make build
|
- mage -compile ./mage-static
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
- name: build
|
||||||
|
image: vikunja/golang-build:latest
|
||||||
|
pull: true
|
||||||
|
environment:
|
||||||
|
GOPROXY: 'https://goproxy.kolaente.de'
|
||||||
|
depends_on: [ mage ]
|
||||||
|
commands:
|
||||||
|
- ./mage-static build:build
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -69,17 +82,17 @@ steps:
|
||||||
GOPROXY: 'https://goproxy.kolaente.de'
|
GOPROXY: 'https://goproxy.kolaente.de'
|
||||||
depends_on: [ build ]
|
depends_on: [ build ]
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make lint
|
- ./mage-static check:lint
|
||||||
- make fmt-check
|
- ./mage-static check:fmt
|
||||||
# - make got-swag # Commented out until we figured out how to get this working on drone
|
- ./mage-static check:got-swag
|
||||||
- make ineffassign-check
|
- ./mage-static check:ineffassign
|
||||||
- make misspell-check
|
- ./mage-static check:misspell
|
||||||
- make goconst-check
|
- ./mage-static check:goconst
|
||||||
- make gocyclo-check
|
- ./mage-static check:gocyclo
|
||||||
- make static-check
|
- ./mage-static check:static
|
||||||
- wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin v2.2.0 # Need to manually install as it does not support being installed via go modules like the rest.
|
- wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin v2.2.0 # Need to manually install as it does not support being installed via go modules like the rest.
|
||||||
- make gosec-check
|
- ./mage-static check:gosec
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -152,9 +165,9 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: 'https://goproxy.kolaente.de'
|
GOPROXY: 'https://goproxy.kolaente.de'
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make test
|
- ./mage-static test:unit
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -166,9 +179,9 @@ steps:
|
||||||
VIKUNJA_TESTS_USE_CONFIG: 1
|
VIKUNJA_TESTS_USE_CONFIG: 1
|
||||||
VIKUNJA_DATABASE_TYPE: sqlite
|
VIKUNJA_DATABASE_TYPE: sqlite
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make test
|
- ./mage-static test:unit
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -184,9 +197,9 @@ steps:
|
||||||
VIKUNJA_DATABASE_PASSWORD: vikunjatest
|
VIKUNJA_DATABASE_PASSWORD: vikunjatest
|
||||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make test
|
- ./mage-static test:unit
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -203,9 +216,9 @@ steps:
|
||||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||||
VIKUNJA_DATABASE_SSLMODE: disable
|
VIKUNJA_DATABASE_SSLMODE: disable
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make test
|
- ./mage-static test:unit
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -215,9 +228,9 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
GOPROXY: 'https://goproxy.kolaente.de'
|
GOPROXY: 'https://goproxy.kolaente.de'
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make integration-test
|
- ./mage-static test:integration
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -229,9 +242,9 @@ steps:
|
||||||
VIKUNJA_TESTS_USE_CONFIG: 1
|
VIKUNJA_TESTS_USE_CONFIG: 1
|
||||||
VIKUNJA_DATABASE_TYPE: sqlite
|
VIKUNJA_DATABASE_TYPE: sqlite
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make integration-test
|
- ./mage-static test:integration
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -247,9 +260,9 @@ steps:
|
||||||
VIKUNJA_DATABASE_PASSWORD: vikunjatest
|
VIKUNJA_DATABASE_PASSWORD: vikunjatest
|
||||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make integration-test
|
- ./mage-static test:integration
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -266,9 +279,9 @@ steps:
|
||||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||||
VIKUNJA_DATABASE_SSLMODE: disable
|
VIKUNJA_DATABASE_SSLMODE: disable
|
||||||
commands:
|
commands:
|
||||||
- make generate
|
- ./mage-static build:generate
|
||||||
- make integration-test
|
- ./mage-static test:integration
|
||||||
depends_on: [ fetch-tags ]
|
depends_on: [ fetch-tags, mage ]
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
@ -299,14 +312,27 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- git fetch --tags
|
- git fetch --tags
|
||||||
|
|
||||||
|
# We're statically compiling the magefile to avoid race condition issues caused by multiple pipeline steps
|
||||||
|
# compiling the same magefile at the same time. It's also faster if each step does not need to compile it first.
|
||||||
|
- name: mage
|
||||||
|
image: vikunja/golang-build:latest
|
||||||
|
pull: true
|
||||||
|
environment:
|
||||||
|
GOPROXY: 'https://goproxy.kolaente.de'
|
||||||
|
commands:
|
||||||
|
- mage -compile ./mage-static
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
- name: before-static-build
|
- name: before-static-build
|
||||||
image: techknowlogick/xgo:latest
|
image: techknowlogick/xgo:latest
|
||||||
pull: true
|
pull: true
|
||||||
commands:
|
commands:
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make generate
|
- go install github.com/magefile/mage
|
||||||
- make release-dirs
|
- ./mage-static build:generate
|
||||||
depends_on: [ fetch-tags ]
|
- ./mage-static release:dirs
|
||||||
|
depends_on: [ fetch-tags, mage ]
|
||||||
|
|
||||||
- name: static-build-windows
|
- name: static-build-windows
|
||||||
image: techknowlogick/xgo:latest
|
image: techknowlogick/xgo:latest
|
||||||
|
@ -317,7 +343,8 @@ steps:
|
||||||
GOPATH: /srv/app
|
GOPATH: /srv/app
|
||||||
commands:
|
commands:
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release-windows
|
- go install github.com/magefile/mage
|
||||||
|
- ./mage-static release:windows
|
||||||
depends_on: [ before-static-build ]
|
depends_on: [ before-static-build ]
|
||||||
|
|
||||||
- name: static-build-linux
|
- name: static-build-linux
|
||||||
|
@ -329,7 +356,8 @@ steps:
|
||||||
GOPATH: /srv/app
|
GOPATH: /srv/app
|
||||||
commands:
|
commands:
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release-linux
|
- go install github.com/magefile/mage
|
||||||
|
- ./mage-static release:linux
|
||||||
depends_on: [ before-static-build ]
|
depends_on: [ before-static-build ]
|
||||||
|
|
||||||
- name: static-build-darwin
|
- name: static-build-darwin
|
||||||
|
@ -341,7 +369,8 @@ steps:
|
||||||
GOPATH: /srv/app
|
GOPATH: /srv/app
|
||||||
commands:
|
commands:
|
||||||
- export PATH=$PATH:$GOPATH/bin
|
- export PATH=$PATH:$GOPATH/bin
|
||||||
- make release-darwin
|
- go install github.com/magefile/mage
|
||||||
|
- ./mage-static release:darwin
|
||||||
depends_on: [ before-static-build ]
|
depends_on: [ before-static-build ]
|
||||||
|
|
||||||
- name: after-build-compress
|
- name: after-build-compress
|
||||||
|
@ -352,7 +381,7 @@ steps:
|
||||||
- static-build-linux
|
- static-build-linux
|
||||||
- static-build-darwin
|
- static-build-darwin
|
||||||
commands:
|
commands:
|
||||||
- make release-compress
|
- ./mage-static release:compress
|
||||||
|
|
||||||
- name: after-build-static
|
- name: after-build-static
|
||||||
image: techknowlogick/xgo:latest
|
image: techknowlogick/xgo:latest
|
||||||
|
@ -360,10 +389,11 @@ steps:
|
||||||
depends_on:
|
depends_on:
|
||||||
- after-build-compress
|
- after-build-compress
|
||||||
commands:
|
commands:
|
||||||
- make release-copy
|
- go install github.com/magefile/mage
|
||||||
- make release-check
|
- ./mage-static release:copy
|
||||||
- make release-os-package
|
- ./mage-static release:check
|
||||||
- make release-zip
|
- ./mage-static release:os-package
|
||||||
|
- ./mage-static release:zip
|
||||||
|
|
||||||
- name: sign-release
|
- name: sign-release
|
||||||
image: plugins/gpgsign:1
|
image: plugins/gpgsign:1
|
||||||
|
@ -428,7 +458,7 @@ steps:
|
||||||
image: kolaente/fpm
|
image: kolaente/fpm
|
||||||
pull: true
|
pull: true
|
||||||
commands:
|
commands:
|
||||||
- make build-deb
|
- ./mage-static build-deb
|
||||||
depends_on: [ static-build-linux ]
|
depends_on: [ static-build-linux ]
|
||||||
|
|
||||||
- name: deb-structure
|
- name: deb-structure
|
||||||
|
@ -446,7 +476,7 @@ steps:
|
||||||
- gpg --import ~/frederik.gpg
|
- gpg --import ~/frederik.gpg
|
||||||
- mkdir debian/conf -p
|
- mkdir debian/conf -p
|
||||||
- cp build/reprepro-dist-conf debian/conf/distributions
|
- cp build/reprepro-dist-conf debian/conf/distributions
|
||||||
- make reprepro
|
- ./mage-static reprepro
|
||||||
depends_on: [ build-deb ]
|
depends_on: [ build-deb ]
|
||||||
|
|
||||||
# Push the releases to our pseudo-s3-bucket
|
# Push the releases to our pseudo-s3-bucket
|
||||||
|
|
179
docs/content/doc/development/mage.md
Normal file
179
docs/content/doc/development/mage.md
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
---
|
||||||
|
date: "2019-02-12:00:00+02:00"
|
||||||
|
title: "Magefile"
|
||||||
|
draft: false
|
||||||
|
type: "doc"
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
parent: "development"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Mage
|
||||||
|
|
||||||
|
Vikunja uses [Mage](https://magefile.org/) to script common development tasks and even releasing.
|
||||||
|
Mage is a pure go solution which allows for greater flexibility and things like better paralelization.
|
||||||
|
|
||||||
|
This document explains what taks are available and what they do.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To use mage, you'll need to install the mage cli.
|
||||||
|
To install it, run the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
go install github.com/magefile/mage
|
||||||
|
```
|
||||||
|
|
||||||
|
## Categories
|
||||||
|
|
||||||
|
There are multiple categories of subcommands in the magefile:
|
||||||
|
|
||||||
|
* `build`: Contains commands to build a single binary
|
||||||
|
* `check`: Contains commands to statically check the source code
|
||||||
|
* `release`: Contains commands to release Vikunja with everything that's required
|
||||||
|
* `test`: Contains commands to run all kinds of tests
|
||||||
|
* `misc`: Commands which do not belong in either of the other categories
|
||||||
|
|
||||||
|
## CI
|
||||||
|
|
||||||
|
These tasks are automatically run in our CI every time someone pushes to master or you update a pull request:
|
||||||
|
|
||||||
|
* `mage check:lint`
|
||||||
|
* `mage check:fmt`
|
||||||
|
* `mage check:ineffassign`
|
||||||
|
* `mage check:misspell`
|
||||||
|
* `mage check:goconst`
|
||||||
|
* `mage build:generate`
|
||||||
|
* `mage build:build`
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
### Build Vikunja
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage build:build
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on.
|
||||||
|
|
||||||
|
### Statically compile all templates into the binary
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage build:generate
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
This generates static code with all templates, meaning no template need to be referenced at runtime.
|
||||||
|
|
||||||
|
### clean
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage build:clean
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Cleans all build, executable and bindata files
|
||||||
|
|
||||||
|
## Check
|
||||||
|
|
||||||
|
All check sub-commands exit with a status code of 1 if the check fails.
|
||||||
|
|
||||||
|
Various code-checks are available:
|
||||||
|
|
||||||
|
* `mage check:all`: Runs fmt-check, lint, got-swag, misspell-check, ineffasign-check, gocyclo-check, static-check, gosec-check, goconst-check all in parallel
|
||||||
|
* `mage check:fmt`: Checks if the code is properly formatted with go fmt
|
||||||
|
* `mage check:go-sec`: Checks the source code for potential security issues by scanning the Go AST using the [gosec tool](https://github.com/securego/gosec)
|
||||||
|
* `mage check:goconst`: Checks for repeated strings that could be replaced by a constant using [goconst](https://github.com/jgautheron/goconst/)
|
||||||
|
* `mage check:gocyclo`: Checks for the cyclomatic complexity of the source code using [gocyclo](https://github.com/fzipp/gocyclo)
|
||||||
|
* `mage check:got-swag`: Checks if the swagger docs need to be re-generated from the code annotations
|
||||||
|
* `mage check:ineffassign`: Checks the source code for ineffectual assigns using [ineffassign](https://github.com/gordonklaus/ineffassign)
|
||||||
|
* `mage check:lint`: Runs golint on all packages
|
||||||
|
* `mage check:misspell`: Checks the source code for misspellings
|
||||||
|
* `mage check:static`: Statically analyzes the source code about a range of different problems using [staticcheck](https://staticcheck.io/docs/)
|
||||||
|
|
||||||
|
## Release
|
||||||
|
|
||||||
|
### Build Releases
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage release
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Builds binaries for all platforms and zips them with a copy of the `templates/` folder.
|
||||||
|
All built zip files are stored into `dist/zips/`. Binaries are stored in `dist/binaries/`,
|
||||||
|
binaries bundled with `templates` are stored in `dist/releases/`.
|
||||||
|
|
||||||
|
All cross-platform binaries built using this series of commands are built with the help of
|
||||||
|
[xgo](https://github.com/techknowlogick/xgo). The mage command will automatically install the
|
||||||
|
binary to be able to use it.
|
||||||
|
|
||||||
|
`mage release:release` is a shortcut to execute `mage release:dirs release:windows release:linux release:darwin release:copy release:check release:os-package release:zip`.
|
||||||
|
|
||||||
|
* `mage release:dirs` creates all directories needed
|
||||||
|
* `mage release:windows`/`release:linux`/`release:darwin` execute xgo to build for their respective platforms
|
||||||
|
* `mage release:copy` bundles binaries with a copy of the `LICENSE` and sample config files to then be zipped
|
||||||
|
* `mage release:check` creates sha256 checksums for each binary which will be included in the zip file
|
||||||
|
* `mage release:os-package` bundles a binary with the `sha256` checksum file, a sample `config.yml` and a copy of the license in a folder for each architecture
|
||||||
|
* `mage release:compress` compresses all build binaries with `upx` to save space
|
||||||
|
* `mage release:zip` paclages a zip file for the files created by `release:os-package`
|
||||||
|
|
||||||
|
### Build debian packages
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage release:deb
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Will build a `.deb` package into the current folder.
|
||||||
|
You need to have [fpm](https://fpm.readthedocs.io/en/latest/intro.html) installed to be able to do this.
|
||||||
|
|
||||||
|
### Make a debian repo
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage release:reprepro
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Takes an already built debian package and creates a debian repo structure around it.
|
||||||
|
|
||||||
|
Used to be run inside a [docker container](https://git.kolaente.de/konrad/reprepro-docker) in the CI process when releasing.
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
### unit
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage test:unit
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Runs all tests except integration tests.
|
||||||
|
|
||||||
|
### coverage
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage test:coverage
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Runs all tests except integration tests and generates a `coverage.html` file to inspect the code coverage.
|
||||||
|
|
||||||
|
### integration
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage test:integration
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Runs all integration tests.
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
|
||||||
|
### Format the code
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage fmt
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Formats all source code using `go fmt`.
|
||||||
|
|
||||||
|
### Generate swagger definitions from code comments
|
||||||
|
|
||||||
|
{{< highlight bash >}}
|
||||||
|
mage do-the-swag
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
Generates swagger definitions from the comment annotations in the code.
|
|
@ -1,151 +0,0 @@
|
||||||
---
|
|
||||||
date: "2019-02-12:00:00+02:00"
|
|
||||||
title: "Makefile"
|
|
||||||
draft: false
|
|
||||||
type: "doc"
|
|
||||||
menu:
|
|
||||||
sidebar:
|
|
||||||
parent: "development"
|
|
||||||
---
|
|
||||||
|
|
||||||
# Makefile
|
|
||||||
|
|
||||||
We scripted a lot of tasks used mostly for developing into the makefile. This documents explains what
|
|
||||||
taks are available and what they do.
|
|
||||||
|
|
||||||
## CI
|
|
||||||
|
|
||||||
These tasks are automatically run in our CI every time someone pushes to master or you update a pull request:
|
|
||||||
|
|
||||||
* `make lint`
|
|
||||||
* `make fmt-check`
|
|
||||||
* `make ineffassign-check`
|
|
||||||
* `make misspell-check`
|
|
||||||
* `make goconst-check`
|
|
||||||
* `make generate`
|
|
||||||
* `make build`
|
|
||||||
|
|
||||||
### clean
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make clean
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Clears all builds and binaries.
|
|
||||||
|
|
||||||
### test
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make test
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Runs all tests in Vikunja.
|
|
||||||
|
|
||||||
### Format the code
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make fmt
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Formats all source code using `go fmt`.
|
|
||||||
|
|
||||||
#### Check formatting
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make fmt-check
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Checks if the code needs to be formatted. Fails if it does.
|
|
||||||
|
|
||||||
### Build Vikunja
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make build
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on.
|
|
||||||
|
|
||||||
### Statically compile all templates into the binary
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make generate
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
This generates static code with all templates, meaning no template need to be referenced at runtime.
|
|
||||||
|
|
||||||
### Compress the built binary
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make compress-build
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Go binaries are very big.
|
|
||||||
To make the vikunja binary smaller, we can compress it using [upx](https://upx.github.io/).
|
|
||||||
|
|
||||||
### Build Releases
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make release
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Builds binaries for all platforms and zips them with a copy of the `templates/` folder.
|
|
||||||
All built zip files are stored into `dist/zips/`. Binaries are stored in `dist/binaries/`,
|
|
||||||
binaries bundled with `templates` are stored in `dist/releases/`.
|
|
||||||
|
|
||||||
All cross-platform binaries built using this series of commands are built with the help of
|
|
||||||
[xgo](https://github.com/techknowlogick/xgo). The make command will automatically install the
|
|
||||||
binary to be able to use it.
|
|
||||||
|
|
||||||
`make release` is actually just a shortcut to execute `make release-dirs release-windows release-linux release-darwin release-copy release-check release-os-package release-zip`.
|
|
||||||
|
|
||||||
* `release-dirs` creates all directories needed
|
|
||||||
* `release-windows`/`release-linux`/`release-darwin` execute xgo to build for their respective platforms
|
|
||||||
* `release-copy` bundles binaries with a copy of `templates/` to then be zipped
|
|
||||||
* `release-check` creates sha256 checksums for each binary which will be included in the zip file
|
|
||||||
* `release-os-package` bundles a binary with a copy of the `templates/` folder, the `sha256` checksum file, a sample `config.yml` and a copy of the license in a folder for each architecture
|
|
||||||
* `release-compress` compresses all build binaries, see `compress-build`
|
|
||||||
* `release-zip` makes a zip file for the files created by `release-os-package`
|
|
||||||
|
|
||||||
### Build debian packages
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make build-deb
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Will build a `.deb` package into the current folder. You need to have [fpm](https://fpm.readthedocs.io/en/latest/intro.html) installed to be able to do this.
|
|
||||||
|
|
||||||
#### Make a debian repo
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make reprepro
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Takes an already built debian package and creates a debian repo structure around it.
|
|
||||||
|
|
||||||
Used to be run inside a [docker container](https://git.kolaente.de/konrad/reprepro-docker) in the CI process when releasing.
|
|
||||||
|
|
||||||
### Generate swagger definitions from code comments
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make do-the-swag
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
Generates swagger definitions from the comments in the code.
|
|
||||||
|
|
||||||
#### Check if swagger generation is needed
|
|
||||||
|
|
||||||
{{< highlight bash >}}
|
|
||||||
make got-swag
|
|
||||||
{{< /highlight >}}
|
|
||||||
|
|
||||||
This command is currently more an experiment, use it with caution.
|
|
||||||
It may bring up wrong results.
|
|
||||||
|
|
||||||
### Code-Checks
|
|
||||||
|
|
||||||
* `misspell-check`: Checks for commonly misspelled words
|
|
||||||
* `ineffassign-check`: Checks for ineffectual assignments in the code using [ineffassign](https://github.com/gordonklaus/ineffassign).
|
|
||||||
* `gocyclo-check`: Calculates cyclomatic complexities of functions using [gocyclo](https://github.com/fzipp/gocyclo).
|
|
||||||
* `static-check`: Analyzes the code for bugs, improvements and more using [staticcheck](https://staticcheck.io/docs/).
|
|
||||||
* `gosec-check`: Inspects source code for security problems by scanning the Go AST using the [gosec tool](https://github.com/securego/gosec).
|
|
||||||
* `goconst-check`: Finds repeated strings that could be replaced by a constant using [goconst](https://github.com/jgautheron/goconst/).
|
|
2
go.mod
2
go.mod
|
@ -46,6 +46,7 @@ require (
|
||||||
github.com/labstack/gommon v0.3.0
|
github.com/labstack/gommon v0.3.0
|
||||||
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
|
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
|
||||||
github.com/lib/pq v1.8.0
|
github.com/lib/pq v1.8.0
|
||||||
|
github.com/magefile/mage v1.10.0
|
||||||
github.com/mailru/easyjson v0.7.0 // indirect
|
github.com/mailru/easyjson v0.7.0 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.2
|
github.com/mattn/go-sqlite3 v1.14.2
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
|
@ -69,6 +70,7 @@ require (
|
||||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||||
golang.org/x/image v0.0.0-20200801110659-972c09e46d76
|
golang.org/x/image v0.0.0-20200801110659-972c09e46d76
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
|
||||||
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
|
||||||
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef // indirect
|
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
|
|
23
go.sum
23
go.sum
|
@ -1,7 +1,5 @@
|
||||||
4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f h1:oyYjGRBNq1TxAIG8aHqtxlvqUfzdZf+MbcRb/oweNfY=
|
4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f h1:oyYjGRBNq1TxAIG8aHqtxlvqUfzdZf+MbcRb/oweNfY=
|
||||||
4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f/go.mod h1:HxEsUxoVZyRxsZML/S6e2xAuieFMlGO0756ncWx1aXE=
|
4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f/go.mod h1:HxEsUxoVZyRxsZML/S6e2xAuieFMlGO0756ncWx1aXE=
|
||||||
4d63.com/tz v1.1.0 h1:Hi58WbeFjiUH4XOWuCpl5iSzuUuw1axZzTqIfMKPKrg=
|
|
||||||
4d63.com/tz v1.1.0/go.mod h1:SHGqVdL7hd2ZaX2T9uEiOZ/OFAUfCCLURdLPJsd8ZNs=
|
|
||||||
4d63.com/tz v1.2.0 h1:EpJt060xY+M+M0Wj8btz+THdOJbSxj4i8jhVQP3Wr0U=
|
4d63.com/tz v1.2.0 h1:EpJt060xY+M+M0Wj8btz+THdOJbSxj4i8jhVQP3Wr0U=
|
||||||
4d63.com/tz v1.2.0/go.mod h1:SHGqVdL7hd2ZaX2T9uEiOZ/OFAUfCCLURdLPJsd8ZNs=
|
4d63.com/tz v1.2.0/go.mod h1:SHGqVdL7hd2ZaX2T9uEiOZ/OFAUfCCLURdLPJsd8ZNs=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
@ -63,12 +61,6 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200817114649-df4adffc9d8c h1:W9P/cRMhwMMfrtInPTAn5rcNu/+vb3zKdGeAd+87tFs=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200817114649-df4adffc9d8c/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200818142706-50839af6027e h1:6P0tOQaAiB0G+etsknZvSDjNpdYshZ7wFXTqJpl41h0=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200818142706-50839af6027e/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200819183940-29e1ff8eb0bb h1:kvlW1qyM1aU3xeyeIVTU2jx5fSvjKpsU3aXvuaCMg3Q=
|
github.com/asaskevich/govalidator v0.0.0-20200819183940-29e1ff8eb0bb h1:kvlW1qyM1aU3xeyeIVTU2jx5fSvjKpsU3aXvuaCMg3Q=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200819183940-29e1ff8eb0bb/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
github.com/asaskevich/govalidator v0.0.0-20200819183940-29e1ff8eb0bb/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||||
|
@ -84,8 +76,6 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I=
|
|
||||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
|
||||||
github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2 h1:t8KYCwSKsOEZBFELI4Pn/phbp38iJ1RRAkDFNin1aak=
|
github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2 h1:t8KYCwSKsOEZBFELI4Pn/phbp38iJ1RRAkDFNin1aak=
|
||||||
github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
|
@ -296,10 +286,6 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 h1:VHgatEHNcBFEB7inlalqfNqw65aNkM1lGX2yt3NmbS8=
|
|
||||||
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
|
||||||
github.com/iancoleman/strcase v0.1.0 h1:Lar8rut26AXkJUmVOb2bRsFGv//+tJBeJLxXvpZpF1Q=
|
|
||||||
github.com/iancoleman/strcase v0.1.0/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
|
||||||
github.com/iancoleman/strcase v0.1.1 h1:2I+LRClyCYB7JgZb9U0k75VHUiQe9RfknRqDyUfzp7k=
|
github.com/iancoleman/strcase v0.1.1 h1:2I+LRClyCYB7JgZb9U0k75VHUiQe9RfknRqDyUfzp7k=
|
||||||
github.com/iancoleman/strcase v0.1.1/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
github.com/iancoleman/strcase v0.1.1/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
|
||||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||||
|
@ -433,6 +419,8 @@ github.com/lib/pq v1.6.0 h1:I5DPxhYJChW9KYc66se+oKFFQX6VuQrKiprsX6ivRZc=
|
||||||
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
|
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
|
||||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
|
||||||
|
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||||
|
@ -469,8 +457,6 @@ github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK86
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
|
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
|
||||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
github.com/mattn/go-sqlite3 v1.14.1 h1:AHx9Ra40wIzl+GelgX2X6AWxmT5tfxhI1PL0523HcSw=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.1/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.2 h1:A2EQLwjYf/hfYaM20FVjs1UewCTTFR7RmjEHkLjldIA=
|
github.com/mattn/go-sqlite3 v1.14.2 h1:A2EQLwjYf/hfYaM20FVjs1UewCTTFR7RmjEHkLjldIA=
|
||||||
github.com/mattn/go-sqlite3 v1.14.2/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
github.com/mattn/go-sqlite3 v1.14.2/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||||
|
@ -594,8 +580,6 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06B
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200627165143-92b8a710ab6c h1:XLPw6rny9Vrrvrzhw8pNLrC2+x/kH0a/3gOx5xWDa6Y=
|
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200627165143-92b8a710ab6c/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
|
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
@ -800,7 +784,10 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
||||||
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
648
magefile.go
Normal file
648
magefile.go
Normal file
|
@ -0,0 +1,648 @@
|
||||||
|
// Vikunja is a to-do list application to facilitate your life.
|
||||||
|
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// +build mage
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
"github.com/magefile/mage/mg"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PACKAGE = `code.vikunja.io/api`
|
||||||
|
DIST = `dist`
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Goflags = []string{
|
||||||
|
"-v",
|
||||||
|
}
|
||||||
|
Executable = "vikunja"
|
||||||
|
Ldflags = ""
|
||||||
|
Tags = ""
|
||||||
|
VersionNumber = "dev"
|
||||||
|
Version = "master" // This holds the built version, master by default, when building from a tag or release branch, their name
|
||||||
|
BinLocation = ""
|
||||||
|
PkgVersion = "master"
|
||||||
|
ApiPackages = []string{}
|
||||||
|
RootPath = ""
|
||||||
|
GoFiles = []string{}
|
||||||
|
|
||||||
|
// Aliases are mage aliases of targets
|
||||||
|
Aliases = map[string]interface{}{
|
||||||
|
"do-the-swag": DoTheSwag,
|
||||||
|
"check:go-sec": Check.GoSec,
|
||||||
|
"check:got-swag": Check.GotSwag,
|
||||||
|
"release:os-package": Release.OsPackage,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func setVersion() {
|
||||||
|
versionCmd := exec.Command("git", "describe", "--tags", "--always", "--abbrev=10")
|
||||||
|
version, err := versionCmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error getting version: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
VersionNumber = strings.Trim(string(version), "\n")
|
||||||
|
VersionNumber = strings.Replace(VersionNumber, "-", "+", 1)
|
||||||
|
VersionNumber = strings.Replace(VersionNumber, "-g", "-", 1)
|
||||||
|
|
||||||
|
if os.Getenv("DRONE_TAG") != "" {
|
||||||
|
Version = os.Getenv("DRONE_TAG")
|
||||||
|
} else if os.Getenv("DRONE_BRANCH") != "" {
|
||||||
|
Version = strings.Replace(os.Getenv("DRONE_BRANCH"), "release/v", "", 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setBinLocation() {
|
||||||
|
if os.Getenv("DRONE_WORKSPACE") != "" {
|
||||||
|
BinLocation = DIST + `/binaries/` + Executable + `-` + Version + `-linux-amd64`
|
||||||
|
} else {
|
||||||
|
BinLocation = Executable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setPkgVersion() {
|
||||||
|
if Version == "master" {
|
||||||
|
PkgVersion = VersionNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setExecutable() {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
Executable += ".exe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setApiPackages() {
|
||||||
|
cmd := exec.Command("go", "list", "all")
|
||||||
|
pkgs, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error getting packages: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for _, p := range strings.Split(string(pkgs), "\n") {
|
||||||
|
if strings.Contains(p, "code.vikunja.io/api") && !strings.Contains(p, "code.vikunja.io/api/pkg/integrations") {
|
||||||
|
ApiPackages = append(ApiPackages, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setRootPath() {
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error getting pwd: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := os.Setenv("VIKUNJA_SERVICE_ROOTPATH", pwd); err != nil {
|
||||||
|
fmt.Printf("Error setting root path: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
RootPath = pwd
|
||||||
|
}
|
||||||
|
|
||||||
|
func setGoFiles() {
|
||||||
|
// GOFILES := $(shell find . -name "*.go" -type f ! -path "*/bindata.go")
|
||||||
|
cmd := exec.Command("find", ".", "-name", "*.go", "-type", "f", "!", "-path", "*/bindata.go")
|
||||||
|
files, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error getting go files: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for _, f := range strings.Split(string(files), "\n") {
|
||||||
|
if strings.HasSuffix(f, ".go") {
|
||||||
|
GoFiles = append(GoFiles, RootPath+strings.TrimLeft(f, "."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Tags = os.Getenv("TAGS")
|
||||||
|
setVersion()
|
||||||
|
setExecutable()
|
||||||
|
setBinLocation()
|
||||||
|
setPkgVersion()
|
||||||
|
setApiPackages()
|
||||||
|
setRootPath()
|
||||||
|
setGoFiles()
|
||||||
|
Ldflags = `-X "` + PACKAGE + `/pkg/version.Version=` + VersionNumber + `" -X "main.Tags=` + Tags + `"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAndStreamOutput(cmd string, args ...string) {
|
||||||
|
c := exec.Command(cmd, args...)
|
||||||
|
|
||||||
|
c.Env = os.Environ()
|
||||||
|
c.Dir = RootPath
|
||||||
|
|
||||||
|
fmt.Printf("%s\n\n", c.String())
|
||||||
|
|
||||||
|
stdout, _ := c.StdoutPipe()
|
||||||
|
errbuf := bytes.Buffer{}
|
||||||
|
c.Stderr = &errbuf
|
||||||
|
c.Start()
|
||||||
|
|
||||||
|
reader := bufio.NewReader(stdout)
|
||||||
|
line, err := reader.ReadString('\n')
|
||||||
|
for err == nil {
|
||||||
|
fmt.Print(line)
|
||||||
|
line, err = reader.ReadString('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.Wait(); err != nil {
|
||||||
|
fmt.Printf(errbuf.String())
|
||||||
|
fmt.Printf("Error: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will check if the tool exists and if not install it from the provided import path
|
||||||
|
// If any errors occur, it will exit with a status code of 1.
|
||||||
|
func checkAndInstallGoTool(tool, importPath string) {
|
||||||
|
if err := exec.Command(tool).Run(); err != nil && strings.Contains(err.Error(), "executable file not found") {
|
||||||
|
fmt.Printf("%s not installed, installing %s...\n", tool, importPath)
|
||||||
|
if err := exec.Command("go", "install", Goflags[0], importPath).Run(); err != nil {
|
||||||
|
fmt.Printf("Error installing %s\n", tool)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println("Installed.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculates a hash of a file
|
||||||
|
func calculateSha256FileHash(path string) (hash string, err error) {
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
h := sha256.New()
|
||||||
|
if _, err := io.Copy(h, f); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the src file to dst. Any existing file will be overwritten and will not
|
||||||
|
// copy file attributes.
|
||||||
|
func copyFile(src, dst string) error {
|
||||||
|
in, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
out, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
si, err := os.Stat(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Chmod(dst, si.Mode()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formats the code using go fmt
|
||||||
|
func Fmt() {
|
||||||
|
args := append([]string{"-s", "-w"}, GoFiles...)
|
||||||
|
runAndStreamOutput("gofmt", args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates the swagger docs from the code annotations
|
||||||
|
func DoTheSwag() {
|
||||||
|
checkAndInstallGoTool("swag", "github.com/swaggo/swag/cmd/swag")
|
||||||
|
runAndStreamOutput("swag", "init", "-g", "./pkg/routes/routes.go", "--parseDependency", "-d", RootPath, "-o", RootPath+"/pkg/swagger")
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test mg.Namespace
|
||||||
|
|
||||||
|
// Runs all tests except integration tests
|
||||||
|
func (Test) Unit() {
|
||||||
|
// We run everything sequentially and not in parallel to prevent issues with real test databases
|
||||||
|
args := append([]string{"test", Goflags[0], "-p", "1"}, ApiPackages...)
|
||||||
|
runAndStreamOutput("go", args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs the tests and builds the coverage html file from coverage output
|
||||||
|
func (Test) Coverage() {
|
||||||
|
mg.Deps(Test.Unit)
|
||||||
|
runAndStreamOutput("go", "tool", "cover", "-html=cover.out", "-o", "cover.html")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs the integration tests
|
||||||
|
func (Test) Integration() {
|
||||||
|
// We run everything sequentially and not in parallel to prevent issues with real test databases
|
||||||
|
runAndStreamOutput("go", "test", Goflags[0], "-p", "1", PACKAGE+"/pkg/integrations")
|
||||||
|
}
|
||||||
|
|
||||||
|
type Check mg.Namespace
|
||||||
|
|
||||||
|
// Checks if the code is properly formatted with go fmt
|
||||||
|
func (Check) Fmt() error {
|
||||||
|
args := append([]string{"-s", "-d"}, GoFiles...)
|
||||||
|
c := exec.Command("gofmt", args...)
|
||||||
|
out, err := c.Output()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(out) > 0 {
|
||||||
|
fmt.Println("Code is not properly gofmt'ed.")
|
||||||
|
fmt.Println("Please run 'mage fmt' and commit the result:")
|
||||||
|
fmt.Print(string(out))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs golint on all packages
|
||||||
|
func (Check) Lint() {
|
||||||
|
checkAndInstallGoTool("golint", "golang.org/x/lint/golint")
|
||||||
|
args := append([]string{"-set_exit_status"}, ApiPackages...)
|
||||||
|
runAndStreamOutput("golint", args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the swagger docs need to be re-generated from the code annotations
|
||||||
|
func (Check) GotSwag() {
|
||||||
|
// The check is pretty cheaply done: We take the hash of the swagger.json file, generate the docs,
|
||||||
|
// hash the file again and compare the two hashes to see if anything changed. If that's the case,
|
||||||
|
// regenerating the docs is necessary.
|
||||||
|
// swag is not capable of just outputting the generated docs to stdout, therefore we need to do it this way.
|
||||||
|
// Another drawback of this is obviously it will only work once - we're not resetting the newly generated
|
||||||
|
// docs after the check. This behaviour is good enough for ci though.
|
||||||
|
oldHash, err := calculateSha256FileHash(RootPath + "/pkg/swagger/swagger.json")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error getting old hash of the swagger docs: %s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
DoTheSwag()
|
||||||
|
|
||||||
|
newHash, err := calculateSha256FileHash(RootPath + "/pkg/swagger/swagger.json")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error getting new hash of the swagger docs: %s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldHash != newHash {
|
||||||
|
fmt.Println("Swagger docs are not up to date.")
|
||||||
|
fmt.Println("Please run 'mage do-the-swag' and commit the result.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks the source code for misspellings
|
||||||
|
func (Check) Misspell() {
|
||||||
|
checkAndInstallGoTool("misspell", "github.com/client9/misspell/cmd/misspell")
|
||||||
|
runAndStreamOutput("misspell", append([]string{"-error"}, GoFiles...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks the source code for ineffectual assigns
|
||||||
|
func (Check) Ineffassign() {
|
||||||
|
checkAndInstallGoTool("ineffassign", "github.com/gordonklaus/ineffassign")
|
||||||
|
runAndStreamOutput("ineffassign", GoFiles...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks for the cyclomatic complexity of the source code
|
||||||
|
func (Check) Gocyclo() {
|
||||||
|
checkAndInstallGoTool("gocyclo", "github.com/fzipp/gocyclo")
|
||||||
|
runAndStreamOutput("gocyclo", append([]string{"-over", "49"}, GoFiles...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statically analyzes the source code about a range of different problems
|
||||||
|
func (Check) Static() {
|
||||||
|
checkAndInstallGoTool("staticcheck", "honnef.co/go/tools/cmd/staticcheck")
|
||||||
|
runAndStreamOutput("staticcheck", ApiPackages...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks the source code for potential security issues
|
||||||
|
func (Check) GoSec() {
|
||||||
|
if err := exec.Command("gosec").Run(); err != nil && strings.Contains(err.Error(), "executable file not found") {
|
||||||
|
fmt.Println("Please manually install gosec by running")
|
||||||
|
fmt.Println("curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | bash -s -- -b $GOPATH/bin v2.2.0")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
runAndStreamOutput("gosec", "./...")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks for repeated strings that could be replaced by a constant
|
||||||
|
func (Check) Goconst() {
|
||||||
|
checkAndInstallGoTool("goconst", "github.com/jgautheron/goconst/cmd/goconst")
|
||||||
|
runAndStreamOutput("goconst", ApiPackages...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs fmt-check, lint, got-swag, misspell-check, ineffasign-check, gocyclo-check, static-check, gosec-check, goconst-check all in parallel
|
||||||
|
func (Check) All() {
|
||||||
|
mg.Deps(
|
||||||
|
Check.Fmt,
|
||||||
|
Check.Lint,
|
||||||
|
Check.GotSwag,
|
||||||
|
Check.Misspell,
|
||||||
|
Check.Ineffassign,
|
||||||
|
Check.Gocyclo,
|
||||||
|
Check.Static,
|
||||||
|
Check.GoSec,
|
||||||
|
Check.Goconst,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Build mg.Namespace
|
||||||
|
|
||||||
|
// Cleans all build, executable and bindata files
|
||||||
|
func (Build) Clean() error {
|
||||||
|
if err := exec.Command("go", "clean", "./...").Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Remove(Executable); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.RemoveAll(DIST); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.RemoveAll(BinLocation); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates static content into the final binary
|
||||||
|
func (Build) Generate() {
|
||||||
|
runAndStreamOutput("go", "generate", PACKAGE+"/pkg/static")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds a vikunja binary, ready to run
|
||||||
|
func (Build) Build() {
|
||||||
|
mg.Deps(Build.Generate)
|
||||||
|
runAndStreamOutput("go", "build", Goflags[0], "-tags", Tags, "-ldflags", "-s -w "+Ldflags, "-o", Executable)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Release mg.Namespace
|
||||||
|
|
||||||
|
// Runs all steps in the right order to create release packages for various platforms
|
||||||
|
func (Release) Release(ctx context.Context) error {
|
||||||
|
mg.Deps(Build.Generate, Release.Dirs)
|
||||||
|
mg.Deps(Release.Windows, Release.Linux, Release.Darwin)
|
||||||
|
|
||||||
|
// Run compiling in parallel to speed it up
|
||||||
|
errs, _ := errgroup.WithContext(ctx)
|
||||||
|
errs.Go((Release{}).Windows)
|
||||||
|
errs.Go((Release{}).Linux)
|
||||||
|
errs.Go((Release{}).Darwin)
|
||||||
|
if err := errs.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := (Release{}).Compress(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := (Release{}).Copy(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := (Release{}).Check(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := (Release{}).OsPackage(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := (Release{}).Zip(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates all directories needed to release vikunja
|
||||||
|
func (Release) Dirs() error {
|
||||||
|
for _, d := range []string{"binaries", "release", "zip"} {
|
||||||
|
if err := os.MkdirAll(RootPath+"/"+DIST+"/"+d, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runXgo(targets string) error {
|
||||||
|
checkAndInstallGoTool("xgo", "src.techknowlogick.com/xgo")
|
||||||
|
runAndStreamOutput("xgo",
|
||||||
|
"-dest", RootPath+"/"+DIST+"/binaries",
|
||||||
|
"-tags", "netgo "+Tags,
|
||||||
|
"-ldflags", `-linkmode external -extldflags "-static" `+Ldflags,
|
||||||
|
"-targets", targets,
|
||||||
|
"-out", Executable+"-"+Version,
|
||||||
|
RootPath)
|
||||||
|
if os.Getenv("DRONE_WORKSPACE") != "" {
|
||||||
|
return filepath.Walk("/build/", func(path string, info os.FileInfo, err error) error {
|
||||||
|
return os.Rename(path, RootPath+"/"+DIST+"/binaries/"+info.Name())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds binaries for windows
|
||||||
|
func (Release) Windows() error {
|
||||||
|
return runXgo("windows/*")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds binaries for linux
|
||||||
|
func (Release) Linux() error {
|
||||||
|
return runXgo("linux/*")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds binaries for darwin
|
||||||
|
func (Release) Darwin() error {
|
||||||
|
return runXgo("darwin/*")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compresses the built binaries in dist/binaries/ to reduce their filesize
|
||||||
|
func (Release) Compress(ctx context.Context) error {
|
||||||
|
// $(foreach file,$(filter-out $(wildcard $(wildcard $(DIST)/binaries/$(EXECUTABLE)-*mips*)),$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*)), upx -9 $(file);)
|
||||||
|
|
||||||
|
errs, _ := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
filepath.Walk(RootPath+"/"+DIST+"/binaries/", func(path string, info os.FileInfo, err error) error {
|
||||||
|
// Only executable files
|
||||||
|
if !strings.Contains(info.Name(), Executable) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// No mips or s390x for you today
|
||||||
|
if strings.Contains(info.Name(), "mips") || strings.Contains(info.Name(), "s390x") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs compressing in parallel since upx is single-threaded
|
||||||
|
errs.Go(func() error {
|
||||||
|
runAndStreamOutput("upx", "-9", path)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return errs.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copies all built binaries to dist/release/ in preparation for creating the os packages
|
||||||
|
func (Release) Copy() error {
|
||||||
|
return filepath.Walk(RootPath+"/"+DIST+"/binaries/", func(path string, info os.FileInfo, err error) error {
|
||||||
|
// Only executable files
|
||||||
|
if !strings.Contains(info.Name(), Executable) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return copyFile(path, RootPath+"/"+DIST+"/release/"+info.Name())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates sha256 checksum files for each binary in dist/release/
|
||||||
|
func (Release) Check() error {
|
||||||
|
p := RootPath + "/" + DIST + "/release/"
|
||||||
|
return filepath.Walk(p, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Create(p + info.Name() + ".sha256")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := calculateSha256FileHash(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = f.WriteString(hash + " " + info.Name())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.Close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a folder for each
|
||||||
|
func (Release) OsPackage() error {
|
||||||
|
p := RootPath + "/" + DIST + "/release/"
|
||||||
|
|
||||||
|
// We first put all files in a map to then iterate over it since the walk function would otherwise also iterate
|
||||||
|
// over the newly created files, creating some kind of endless loop.
|
||||||
|
bins := make(map[string]os.FileInfo)
|
||||||
|
if err := filepath.Walk(p, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if strings.Contains(info.Name(), ".sha256") || info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
bins[path] = info
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for path, info := range bins {
|
||||||
|
folder := p + info.Name() + "-full/"
|
||||||
|
if err := os.Mkdir(folder, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Rename(p+info.Name()+".sha256", folder+info.Name()+".sha256"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Rename(path, folder+info.Name()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := copyFile(RootPath+"/config.yml.sample", folder+"config.yml.sample"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := copyFile(RootPath+"/LICENSE", folder+"LICENSE"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a zip file from all os-package folders in dist/release
|
||||||
|
func (Release) Zip() error {
|
||||||
|
p := RootPath + "/" + DIST + "/release/"
|
||||||
|
if err := filepath.Walk(p, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if !info.IsDir() || info.Name() == "release" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Zipping %s...\n", info.Name())
|
||||||
|
|
||||||
|
c := exec.Command("zip", "-r", RootPath+"/"+DIST+"/zip/"+info.Name(), ".", "-i", "*")
|
||||||
|
c.Dir = path
|
||||||
|
out, err := c.Output()
|
||||||
|
fmt.Print(string(out))
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a debian package from a built binary
|
||||||
|
func (Release) Deb() {
|
||||||
|
runAndStreamOutput(
|
||||||
|
"fpm",
|
||||||
|
"-s", "dir",
|
||||||
|
"-t", "deb",
|
||||||
|
"--url", "https://vikunja.io",
|
||||||
|
"-n", "vikunja",
|
||||||
|
"-v", PkgVersion,
|
||||||
|
"--license", "GPLv3",
|
||||||
|
"--directories", "/opt/vikunja",
|
||||||
|
"--after-install", "./build/after-install.sh",
|
||||||
|
"--description", "'Vikunja is an open-source todo application, written in Go. It lets you create lists,tasks and share them via teams or directly between users.'",
|
||||||
|
"-m", "maintainers@vikunja.io",
|
||||||
|
"-p", RootPath+"/"+Executable+"-"+Version+"_amd64.deb",
|
||||||
|
"./"+BinLocation+"=/opt/vikunja/vikunja",
|
||||||
|
"./config.yml.sample=/etc/vikunja/config.yml",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a debian repo structure
|
||||||
|
func (Release) Reprepro() {
|
||||||
|
runAndStreamOutput("reprepro_expect", "debian", "includedeb", "strech", RootPath+"/"+Executable+"-"+Version+"_amd64.deb")
|
||||||
|
}
|
|
@ -6157,7 +6157,6 @@ var doc = `{
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"code.vikunja.io.web.HTTPError": {"type": "object","properties": {"code": {"type": "integer"},"message": {"type": "string"}}},
|
|
||||||
"afero.File": {
|
"afero.File": {
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,4 +20,4 @@ package version
|
||||||
// It is an own package to avoid import cycles
|
// It is an own package to avoid import cycles
|
||||||
|
|
||||||
// Version sets the version to be printed to the user. Gets overwritten by "make release" or "make build" with last git commit or tag.
|
// Version sets the version to be printed to the user. Gets overwritten by "make release" or "make build" with last git commit or tag.
|
||||||
var Version = "0.7"
|
var Version = "dev"
|
||||||
|
|
2
tools.go
2
tools.go
|
@ -33,4 +33,6 @@ import (
|
||||||
_ "honnef.co/go/tools/cmd/staticcheck"
|
_ "honnef.co/go/tools/cmd/staticcheck"
|
||||||
|
|
||||||
_ "github.com/shurcooL/vfsgen"
|
_ "github.com/shurcooL/vfsgen"
|
||||||
|
|
||||||
|
_ "github.com/magefile/mage"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue