Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat(render): Copy the theme assets in the ouput directory #13

Merged
merged 6 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json

Expand Down
14 changes: 3 additions & 11 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

version: 2

project_name: cvwonder

before:
hooks:
- go mod tidy
Expand All @@ -18,17 +20,7 @@ builds:
main: ./cmd/{{ .ProjectName }}/main.go

archives:
- format: tar.gz
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
format_overrides:
- goos: windows
format: zip
- format: binary

changelog:
sort: asc
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Download the latest release from the [releases page](https://github.com/germainl

```bash
DISTRIBUTION=Linux
CPU_ARCH=x86_64
CPU_ARCH=amd64
VERSION=$(curl -s "https://api.github.com/repos/germainlefebvre4/cvwonder/releases/latest" | jq -r '.tag_name')
curl -L -o cvwonder.tar.gz "https://github.com/germainlefebvre4/cvwonder/releases/download/${VERSION}/cvwonder_${DISTRIBUTION}_${CPU_ARCH}.tar.gz"
tar -xzf cvwonder.tar.gz
Expand Down
59 changes: 39 additions & 20 deletions internal/cvrender/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,48 @@ func RenderFormatHTML(cv model.CV, outputDirectory string, inputFilename string,
// Theme directory
currentDirectory, err := os.Getwd()
utils.CheckError(err)
themeDirectory := currentDirectory + "/themes"
themeDirectory := filepath.Join(currentDirectory, "themes", themeName)

// Inject custom functions in template
// Output file
outputDirectory, err = filepath.Abs(outputDirectory)
utils.CheckError(err)
outputFilename := filepath.Base(inputFilename) + ".html"
outputFilePath := filepath.Join(outputDirectory, outputFilename)
outputTmpFilePath := outputFilePath + ".tmp"

// Generate template file
err = generateTemplateFile(themeDirectory, outputDirectory, outputFilePath, outputTmpFilePath, cv)
utils.CheckError(err)

// Copy template file to output directory
err = copyFileContent(outputTmpFilePath, outputFilePath)
utils.CheckError(err)

// Copy theme assets to output directory
err = utils.CopyDirectory(themeDirectory, outputDirectory)
utils.CheckError(err)

return err
}

func getTemplateFunctions() template.FuncMap {
funcMap := template.FuncMap{
"dec": func(i int) int { return i - 1 },
"replace": strings.ReplaceAll,
"join": strings.Join,
}
return funcMap
}

func generateTemplateFile(themeDirectory string, outputDirectory string, outputFilePath string, outputTmpFilePath string, cv model.CV) error {
// Inject custom functions in template
funcMap := getTemplateFunctions()

// Template file
tmplFile := themeDirectory + "/" + themeName + "/index.html"
tmplFile := themeDirectory + "/index.html"
tmpl, err := template.New("index.html").Funcs(funcMap).ParseFiles(tmplFile)
utils.CheckError(err)

// Output file
outputDirectory, err = filepath.Abs(outputDirectory)
utils.CheckError(err)
outputFilename := filepath.Base(inputFilename) + ".html"
outputFilePath := outputDirectory + "/" + outputFilename
outputTmpFilePath := outputFilePath + ".tmp"

// Create output file and directory
if _, err := os.Stat(outputDirectory); errors.Is(err, os.ErrNotExist) {
err = os.MkdirAll(outputDirectory, os.ModePerm)
Expand All @@ -53,18 +74,19 @@ func RenderFormatHTML(cv model.CV, outputDirectory string, inputFilename string,
outputTmpFile, err = os.Create(outputTmpFilePath)
utils.CheckError(err)
defer outputTmpFile.Close()
} else {
outputTmpFile, err = os.OpenFile(outputTmpFilePath, os.O_WRONLY, 0644)
utils.CheckError(err)
defer outputTmpFile.Close()
}

// Generate output
err = tmpl.ExecuteTemplate(outputTmpFile, "index.html", cv)
utils.CheckError(err)

// Copy file content from tmp to final
// This approach avoid flooding file events in the watcher
logrus.Debug("HTML file generated at:", outputFilePath)

return nil
}

func copyFileContent(outputTmpFilePath string, outputFilePath string) error {
// Note: Copy file content from tmp to final to avoid flooding file events in the watcher
input, err := os.ReadFile(outputTmpFilePath)
utils.CheckError(err)
err = os.WriteFile(outputFilePath, input, 0644)
Expand All @@ -74,8 +96,5 @@ func RenderFormatHTML(cv model.CV, outputDirectory string, inputFilename string,
err = os.Remove(outputTmpFilePath)
utils.CheckError(err)

logrus.Debug("HTML file generated at:", outputFile)
logrus.Debug("HTML file generated at:", outputFilePath)

return err
return nil
}
4 changes: 2 additions & 2 deletions internal/cvrender/pdf/pdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ func RenderFormatPDF(cv model.CV, outputDirectory string, inputFilename string,
utils.CheckError(err)
defer w.Close()

localServerUrl := fmt.Sprintf("http://localhost:%d", utils.CliArgs.Port)
localServerUrl := fmt.Sprintf("http://localhost:%d/%s.html", utils.CliArgs.Port, inputFilename)

// Run the server to output the HTML
logrus.Info("Starting a temporary server at address ", localServerUrl)
logrus.Info("Serve temporary the CV on server at address ", localServerUrl)
go func() {
cvserve.StartServer(outputDirectory)

Expand Down
119 changes: 119 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package utils

import (
"fmt"
"io"
"os"
"path/filepath"

"github.com/sirupsen/logrus"
)

Expand All @@ -9,3 +14,117 @@ func CheckError(err error) {
logrus.Fatal(err)
}
}

func ReadDirectory(path string) ([]string, error) {
files, err := os.ReadDir(path)
CheckError(err)

result := make([]string, 0)
for _, file := range files {
result = append(result, file.Name())
}

return result, nil
}

func Copy(srcFile, dstFile string) error {
out, err := os.Create(dstFile)
if err != nil {
return err
}

defer out.Close()

in, err := os.Open(srcFile)
if err != nil {
return err
}

defer in.Close()

_, err = io.Copy(out, in)
if err != nil {
return err
}

return nil
}

func CopyDirectory(scrDir string, dest string) error {
entries, err := os.ReadDir(scrDir)
if err != nil {
return err
}
for _, entry := range entries {
sourcePath := filepath.Join(scrDir, entry.Name())
destPath := filepath.Join(dest, entry.Name())

fileInfo, err := os.Stat(sourcePath)
if err != nil {
return err
}

switch fileInfo.Mode() & os.ModeType {
case os.ModeDir:
if err := CreateIfNotExists(destPath, 0755); err != nil {
return err
}
if err := CopyDirectory(sourcePath, destPath); err != nil {
return err
}
case os.ModeSymlink:
if err := CopySymLink(sourcePath, destPath); err != nil {
return err
}
default:
// Exclude the templated index.html theme file from copying
if destPath == filepath.Join(dest, "index.html") {
continue
}
if err := Copy(sourcePath, destPath); err != nil {
return err
}
}

fInfo, err := entry.Info()
if err != nil {
return err
}

isSymlink := fInfo.Mode()&os.ModeSymlink != 0
if !isSymlink {
if err := os.Chmod(destPath, fInfo.Mode()); err != nil {
return err
}
}
}
return nil
}

func Exists(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
}

return true
}

func CreateIfNotExists(dir string, perm os.FileMode) error {
if Exists(dir) {
return nil
}

if err := os.MkdirAll(dir, perm); err != nil {
return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error())
}

return nil
}

func CopySymLink(source, dest string) error {
link, err := os.Readlink(source)
if err != nil {
return err
}
return os.Symlink(link, dest)
}
5 changes: 5 additions & 0 deletions themes/default/css/bootstrap.min.css

Large diffs are not rendered by default.

Loading