package command import ( "log" "net/url" "os" "gitlab.com/wpetit/scaffold/internal/template" "github.com/manifoldco/promptui" "gitlab.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: "", 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") } manifestFile := c.String("manifest") manifestStat, err := vfs.Stat(manifestFile) if err != nil && !os.IsNotExist(err) { return errors.Wrap(err, "could not stat manifest file") } templateData := make(map[string]interface{}) if os.IsNotExist(err) { log.Println("Could not find scaffold manifest.") } else { if manifestStat.IsDir() { return errors.New("scaffold manifest is not a file") } log.Println("Loading template scaffold manifest...") } directory := c.String("directory") return template.CopyDir(vfs, ".", directory, &template.Option{ TemplateData: templateData, TemplateExt: ".gotpl", IgnorePatterns: []string{manifestFile}, }) } func promptForProjectName() (string, error) { validate := func(input string) error { if input == "" { return errors.New("Project name cannot be empty") } return nil } prompt := promptui.Prompt{ Label: "Project Name", Validate: validate, } return prompt.Run() } func promptForProjectNamespace() (string, error) { validate := func(input string) error { if input == "" { return errors.New("Project namespace cannot be empty") } return nil } prompt := promptui.Prompt{ Label: "Project namespace", Validate: validate, } return prompt.Run() } func promptForProjectType() (string, error) { prompt := promptui.Select{ Label: "Project Type", Items: []string{"web"}, } _, result, err := prompt.Run() return result, err }