diff options
Diffstat (limited to 'cmd/ponzu/main.go')
-rw-r--r-- | cmd/ponzu/main.go | 273 |
1 files changed, 93 insertions, 180 deletions
diff --git a/cmd/ponzu/main.go b/cmd/ponzu/main.go index d57e776..362ff6a 100644 --- a/cmd/ponzu/main.go +++ b/cmd/ponzu/main.go @@ -5,7 +5,7 @@ package main import ( - "flag" + "errors" "fmt" "log" "net/http" @@ -13,19 +13,19 @@ import ( "os/exec" "path/filepath" "strings" + "time" + _ "github.com/ponzu-cms/ponzu/content" "github.com/ponzu-cms/ponzu/system/admin" "github.com/ponzu-cms/ponzu/system/api" "github.com/ponzu-cms/ponzu/system/api/analytics" "github.com/ponzu-cms/ponzu/system/db" "github.com/ponzu-cms/ponzu/system/tls" - _ "github.com/ponzu-cms/ponzu/content" + "github.com/spf13/cobra" ) var ( - usage = usageHeader + usageNew + usageGenerate + - usageBuild + usageRun + usageUpgrade + usageAdd + usageVersion port int httpsport int https bool @@ -36,107 +36,40 @@ var ( dev bool fork string gocmd string + year = fmt.Sprintf("%d", time.Now().Year()) ) -func main() { - flag.Usage = func() { - fmt.Println(usage) - } - - flag.IntVar(&port, "port", 8080, "port for ponzu to bind its HTTP listener") - flag.IntVar(&httpsport, "httpsport", 443, "port for ponzu to bind its HTTPS listener") - flag.BoolVar(&https, "https", false, "enable automatic TLS/SSL certificate management") - flag.BoolVar(&devhttps, "devhttps", false, "[dev environment] enable automatic TLS/SSL certificate management") - flag.BoolVar(&dev, "dev", false, "modify environment for Ponzu core development") - flag.BoolVar(&cli, "cli", false, "specify that information should be returned about the CLI, not project") - flag.StringVar(&fork, "fork", "", "modify repo source for Ponzu core development") - flag.StringVar(&gocmd, "gocmd", "go", "custom go command if using beta or new release of Go") - flag.Parse() - - args := flag.Args() - - if len(args) < 1 { - fmt.Println(usage) - os.Exit(0) - } - - switch args[0] { - case "help", "h": - if len(args) < 2 { - fmt.Println(usageHelp) - fmt.Println(usage) - os.Exit(0) - } - - switch args[1] { - case "new": - fmt.Println(usageNew) - os.Exit(0) - - case "generate", "gen", "g": - fmt.Println(usageGenerate) - os.Exit(0) - - case "build": - fmt.Println(usageBuild) - os.Exit(0) - - case "run": - fmt.Println(usageRun) - os.Exit(0) - - case "upgrade": - fmt.Println(usageUpgrade) - os.Exit(0) - - case "version", "v": - fmt.Println(usageVersion) - os.Exit(0) - - case "add", "a": - fmt.Println(usageAdd) - os.Exit(0) - } - - case "new": - if len(args) < 2 { - fmt.Println(usageNew) - os.Exit(0) - } - - err := newProjectInDir(args[1]) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - case "generate", "gen", "g": - if len(args) < 3 { - fmt.Println(usageGenerate) - os.Exit(0) - } - - // check what we are asked to generate - switch args[1] { - case "content", "c": - err := generateContentType(args[2:]) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - default: - msg := fmt.Sprintf("Generator '%s' is not implemented.", args[1]) - fmt.Println(msg) - } - - case "build": - err := buildPonzuServer(args) - if err != nil { - fmt.Println(err) - os.Exit(1) - } +var rootCmd = &cobra.Command{ + Use: "ponzu", + Long: `Ponzu is an open-source HTTP server framework and CMS, released under +the BSD-3-Clause license. +(c) 2016 - ` + year + ` Boss Sauce Creative, LLC`, +} - case "run": +var runCmd = &cobra.Command{ + Use: "run [flags] <service(,service)>", + Short: "starts the 'ponzu' HTTP server for the JSON API and or Admin System.", + Long: `Starts the 'ponzu' HTTP server for the JSON API, Admin System, or both. +The segments, separated by a comma, describe which services to start, either +'admin' (Admin System / CMS backend) or 'api' (JSON API), and, optionally, +if the server should utilize TLS encryption - served over HTTPS, which is +automatically managed using Let's Encrypt (https://letsencrypt.org) + +Defaults to 'run -port=8080 admin,api' (running Admin & API on port 8080, without TLS) + +Note: +Admin and API cannot run on separate processes unless you use a copy of the +database, since the first process to open it receives a lock. If you intend +to run the Admin and API on separate processes, you must call them with the +'ponzu' command independently.`, + Example: `$ ponzu run +(or) +$ ponzu run --port=8080 --https admin,api +(or) +$ ponzu run admin +(or) +$ ponzu run --port=8888 api`, + RunE: func(cmd *cobra.Command, args []string) error { var addTLS string if https { addTLS = "--https" @@ -149,8 +82,8 @@ func main() { } var services string - if len(args) > 1 { - services = args[1] + if len(args) > 0 { + services = args[0] } else { services = "admin,api" } @@ -159,7 +92,7 @@ func main() { buildPathName := strings.Join([]string{".", name}, string(filepath.Separator)) serve := exec.Command(buildPathName, fmt.Sprintf("--port=%d", port), - fmt.Sprintf("--httpsport=%d", httpsport), + fmt.Sprintf("--https-port=%d", httpsport), addTLS, "serve", services, @@ -167,32 +100,40 @@ func main() { serve.Stderr = os.Stderr serve.Stdout = os.Stdout - err := serve.Run() - if err != nil { - fmt.Println(err) - os.Exit(1) + return serve.Run() + }, +} + +// ErrWrongOrMissingService informs a user that the services to run must be +// explicitly specified when serve is called +var ErrWrongOrMissingService = errors.New("To execute 'ponzu serve', " + + "you must specify which service to run.") + +var serveCmd = &cobra.Command{ + Use: "serve [flags] <service,service>", + Aliases: []string{"s"}, + Short: "actually run the server (serve is wrapped by the run command)", + Hidden: true, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return ErrWrongOrMissingService } - case "serve", "s": db.Init() defer db.Close() analytics.Init() defer analytics.Close() - if len(args) > 1 { - services := strings.Split(args[1], ",") - - for _, service := range services { - if service == "api" { - api.Run() - } else if service == "admin" { - admin.Run() - } else { - fmt.Println("To execute 'ponzu serve', you must specify which service to run.") - fmt.Println("$ ponzu --help") - os.Exit(1) - } + services := strings.Split(args[0], ",") + + for _, service := range services { + if service == "api" { + api.Run() + } else if service == "admin" { + admin.Run() + } else { + return ErrWrongOrMissingService } } @@ -229,69 +170,41 @@ func main() { fmt.Printf("Server listening on :%d for HTTP requests...\n", port) fmt.Println("\nvisit `/admin` to get started.") log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) + return nil + }, +} - case "version", "v": - // read ponzu.json value to Stdout - - p, err := ponzu(cli) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Fprintf(os.Stdout, "Ponzu v%s\n", p["version"]) - - case "upgrade": - // confirm since upgrade will replace Ponzu core files - path, err := os.Getwd() - if err != nil { - fmt.Println("Failed to find current directory.", err) - os.Exit(1) - } - - fmt.Println("Only files you added to this directory, 'addons' and 'content' will be preserved.") - fmt.Println("Upgrade this project? (y/N):") - - answer, err := getAnswer() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - switch answer { - case "n", "no", "\r\n", "\n", "": - fmt.Println("") +func init() { + for _, cmd := range []*cobra.Command{runCmd, serveCmd} { + cmd.Flags().IntVar(&port, "port", 8080, "port for ponzu to bind its HTTP listener") + cmd.Flags().IntVar(&httpsport, "https-port", 443, "port for ponzu to bind its HTTPS listener") + cmd.Flags().BoolVar(&https, "https", false, "enable automatic TLS/SSL certificate management") + cmd.Flags().BoolVar(&devhttps, "dev-https", false, "[dev environment] enable automatic TLS/SSL certificate management") + } - case "y", "yes": - err := upgradePonzuProjectDir(path) - if err != nil { - fmt.Println(err) - os.Exit(1) - } + RegisterCmdlineCommand(runCmd) + RegisterCmdlineCommand(serveCmd) - default: - fmt.Println("Input not recognized. No upgrade made. Answer as 'y' or 'n' only.") - } + pflags := rootCmd.PersistentFlags() + pflags.StringVar(&gocmd, "gocmd", "go", "custom go command if using beta or new release of Go") +} - case "add", "a": - // expecting two args, add and the go gettable package uri - if len(args) < 2 { - fmt.Println(usageAdd) - os.Exit(0) - } +func main() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} - err := getAddon(args) - if err != nil { - fmt.Println(err) - os.Exit(1) - } +func execAndWait(command string, arg ...string) error { + cmd := exec.Command(command, arg...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout - case "": - fmt.Println(usage) - fmt.Println(usageHelp) + err := cmd.Start() + if err != nil { + return err - default: - fmt.Println(usage) - fmt.Println(usageHelp) } + return cmd.Wait() } |