Skip to content

Commit

Permalink
Support for embed FS
Browse files Browse the repository at this point in the history
This allows to provide default templates, that will be available within the binary.
  • Loading branch information
aborroy committed Oct 3, 2023
1 parent fb1c7c8 commit 9eaf901
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 9 deletions.
5 changes: 3 additions & 2 deletions cmd/docker/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package docker

import (
"fmt"
"io/fs"
"log"
"os"

Expand All @@ -15,7 +16,7 @@ var catalogCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {

if templateName == "" {
files, err := os.ReadDir("templates")
files, err := fs.ReadDir(TemplateFs, TemplateRootPath)
if err != nil {
log.Fatal(err)
}
Expand All @@ -36,7 +37,7 @@ var catalogCmd = &cobra.Command{
}
}
} else {
body, err := os.ReadFile("templates/" + templateName + "/prompts.yaml")
body, err := fs.ReadFile(TemplateFs, TemplateRootPath+"/"+templateName+"/prompts.yaml")
if err != nil {
if templateDirectory == "" {
log.Fatalf("unable to read file: %v", err)
Expand Down
8 changes: 6 additions & 2 deletions cmd/docker/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var initCmd = &cobra.Command{
}
promptValues := pkg.GetPromptValues(templateRoot, templateName, defaultPromptValues)

templateList, err := pkg.GetTemplatesInPathHierarchy(templateRoot + "/" + templateName)
templateList, err := pkg.GetTemplatesInPathHierarchy(templateRoot+"/"+templateName, templateDirectory == "")
if err != nil {
panic(err)
}
Expand All @@ -57,7 +57,11 @@ var initCmd = &cobra.Command{
panic(err)
}
name := filepath.Base(t)
tpl := template.Must(template.New(name).Funcs(templateFuncs).ParseFiles(t))
// Parsing template files from embedded FS or external FS
tpl, err := template.New(name).Funcs(templateFuncs).ParseFS(pkg.TemplateFs, t)
if err != nil {
tpl = template.Must(template.New(name).Funcs(templateFuncs).ParseFiles(t))
}
err = tpl.ExecuteTemplate(f, name, promptValues)
if err != nil {
panic(err)
Expand Down
3 changes: 3 additions & 0 deletions cmd/docker/root.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package docker

import (
"embed"
"fmt"
"os"

"github.com/spf13/cobra"
)

var TemplateFs embed.FS

var rootCmd = &cobra.Command{
Use: "docker",
Short: "docker - a fake CLI to support Init command extension",
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package main

import (
"embed"

"github.com/aborroy/docker-init-with-templates/cmd/docker"
"github.com/aborroy/docker-init-with-templates/pkg"
)

//go:embed all:templates
var templateFs embed.FS

func main() {
pkg.TemplateFs = templateFs
docker.TemplateFs = templateFs
docker.Execute()
}
9 changes: 9 additions & 0 deletions pkg/hidden.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package pkg

import "slices"

var Allowed = []string{".env.tpl", ".dockerignore.tpl"}

func IsAllowedHiddenFile(name string) bool {
return slices.Contains(Allowed, name)
}
2 changes: 1 addition & 1 deletion pkg/hidden_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ package pkg
const dotCharacter = 46

func IsHidden(path string) bool {
return path[0] == dotCharacter
return path[0] == dotCharacter && !IsAllowedHiddenFile(path)
}
2 changes: 1 addition & 1 deletion pkg/hidden_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const dotCharacter = 46

func IsHidden(path string) bool {
if path[0] == dotCharacter {
return true
return !IsAllowedHiddenFile(path)
}

absPath, err := filepath.Abs(path)
Expand Down
34 changes: 33 additions & 1 deletion pkg/io.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
package pkg

import (
"embed"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
)

const TemplateExtension string = ".tpl"

func GetTemplatesInPathHierarchy(path string) ([]string, error) {
var TemplateFs embed.FS

func EmbedWalk(root string) ([]string, error) {
var paths []string
fs.WalkDir(TemplateFs, root, func(path string, d fs.DirEntry, err error) error {
if err != nil {
panic(err)
}
if d.IsDir() {
return nil
}
if err != nil {
return err
}
if strings.HasSuffix(path, TemplateExtension) {
paths = append(paths, path)
}
return nil
})
return paths, nil
}

func FilesystemWalk(path string) ([]string, error) {
var paths []string
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
Expand All @@ -26,6 +50,14 @@ func GetTemplatesInPathHierarchy(path string) ([]string, error) {
return paths, nil
}

func GetTemplatesInPathHierarchy(path string, useFS bool) ([]string, error) {
if useFS {
return EmbedWalk(path)
} else {
return FilesystemWalk(path)
}
}

func CreateOutputFile(outputRoot string, outputFile string, templateName string) (io.Writer, string, error) {
position := strings.Index(outputFile, "/"+templateName+"/")
outputFile = outputFile[position+len("/"+templateName+"/"):]
Expand Down
9 changes: 7 additions & 2 deletions pkg/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pkg

import (
"fmt"
"io/fs"
"os"
"reflect"
"strings"
Expand Down Expand Up @@ -100,9 +101,13 @@ func IsPromptVisible(expression string, values map[string]interface{}) bool {

func GetPromptValues(templateRootPath string, template string, cmdPromptValues map[string]string) reflect.Value {

file, err := os.ReadFile(templateRootPath + "/" + template + "/prompts.yaml")
// Read prompt file from embed FS or external FS
file, err := fs.ReadFile(TemplateFs, templateRootPath+"/"+template+"/prompts.yaml")
if err != nil {
panic(err)
file, err = os.ReadFile(templateRootPath + "/" + template + "/prompts.yaml")
if err != nil {
panic(err)
}
}

data := orderedmap.New[string, Prompt]()
Expand Down

0 comments on commit 9eaf901

Please sign in to comment.