func (n *newCmd) configureSample( add *addCmd, name string, appConfig parsecli.AppConfig, args []string, e *parsecli.Env, ) error { if err := add.addSelectedApp(name, appConfig, args, e); err != nil { return err } masterKey, err := appConfig.GetMasterKey(e) if err != nil { return err } e.ParseAPIClient = e.ParseAPIClient.WithCredentials( parse.MasterKey{ ApplicationID: appConfig.GetApplicationID(), MasterKey: masterKey, }, ) if e.Type == parsecli.ParseFormat { return parsecmd.UseLatestJSSDK(e) } return nil }
func CloneSampleCloudCode( e *parsecli.Env, isNew, configOnly bool, appConfig parsecli.AppConfig) (bool, error) { dumpTemplate := false if !isNew && !configOnly { // if parse app was already created try to fetch Cloud Code and populate dir masterKey, err := appConfig.GetMasterKey(e) if err != nil { return false, err } e.ParseAPIClient = e.ParseAPIClient.WithCredentials( parse.MasterKey{ ApplicationID: appConfig.GetApplicationID(), MasterKey: masterKey, }, ) d := &downloadCmd{destination: e.Root} err = d.run(e, nil) if err != nil { if err == errNoFiles { dumpTemplate = true } else { fmt.Fprintln( e.Out, ` NOTE: If you like to fetch the latest deployed Cloud Code from Parse, you can use the "parse download" command after finishing the set up. This will download Cloud Code to a temporary location. `, ) } } } dumpTemplate = (isNew || dumpTemplate) && !configOnly return dumpTemplate, parsecli.CloneSampleCloudCode(e, dumpTemplate) }
func (n *newCmd) run(e *parsecli.Env) error { apps := &parsecli.Apps{} addCmd := &addCmd{MakeDefault: true, apps: apps} if err := apps.Login.AuthUser(e, false); err != nil { return err } var ( app *parsecli.App err error ) nonInteractive := n.parseAppName != "" && n.codeLocation != "" decision, err := n.promptCreateNewApp(e, nonInteractive) if err != nil { return err } isNew := false switch decision { case "new", "n": isNew = true var createRetries int if n.noCode { createRetries = 1 } // we pass retries so that even in non interactive mode we can create an app, // and failure does not print 3 times to the screen app, err = apps.CreateApp(e, n.parseAppName, createRetries) if err != nil { return err } if n.noCode { fmt.Fprintln(e.Out, "Successfully created the app.") return apps.PrintApp(e, app) } case "existing", "e": app, err = addCmd.selectApp(e, n.parseAppName) if err != nil { return err } if n.noCode { fmt.Fprintln(e.Out, "Successfully selected the app.") return apps.PrintApp(e, app) } } projectType, err := herokucmd.PromptCreateWebhooks(e) if err != nil { return err } var appConfig parsecli.AppConfig switch projectType { case "heroku": e.Type = parsecli.HerokuFormat var newHerokuApp bool newHerokuApp, appConfig, err = herokucmd.GetLinkedHerokuAppConfig(app, e) if err != nil { return err } isNew = isNew || newHerokuApp case "parse": e.Type = parsecli.ParseFormat appConfig = parsecmd.GetParseAppConfig(app) } dumpTemplate, err := n.setupSample(e, app.Name, appConfig, isNew, nonInteractive) if err != nil { return err } if err := n.configureSample(addCmd, app.Name, appConfig, nil, e); err != nil { return err } if token := apps.Login.Credentials.Token; token != "" { email, err := apps.Login.AuthToken(e, token) if err != nil { return err } if err := parsecli.SetParserEmail(e, email); err != nil { return err } } if dumpTemplate { fmt.Fprintf(e.Out, n.cloudCodeHelpMessage(e, app)) } return nil }
func (n *newCmd) setupSample( e *parsecli.Env, name string, appConfig parsecli.AppConfig, isNew bool, nonInteractive bool, ) (bool, error) { found := parsecli.IsProjectDir(parsecli.GetProjectRoot(e, e.Root)) if !found { root := parsecli.GetLegacyProjectRoot(e, e.Root) _, err := os.Lstat(filepath.Join(root, parsecli.LegacyConfigFile)) found = err == nil } if found { return false, stackerr.New( `Detected that you are already inside a Parse project. Please refrain from creating a Parse project inside another Parse project. `, ) } var ( cloudCodeDir string err error ) if nonInteractive { cloudCodeDir = n.codeLocation } else if n.configOnly { cloudCodeDir = "" // ensures that "parse new --init" inits the current directory } else { cloudCodeDir, err = n.getCloudCodeDir(e, name, isNew) if err != nil { return false, err } } e.Root = filepath.Join(e.Root, cloudCodeDir) switch e.Type { case parsecli.ParseFormat: if !n.configOnly { var decision string if isNew { fmt.Fprint(e.Out, ` You can either set up a blank project or create a sample Cloud Code project. Please type "(b)lank" if you wish to setup a blank project, otherwise press ENTER: `) } else { fmt.Fprint(e.Out, ` You can either set up a blank project or download the current deployed Cloud Code. Please type "(b)lank" if you wish to setup a blank project, otherwise press ENTER: `) } fmt.Fscanf(e.In, "%s\n", &decision) decision = strings.ToLower(strings.TrimSpace(decision)) if decision != "" && decision == "b" || decision == "blank" { n.configOnly = true } } return parsecmd.CloneSampleCloudCode(e, isNew, n.configOnly, appConfig) case parsecli.HerokuFormat: if !n.configOnly { var decision string if isNew { fmt.Fprint(e.Out, ` You can either set up a blank project or create a sample Node.js project. Please type "(b)lank" if you wish to setup a blank project, otherwise press ENTER: `) } else { fmt.Fprint(e.Out, ` You can either set up a blank project or download the server code currently deployed to Heroku. Please type "(b)lank" if you wish to setup a blank project, otherwise press ENTER: `) } fmt.Fscanf(e.In, "%s\n", &decision) decision = strings.ToLower(strings.TrimSpace(decision)) if decision != "" && decision == "b" || decision == "blank" { n.configOnly = true } } return herokucmd.CloneNodeCode(e, isNew, n.configOnly, appConfig) } return false, stackerr.Newf("Unknown project type: %d", e.Type) }
func main() { // some parts of apps.go are unable to handle // interrupts, this logic ensures we exit on system interrupts interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) go func() { <-interrupt os.Exit(1) }() e := parsecli.Env{ Root: os.Getenv("PARSE_ROOT"), Server: os.Getenv("PARSE_SERVER"), ErrorStack: os.Getenv("PARSE_ERROR_STACK") == "1", ParserEmail: os.Getenv("PARSER_EMAIL"), Out: os.Stdout, Err: os.Stderr, In: os.Stdin, Exit: os.Exit, Clock: clock.New(), } if e.Root == "" { cur, err := os.Getwd() if err != nil { fmt.Fprintf(e.Err, "Failed to get current directory:\n%s\n", err) os.Exit(1) } root := parsecli.GetProjectRoot(&e, cur) if parsecli.IsProjectDir(root) { e.Root = root config, err := parsecli.ConfigFromDir(root) if err != nil { fmt.Fprintln(e.Err, err) os.Exit(1) } e.Type = config.GetProjectConfig().Type if e.ParserEmail == "" { e.ParserEmail = config.GetProjectConfig().ParserEmail } } else { e.Type = parsecli.LegacyParseFormat e.Root = parsecli.GetLegacyProjectRoot(&e, cur) } } if e.Type != parsecli.LegacyParseFormat && e.Type != parsecli.ParseFormat && e.Type != parsecli.HerokuFormat { fmt.Fprintf(e.Err, "Unknown project type %d.\n", e.Type) os.Exit(1) } if e.Server == "" { e.Server = parsecli.DefaultBaseURL } apiClient, err := parsecli.NewParseAPIClient(&e) if err != nil { fmt.Fprintln(e.Err, err) os.Exit(1) } e.ParseAPIClient = apiClient if e.Type == parsecli.HerokuFormat { apiClient, err := parsecli.NewHerokuAPIClient(&e) if err != nil { fmt.Fprintln(e.Err, err) os.Exit(1) } e.HerokuAPIClient = apiClient } var ( rootCmd *cobra.Command command []string ) switch e.Type { case parsecli.LegacyParseFormat, parsecli.ParseFormat: command, rootCmd = parseRootCmd(&e) case parsecli.HerokuFormat: command, rootCmd = herokuRootCmd(&e) } if len(command) == 0 || command[0] != "update" { message, err := checkIfSupported(&e, parsecli.Version, command...) if err != nil { fmt.Fprintln(e.Err, err) os.Exit(1) } if message != "" { fmt.Fprintln(e.Err, message) } } if err := rootCmd.Execute(); err != nil { // Error is already printed in Execute() os.Exit(1) } }