// +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 }