refactor: replace make with mage

This commit removes the Makefile and uses mage to build the CV files and Docker images.

Changes include:

- All make targets are re-written in go in magefile.go
- The spellcheck script is now written in go and is part of the magefile
- Created mage.go to remove dependency on a mage binary
- Updated CI pipelines to use mage
- Removed unused Makefile
- Removed unused spellcheck bash script
- Cleaned up .gitignore
- Updated .aspell/.aspell.en.pws

NOTE: The updated pipeline for generating the docker image is untested for this MR.
This commit is contained in:
Dan Anglin 2020-08-09 05:08:30 +01:00
parent 64e3560d69
commit 5fd72b045a
No known key found for this signature in database
GPG key ID: 7AC2B18EC1D09F27
10 changed files with 175 additions and 119 deletions

View file

@ -1,4 +1,4 @@
personal_ws-1.1 en 50
personal_ws-1.1 en 52
Alertmanager
Anglin
Ansible

3
.gitignore vendored
View file

@ -1,5 +1,2 @@
__output/*
!__output/cv.pdf
tags
notes.txt
aspell_output

View file

@ -1,79 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
ASPELL_LANG='en_GB'
ASPELL_PERSONAL_WORDLIST='./.aspell/.aspell.en.pws'
DEFAULT_OUTPUT='aspell_output'
RED='\033[1;31m'
AMBER='\033[1;33m'
GREEN='\033[1;32m'
NC='\033[0m'
inputFile=''
outputFile=''
usage () {
echo "Usage:"
echo "spellcheck [OPTION]..."
echo
echo "Description:"
echo -e "\tspellcheck is a wrapper script that uses aspell to check the spelling of"
echo -e "\tall words in a file. Any detected spelling errors are printed to screen"
echo -e "\tand to an output file."
echo
echo "Options:"
echo -e "\t-i\tinput file for spell checking."
echo -e "\t-o\toutput file where list of spelling errors are written to."
echo -e "\t\tThe default output file is ${DEFAULT_OUTPUT}."
echo -e "\t-h\tprints usage."
echo
echo -e "Examples:"
echo -e "\tspellcheck -i my_file.txt -o output.txt"
echo -e "\tspellcheck -i my_file"
}
validate_args() {
if [ -z "$inputFile" ]; then
echo -e "${RED}ERROR: ${NC}Option '-i' is not set or is empty."
usage
return 1
fi
if [ -z "$outputFile" ]; then
echo -e "${AMBER}WARNING: ${NC}Option '-o' is not set or is empty. The output file will be set to ${DEFAULT_OUTPUT}"
outputFile=${DEFAULT_OUTPUT}
fi
return 0
}
spellcheck() {
cat ${inputFile} | aspell -d ${ASPELL_LANG} -p ${ASPELL_PERSONAL_WORDLIST} list > ${outputFile}
let spellingErrors=$( cat ${outputFile} | wc -l )
if [ $spellingErrors -gt 0 ]; then
echo
echo -e "${RED}ERROR: ${NC}The following spelling errors were found in ${inputFile}:"
cat ${outputFile}
return 1
else
echo
echo -e "${GREEN}INFO: ${NC}No spelling errors found."
fi
return 0
}
while getopts 'i:o:h' flag; do
case "${flag}" in
i) inputFile=${OPTARG} ;;
o) outputFile=${OPTARG} ;;
h) usage && exit 0 ;;
*) usage && exit 2 ;;
esac
done
validate_args || exit 1
spellcheck || exit 1

View file

@ -27,13 +27,13 @@
test:spellcheck:
before_script:
- apt-get update
- apt-get -y install aspell make
- apt-get -y install aspell aspell-en
extends:
- .cv-test-rules
image: ubuntu:18.04
- .use-cv-builder
stage: test
script:
- make spellcheck
- go run mage.go spellcheck
test:pdf:
artifacts:
@ -45,7 +45,7 @@ test:pdf:
- .cv-test-rules
stage: test
script:
- make clean pdf
- go run mage.go pdf
publish:pdf:
extends:
@ -62,7 +62,7 @@ publish:pdf:
- git config --global user.name "${GITLAB_USER_NAME}"
stage: publish
script:
- make clean pdf
- go run mage.go pdf
- git checkout master
- git add __output/cv.pdf
- 'git commit -m "auto: [skip ci] update CV."'

View file

@ -7,7 +7,7 @@
services:
- docker:19.03.12-dind
before_script:
- apk add --no-cache make
- apk add --no-cache go
.dockerfile-lint:
stage: test
@ -29,7 +29,7 @@
stage: publish
extends: .docker-build-setup
before_script:
- apk add --no-cache make
- apk add --no-cache go
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
after_script:
- docker logout ${CI_REGISTRY}
@ -55,11 +55,11 @@ test:docker:build:
- .dockerbuild-test
- .docker-test-rules
script:
- make image
- go run mage.go image
publish:docker-image:
extends:
- .docker-publish-pre-post
- .docker-publish-rules
script:
- make publish
- go run mage.go publishImage

View file

@ -1,27 +0,0 @@
DOCKERFILE = ./docker/Dockerfile
IMAGE_NAME ?= cv-builder
IMAGE_TAG ?= latest
OUTPUT_DIR = __output/
CV_DATA_FILE = ./data/cv.json
.PHONY: all image publish tex pdf clean
all: pdf
image:
@docker build -f $(DOCKERFILE) -t $(IMAGE_NAME):$(IMAGE_TAG) .
publish: image
@docker push $(IMAGE_NAME):$(IMAGE_TAG)
spellcheck:
@./.gitlab/ci/bin/spellcheck -i $(CV_DATA_FILE)
tex:
@go run .
pdf: tex
@mtxrun --path=$(OUTPUT_DIR) --script context cv.tex
clean:
@rm -rf $(OUTPUT_DIR)

2
go.mod
View file

@ -1,3 +1,5 @@
module gitlab.com/dananglin/cv
go 1.12
require github.com/magefile/mage v1.10.0

2
go.sum Normal file
View file

@ -0,0 +1,2 @@
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=

13
mage.go Normal file
View file

@ -0,0 +1,13 @@
// +build ignore
package main
import (
"os"
"github.com/magefile/mage/mage"
)
func main() {
os.Exit(mage.Main())
}

148
magefile.go Normal file
View file

@ -0,0 +1,148 @@
// +build mage
package main
import (
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"strings"
"github.com/magefile/mage/mg"
"github.com/magefile/mage/sh"
)
const (
aspellLang string = "en_GB"
aspellPersonalWordlist string = "./.aspell/.aspell.en.pws"
cvJsonDataFile string = "./data/cv.json"
defaultImageName string = "cv-builder"
defaultImageTag string = "latest"
dockerfile string = "./docker/Dockerfile"
outputDir string = "./__output"
)
// Default sets the default target.
var Default = Pdf
// SpellCheck checks the CV JSON file for spelling errors. If there are any
// misspelt words found the function returns a list of those words in an error.
// Any error found while gathering the list is returned.
// This function depends on the aspell program.
func SpellCheck() error {
fmt.Printf("Reading data from %s...\n", cvJsonDataFile)
data, err := ioutil.ReadFile(cvJsonDataFile)
if err != nil {
return fmt.Errorf("unable to read data from %s, %s", cvJsonDataFile, err.Error())
}
// declare the aspell command and its standard input pipe.
cmd := exec.Command("aspell", "-d", aspellLang, "-p", aspellPersonalWordlist, "list")
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
// write the CV data to standard input for piping.
go func() {
defer stdin.Close()
io.WriteString(stdin, string(data))
}()
// run aspell and get the list of mispelt words (if any).
// (the output is a string.)
fmt.Println("Running aspell...")
out, err := cmd.CombinedOutput()
if err != nil {
return err
}
list := strings.Split(string(out), "\n")
if list[len(list)-1] == "" {
list = list[:len(list)-1]
}
if len(list) > 0 {
var b strings.Builder
errMsg := fmt.Sprintf("the following spelling errors were found in %s:", cvJsonDataFile)
b.WriteString(errMsg)
for _, v := range list {
s := "\n- " + v
b.WriteString(s)
}
return fmt.Errorf(b.String())
} else {
fmt.Println("No spelling errors were found.")
}
return nil
}
// Tex takes the CV data file and generates the output tex file from
// template.
func Tex() error {
fmt.Println("Generating the tex file...")
mg.Deps(Clean)
gocmd := mg.GoCmd()
return sh.Run(gocmd, "run", ".")
}
// Pdf takes the output tex file generated by the Tex target and
// generates the output PDF file.
func Pdf() error {
mg.Deps(Tex)
pathArg := "--path=" + outputDir
fmt.Println("Generating the PDF file...")
return sh.Run("mtxrun", pathArg, "--script", "context", "cv.tex")
}
// Image builds the CV builder docker image.
func Image() error {
image := imageName()
return sh.Run("docker", "build", "-f", dockerfile, "-t", image, ".")
}
// PublishImage publishes the CV builder docker image
// to the docker registry.
func PublishImage() error {
mg.Deps(Image)
image := imageName()
return sh.Run("docker", "push", image)
}
// Clean removes the directory where the output files
// are generated.
func Clean() error {
if err := sh.Rm(outputDir); err != nil {
return err
}
return nil
}
// imageName generates the docker image name from the environment
// variables IMAGE_NAME and IMAGE_TAG. Default vaules will be used
// if these variables are not set or empty.
func imageName() string {
name := os.Getenv("IMAGE_NAME")
if len(name) == 0 {
name = defaultImageName
}
tag := os.Getenv("IMAGE_TAG")
if len(tag) == 0 {
tag = defaultImageTag
}
return name + ":" + tag
}