-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
394 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: ada-cli | ||
type: go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package cache | ||
|
||
import ( | ||
"os" | ||
"os/user" | ||
"path/filepath" | ||
) | ||
|
||
func Dir() string { | ||
dir, err := cacheDir() | ||
if err != nil { | ||
panic(err) | ||
} | ||
return dir | ||
} | ||
|
||
func cacheDir() (string, error) { | ||
usr, _ := user.Current() | ||
dir := usr.HomeDir | ||
cacheDir := filepath.Join(dir, ".ada") | ||
if _, err := os.Stat(cacheDir); !os.IsNotExist(err) { | ||
return cacheDir, err | ||
} | ||
|
||
if errMkdir := os.Mkdir(cacheDir, 0755); errMkdir != nil { | ||
return cacheDir, errMkdir | ||
} | ||
return cacheDir, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package cache | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"os/user" | ||
"path/filepath" | ||
|
||
"github.com/container-labs/ada/internal/common" | ||
"github.com/go-git/go-git/v5" | ||
"github.com/go-git/go-git/v5/plumbing/transport/ssh" | ||
) | ||
|
||
const SoyTemplatesRepository = "ssh://github.com:7999/gst/ada-templates.git" | ||
|
||
// const SoyTemplatesRepository = "https://github.com/massdriver-cloud/application-templates" | ||
|
||
var logger = common.Logger() | ||
|
||
// TemplateCacheDir is a reader function to access the local cache of templates. | ||
// When developing templates, the cache source can be overwritten for reads by setting `MD_DEV_TEMPLATES_PATH` | ||
func TemplateCacheDir() string { | ||
var templatesPath string | ||
localDevTemplatesPath := os.Getenv("ada_DEV_TEMPLATES_PATH") | ||
if localDevTemplatesPath == "" { | ||
dir, _ := templateCacheDir() | ||
templatesPath = dir | ||
} else { | ||
logger.Info(fmt.Sprintf("Reading templates for local development path: %s", localDevTemplatesPath)) | ||
templatesPath = localDevTemplatesPath | ||
} | ||
|
||
return templatesPath | ||
} | ||
|
||
func Templates() ([]string, error) { | ||
templates := []string{} | ||
templateDirs, err := ioutil.ReadDir(TemplateCacheDir()) | ||
if err != nil { | ||
return templates, err | ||
} | ||
|
||
for _, f := range templateDirs { | ||
// all directories that aren't .git | ||
// cheap way of listing templates | ||
if f.IsDir() && f.Name() != ".git" { | ||
templates = append(templates, f.Name()) | ||
} | ||
} | ||
return templates, nil | ||
} | ||
|
||
func RefreshTemplates() error { | ||
if err := clearTemplateCache(); err != nil { | ||
return err | ||
} | ||
return downloadTemplates() | ||
} | ||
|
||
// templateCacheDir is the actual cache directory. This should be used internally when managing | ||
// files so that development template directories aren't overwritten on accident. | ||
func templateCacheDir() (string, error) { | ||
cacheDir, err := cacheDir() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
templateDir := filepath.Join(cacheDir, "templates") | ||
if _, errDir := os.Stat(templateDir); !os.IsNotExist(errDir) { | ||
return templateDir, errDir | ||
} | ||
|
||
if errMkdir := os.Mkdir(templateDir, 0755); errMkdir != nil { | ||
return templateDir, errMkdir | ||
} | ||
return templateDir, nil | ||
} | ||
|
||
func clearTemplateCache() error { | ||
templateCacheDir, _ := templateCacheDir() | ||
if err := os.RemoveAll(templateCacheDir); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func downloadTemplates() error { | ||
templateCacheDir, _ := templateCacheDir() | ||
// log.Debug().Msgf("Downloading templates to %s", templateCacheDir) | ||
|
||
// begin: remove for public repo | ||
usr, err := user.Current() | ||
if err != nil { | ||
return err | ||
} | ||
homeDir := usr.HomeDir | ||
|
||
var publicKeys *ssh.PublicKeys | ||
publicKeys, err = ssh.NewPublicKeysFromFile("git", filepath.Join(homeDir, ".ssh/id_ed25519"), "") | ||
if err != nil { | ||
return err | ||
} | ||
// end: remove for public repo | ||
|
||
_, cloneErr := git.PlainClone(templateCacheDir, false, &git.CloneOptions{ | ||
URL: SoyTemplatesRepository, | ||
Auth: publicKeys, | ||
// Progress: os.Stdout, | ||
Depth: 1, | ||
}) | ||
if cloneErr != nil { | ||
return cloneErr | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package template | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/container-labs/ada/internal/cache" | ||
"github.com/container-labs/ada/internal/common" | ||
) | ||
|
||
var logger = common.Logger() | ||
|
||
func List() error { | ||
templates, err := cache.Templates() | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
logger.Info(fmt.Sprintf("Templates:\n %s\n", strings.Join(templates, "\n "))) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package template | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
jsoniter "github.com/json-iterator/go" | ||
"github.com/osteele/liquid" | ||
) | ||
|
||
type RenderData struct { | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
OutputDir string | ||
} | ||
|
||
func Render(templateDir string, data *RenderData) error { | ||
// templateDir := fmt.Sprintf("%s/%s", cache.TemplateCacheDir(), "helm-chart") | ||
fmt.Println(data) | ||
|
||
files, readDirErr := os.ReadDir(templateDir) | ||
if readDirErr != nil { | ||
return readDirErr | ||
} | ||
|
||
if _, checkDirExistsErr := os.Stat(data.OutputDir); errors.Is(checkDirExistsErr, os.ErrNotExist) { | ||
mkdirErr := os.MkdirAll(data.OutputDir, os.ModePerm) | ||
if mkdirErr != nil { | ||
return mkdirErr | ||
} | ||
} | ||
|
||
for _, file := range files { | ||
srcPath := templateDir + "/" + file.Name() | ||
destPath := data.OutputDir + "/" + file.Name() | ||
|
||
if _, err := os.Stat(destPath); err == nil { | ||
fmt.Printf("%s exists. Overwrite? (y|N): ", destPath) | ||
var response string | ||
fmt.Scanln(&response) | ||
|
||
if response != "y" && response != "Y" && response != "yes" { | ||
continue | ||
} | ||
} | ||
|
||
if file.IsDir() { | ||
dataCopy := RenderData{} | ||
// copy(dataCopy, data) | ||
// TODO: better copy | ||
dataCopy.Name = data.Name | ||
dataCopy.OutputDir = fmt.Sprintf("%s/%s", data.OutputDir, file.Name()) | ||
|
||
errRender := Render(fmt.Sprintf("%s/%s", templateDir, file.Name()), &dataCopy) | ||
if errRender != nil { | ||
return errRender | ||
} | ||
} else { | ||
|
||
contents, err := os.ReadFile(srcPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = WriteToFile(destPath, contents, data) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func WriteToFile(filePath string, template []byte, data *RenderData) error { | ||
var json = jsoniter.ConfigCompatibleWithStandardLibrary | ||
engine := liquid.NewEngine() | ||
|
||
var bindings map[string]interface{} | ||
inrec, errMarshal := json.Marshal(data) | ||
if errMarshal != nil { | ||
return errMarshal | ||
} | ||
json.Unmarshal(inrec, &bindings) | ||
|
||
out, renderErr := engine.ParseAndRender(template, bindings) | ||
if renderErr != nil { | ||
return renderErr | ||
} | ||
|
||
// hack hack hack | ||
// find-replace { { with {{ and } } with }} | ||
newSlice := bytes.Replace(out, []byte("{ {"), []byte("{{"), -1) | ||
lastSlice := bytes.Replace(newSlice, []byte("} }"), []byte("}}"), -1) | ||
|
||
return os.WriteFile(filePath, lastSlice, 0600) | ||
} |