Add helpers, tests, and refactor download vs save
Signed-off-by: jolheiser <john.olheiser@gmail.com>pull/7/head v0.0.2
parent
5e164b9bb9
commit
cae16cdbdc
8
DOCS.md
8
DOCS.md
|
@ -51,8 +51,6 @@ Remove a template
|
|||
|
||||
Save a local template
|
||||
|
||||
**--branch, -b**="": Branch to clone (default: main)
|
||||
|
||||
## source
|
||||
|
||||
Commands for working with sources
|
||||
|
@ -63,11 +61,11 @@ List available sources
|
|||
|
||||
### add
|
||||
|
||||
AddTemplate a source
|
||||
Add a source
|
||||
|
||||
### remove
|
||||
|
||||
RemoveTemplate a source
|
||||
Remove a source
|
||||
|
||||
## test
|
||||
|
||||
|
@ -80,3 +78,5 @@ Update a template
|
|||
## use
|
||||
|
||||
Use a template
|
||||
|
||||
**--defaults**: Use template defaults
|
||||
|
|
|
@ -8,6 +8,10 @@ The two projects share many similarities, however other than general layout/stru
|
|||
|
||||
[CLI Docs](DOCS.md)
|
||||
|
||||
## Examples
|
||||
|
||||
Checkout the [license](https://gitea.com/jolheiser/tmpls/src/branch/license) and [makefile](https://gitea.com/jolheiser/tmpls/src/branch/makefile) branch of my [template repository](https://gitea.com/jolheiser/tmpls).
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
|
|
@ -59,7 +59,7 @@ func runDownload(ctx *cli.Context) error {
|
|||
cloneURL = source.CloneURL(cloneURL)
|
||||
}
|
||||
|
||||
t, err := reg.AddTemplate(ctx.Args().Get(1), cloneURL, ctx.String("branch"))
|
||||
t, err := reg.DownloadTemplate(ctx.Args().Get(1), cloneURL, ctx.String("branch"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
18
cmd/save.go
18
cmd/save.go
|
@ -3,7 +3,6 @@ package cmd
|
|||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"go.jolheiser.com/tmpl/cmd/flags"
|
||||
"go.jolheiser.com/tmpl/registry"
|
||||
|
@ -16,16 +15,7 @@ var Save = &cli.Command{
|
|||
Name: "save",
|
||||
Usage: "Save a local template",
|
||||
Description: "Save a local template to the registry",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "branch",
|
||||
Aliases: []string{"b"},
|
||||
Usage: "Branch to clone",
|
||||
Value: "main",
|
||||
EnvVars: []string{"TMPL_BRANCH"},
|
||||
},
|
||||
},
|
||||
Action: runSave,
|
||||
Action: runSave,
|
||||
}
|
||||
|
||||
func runSave(ctx *cli.Context) error {
|
||||
|
@ -38,17 +28,13 @@ func runSave(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Did the user give us the root path, or the .git directory?
|
||||
localPath := ctx.Args().First()
|
||||
if !strings.HasSuffix(localPath, ".git") {
|
||||
localPath = filepath.Join(localPath, ".git")
|
||||
}
|
||||
localPath, err = filepath.Abs(localPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t, err := reg.AddTemplate(ctx.Args().Get(1), localPath, ctx.String("branch"))
|
||||
t, err := reg.SaveTemplate(ctx.Args().Get(1), localPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -35,15 +35,15 @@ var (
|
|||
|
||||
SourceAdd = &cli.Command{
|
||||
Name: "add",
|
||||
Usage: "AddTemplate a source",
|
||||
Description: "AddTemplate a new source to the registry",
|
||||
Usage: "Add a source",
|
||||
Description: "Add a new source to the registry",
|
||||
Action: runSourceAdd,
|
||||
}
|
||||
|
||||
SourceRemove = &cli.Command{
|
||||
Name: "remove",
|
||||
Usage: "RemoveTemplate a source",
|
||||
Description: "RemoveTemplate a source from the registry",
|
||||
Usage: "Remove a source",
|
||||
Description: "Remove a source from the registry",
|
||||
Action: runSourceRemove,
|
||||
}
|
||||
)
|
||||
|
|
|
@ -36,7 +36,12 @@ func runUpdate(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if _, err := reg.AddTemplate(tmpl.Name, tmpl.Repository, tmpl.Branch); err != nil {
|
||||
if tmpl.Path != "" {
|
||||
_, err = reg.SaveTemplate(tmpl.Name, tmpl.Path)
|
||||
} else {
|
||||
_, err = reg.DownloadTemplate(tmpl.Name, tmpl.Repository, tmpl.Branch)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
10
cmd/use.go
10
cmd/use.go
|
@ -14,7 +14,13 @@ var Use = &cli.Command{
|
|||
Name: "use",
|
||||
Usage: "Use a template",
|
||||
Description: "Use (execute) a template from the registry",
|
||||
Action: runUse,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "defaults",
|
||||
Usage: "Use template defaults",
|
||||
},
|
||||
},
|
||||
Action: runUse,
|
||||
}
|
||||
|
||||
func runUse(ctx *cli.Context) error {
|
||||
|
@ -32,7 +38,7 @@ func runUse(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(ctx.Args().Get(1)); err != nil {
|
||||
if err := tmpl.Execute(ctx.Args().Get(1), ctx.Bool("defaults")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.15
|
|||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.2.2
|
||||
github.com/go-git/go-git/v5 v5.2.0
|
||||
github.com/huandu/xstrings v1.3.2
|
||||
github.com/mholt/archiver/v3 v3.5.0
|
||||
github.com/pelletier/go-toml v1.8.1
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
|
|
26
go.sum
26
go.sum
|
@ -1,38 +1,47 @@
|
|||
github.com/AlecAivazis/survey v1.8.8 h1:Y4yypp763E8cbqb5RBqZhGgkCFLRFnbRBHrxnpMMsgQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.2.2 h1:1I4qBrNsHQE+91tQCqVlfrKe9DEL65949d1oKZWVELY=
|
||||
github.com/AlecAivazis/survey/v2 v2.2.2/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
||||
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git v1.0.0 h1:YcN9iDGDoXuIw0vHls6rINwV416HYa0EB2X+RBsyYp4=
|
||||
github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||
github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI=
|
||||
github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
|
@ -50,8 +59,10 @@ github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A
|
|||
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
|
||||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
|
@ -59,12 +70,11 @@ github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE
|
|||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mholt/archiver v1.1.2 h1:xukR55YIrnhDHp10lrNtRSsAK5THpWrOCuviweNSBw4=
|
||||
github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=
|
||||
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
|
||||
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||
|
@ -72,7 +82,9 @@ github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNC
|
|||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pierrec/lz4/v4 v4.0.3 h1:vNQKSVZNYUEAvRY9FaUXAF1XPbSOHJtDTiP41kzDz2E=
|
||||
github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
|
@ -82,11 +94,11 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
|||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
|
||||
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
|
@ -118,9 +130,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
3
main.go
3
main.go
|
@ -6,11 +6,12 @@ import (
|
|||
"go.jolheiser.com/tmpl/cmd"
|
||||
|
||||
"go.jolheiser.com/beaver"
|
||||
"go.jolheiser.com/beaver/color"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := cmd.NewApp()
|
||||
|
||||
color.Fatal = color.Error // Easier to read, doesn't need to stand out as much in a CLI
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
beaver.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/huandu/xstrings"
|
||||
)
|
||||
|
||||
var funcMap = map[string]interface{}{
|
||||
|
||||
// String conversions
|
||||
"upper": strings.ToUpper,
|
||||
"lower": strings.ToLower,
|
||||
"title": strings.Title,
|
||||
"snake": xstrings.ToSnakeCase,
|
||||
"kebab": xstrings.ToKebabCase,
|
||||
"pascal": xstrings.ToCamelCase,
|
||||
"camel": func(in string) string {
|
||||
return xstrings.FirstRuneToLower(xstrings.ToCamelCase(in))
|
||||
},
|
||||
|
||||
// Other
|
||||
"env": os.Getenv,
|
||||
"sep": func() string {
|
||||
return string(filepath.Separator)
|
||||
},
|
||||
"time": func(fmt string) string {
|
||||
return time.Now().Format(fmt)
|
||||
},
|
||||
}
|
|
@ -48,8 +48,8 @@ func (r *Registry) GetTemplate(name string) (*Template, error) {
|
|||
return nil, ErrTemplateNotFound{Name: name}
|
||||
}
|
||||
|
||||
// AddTemplate downloads and adds a new Template to the Registry
|
||||
func (r *Registry) AddTemplate(name, repo, branch string) (*Template, error) {
|
||||
// DownloadTemplate downloads and adds a new Template to the Registry
|
||||
func (r *Registry) DownloadTemplate(name, repo, branch string) (*Template, error) {
|
||||
t := &Template{
|
||||
reg: r,
|
||||
Name: name,
|
||||
|
@ -66,6 +66,23 @@ func (r *Registry) AddTemplate(name, repo, branch string) (*Template, error) {
|
|||
return t, r.save()
|
||||
}
|
||||
|
||||
// SaveTemplate saves a local Template to the Registry
|
||||
func (r *Registry) SaveTemplate(name, path string) (*Template, error) {
|
||||
t := &Template{
|
||||
reg: r,
|
||||
Name: name,
|
||||
Path: path,
|
||||
Created: time.Now(),
|
||||
}
|
||||
r.Templates = append(r.Templates, t)
|
||||
|
||||
if err := save(path, t.ArchivePath()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return t, r.save()
|
||||
}
|
||||
|
||||
// RemoveTemplate removes the Template from disk and meta
|
||||
func (r *Registry) RemoveTemplate(name string) error {
|
||||
_, err := r.GetTemplate(name)
|
||||
|
@ -178,11 +195,21 @@ func download(cloneURL, branch, dest string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Make sure it's a valid template
|
||||
if _, err := os.Lstat(filepath.Join(tmp, "template.toml")); err != nil {
|
||||
// Save the template
|
||||
if err := save(tmp, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
fi, err := os.Lstat(filepath.Join(tmp, "template"))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func save(source, dest string) error {
|
||||
|
||||
// Make sure it's a valid template
|
||||
if _, err := os.Lstat(filepath.Join(source, "template.toml")); err != nil {
|
||||
return err
|
||||
}
|
||||
fi, err := os.Lstat(filepath.Join(source, "template"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -191,7 +218,7 @@ func download(cloneURL, branch, dest string) error {
|
|||
}
|
||||
|
||||
// Create archive
|
||||
glob, err := filepath.Glob(filepath.Join(tmp, "*"))
|
||||
glob, err := filepath.Glob(filepath.Join(source, "*"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
tmplDir string
|
||||
regDir string
|
||||
destDir string
|
||||
reg *Registry
|
||||
|
||||
tmplContents = `{{title name}} {{year}}`
|
||||
tmplTemplate = `name = "john olheiser"
|
||||
year = 2020`
|
||||
tmplGold = "John Olheiser 2020"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
var err error
|
||||
destDir, err = ioutil.TempDir(os.TempDir(), "tmpl")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set up template
|
||||
setupTemplate()
|
||||
|
||||
// Set up registry
|
||||
setupRegistry()
|
||||
|
||||
status := m.Run()
|
||||
|
||||
if err = os.RemoveAll(destDir); err != nil {
|
||||
fmt.Printf("could not clean up temp directory %s\n", destDir)
|
||||
}
|
||||
if err = os.RemoveAll(tmplDir); err != nil {
|
||||
fmt.Printf("could not clean up temp directory %s\n", tmplDir)
|
||||
}
|
||||
if err = os.RemoveAll(regDir); err != nil {
|
||||
fmt.Printf("could not clean up temp directory %s\n", regDir)
|
||||
}
|
||||
|
||||
os.Exit(status)
|
||||
}
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
t.Run("save", testSave)
|
||||
t.Run("get", testGet)
|
||||
t.Run("get-fail", testGetFail)
|
||||
t.Run("execute", testExecute)
|
||||
}
|
||||
|
||||
func testSave(t *testing.T) {
|
||||
if _, err := reg.SaveTemplate("test", tmplDir); err != nil {
|
||||
t.Log("could not save template")
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func testGet(t *testing.T) {
|
||||
_, err := reg.GetTemplate("test")
|
||||
if err != nil {
|
||||
t.Logf("could not get template")
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func testGetFail(t *testing.T) {
|
||||
_, err := reg.GetTemplate("fail")
|
||||
if !IsErrTemplateNotFound(err) {
|
||||
t.Logf("template should not exist")
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func testExecute(t *testing.T) {
|
||||
tmpl, err := reg.GetTemplate("test")
|
||||
if err != nil {
|
||||
t.Logf("could not get template")
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(destDir, true); err != nil {
|
||||
t.Logf("could not execute template: %v\n", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
contents, err := ioutil.ReadFile(filepath.Join(destDir, "TEST"))
|
||||
if err != nil {
|
||||
t.Logf("could not read file: %v\n", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if string(contents) != tmplGold {
|
||||
t.Logf("contents did not match:\n\tExpected: %s\n\tGot: %s", tmplGold, string(contents))
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func setupTemplate() {
|
||||
var err error
|
||||
tmplDir, err = ioutil.TempDir(os.TempDir(), "tmpl")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Template config
|
||||
fi, err := os.Create(filepath.Join(tmplDir, "template.toml"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = fi.WriteString(tmplTemplate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := fi.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Template file
|
||||
if err := os.Mkdir(filepath.Join(tmplDir, "template"), os.ModePerm); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err = os.Create(filepath.Join(tmplDir, "template", "TEST"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = fi.WriteString(tmplContents)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := fi.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func setupRegistry() {
|
||||
var err error
|
||||
regDir, err = ioutil.TempDir(os.TempDir(), "tmpl")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
reg, err = Open(regDir)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ package registry
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
|
@ -19,6 +19,7 @@ import (
|
|||
type Template struct {
|
||||
reg *Registry `toml:"-"`
|
||||
Name string `toml:"name"`
|
||||
Path string `toml:"path"`
|
||||
Repository string `toml:"repository"`
|
||||
Branch string `toml:"branch"`
|
||||
Created time.Time `toml:"created"`
|
||||
|
@ -35,7 +36,7 @@ func (t *Template) ArchivePath() string {
|
|||
}
|
||||
|
||||
// Execute runs the Template and copies to dest
|
||||
func (t *Template) Execute(dest string) error {
|
||||
func (t *Template) Execute(dest string, defaults bool) error {
|
||||
tmp, err := ioutil.TempDir(os.TempDir(), "tmpl")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -46,7 +47,7 @@ func (t *Template) Execute(dest string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
vars, err := prompt(tmp)
|
||||
vars, err := prompt(tmp, defaults)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -66,7 +67,7 @@ func (t *Template) Execute(dest string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
tmpl, err := template.New("tmpl").Parse(string(contents))
|
||||
tmpl, err := template.New("tmpl").Funcs(mergeMaps(funcMap, convertMap(vars))).Parse(string(contents))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -95,7 +96,7 @@ func (t *Template) Execute(dest string) error {
|
|||
})
|
||||
}
|
||||
|
||||
func prompt(dir string) (map[string]interface{}, error) {
|
||||
func prompt(dir string, defaults bool) (map[string]interface{}, error) {
|
||||
templatePath := filepath.Join(dir, "template.toml")
|
||||
if _, err := os.Lstat(templatePath); err != nil {
|
||||
return nil, err
|
||||
|
@ -105,9 +106,14 @@ func prompt(dir string) (map[string]interface{}, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vars := tree.ToMap()
|
||||
|
||||
// Return early if we only want defaults
|
||||
if defaults {
|
||||
return vars, nil
|
||||
}
|
||||
|
||||
// Sort the map keys so they are consistent
|
||||
vars := tree.ToMap()
|
||||
sorted := make([]string, 0, len(vars))
|
||||
for k := range vars {
|
||||
sorted = append(sorted, k)
|
||||
|
@ -147,3 +153,24 @@ func prompt(dir string) (map[string]interface{}, error) {
|
|||
|
||||
return vars, nil
|
||||
}
|
||||
|
||||
func convertMap(m map[string]interface{}) template.FuncMap {
|
||||
mm := make(template.FuncMap)
|
||||
for k, v := range m {
|
||||
vv := v // Enclosures in a loop
|
||||
mm[k] = func() interface{} {
|
||||
return fmt.Sprintf("%v", vv)
|
||||
}
|
||||
}
|
||||
return mm
|
||||
}
|
||||
|
||||
func mergeMaps(maps ...map[string]interface{}) map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
for _, mm := range maps {
|
||||
for k, v := range mm {
|
||||
m[k] = v
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue