func (a *androidSymbolUploader) getBuildVersionFromAPK() (int, error) {
	if a.Apk == "" {
		return 0, stackerr.New("Please provide apk file path.")
	}
	if a.AAPT == "" {
		androidHome := os.Getenv("ANDROID_HOME")
		if androidHome == "" {
			androidHome = os.Getenv("ANDROID_SDK")
		}
		if androidHome == "" {
			return 0, stackerr.New("Cannot find aapt, you might need to set ANDROID_HOME.")
		}

		aapt, err := a.getAAPT(androidHome)
		if err != nil {
			return 0, err
		}
		a.AAPT = aapt
	}

	bytes, err := exec.Command(a.AAPT, "dump", "badging", a.Apk).Output()
	if err != nil {
		return 0, stackerr.Wrap(err)
	}
	return parseVersionFromBytes(bytes)
}
Пример #2
0
func NewDaemon(options ...DaemonOption) (*daemon, error) {
	d := &daemon{}
	for _, option := range options {
		option(d)
	}

	if d.log == nil {
		return nil, stackerr.New("A logger must be provided")
	}

	if d.host == "" {
		return nil, stackerr.New("Host name/IP must be provided")
	}

	if d.port == "" {
		return nil, stackerr.New("Host port must be provided")
	}

	if err := d.validateFile(); err != nil {
		return nil, err
	}

	cm, err := dyconf.NewManager(d.fileName)
	if err != nil {
		return nil, err
	}
	d.confManager = cm

	return d, nil
}
Пример #3
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
}
Пример #4
0
func TestStackErrorString(t *testing.T) {
	t.Parallel()

	h := newHarness(t)
	defer h.Stop()

	err := stackerr.New("error")

	h.env.ErrorStack = false
	errStr := errorString(h.env, err)

	ensure.DeepEqual(t, errStr, "error")

	h.env.ErrorStack = true
	errStr = errorString(h.env, err)

	ensure.StringContains(t, errStr, "error")
	ensure.StringContains(t, errStr, ".go")

	err = stackerr.Wrap(&parse.Error{Message: "message", Code: 1})
	h.env.ErrorStack = false
	errStr = errorString(h.env, err)

	ensure.DeepEqual(t, errStr, "message")

	h.env.ErrorStack = true
	errStr = errorString(h.env, err)

	ensure.StringContains(t, errStr, `parse: api error with code=1 and message="message`)
	ensure.StringContains(t, errStr, ".go")
}
Пример #5
0
func (s *symbolsCmd) run(e *env, c *context) error {
	android := &androidSymbolUploader{
		Path:     s.path,
		Apk:      s.apk,
		Manifest: s.manifest,
		AAPT:     s.aapt}
	ios := &iosSymbolUploader{
		Path:        s.path,
		SkipOsCheck: s.skipOsCheck}
	switch {
	case android.acceptsPath():
		if err := android.validate(); err != nil {
			return err
		}
		fmt.Fprintln(e.Out, "Uploading Android symbol files...")
		return android.uploadSymbols(e)
	case ios.acceptsPath():
		if err := ios.validate(); err != nil {
			return err
		}
		fmt.Fprintln(e.Out, "Uploading iOS symbol files...")
		return ios.uploadSymbols(e)
	default:
		if s.path == "" {
			return stackerr.New("Please specify path to symbol files")
		}
		return stackerr.Newf("Do not understand symbol files at : %s", s.path)
	}
}
Пример #6
0
func (l *loginCmd) run(e *env) error {
	fmt.Fprintf(e.Out,
		`Please enter the email id you used to register with Parse
and an account key if you already generated it.
If you do not have an account key or would like to generate a new one,
please type: "y" to open the browser or "n" to continue: `,
	)
	l.helpCreateToken(e)

	var credentials credentials
	fmt.Fprintf(e.Out, "Email: ")
	fmt.Fscanf(e.In, "%s\n", &credentials.email)
	fmt.Fprintf(e.Out, "Account Key: ")
	fmt.Fscanf(e.In, "%s\n", &credentials.token)

	_, err := (&apps{login: loginCmd{credentials: credentials}}).restFetchApps(e)
	if err != nil {
		if err == errAuth {
			fmt.Fprintf(e.Err, `Sorry, we do not have a user with this email and account key.
Please follow instructions at %s to generate a new account key.
`,
				keysURL,
			)
		} else {
			fmt.Fprintf(e.Err, "Unable to validate token with error:\n%s\n", err)
		}
		return stackerr.New("Could not store credentials. Please try again.")
	}

	err = l.storeCredentials(e, &credentials)
	if err == nil {
		fmt.Fprintln(e.Out, "Successfully stored credentials.")
	}
	return stackerr.Wrap(err)
}
Пример #7
0
func (h *Hooks) deployTriggerHook(e *parsecli.Env, op *hookOperation) error {
	if op.Trigger == nil {
		return stackerr.New("cannot deploy nil trigger hook")
	}

	exists, err := h.triggerHookExists(e, op.Trigger.ClassName, op.Trigger.TriggerName)
	if err != nil {
		return err
	}
	restOp, suppressed, err := h.checkStrictMode(op.Method, exists)
	if err != nil {
		return err
	}

	trigger := &triggerHooksCmd{Trigger: op.Trigger, All: false}
	switch restOp {
	case "POST":
		return trigger.triggerHooksCreate(e, nil)
	case "PUT":
		return trigger.triggerHooksUpdate(e, nil)
	case "DELETE":
		if suppressed {
			return nil
		}
		return trigger.triggerHooksDelete(e, nil)
	}
	return stackerr.Wrap(errInvalidFormat)

}
Пример #8
0
func (h *Hooks) deployFunctionHook(e *parsecli.Env, op *hookOperation) error {
	if op.Function == nil {
		return stackerr.New("cannot deploy nil function hook")
	}
	exists, err := h.functionHookExists(e, op.Function.FunctionName)
	if err != nil {
		return err
	}

	restOp, suppressed, err := h.checkStrictMode(op.Method, exists)
	if err != nil {
		return err
	}

	function := &functionHooksCmd{Function: op.Function}
	switch restOp {
	case "POST":
		return function.functionHooksCreate(e, nil)
	case "PUT":
		return function.functionHooksUpdate(e, nil)
	case "DELETE":
		if suppressed {
			return nil
		}
		return function.functionHooksDelete(e, nil)
	}
	return stackerr.Wrap(errInvalidFormat)
}
Пример #9
0
func (c *configureCmd) accountKey(e *env) error {
	token, err := c.login.helpCreateToken(e)
	if err != nil {
		return err
	}

	credentials := credentials{token: token}
	_, err = (&apps{login: login{credentials: credentials}}).restFetchApps(e)
	if err != nil {
		if err == errAuth {
			fmt.Fprintf(e.Err,
				`Sorry, the account key you provided is not valid.
Please follow instructions at %s to generate a new account key.
`,
				keysURL,
			)
		} else {
			fmt.Fprintf(e.Err, "Unable to validate token with error:\n%s\n", err)
		}
		return stackerr.New("Could not store credentials. Please try again.")
	}

	err = c.login.storeCredentials(e, &credentials)
	if err == nil {
		fmt.Fprintln(e.Out, "Successfully stored credentials.")
	}
	return stackerr.Wrap(err)
}
Пример #10
0
func (j *jsSDKCmd) setVersion(e *env, c *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 := configFromDir(e.Root)
	if err != nil {
		return err
	}
	conf.getProjectConfig().Parse.JSSDK = j.newVersion
	if err := storeProjectConfig(e, conf); err != nil {
		return err
	}

	fmt.Fprintf(e.Out, "Current JavaScript SDK version is %s\n", conf.getProjectConfig().Parse.JSSDK)
	return nil
}
Пример #11
0
func PromptCreateWebhooks(e *parsecli.Env) (string, error) {
	selections := map[int]string{
		1: "Heroku (https://www.heroku.com)",
		2: "Parse  (https://parse.com/docs/cloudcode/guide)",
	}

	msg := "Sorry! CLI supports only Parse Cloud Code and Heroku."

	projectType := 0
	for i := 0; i < 3; i++ {
		fmt.Fprintf(
			e.Out,
			`Which of these providers would you like use for running your server code:
%d) %s
%d) %s
Type 1 or 2 to make a selection: `,
			1, selections[1],
			2, selections[2],
		)
		fmt.Fscanf(e.In, "%d\n", &projectType)
		fmt.Fprintln(e.Out)
		switch projectType {
		case 1:
			recordDecision(e, "heroku")
			return "heroku", nil
		case 2:
			recordDecision(e, "parse")
			return "parse", nil
		}
		fmt.Fprintln(e.Err, msg)
	}
	return "", stackerr.New(msg)
}
Пример #12
0
// BestEfforDockerClient creates a docker client from one of:
//
// 1. Environment variables as defined in
//    https://docs.docker.com/reference/commandline/cli/. Specifically
//    DOCKER_HOST, DOCKER_TLS_VERIFY & DOCKER_CERT_PATH.
//
// 2. bootdocker, if darwin.
//
// 3. /run/docker.sock, if it exists.
//
// 4. /var/run/docker.sock, if it exists.
func BestEffortDockerClient() (*dockerclient.DockerClient, error) {
	host := os.Getenv("DOCKER_HOST")

	if host == "" {
		if runtime.GOOS == "darwin" {
			return Boot2DockerClient()
		}

		socketLocations := []string{"/run/docker.sock", "/var/run/docker.sock"}
		for _, l := range socketLocations {
			if _, err := os.Stat(l); err == nil {
				c, err := dockerclient.NewDockerClient(fmt.Sprintf("unix://%s", l), nil)
				if err != nil {
					return nil, stackerr.Wrap(err)
				}
				return c, nil
			}
		}

		return nil, stackerr.New("docker not configured")
	}

	if os.Getenv("DOCKER_TLS_VERIFY") != "" {
		return DockerWithTLS(host, os.Getenv("DOCKER_CERT_PATH"))
	}

	c, err := dockerclient.NewDockerClient(host, nil)
	if err != nil {
		return nil, stackerr.Wrap(err)
	}

	return c, nil
}
Пример #13
0
func TestMultiErrorString(t *testing.T) {
	t.Parallel()

	h := newHarness(t)
	defer h.Stop()

	err := errgroup.MultiError(
		[]error{
			stackerr.New("error"),
			stackerr.Wrap(&parse.Error{Message: "message", Code: 1}),
		},
	)

	h.env.ErrorStack = false
	errStr := errorString(h.env, err)

	ensure.DeepEqual(t, errStr, "multiple errors: error | message")

	h.env.ErrorStack = true
	errStr = errorString(h.env, err)

	ensure.StringContains(t, errStr, "multiple errors")
	ensure.StringContains(t, errStr, `parse: api error with code=1 and message="message"`)
	ensure.StringContains(t, errStr, ".go")
}
Пример #14
0
func (d *defaultCmd) run(e *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 := 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 d.printDefault(e, defaultApp)
	default:
		return d.setDefault(e, newDefault, defaultApp, config)
	}
}
Пример #15
0
func (h *logsCmd) run(e *parsecli.Env, ctx *parsecli.Context) error {
	hkConfig, ok := ctx.AppConfig.(*parsecli.HerokuAppConfig)
	if !ok {
		return stackerr.New("Unexpected config format")
	}

	opts := &heroku.LogSessionCreateOpts{}
	if h.num == 0 {
		h.num = 50
	}
	//source := "app"
	//opts.Source = &source
	opts.Lines = &h.num
	opts.Tail = &h.tail

	session, err := e.HerokuAPIClient.LogSessionCreate(
		hkConfig.HerokuAppID,
		opts,
	)
	if err != nil {
		return stackerr.Wrap(err)
	}
	resp, err := http.Get(session.LogplexURL)
	if err != nil {
		return stackerr.Wrap(err)
	}
	_, err = io.Copy(e.Out, resp.Body)
	return stackerr.Wrap(err)
}
Пример #16
0
func (a *addCmd) run(e *parsecli.Env, args []string) error {

	if err := a.apps.Login.AuthUser(e, false); err != nil {
		return err
	}
	var appName string
	if len(args) > 1 {
		return stackerr.New("Only an optional Parse app name is expected.")
	}
	if len(args) == 1 {
		appName = args[0]
	}

	app, err := a.selectApp(e, appName)
	if err != nil {
		return err
	}

	var appConfig parsecli.AppConfig
	switch e.Type {
	case parsecli.LegacyParseFormat, parsecli.ParseFormat:
		appConfig = parsecmd.GetParseAppConfig(app)

	case parsecli.HerokuFormat:
		_, appConfig, err = herokucmd.GetLinkedHerokuAppConfig(app, e)
		if err != nil {
			return err
		}
	}

	return a.addSelectedApp(app.Name, appConfig, args, e)
}
Пример #17
0
func (d *defaultCmd) printDefault(e *env, defaultApp string) error {
	if defaultApp == "" {
		return stackerr.New("No app is set as default app")
	}
	fmt.Fprintf(e.Out, "Current default app is %s\n", defaultApp)
	return nil
}
Пример #18
0
func (r *rollbackCmd) run(e *parsecli.Env, c *parsecli.Context) error {
	appConfig, ok := c.AppConfig.(*parsecli.HerokuAppConfig)
	if !ok {
		return stackerr.New("Invalid Heroku app config")
	}
	releaseName := r.ReleaseName
	if releaseName == "" {
		lastSecond, err := r.getLastSecondVersion(e, appConfig.HerokuAppID)
		if err != nil {
			return err
		}
		releaseName = fmt.Sprintf("%d", lastSecond)
	}
	release, err := e.HerokuAPIClient.ReleaseRollback(appConfig.HerokuAppID, releaseName)
	if err != nil {
		return stackerr.Wrap(err)
	}
	fmt.Fprintf(
		e.Out,
		`%s
Current version: %d
`,
		release.Description,
		release.Version,
	)
	return nil
}
Пример #19
0
func (n *newCmd) promptCreateNewApp(e *env, nonInteractive bool) (string, error) {
	if nonInteractive {
		if n.createNewApp {
			return "new", nil
		}
		return "existing", nil
	}

	msg := `"new" and "existing" are the only valid options.
Please try again ...`

	var decision string
	for i := 0; i < 3; i++ {
		fmt.Fprintf(e.Out,
			`Would you like to create a new app, or add Cloud Code to an existing app?
Type "(n)ew" or "(e)xisting": `,
		)
		fmt.Fscanf(e.In, "%s\n", &decision)
		decision = strings.ToLower(decision)

		if decision == "new" || decision == "n" || decision == "existing" || decision == "e" {
			return decision, nil
		}
		fmt.Fprintln(e.Err, msg)
	}
	return "", stackerr.New(msg)
}
Пример #20
0
func (c *configureCmd) accessToken(e *env) error {
	fmt.Fprintf(e.Out,
		`Please enter an access token if you already generated it.

If you do not have an access token or would like to generate a new one,
please type: "y" to open the browser or "n" to continue: `,
	)

	c.login.helpCreateToken(e)

	var credentials credentials
	fmt.Fprintf(e.Out, "Access Token: ")
	fmt.Fscanf(e.In, "%s\n", &credentials.token)

	_, err := (&apps{login: login{credentials: credentials}}).restFetchApps(e)
	if err != nil {
		if err == errAuth {
			fmt.Fprintf(e.Err,
				`Sorry, the access token you provided is not valid.
Please follow instructions at %s to generate a new access token.
`,
				keysURL,
			)
		} else {
			fmt.Fprintf(e.Err, "Unable to validate token with error:\n%s\n", err)
		}
		return stackerr.New("Could not store credentials. Please try again.")
	}

	err = c.login.storeCredentials(e, &credentials)
	if err == nil {
		fmt.Fprintln(e.Out, "Successfully stored credentials.")
	}
	return stackerr.Wrap(err)
}
Пример #21
0
func (l *Login) HelpCreateToken(e *Env) (string, error) {
	for i := 0; i < 4; i++ {
		fmt.Fprintf(e.Out, `
Input your account key or press ENTER to generate a new one.
NOTE: on pressing ENTER we'll try to open the url:
	%q
in default browser.
`,
			keysURL,
		)
		fmt.Fprintf(e.Out, `Account Key: `)

		var token string
		fmt.Fscanf(e.In, "%s\n", &token)
		token = strings.TrimSpace(token)
		if token != "" {
			return token, nil
		}

		err := open.Run(keysURL)
		if err != nil {
			fmt.Fprintf(e.Err,
				`Sorry, we couldn’t open the browser for you.
Go here to generate an account key: %q
`,
				keysURL,
			)
		}
	}
	return "", stackerr.New("Account key cannot be empty. Please try again.")
}
Пример #22
0
func (g *gitInfo) whichGit() error {
	_, err := exec.LookPath("git")
	if err != nil {
		return stackerr.New(`Unable to locate "git".
Please install "git" and ensure that you are able to run "git help" from the command prompt.`,
		)
	}
	return nil
}
Пример #23
0
func TestNew(t *testing.T) {
	const errStr = "foo bar baz"
	e := stackerr.New(errStr)
	matches := []string{
		errStr,
		"stackerr_test.go:15 +TestNew$",
	}
	match(t, e.Error(), matches)
}
Пример #24
0
func (i *iosSymbolUploader) validate() error {
	if i.SkipOsCheck {
		return nil
	}
	if runtime.GOOS != "darwin" {
		return stackerr.New("Upload of iOS symbol files is only available on OS X.")
	}
	return nil
}
Пример #25
0
func (d *defaultCmd) setDefault(e *env, newDefault, defaultApp string, c config) error {
	if c.getProjectConfig().Type == legacy {
		p, ok := c.(*parseConfig)
		if !ok {
			return stackerr.New("Invalid Cloud Code config.")
		}
		return d.setParseDefault(e, newDefault, defaultApp, p)
	}
	return stackerr.Newf("Project type not configured.")
}
Пример #26
0
func TestReleasesCmdError(t *testing.T) {
	h, c := newReleasesCmdHarness(t)
	defer h.Stop()
	ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) {
		return nil, stackerr.New("Throws error")
	})
	h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}}

	ensure.NotNil(t, c.run(h.Env, &parsecli.Context{}))
}
Пример #27
0
func TestErrorStringWithStack(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	h.env.ErrorStack = true
	const message = "hello world"
	actual := errorString(h.env, stackerr.New(message))
	ensure.StringContains(t, actual, message)
	ensure.StringContains(t, actual, ".go")
}
Пример #28
0
func TestErrorStringWithoutStack(t *testing.T) {
	t.Parallel()
	h := NewHarness(t)
	defer h.Stop()
	h.Env.ErrorStack = false
	const message = "hello world"
	actual := ErrorString(h.Env, stackerr.New(message))
	ensure.StringContains(t, actual, message)
	ensure.StringDoesNotContain(t, actual, ".go")
}
func parseVersionFromBytes(bytes []byte) (int, error) {
	v := androidCodeversion.FindAllSubmatch(bytes, 1)
	if len(v) == 0 {
		return 0, stackerr.New("Cannot determine build version.")
	}
	version, err := strconv.Atoi(string(v[0][1]))
	if err != nil {
		return 0, stackerr.Wrap(err)
	}
	return int(version), nil
}
Пример #30
0
func SetDefault(e *Env, newDefault, defaultApp string, c Config) error {
	projectType := c.GetProjectConfig().Type
	switch projectType {
	case LegacyParseFormat, ParseFormat:
		p, ok := c.(*ParseConfig)
		if !ok {
			return stackerr.New("Invalid Cloud Code config.")
		}
		return setParseDefault(e, newDefault, defaultApp, p)

	case HerokuFormat:
		h, ok := c.(*HerokuConfig)
		if !ok {
			return stackerr.New("Invalid Cloud Code config.")
		}
		return SetHerokuDefault(e, newDefault, defaultApp, h)
	}

	return stackerr.Newf("Unknown project type: %d.", projectType)
}