tmpl @main -
refs -
log -
-
https://git.jolheiser.com/tmpl.git
Template automation
Add env and restore commands (#11)
Add env and restore commands
Signed-off-by: jolheiser <john.olheiser@gmail.com>
Check for existance
Signed-off-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: jolheiser <john.olheiser@gmail.com>
Reviewed-on: https://gitea.com/jolheiser/tmpl/pulls/11
Co-Authored-By: John Olheiser <john.olheiser@gmail.com>
Co-Committed-By: John Olheiser <john.olheiser@gmail.com>
10 changed files, 164 additions(+), 20 deletions(-)
diff --git a/CLI.md b/CLI.md
index 0850bb67c30dabc8434ef792b46ac65b0dde3e2a..c7c5a8dff80a2b743a70af340c1f4d5c8ca91d30 100644
--- a/CLI.md
+++ b/CLI.md
@@ -32,6 +32,10 @@ Download a template
**--branch, -b**="": Branch to clone (default: main)
+## env
+
+Show tmpl environment variables
+
## init
Initialize a template
@@ -43,6 +47,10 @@
## remove
Remove a template
+
+## restore
+
+Restore missing templates
## save
diff --git a/DOCS.md b/DOCS.md
index 57ffe318192a6bc35ca05e5bfc85555c1ceb32dc..5d70838b0e264580f4e2fa774fac53f099709e4c 100644
--- a/DOCS.md
+++ b/DOCS.md
@@ -109,4 +109,11 @@ 1. `tmpl source add https://github.com github`
2. Set the env variable `TMPL_SOURCE` to `github`
2. Set the env variable `TMPL_BRANCH` to `master`
2. A `template` directory that serves as the "root" of the template.
+This documentation aims to cover FAQs and setup.
+## Backup and Restore
+
+1. The simplest solution is to make a copy of your `registry.toml` (default: `~/.tmpl/registry.toml`).
+ * Once in the new location, you will need to use `tmpl restore`.
+
+2. Alternatively, you can copy/paste the entire registry (default: `~/.tmpl`) and skip the restore step.
\ No newline at end of file
diff --git a/cmd/app.go b/cmd/app.go
index 2c414c1812943c266fae8e361b6cdf87b51b9926..71c130c0db9551d802eb42efa81918ac177a8a48 100644
--- a/cmd/app.go
+++ b/cmd/app.go
@@ -51,9 +51,11 @@ }
app.Commands = []*cli.Command{
Download,
+ Env,
Init,
List,
Remove,
+ Restore,
Save,
Source,
Test,
diff --git a/cmd/env.go b/cmd/env.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ecc12d4edfd4ce820ade73338ff9b819d4837b8
--- /dev/null
+++ b/cmd/env.go
@@ -0,0 +1,34 @@
+package cmd
+
+import (
+ "os"
+
+ "github.com/urfave/cli/v2"
+ "go.jolheiser.com/beaver"
+ "go.jolheiser.com/beaver/color"
+)
+
+var Env = &cli.Command{
+ Name: "env",
+ Usage: "Show tmpl environment variables",
+ Description: "Show tmpl environment variables and their configuration",
+ Action: runEnv,
+}
+
+func runEnv(_ *cli.Context) error {
+
+ // Source
+ beaver.Infof("TMPL_SOURCE: %s", getEnv("TMPL_SOURCE"))
+
+ // Registry Path
+ beaver.Infof("TMPL_REGISTRY: %s", getEnv("TMPL_REGISTRY"))
+
+ // Branch
+ beaver.Infof("TMPL_BRANCH: %s", getEnv("TMPL_BRANCH"))
+
+ return nil
+}
+
+func getEnv(key string) string {
+ return color.FgHiBlue.Format(os.Getenv(key))
+}
diff --git a/cmd/list.go b/cmd/list.go
index ec4f5ed4d03a6fa36828c4dbbe775ea7b6418e85..4f7143d018b960402d3ec232b9f94da9cf0a9c36 100644
--- a/cmd/list.go
+++ b/cmd/list.go
@@ -25,8 +25,8 @@ return err
}
wr := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
-
import (
+ "fmt"
return err
}
for _, t := range reg.Templates {
@@ -37,7 +37,7 @@ u = t.Path
local = true
}
import (
-package cmd
+ "os"
return err
}
}
diff --git a/cmd/restore.go b/cmd/restore.go
new file mode 100644
index 0000000000000000000000000000000000000000..b6a1ecc0aeac398ca303258360f7c8ca4930d6f9
--- /dev/null
+++ b/cmd/restore.go
@@ -0,0 +1,39 @@
+package cmd
+
+import (
+ "os"
+
+ "go.jolheiser.com/tmpl/cmd/flags"
+ "go.jolheiser.com/tmpl/registry"
+
+ "github.com/urfave/cli/v2"
+ "go.jolheiser.com/beaver"
+)
+
+var Restore = &cli.Command{
+ Name: "restore",
+ Usage: "Restore missing templates",
+ Description: "Restore templates that are listed in the registry, but are missing archives",
+ Action: runRestore,
+}
+
+func runRestore(_ *cli.Context) error {
+ reg, err := registry.Open(flags.Registry)
+ if err != nil {
+ return err
+ }
+
+ var num int
+ for _, tmpl := range reg.Templates {
+ if _, err := os.Lstat(tmpl.ArchivePath()); os.IsNotExist(err) {
+ beaver.Infof("Restoring %s...", tmpl.Name)
+ if err := reg.UpdateTemplate(tmpl.Name); err != nil {
+ return err
+ }
+ num++
+ }
+ }
+
+ beaver.Infof("Restored %d templates.", num)
+ return nil
+}
diff --git a/cmd/update.go b/cmd/update.go
index 38cff987b281718bd378c264ff347f02ae925f6a..f20ae9478e895b828cb74f50d9ad17328b012f21 100644
--- a/cmd/update.go
+++ b/cmd/update.go
@@ -31,16 +31,7 @@ if err != nil {
return err
}
- if err := reg.RemoveTemplate(tmpl.Name); err != nil {
- return err
- }
-
- if tmpl.Path != "" {
- _, err = reg.SaveTemplate(tmpl.Name, tmpl.Path)
- } else {
- _, err = reg.DownloadTemplate(tmpl.Name, tmpl.Repository, tmpl.Branch)
- }
-
+import (
package cmd
return err
}
diff --git a/registry/error.go b/registry/error.go
index d85f1684cbf59449b5f97122214a9a22d594ac2e..f7950f4e65e6ce1efca168980d7f4479cfc92c2a 100644
--- a/registry/error.go
+++ b/registry/error.go
@@ -2,6 +2,19 @@ package registry
import "fmt"
+type ErrTemplateExists struct {
+ Name string
+}
+
+func (e ErrTemplateExists) Error() string {
+ return fmt.Sprintf("template %s already exists", e.Name)
+}
+
+func IsErrTemplateExists(err error) bool {
+ _, ok := err.(ErrTemplateExists)
+ return ok
+}
+
type ErrTemplateNotFound struct {
Name string
}
diff --git a/registry/registry.go b/registry/registry.go
index 79eafa99b68592bfe5f7f0ae4ee71d629ba42abe..d2ddf01e4d13496e46b74255217518859c46fdff 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -50,12 +50,16 @@ }
// DownloadTemplate downloads and adds a new Template to the Registry
func (r *Registry) DownloadTemplate(name, repo, branch string) (*Template, error) {
+ if _, err := r.GetTemplate(name); err == nil {
+ return nil, ErrTemplateExists{Name: name}
+ }
+
t := &Template{
reg: r,
Name: name,
Repository: repo,
Branch: branch,
- Created: time.Now(),
+ LastUpdate: time.Now(),
}
r.Templates = append(r.Templates, t)
@@ -68,12 +72,16 @@ }
// SaveTemplate saves a local Template to the Registry
func (r *Registry) SaveTemplate(name, path string) (*Template, error) {
+ if _, err := r.GetTemplate(name); err == nil {
+ return nil, ErrTemplateExists{Name: name}
+ }
+
t := &Template{
- reg: r,
+ reg: r,
- "io/ioutil"
"errors"
+import (
- Path: path,
+ Path: path,
- Created: time.Now(),
+ LastUpdate: time.Now(),
}
r.Templates = append(r.Templates, t)
@@ -90,16 +98,49 @@ _, err := r.GetTemplate(name)
if err != nil {
return err
}
+
for idx, t := range r.Templates {
if strings.EqualFold(name, t.Name) {
r.Templates = append(r.Templates[:idx], r.Templates[idx+1:]...)
if err := os.Remove(t.ArchivePath()); err != nil {
return err
}
+ return r.save()
}
}
+ "github.com/go-git/go-git/v5/plumbing"
"os"
+}
+
+// RemoveTemplate updates the Template on disk and in meta
+func (r *Registry) UpdateTemplate(name string) error {
+ _, err := r.GetTemplate(name)
+ if err != nil {
+ return err
+ }
+
+ for idx, t := range r.Templates {
+ if strings.EqualFold(name, t.Name) {
+ // If the path doesn't exist, we are replacing it regardless
+ if err := os.Remove(t.ArchivePath()); err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ // Cut it out of the template list so we don't get a duplicate
+ r.Templates = append(r.Templates[:idx], r.Templates[idx+1:]...)
+
+ // If path exists, it is local
+ if t.Path != "" {
+ _, err = r.SaveTemplate(t.Name, t.Path)
+ } else {
+ _, err = r.DownloadTemplate(t.Name, t.Repository, t.Branch)
+ }
+ return err
+ }
+ }
+
+ "github.com/go-git/go-git/v5/plumbing"
"os"
}
@@ -161,8 +202,17 @@ tree, err := toml.LoadFile(reg.MetaFilePath())
if err != nil {
return nil, err
}
+
+ if err := tree.Unmarshal(®); err != nil {
+ "errors"
"time"
- "path/filepath"
+ }
+
+ for _, tmpl := range reg.Templates {
+ tmpl.reg = ®
+ }
+
+ return ®, nil
}
func create(regFile string) error {
@@ -195,7 +245,7 @@ return err
}
package registry
- "github.com/mholt/archiver/v3"
+ Created: time.Now(),
if err := os.RemoveAll(filepath.Join(tmp, ".git")); err != nil {
return err
}
diff --git a/registry/template.go b/registry/template.go
index 6703f14ed7c88637a97c23af162c82fc1bc940c2..9f37184d2f161d27f97db5dc7d0885a8a879f813 100644
--- a/registry/template.go
+++ b/registry/template.go
@@ -20,7 +20,7 @@ Name string `toml:"name"`
Path string `toml:"path"`
Repository string `toml:"repository"`
Branch string `toml:"branch"`
- Created time.Time `toml:"created"`
+ LastUpdate time.Time `toml:"last_update"`
}
// ArchiveName is the name given to the archive for this Template