scaffold/internal/command/new_project.go

107 lines
2.3 KiB
Go

package command
import (
"log"
"net/url"
"os"
"forge.cadoles.com/wpetit/scaffold/internal/template"
"forge.cadoles.com/wpetit/scaffold/internal/project"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)
func newProjectCommand() *cli.Command {
return &cli.Command{
Name: "new",
Aliases: []string{"n"},
Usage: "generate a new project from a given template url",
ArgsUsage: "<URL>",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "directory",
Aliases: []string{"d"},
Usage: "Set destination to `DIR`",
Value: "./",
},
&cli.StringFlag{
Name: "manifest",
Aliases: []string{"m"},
Usage: "The scaffold manifest `FILE`",
Value: "scaffold.yml",
},
},
Action: newProjectAction,
}
}
func newProjectAction(c *cli.Context) error {
rawURL := c.Args().First()
projectURL, err := url.Parse(rawURL)
if err != nil {
return errors.Wrap(err, "could not parse url")
}
availableFetchers := []project.Fetcher{
project.NewGitFetcher(),
project.NewLocalFetcher(),
}
var fetcher project.Fetcher
for _, f := range availableFetchers {
if f.Match(projectURL) {
fetcher = f
break
}
}
vfs, err := fetcher.Fetch(projectURL)
if err != nil {
return errors.Wrap(err, "could not fetch project")
}
templateData := template.Data{}
manifestPath := c.String("manifest")
manifestFile, err := vfs.Open(manifestPath)
if err != nil {
if !os.IsNotExist(err) {
return errors.Wrapf(err, "could not read manifest '%s'", manifestPath)
}
log.Println("Could not find scaffold manifest.")
}
if manifestFile != nil {
defer manifestFile.Close()
log.Println("Loading template scaffold manifest...")
manifest, err := template.Load(manifestFile)
if err != nil {
return errors.Wrapf(err, "could not load manifest '%s'", manifestPath)
}
if err := manifest.Validate(); err != nil {
return errors.Wrapf(err, "could not validate manifest '%s'", manifestPath)
}
if err := template.Prompt(manifest, templateData); err != nil {
return errors.Wrap(err, "could not prompt for template data")
}
}
directory := c.String("directory")
return template.CopyDir(vfs, ".", directory, &template.Option{
TemplateData: templateData,
TemplateExt: ".gotpl",
IgnorePatterns: []string{manifestPath},
})
}