140 lines
2.7 KiB
Go
140 lines
2.7 KiB
Go
|
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: "<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")
|
||
|
}
|
||
|
|
||
|
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
|
||
|
}
|