From 86215c2e57206da22b04a49838630bb2bce41774 Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Tue, 14 Feb 2023 08:21:46 +0000 Subject: [PATCH] chore: remove CV builder code from repository The code is now managed in the cv-builder repository in apollo. --- .dockerignore | 5 -- .hadolint.yaml | 2 - LICENSE | 21 ----- README.md | 96 ---------------------- data/cv.json => cv.json | 0 docker/Dockerfile | 47 ----------- go.mod | 5 -- go.sum | 2 - magefiles/cv.go | 53 ------------ magefiles/helpers.go | 145 --------------------------------- magefiles/mage.go | 77 ----------------- magefiles/templatefuncs.go | 36 -------- template/tex/cv.tmpl.tex | 54 ------------ template/tex/cv_setup.tmpl.tex | 78 ------------------ 14 files changed, 621 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .hadolint.yaml delete mode 100644 LICENSE delete mode 100644 README.md rename data/cv.json => cv.json (100%) delete mode 100644 docker/Dockerfile delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 magefiles/cv.go delete mode 100644 magefiles/helpers.go delete mode 100644 magefiles/mage.go delete mode 100644 magefiles/templatefuncs.go delete mode 100644 template/tex/cv.tmpl.tex delete mode 100644 template/tex/cv_setup.tmpl.tex diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 214118b..0000000 --- a/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -* -!magefile.go -!helpers/* -!go.mod -!go.sum diff --git a/.hadolint.yaml b/.hadolint.yaml deleted file mode 100644 index afcc8b3..0000000 --- a/.hadolint.yaml +++ /dev/null @@ -1,2 +0,0 @@ -ignored: -- DL3015 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7a0d3d6..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Dan Anglin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 3baf13a..0000000 --- a/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# My CV Project - -## Table of Contents - -- [Overview](#overview) -- [Dependencies](#dependencies) -- [Using Docker as an alternative](#using-docker-as-an-alternative) -- [Generating the PDF Document](#generating-the-pdf-document) -- [Inspirations](#inspirations) - -## Overview - -This project parses my [CV](./data/cv.json) that is written as -a JSON document and generates a PDF document. -This project contains a Go application and uses the ConTeXt document processor -which are used to parse and generate a PDF document from the CV. -I chose to use ConTeXt as the document processor because it gives me more -control to edit page layouts, configure fonts, -perform additional formatting and add custom functionality. - -Support for other formats such as HTML will be available soon. - -### View/Download the CV - -The latest build of the generated PDF document can be downloaded from the [release](https://gitlab.com/dananglin/cv/-/releases) page of the project in GitLab. - -## Dependencies - -If you are interested in generating the PDF document on your own machines -or want to use the project to generate your own CV, then below is a list -of dependencies that you'll need to install: - -- **Go** - Please go [here](https://golang.org/dl/) to download the latest version of the Go programming language. -- **ConTeXt** - I recommend installing version 1.02 or higher. Please go [here](https://wiki.contextgarden.net/ConTeXt_Standalone) for installation instructions for your distribution. -- **The Carlito font (ttf-carlito)** - In prevous iterations of my CV I used the Calibri font. Carlito is the free, metric compatible alternative to this and is specified in the TEX template. - - For Ubuntu/Debian installation you can use `apt`: - ```bash - $ apt-get install font-crosextra-carlito - ``` - - For Arch Linux you can use `pacman`: - ```bash - $ pacman -S ttf-carlito - ``` - - Alternatively you can download the font from https://fontlibrary.org/en/font/carlito - - Once this font is installed you'll need to update ConTeXt so it can find the font when generating the PDF: - ```bash - $ OSFONTDIR=/usr/share/fonts - $ mtxrun --script fonts --reload - ``` - -Once the dependencies are installed you can follow the -[Generating the PDF Document](#generating-the-pdf-document) section below. - -## Using Docker as an alternative - -If you prefer not to install the dependencies above, -I have created a Docker image installed with the above dependencies. -This image is used to build and publish the CV via the GitLab CI pipleines. -The image is built using this [Dockerfile](./docker/Dockerfile) and is -pullable from [GitLab's container registry](https://gitlab.com/dananglin/cv/container_registry). - -To use the image follow the steps below: - -1. Make sure you've clone this project to your workspace: - ```bash - $ git clone https://gitlab.com/dananglin/cv.git - $ cd cv - ``` - -2. Create the docker container and mount the current directory to the /project directory inside the container: - ```bash - $ docker run --rm -it -v ${PWD}:/project registry.gitlab.com/dananglin/cv/cv-builder:master-44f2a31c bash - - # Once inside the docker container - $ cd /project - ``` - -3. Follow the [Generating the PDF Document](#generating-the-pdf-document) section below. - -## Generating the PDF Document - -The PDF document can be generated by running the following command: - -```bash -$ go run mage.go pdf -``` - -The PDF generation is completed in two steps: - -1. The Go application will generate a TEX file using the JSON document and the TEX template files located in the [template](./template) directory. -2. ConTeXt is then used to generate the PDF document from the generated TEX file. - -## Inspirations - -- [The Markdown Resume](https://mszep.github.io/pandoc_resume/) - This project uses ConTeXt and pandoc to convert Markdown based CVs into multiple formats including PDF, HTML and DOCX. This is where I discovered ConTeXt. -- [melkir/resume](https://github.com/melkir/resume) - This project generates CVs using Go and LaTeX. diff --git a/data/cv.json b/cv.json similarity index 100% rename from data/cv.json rename to cv.json diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index d5e6d83..0000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,47 +0,0 @@ -FROM golang:1.19-buster AS builder - -RUN git clone https://github.com/magefile/mage "${GOPATH}/src/mage" - -WORKDIR ${GOPATH}/src/mage - -RUN go run bootstrap.go - -COPY go.mod ${GOPATH}/cv-builder/ -COPY go.sum ${GOPATH}/cv-builder/ -COPY magefile.go ${GOPATH}/cv-builder/ -COPY helpers ${GOPATH}/cv-builder/helpers - -WORKDIR ${GOPATH}/cv-builder - -RUN mage -compile /usr/local/bin/cv-make - -FROM debian:buster - -COPY --from=builder /usr/local/bin/cv-make /usr/local/bin - -# Install dependencies -RUN \ - apt-get update \ - && apt-get install -y \ - fonts-crosextra-carlito \ - rsync \ - curl= \ - aspell \ - aspell-en \ - && apt-get clean autoclean \ - && apt-get autoremove -y \ - && rm -rf /var/lib/apt/lists/* /tmp/* \ - && mkdir /opt/context - -WORKDIR /opt/context - -# Install ConTeXt standalone -RUN \ - curl -LO http://minimals.contextgarden.net/setup/first-setup.sh \ - && sh first-setup.sh --context=current --engine=luatex \ - && rm -rf /opt/context/tex/texmf-context/doc - -ENV PATH=${PATH}:/opt/context/tex/texmf-linux-64/bin \ - OSFONTDIR=/usr/share/fonts - -RUN mtxrun --script fonts --reload diff --git a/go.mod b/go.mod deleted file mode 100644 index 292f808..0000000 --- a/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module gitlab.com/dananglin/cv - -go 1.19 - -require github.com/magefile/mage v1.14.0 diff --git a/go.sum b/go.sum deleted file mode 100644 index f8bfb2f..0000000 --- a/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= -github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= diff --git a/magefiles/cv.go b/magefiles/cv.go deleted file mode 100644 index 5348620..0000000 --- a/magefiles/cv.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build mage - -package main - -type Cv struct { - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - JobTitle string `json:"jobTitle"` - Contact Contact `json:"contact"` - Links Links `json:"links"` - Summary []string `json:"summary"` - Technologies []Technologies `json:"technologies"` - Employment []Experience `json:"employment"` - Education []Experience `json:"education"` - Interests []string `json:"interests"` -} - -type Contact struct { - Email string `json:"email"` - Phone string `json:"phone"` - Location string `json:"location"` -} - -type Links struct { - LinkedIn string `json:"linkedin"` - GitHub string `json:"github"` -} - -type Technologies struct { - Category string `json:"category"` - Values []string `json:"values"` -} - -type Experience struct { - Company string `json:"company,omitempty"` - School string `json:"school,omitempty"` - Location string `json:"location"` - JobTitle string `json:"jobTitle,omitempty"` - Qualification string `json:"qualification,omitempty"` - Duration Duration `json:"duration"` - Details []string `json:"details"` -} - -type Duration struct { - Start Date `json:"start"` - End Date `json:"end"` - Present string `json:"present"` -} - -type Date struct { - Year string `json:"year"` - Month string `json:"month"` -} diff --git a/magefiles/helpers.go b/magefiles/helpers.go deleted file mode 100644 index 3e90a02..0000000 --- a/magefiles/helpers.go +++ /dev/null @@ -1,145 +0,0 @@ -//go:build mage - -package main - -import ( - "encoding/json" - "fmt" - "io" - "os" - "os/exec" - "strings" - "text/template" -) - -const ( - aspellLang string = "en_GB" - defaultImageName string = "cv-builder" - defaultImageTag string = "latest" -) - -// 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 -} - -// createCVTex generates the CV docuemnt as a Tex file. -func createCVTex(cvJsonDataFile, cvTemplateDir, cvOutputDir, cvOutputFileName string) error { - fmt.Printf("INFO: Attempting to read data from %s...\n", cvJsonDataFile) - - data, err := os.ReadFile(cvJsonDataFile) - if err != nil { - return fmt.Errorf("unable to read data from file. %w", err) - } - - fmt.Println("INFO: Successfully read data.") - - fmt.Println("INFO: Attempting to unmarshal JSON data...") - - var cv Cv - if err = json.Unmarshal(data, &cv); err != nil { - return fmt.Errorf("unable to unmarshal JSON data; %w", err) - } - - fmt.Println("INFO: JSON unmarshalling was successful.") - - // if CV_CONTACT_PHONE is set then add it to the CV - phone := os.Getenv("CV_CONTACT_PHONE") - if len(phone) > 0 { - cv.Contact.Phone = phone - } - - cvOutputPath := cvOutputDir + "/" + cvOutputFileName - fmt.Printf("INFO: Attempting to create output file %s...\n", cvOutputPath) - - if err = os.MkdirAll(cvOutputDir, 0750); err != nil { - return fmt.Errorf("unable to create output directory %s; %w", cvOutputDir, err) - } - - output, err := os.Create(cvOutputPath) - if err != nil { - return fmt.Errorf("unable to create output file %s; %w", cvOutputPath, err) - } - fmt.Printf("INFO: Successfully created output file %s.\n", cvOutputPath) - defer output.Close() - - fmt.Println("INFO: Attempting template execution...") - fmap := template.FuncMap{ - "notLastElement": notLastElement, - "join": join, - "durationToString": durationToString, - } - - t := template.Must(template.New("cv.tmpl.tex").Funcs(fmap).Delims("<<", ">>").ParseGlob(cvTemplateDir + "*.tmpl.tex")) - - if err = t.Execute(output, cv); err != nil { - return fmt.Errorf("unable to execute the CV template. %w", err) - } - fmt.Println("INFO: Template execution successful.") - - return nil -} - -func spellCheck(dataFile, aspellPersonalWordlist string) error { - fmt.Printf("INFO: Reading data from %s...\n", dataFile) - - data, err := os.ReadFile(dataFile) - if err != nil { - return fmt.Errorf("unable to read data from %s, %s", dataFile, 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:", dataFile) - 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 -} diff --git a/magefiles/mage.go b/magefiles/mage.go deleted file mode 100644 index d8ce030..0000000 --- a/magefiles/mage.go +++ /dev/null @@ -1,77 +0,0 @@ -//go:build mage - -package main - -import ( - "fmt" - - "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" -) - -const ( - aspellPersonalWordlist string = "./.aspell/.aspell.en.pws" - cvJsonDataFile string = "./data/cv.json" - cvOutputDir string = "./__output" - cvTemplateDir string = "./template/tex/" - cvOutputFileName string = "cv.tex" - dockerfile string = "./docker/Dockerfile" -) - -// 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 { - return spellCheck(cvJsonDataFile, aspellPersonalWordlist) -} - -// 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) - - return createCVTex(cvJsonDataFile, cvTemplateDir, cvOutputDir, cvOutputFileName) -} - -// 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=" + cvOutputDir - - 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(cvOutputDir); err != nil { - return err - } - - return nil -} diff --git a/magefiles/templatefuncs.go b/magefiles/templatefuncs.go deleted file mode 100644 index f42ad30..0000000 --- a/magefiles/templatefuncs.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build mage - -package main - -import ( - "fmt" - "strings" -) - -// notLastElement returns true if an element of an array -// or a slice is not the last. -func notLastElement(pos, length int) bool { - return pos < length-1 -} - -// join uses strings.Join to join all string elements into -// a single string. -func join(s []string) string { - return strings.Join(s, " ") -} - -// durationToString outputs the employment/education -// duration as a formatted string. -func durationToString(d Duration) string { - start := fmt.Sprintf("%s, %s", d.Start.Month, d.Start.Year) - present := strings.ToLower(d.Present) - end := "" - - if present == "yes" || present == "true" { - end = "Present" - } else { - end = fmt.Sprintf("%s, %s", d.End.Month, d.End.Year) - } - - return start + " - " + end -} diff --git a/template/tex/cv.tmpl.tex b/template/tex/cv.tmpl.tex deleted file mode 100644 index 35caa3a..0000000 --- a/template/tex/cv.tmpl.tex +++ /dev/null @@ -1,54 +0,0 @@ -<<- /* Prepend the setup area */ ->> -<< template "cv_setup.tmpl.tex" .>> - -\starttext - \starttitleAndContact - \cvtitle{<<.FirstName>> <<.LastName>>}{<<.JobTitle>>} - \titleAndContact - {\bf Email:} <<.Contact.Email>>\blank[none] - <>{\bf Phone:} <<.Contact.Phone>>\blank[none]<> - {\bf Location:} <<.Contact.Location>>\blank[medium] - - <>{\bf LinkedIn:} <<.Links.LinkedIn>>\blank[none]<> - <>{\bf GitHub:} <<.Links.GitHub>>\blank[none]<> - \stoptitleAndContact - - \section{SUMMARY} - <> - - \section{SKILLS SUMMARY} - \starttabulate[|w(0.3\textwidth)lB|lp(0.7\textwidth)|] - <<$lenTech := len .Technologies>> - <> - <<$lenValues := len $tech.Values>> - \NC <<$tech.Category>> \NC <><<$val>><>, <><>\NC\NR - <>\TB[1mm]<> - <> - \stoptabulate - - \section{EXPERIENCE} - <<- range .Employment>> - \jobsection{<<.Company>>}{<<.Location>>}{<<.JobTitle>>}{<>} - \startitemize - <> - \item <<.>> - <> - \stopitemize - <> - - \section{EDUCATION} - <> - \jobsection{<<.School>>}{<<.Location>>}{<<.Qualification>>}{<>} - \startitemize - <> - \item <<.>> - <> - \stopitemize - <> - - \section{INTERESTS AND HOBBIES} - <> - - \section{REFERENCES} - References are available upon request. -\stoptext diff --git a/template/tex/cv_setup.tmpl.tex b/template/tex/cv_setup.tmpl.tex deleted file mode 100644 index da9725b..0000000 --- a/template/tex/cv_setup.tmpl.tex +++ /dev/null @@ -1,78 +0,0 @@ -\version [final] - -% set main language to English -\mainlanguage [en] - -% set paper size to A4 -\setuppapersize [A4] - -% define the page layout -\setuplayout - [backspace=20mm, - bottomspace=20mm, - cutspace=0mm, - footer=0mm, - header=0mm, - height=middle, - topspace=10mm, - width=middle] -% \showframe - -% remove page numbers by setting an empty location -\setuppagenumbering[location=] - -% Colour definitions for headings -\definecolor [bluetheme][h=1155cc] -\definecolor [greytheme][h=434343] - -% Font setup -% https://wiki.contextgarden.net/Simplefonts -\definefontfamily [cvfontfamily][rm][LiberationSerif] -\definefontfamily [cvfontfamily][ss][Carlito] -\definefontfamily [cvfontfamily][tt][LiberationMono] -\definefontfamily [cvfontfamily][mm][LibertinusMath] -\setupbodyfont [cvfontfamily,ss,10pt] - -% define the font scaling when using commands such as \tfa, \tfb, etc -\definebodyfontenvironment [10pt][a=11pt,b=20pt,c=32pt] - -% cvtitle outputs the title of the CV -% arguments: -% #1 - name: name of the individual -% #2 - role: job role of the individual -\define[2]\cvtitle{ - {\bfc#1}\blank[small]{\tfb#2} -} - -% jobsection outputs the summary of a work experience -% arguments: -% #1 - company: the company where the work experience took place -% #2 - location: the location of the work experience -% #3 - role: the role of the work experience -% #4 - duration: the duration of the work experience (e.g. March, 2017 - April, 2018) -\define[4]\jobsection{ - {\bfa#1,} {\tfa#2} — {\tfa\em#3}\blank[small]\color[greytheme]{#4}\blank[line] -} -\definehead [skillssection][subsection] - -\setuphead [section][color=bluetheme] -\setuphead [skillssection][color=black] -\setuphead [section, skillssection][number=no, align=right, style=\bfa] - -% setup the format of items (bullet points) -\setupitemize - [1] - [packed] - [align=right, - symbol=1, - margin=no, - distance=1mm] - -% defineparagraphs and setupparagraphs allows us to create custom -% columns. Here we define and configure a paragraph environment for the CV title -% and contact columns. -% https://wiki.contextgarden.net/Command/defineparagraphs -% https://wiki.contextgarden.net/Command/setupparagraphs -\defineparagraphs[titleAndContact][n=2,after={\blank}] -\setupparagraphs [titleAndContact][1][width=0.5\textwidth] -\setupparagraphs [titleAndContact][2][width=0.5\textwidth]