131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
package command
|
|
|
|
import (
|
|
"fmt"
|
|
"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 fromCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "from",
|
|
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",
|
|
},
|
|
&cli.StringSliceFlag{
|
|
Name: "ignore",
|
|
Aliases: []string{"i"},
|
|
Usage: "Ignore files matching pattern",
|
|
Value: cli.NewStringSlice(".git", ".git/**", "./.git/**/*"),
|
|
},
|
|
},
|
|
Action: fromAction,
|
|
}
|
|
}
|
|
|
|
func fromAction(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
|
|
}
|
|
}
|
|
|
|
if fetcher == nil {
|
|
return errors.Errorf("could not find any fetcher matching URL '%v'", projectURL)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
fmt.Println("Could not find scaffold manifest.")
|
|
}
|
|
|
|
if manifestFile != nil {
|
|
defer manifestFile.Close()
|
|
|
|
fmt.Println("Loading 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)
|
|
}
|
|
|
|
fmt.Println("Prompting for templates variables.")
|
|
if err := template.Prompt(manifest, templateData); err != nil {
|
|
return errors.Wrap(err, "could not prompt for template data")
|
|
}
|
|
}
|
|
|
|
directory := c.String("directory")
|
|
|
|
ignore := c.StringSlice("ignore")
|
|
ignore = append(ignore, manifestPath)
|
|
|
|
fmt.Println("Generating project tree.")
|
|
|
|
err = template.CopyDir(vfs, ".", directory, &template.Option{
|
|
TemplateData: templateData,
|
|
TemplateExt: ".gotpl",
|
|
IgnorePatterns: ignore,
|
|
PreferredStrategy: template.Undefined,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("Done.")
|
|
|
|
return nil
|
|
}
|