Example #1
0
func (j *jsSDKCmd) setVersion(e *parsecli.Env, c *parsecli.Context) error {
	allVersions, err := j.getAllJSSdks(e)
	if err != nil {
		return err
	}
	valid := false
	for _, version := range allVersions {
		if version == j.newVersion {
			valid = true
		}
	}
	if !valid {
		return stackerr.New("Invalid SDK version selected.")
	}

	conf, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		return err
	}
	conf.GetProjectConfig().Parse.JSSDK = j.newVersion
	if err := parsecli.StoreProjectConfig(e, conf); err != nil {
		return err
	}

	fmt.Fprintf(e.Out, "Current JavaScript SDK version is %s\n", conf.GetProjectConfig().Parse.JSSDK)
	return nil
}
Example #2
0
func (m *migrateCmd) run(e *parsecli.Env) error {
	c, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		return err
	}

	c, err = m.upgradeLegacy(e, c)
	if err != nil {
		return err
	}
	localErr := parsecli.StoreConfig(e, c)
	projectErr := parsecli.StoreProjectConfig(e, c)
	if localErr == nil && projectErr == nil {
		legacy := filepath.Join(e.Root, parsecli.LegacyConfigFile)
		err := os.Remove(legacy)
		if err != nil {
			fmt.Fprintf(e.Err, "Could not delete: %q. Please remove this file manually.\n", legacy)
		}
	} else {
		local := filepath.Join(e.Root, parsecli.ParseLocal)
		err := os.Remove(local)
		if err != nil {
			fmt.Fprintf(e.Err, "Failed to clean up: %q. Please remove this file manually.\n", local)
		}
		project := filepath.Join(e.Root, parsecli.ParseProject)
		err = os.Remove(project)
		if err != nil {
			fmt.Fprintf(e.Err, "Failed to clean up: %q. Please remove this file manually.\n", project)
		}
	}
	fmt.Fprintln(e.Out, "Successfully migrated to the preferred config format.")
	return nil
}
Example #3
0
func (d *defaultCmd) run(e *parsecli.Env, args []string) error {
	var newDefault string
	if len(args) > 1 {
		return stackerr.Newf("unexpected arguments, only an optional app name is expected: %v", args)
	}
	if len(args) == 1 {
		newDefault = args[0]
	}

	config, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		return err
	}

	if config.GetNumApps() == 0 {
		return stackerr.New("No apps are associated with this project. You can add some with parse add")
	}

	defaultApp := config.GetDefaultApp()

	switch newDefault {
	case "":
		return parsecli.PrintDefault(e, defaultApp)
	default:
		return parsecli.SetDefault(e, newDefault, defaultApp, config)
	}
}
Example #4
0
func AddSelectedParseApp(
	appName string,
	appConfig *parsecli.ParseAppConfig,
	args []string,
	makeDefault, verbose bool,
	e *parsecli.Env,
) error {
	config, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		return err
	}
	parseConfig, ok := config.(*parsecli.ParseConfig)
	if !ok {
		return stackerr.New("Invalid Cloud Code config.")
	}

	// add app to config
	if _, ok := parseConfig.Applications[appName]; ok {
		return stackerr.Newf("App %s has already been added", appName)
	}

	parseConfig.Applications[appName] = appConfig

	if len(args) > 0 && args[0] != "" {
		alias := args[0]
		aliasConfig, ok := parseConfig.Applications[alias]
		if !ok {
			parseConfig.Applications[alias] = &parsecli.ParseAppConfig{Link: appName}
		}
		if ok && aliasConfig.GetLink() != "" {
			fmt.Fprintf(e.Out, "Overwriting alias: %q to point to %q\n", alias, appName)
			parseConfig.Applications[alias] = &parsecli.ParseAppConfig{Link: appName}
		}
	}

	if makeDefault {
		if _, ok := parseConfig.Applications[parsecli.DefaultKey]; ok {
			return stackerr.New(`Default key already set. To override default, use command "parse default"`)
		}
		parseConfig.Applications[parsecli.DefaultKey] = &parsecli.ParseAppConfig{Link: appName}
	}

	if err := parsecli.StoreConfig(e, parseConfig); err != nil {
		return err
	}
	if verbose {
		fmt.Fprintf(e.Out, "Written config for %q\n", appName)
		if makeDefault {
			fmt.Fprintf(e.Out, "Set %q as default\n", appName)
		}
	}

	return nil
}
Example #5
0
func (l *listCmd) printListOfApps(e *parsecli.Env) error {
	config, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		if os.IsNotExist(err) {
			// print nothing if we are not in a parse app directory
			return nil
		}
		return stackerr.Wrap(err)
	}
	config.PrettyPrintApps(e)
	fmt.Fprintln(e.Out, "")
	return nil
}
Example #6
0
func newJsSdkHarnessWithConfig(t testing.TB) (*parsecli.Harness, *parsecli.Context) {
	h := newJsSdkHarness(t)
	h.MakeEmptyRoot()

	ensure.Nil(t, parsecli.CloneSampleCloudCode(h.Env, true))
	h.Out.Reset()

	c, err := parsecli.ConfigFromDir(h.Env.Root)
	ensure.Nil(t, err)

	config, ok := (c).(*parsecli.ParseConfig)
	ensure.True(t, ok)

	return h, &parsecli.Context{Config: config}
}
Example #7
0
func (d *developCmd) contDeploy(e *parsecli.Env, deployer deployFunc, first, done chan struct{}) {
	if d.deployInterval == 0 {
		d.deployInterval = time.Second
	}

	var prevDeplInfo *deployInfo
	ticker := e.Clock.Ticker(d.deployInterval)
	defer ticker.Stop()

	latestError := false
	for {
		select {
		case <-ticker.C:
		case <-done:
			return
		}
		config, err := parsecli.ConfigFromDir(e.Root)
		if err != nil {
			if !latestError {
				latestError = true
			}
			if latestError {
				fmt.Fprintf(
					e.Err,
					`Config malformed.
Please fix your config file in %s and try again.
`,
					parsecli.GetConfigFile(e),
				)
			}
			if first != nil { // first deploy aborted
				close(first)
				first = nil
			}
			continue
		}
		latestError = false
		newDeplInfo, _ := deployer(config.GetProjectConfig().Parse.JSSDK, prevDeplInfo, true, e)
		if !d.mustFetch {
			prevDeplInfo = newDeplInfo
		}
		if first != nil { // first deploy finished
			close(first)
			first = nil
		}
	}
}
Example #8
0
// useLatestJSSDK is a utility method used by deploy & develop
// to write set jssdk version to latest available, if none set
func UseLatestJSSDK(e *parsecli.Env) error {
	var j jsSDKCmd
	versions, err := j.getAllJSSdks(e)
	if err != nil {
		return err
	}

	if len(versions) == 0 {
		return stackerr.New("No JavaScript SDK version is available.")
	}

	config, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		return err
	}

	config.GetProjectConfig().Parse.JSSDK = versions[0]
	return parsecli.StoreProjectConfig(e, config)
}
Example #9
0
func newDefaultParseConfig(t testing.TB, h *parsecli.Harness) *parsecli.ParseConfig {
	c, err := parsecli.ConfigFromDir(h.Env.Root)
	ensure.Nil(t, err)

	config, ok := c.(*parsecli.ParseConfig)
	ensure.True(t, ok)
	config.Applications = map[string]*parsecli.ParseAppConfig{
		"first":             {},
		"second":            {},
		parsecli.DefaultKey: {Link: "first"},
	}
	config.ProjectConfig = &parsecli.ProjectConfig{
		Type:  parsecli.LegacyParseFormat,
		Parse: &parsecli.ParseProjectConfig{},
	}
	ensure.Nil(t, parsecli.StoreConfig(h.Env, config))

	return config
}
Example #10
0
// NOTE: testing for legacy config format
func newLegacyJsSdkHarnessWithConfig(t testing.TB) (*parsecli.Harness, *parsecli.Context) {
	h := newJsSdkHarness(t)
	h.MakeEmptyRoot()

	ensure.Nil(t, os.Mkdir(filepath.Join(h.Env.Root, parsecli.ConfigDir), 0755))
	path := filepath.Join(h.Env.Root, parsecli.LegacyConfigFile)
	ensure.Nil(t, ioutil.WriteFile(path,
		[]byte(`{
		"global": {
			"parseVersion" : "1.2.9"
		}
	}`),
		0600))

	c, err := parsecli.ConfigFromDir(h.Env.Root)
	ensure.Nil(t, err)

	config, ok := (c).(*parsecli.ParseConfig)
	ensure.True(t, ok)

	return h, &parsecli.Context{Config: config}
}
Example #11
0
func TestDeployFilesNoVersion(t *testing.T) {
	t.Parallel()
	info := &deployInfo{
		ReleaseName:  "v1",
		ParseVersion: "latest",
		Checksums: deployFileData{
			Cloud:  map[string]string{"main.js": "d41d8cd98f00b204e9800998ecf8427e"},
			Public: map[string]string{"index.html": "d41d8cd98f00b204e9800998ecf8427e"},
		},
		Versions: deployFileData{
			Cloud:  map[string]string{"main.js": "f1"},
			Public: map[string]string{"index.html": "f1"},
		},
	}

	h := setupForDeploy(t, info)
	defer h.Stop()

	d := deployCmd{Verbose: true}
	res, err := d.deploy("", nil, false, h.Env)
	ensure.Nil(t, err)

	expected := &deployInfo{
		ParseVersion: "latest",
		Checksums: deployFileData{
			Cloud:  map[string]string{"main.js": "4ece160cc8e5e828ee718e7367cf5d37"},
			Public: map[string]string{"index.html": "9e2354a0ebac5852bc674026137c8612"},
		},
		Versions: deployFileData{
			Cloud:  map[string]string{"main.js": "f2"},
			Public: map[string]string{"index.html": "f2"},
		},
	}

	ensure.DeepEqual(t, res, expected)
	ensure.DeepEqual(t,
		h.Out.String(),
		fmt.Sprintf(`Uploading source files
Uploading recent changes to scripts...
The following files will be uploaded:
%s
The following files will be ignored:
%s
Uploading recent changes to hosting...
The following files will be uploaded:
%s
The following files will be ignored:
%s
Finished uploading files
New release is named v1 (using Parse JavaScript SDK vlatest)
`,
			filepath.Join(h.Env.Root, parsecli.CloudDir, "main.js"),
			strings.Join([]string{
				filepath.Join(h.Env.Root, parsecli.CloudDir, "sample.txt"),
				filepath.Join(h.Env.Root, parsecli.CloudDir, "test~")},
				"\n"),
			filepath.Join(h.Env.Root, parsecli.HostingDir, "index.html"),
			strings.Join([]string{
				filepath.Join(h.Env.Root, parsecli.HostingDir, "#ignore"),
				filepath.Join(h.Env.Root, parsecli.HostingDir, ".ignore")},
				"\n"),
		),
	)

	c, err := parsecli.ConfigFromDir(h.Env.Root)
	ensure.Nil(t, err)
	config, ok := (c).(*parsecli.ParseConfig)
	ensure.True(t, ok)
	ensure.DeepEqual(t, config.ProjectConfig.Parse.JSSDK, "2.0")
	ensure.True(t, strings.Contains(h.Err.String(), `JS SDK version not set, setting it to latest available JS SDK version
`),
	)
}
Example #12
0
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)
	}
}
Example #13
0
func (c *configureCmd) projectType(e *parsecli.Env, args []string) error {
	config, err := parsecli.ConfigFromDir(e.Root)
	if err != nil {
		return err
	}
	if len(args) > 1 {
		return stackerr.Newf("Invalid args: %v, only an optional project type argument is expected.", args)
	}
	validTypes := map[string]int{"parse": parsecli.ParseFormat}
	invertedTypes := map[int]string{parsecli.ParseFormat: "parse"}
	numKeys := len(validTypes)
	var validKeys []string
	for key := range validTypes {
		validKeys = append(validKeys, key)
	}
	sort.Strings(validKeys)
	var selectionString string
	for n, key := range validKeys {
		selectionString += fmt.Sprintf("%d: %s\n", 1+n, key)
	}

	selectedProjectType := -1
	if len(args) != 0 {
		projectType, ok := validTypes[args[0]]
		if !ok {
			return stackerr.Newf("Invalid projectType: %v, valid types are: \n%s", selectionString)
		}
		selectedProjectType = projectType
	}

	for i := 0; i < 3; i++ {
		fmt.Fprintf(e.Out, `Select from the listed project types:
%s
Enter a number between 1 and %d: `,
			selectionString,
			numKeys,
		)
		var selection string
		fmt.Fscanf(e.In, "%s\n", &selection)
		num, err := strconv.Atoi(selection)
		if err != nil || num < 1 || num > numKeys {
			fmt.Fprintf(e.Err, "Invalid selection. Please enter a number between 1 and %d\n", numKeys)
			continue
		}
		projectType, ok := validTypes[validKeys[num-1]]
		if !ok {
			return stackerr.Newf("Invalid projectType: %v, valid types are: \n%s", selectionString)
		}
		selectedProjectType = projectType
		break
	}
	if selectedProjectType == -1 {
		return stackerr.Newf("Could not make a selection. Please try again.")
	}

	config.GetProjectConfig().Type = selectedProjectType
	if err := parsecli.StoreProjectConfig(e, config); err != nil {
		fmt.Fprintln(e.Err, "Could not save selected project type to project config")
		return err
	}
	fmt.Fprintf(e.Out, "Successfully set project type to: %v\n", invertedTypes[selectedProjectType])
	return nil
}