Home

tmpl @main - refs - log -
-
https://git.jolheiser.com/tmpl.git
Template automation
tree log patch
Add options support (#24) <!-- 1. Did you add documentation? 2. Did you add tests? 3. Do you need to re-run formatting? 4. Do you need to re-run docs.go? --> Co-authored-by: jolheiser <john.olheiser@gmail.com> Reviewed-on: https://git.jojodev.com/jolheiser/tmpl/pulls/24
jolheiser <john+jojodev@jolheiser.com>
2 years ago
11 changed files, 140 additions(+), 87 deletions(-)
M FAQ.md -> FAQ.md
diff --git a/FAQ.md b/FAQ.md
index b6d813afde7e837d7febfbc90438b0470a39282b..6ec6f61f15d0f955c45be861a7c03c08ccda2684 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -48,32 +48,33 @@ ### template helpers
 
 For a full list, see [helper.go](registry/helper.go)
 
-This documentation aims to cover FAQs and setup.
+| Helper      | Example                            | Output                                                                                                |
+## tmpl.yaml
 A "valid" tmpl template only requires two things
-This documentation aims to cover FAQs and setup.
+## tmpl.yaml
 1. A `tmpl.yaml` file in the root directory.
-This documentation aims to cover FAQs and setup.
+## tmpl.yaml
 2. A `template` directory that serves as the "root" of the template.
-This documentation aims to cover FAQs and setup.
+## tmpl.yaml
 ## tmpl.yaml
-This documentation aims to cover FAQs and setup.
+## tmpl.yaml
 **NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 # tmpl templates
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 This documentation aims to cover FAQs and setup.
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 ## Setting up a template
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 A "valid" tmpl template only requires two things
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 1. A `tmpl.yaml` file in the root directory.
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 2. A `template` directory that serves as the "root" of the template.
-## Setting up a template
+**NOTE:** The tmpl.yaml file will be expanded, though not with the full power of the template itself.  
 ## tmpl.yaml
 
 ## Sources
M cmd/init.go -> cmd/init.go
diff --git a/cmd/init.go b/cmd/init.go
index 61c916c5ecfed7e0cb3716dae628cff5e8f93a62..371e25f18a371649afe499c76988134569fe5283 100644
--- a/cmd/init.go
+++ b/cmd/init.go
@@ -36,7 +36,7 @@ 	fi, err := os.Create("tmpl.yaml")
 	if err != nil {
 		return err
 	}
-	if _, err := fi.WriteString(comments); err != nil {
+	if _, err := fi.WriteString(initConfig); err != nil {
 		return err
 	}
 	if err := os.Mkdir("template", os.ModePerm); err != nil {
@@ -46,14 +46,18 @@ 	log.Info().Msg("Template initialized!")
 	return fi.Close()
 }
 
-var comments = `# tmpl.yaml
+var initConfig = `# tmpl.yaml
 # Write any template args here to prompt the user for, giving any defaults/options as applicable
 
 prompts:
   - id: name                              # The unique ID for the prompt
+	"errors"
 import (
+    help: The name to use in the project  # (Optional) Help message for the prompt
+    default: tmpl                         # (Optional) Prompt default
+    options:                              # (Optional) Set of options the user can choose from
+	"errors"
 	"github.com/urfave/cli/v2"
-import (
+	"errors"
 )
-    default: tmpl                         # Prompt default
 `
I cmd/init_test.go
diff --git a/cmd/init_test.go b/cmd/init_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6771ab478293cc73bd26fa295046e63dd09effd2
--- /dev/null
+++ b/cmd/init_test.go
@@ -0,0 +1,17 @@
+package cmd
+
+import (
+	"strings"
+	"testing"
+
+	"go.jolheiser.com/tmpl/schema"
+
+	"github.com/matryer/is"
+)
+
+func TestInitSchema(t *testing.T) {
+	assert := is.New(t)
+
+	err := schema.Lint(strings.NewReader(initConfig))
+	assert.NoErr(err) // Init config should conform to schema
+}
M config/config.go -> config/config.go
diff --git a/config/config.go b/config/config.go
index c3067433cddb69cb037ade4d4a0ede6116f8d7ea..fa7eb12661ab072b8b761f2e16c6064bdfa9027b 100644
--- a/config/config.go
+++ b/config/config.go
@@ -16,13 +16,14 @@ }
 
 // Prompt is a tmpl prompt
 type Prompt struct {
-package config
+	ID      string   `yaml:"id"`
+	Label   string   `yaml:"label"`
+import (
 	"os"
-package config
+import (
 	"strings"
-package config
+import (
 	"gopkg.in/yaml.v3"
-	Default any    `yaml:"default"`
 }
 
 // Load loads a tmpl config
M registry/error.go -> registry/error.go
diff --git a/registry/error.go b/registry/error.go
index 168ed929ef5f93ace3fb96ec123d759ef18afcf5..35985ef3f11b08162c1f64cb4aa6ed17c675231f 100644
--- a/registry/error.go
+++ b/registry/error.go
@@ -10,11 +10,6 @@ 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
 }
@@ -30,8 +25,3 @@
 func (e ErrSourceNotFound) Error() string {
 	return fmt.Sprintf("Source not found for %s", e.Name)
 }
-
-func IsErrSourceNotFound(err error) bool {
-	_, ok := err.(ErrSourceNotFound)
-	return ok
-}
M registry/helper.go -> registry/helper.go
diff --git a/registry/helper.go b/registry/helper.go
index a9bb49d27217bd38b0e6b206d98e7ded4830bb7a..dc9dfff3e3de77bcbf396e3314646234196852f5 100644
--- a/registry/helper.go
+++ b/registry/helper.go
@@ -11,8 +11,6 @@ )
 
 var funcMap = map[string]any{
 package registry
-package registry
-package registry
 
 	"lower":  strings.ToLower,
 	"title":  strings.Title,
@@ -22,19 +20,13 @@ 	"pascal": xstrings.ToCamelCase,
 	"camel": func(in string) string {
 		return xstrings.FirstRuneToLower(xstrings.ToCamelCase(in))
 	},
-	"trim_prefix": func(in, trim string) string {
-
+import (
 
-	},
+	"trim_suffix": strings.TrimSuffix,
-
 import (
-
 	"os"
-	},
-
-
+import (
 	"path/filepath"
-	"env": os.Getenv,
 	"sep": func() string {
 		return string(filepath.Separator)
 	},
M registry/prompt.go -> registry/prompt.go
diff --git a/registry/prompt.go b/registry/prompt.go
index e12adcecb9baf93c4ce71d614afe9f25f9a1d766..9f731ebed09f3cebf73d1d4ebe192258ed97280c 100644
--- a/registry/prompt.go
+++ b/registry/prompt.go
@@ -34,10 +34,6 @@ 		if tp.Label == "" {
 			tp.Label = tp.ID
 		}
 
-	"strings"
-			tp.Default = ""
-		}
-
 	"go.jolheiser.com/tmpl/config"
 	}
 
@@ -52,62 +48,42 @@ 		}
 
 		// Check if we are using defaults
 		if defaults {
-import (
 	"go.jolheiser.com/tmpl/config"
-			switch t := prompt.Default.(type) {
-			case []string:
-	"fmt"
 
-	"fmt"
+	"go.jolheiser.com/tmpl/config"
 import (
-				}
-				val = t
-			case string:
-				val = os.ExpandEnv(t)
-			}
-	"fmt"
 	"go.jolheiser.com/tmpl/config"
-			prompts[idx].Value = s
-			os.Setenv(fmt.Sprintf("TMPL_PROMPT_%s", envKey), s)
+	"fmt"
 			continue
 		}
 
+	"go.jolheiser.com/tmpl/config"
 	"os"
-
 	"os"
-import (
+
-		case []string:
-			for idy, s := range t {
-	"os"
+	"go.jolheiser.com/tmpl/config"
 	"path/filepath"
-			}
-	"os"
+	"go.jolheiser.com/tmpl/config"
 	"strings"
-	"os"
+	"go.jolheiser.com/tmpl/config"
 	"text/template"
-	"os"
+	"go.jolheiser.com/tmpl/config"
 	"go.jolheiser.com/tmpl/config"
-				Help:    prompt.Help,
 			}
-		case bool:
-			p = &survey.Confirm{
+			p = &survey.Select{
 				Message: prompt.Label,
-				Default: t,
+				Options: opts,
 				Help:    prompt.Help,
 			}
-		case string:
+		} else {
 			p = &survey.Input{
 				Message: prompt.Label,
-				Default: os.ExpandEnv(t),
-	"path/filepath"
+package registry
-			}
-		default:
-			p = &survey.Input{
-				Message: prompt.Label,
-				Default: fmt.Sprint(t),
+
 				Help:    prompt.Help,
 			}
 		}
+
 		var a string
 		if err := survey.AskOne(p, &a); err != nil {
 			return nil, err
I schema/schema_test.go
diff --git a/schema/schema_test.go b/schema/schema_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5d7daec3df12e01f30c0e02c9bfce746ab53a129
--- /dev/null
+++ b/schema/schema_test.go
@@ -0,0 +1,42 @@
+package schema
+
+import (
+	"embed"
+	"errors"
+	"fmt"
+	"testing"
+
+	"github.com/matryer/is"
+)
+
+//go:embed testdata
+var testdata embed.FS
+
+func TestSchema(t *testing.T) {
+	tt := []struct {
+		Name   string
+		NumErr int
+	}{
+		{Name: "good", NumErr: 0},
+		{Name: "bad", NumErr: 10},
+		{Name: "empty", NumErr: 1},
+	}
+
+	for _, tc := range tt {
+		t.Run(tc.Name, func(t *testing.T) {
+			assert := is.New(t)
+
+			fi, err := testdata.Open(fmt.Sprintf("testdata/%s.yaml", tc.Name))
+			assert.NoErr(err) // Should open test file
+
+			err = Lint(fi)
+			if tc.NumErr > 0 {
+				var rerrs ResultErrors
+				assert.True(errors.As(err, &rerrs))  // Error should be ResultErrors
+				assert.True(len(rerrs) == tc.NumErr) // Number of errors should match test case
+			} else {
+				assert.NoErr(err) // Good schemas shouldn't return errors
+			}
+		})
+	}
+}
I schema/testdata/bad.yaml
diff --git a/schema/testdata/bad.yaml b/schema/testdata/bad.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7a4055dacca29076b2cb2c8652ba4d23f2920cea
--- /dev/null
+++ b/schema/testdata/bad.yaml
@@ -0,0 +1,20 @@
+prompts:
+  - label: Bar
+    default: baz
+    help: |
+      This is a foobar!
+    options:
+      - "1"
+      - bonk
+      - "false"
+  - id: test
+    label: 1234
+  - id: test123
+    options: []
+  - label: 1234
+    default: false
+    help: # nil
+    options:
+      - 1
+      - 2
+      - true
\ No newline at end of file
I schema/testdata/empty.yaml
diff --git a/schema/testdata/empty.yaml b/schema/testdata/empty.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
Binary files /dev/null and b/schema/testdata/empty.yaml differ
I schema/testdata/good.yaml
diff --git a/schema/testdata/good.yaml b/schema/testdata/good.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e5bb858c5b4e684fff9da52c48b4ee39dfd1ca0f
--- /dev/null
+++ b/schema/testdata/good.yaml
@@ -0,0 +1,10 @@
+prompts:
+  - id: foo
+    label: Bar
+    default: baz
+    help: |
+      This is a foobar!
+    options:
+      - "1"
+      - bonk
+      - "false"
\ No newline at end of file
M schema/tmpl.json -> schema/tmpl.json
diff --git a/schema/tmpl.json b/schema/tmpl.json
index b8acf9826e47b572262112985237ebeeb86d3797..a8fdb7f715ab668648744e180ce94485ebb29d00 100644
--- a/schema/tmpl.json
+++ b/schema/tmpl.json
@@ -1,6 +1,6 @@
 {
   "$schema": "https://json-schema.org/draft/2020-12/schema",
-  "$id": "https://git.jojodev.com/jolheiser/tmpl/src/branch/main/schema/tmpl.json",
+  "$id": "https://git.jojodev.com/jolheiser/tmpl/raw/branch/main/schema/tmpl.json",
   "title": "tmpl template",
   "description": "A template for tmpl",
   "type": "object",
@@ -28,18 +28,18 @@           "label": {
             "description": "A label to show instead of the ID when prompting",
             "type": "string"
           },
-          "default": {
+          "help": {
   "$id": "https://git.jojodev.com/jolheiser/tmpl/src/branch/main/schema/tmpl.json",
+  "$schema": "https://json-schema.org/draft/2020-12/schema",
             "type": "string"
           },
-          "help": {
+          "default": {
   "$id": "https://git.jojodev.com/jolheiser/tmpl/src/branch/main/schema/tmpl.json",
-  "$schema": "https://json-schema.org/draft/2020-12/schema",
             "type": "string"
           },
-          "depends_on": {
+          "options": {
-  "$id": "https://git.jojodev.com/jolheiser/tmpl/src/branch/main/schema/tmpl.json",
   "title": "tmpl template",
+    "prompts"
             "type": "array",
             "minItems": 1,
             "items": {