Example #1
0
func checkArgs(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("You must provide at least one package name")
		cli.ShowSubcommandHelp(c)
		os.Exit(2)
	}
}
Example #2
0
func slackMethod() cli.Command {
	return cli.Command{
		Name:  "run",
		Usage: "[method]",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:   "token",
				Usage:  "Your Slack API token",
				EnvVar: "SLACK_TOKEN",
			},
		},
		Description: "Hits the SlackAPI using the format: https://slack.com/api/{method}",
		Action: func(ctx *cli.Context) {
			if len(ctx.Args()) == 0 {
				cli.ShowSubcommandHelp(ctx)
				return
			}

			method := ctx.Args()[0]
			token := ctx.String("token")

			client := slacker.NewAPIClient(token, "")
			b, err := client.RunMethod(method)
			if err != nil {
				fmt.Printf("Error running method: %s", err.Error())
				return
			}

			fmt.Println(string(b))
		},
	}
}
Example #3
0
func eventCommand() cli.Command {
	eventFlag := cli.StringFlag{
		Name:  "event.name",
		Usage: "event name",
	}
	return cli.Command{
		Name:    "event",
		Aliases: []string{"e"},
		Usage:   "event related actions",
		Action: func(c *cli.Context) {
			cli.ShowSubcommandHelp(c)
			os.Exit(1)
		},
		Subcommands: []cli.Command{
			cli.Command{
				Name:    "list",
				Aliases: []string{"l"},
				Usage:   "list latest events an agent has seen",
				Flags:   append([]cli.Flag{eventFlag}, queryOptionFlags()...),
				Action: func(c *cli.Context) {
					cc := consulClient(c)
					name := c.String(eventFlag.Name)
					events, _, err := cc.Event().List(name, queryOptions(c))
					if err != nil {
						log.Fatalf("failed to fetch agent events: %v", err)
					}
					prettyPrint(events)
				},
			},
		},
	}
}
Example #4
0
func createBundle(c *cli.Context) {
	if !c.Args().Present() {
		cli.ShowSubcommandHelp(c)
		log.Fatalf("Usage: %v name (common name defaults to name, use --cn and "+
			"different name if you need multiple certs for same cn)", c.Command.FullName())
	}

	commonName := strings.Join(c.Args()[:], " ")
	var filename string
	if filename = c.String("filename"); len(filename) == 0 {
		filename = strings.Replace(commonName, " ", "_", -1)
		filename = strings.Replace(filename, "*", "wildcard", -1)
	}

	subject := pkix.Name{CommonName: commonName}
	if str := c.String("organization"); len(str) > 0 {
		subject.Organization = []string{str}
	}
	if str := c.String("locality"); len(str) > 0 {
		subject.Locality = []string{str}
	}
	if str := c.String("country"); len(str) > 0 {
		subject.Country = []string{str}
	}
	if str := c.String("province"); len(str) > 0 {
		subject.Province = []string{str}
	}
	if str := c.String("organizational-unit"); len(str) > 0 {
		subject.OrganizationalUnit = []string{str}
	}

	template := &x509.Certificate{
		Subject:  subject,
		NotAfter: time.Now().AddDate(0, 0, c.Int("expire")),
	}

	if c.Bool("ca") {
		template.IsCA = true
		filename = "ca"
	} else if c.Bool("client") {
		template.ExtKeyUsage = append(template.ExtKeyUsage, x509.ExtKeyUsageClientAuth)
		template.EmailAddresses = c.StringSlice("email")
	} else {
		// We default to server
		template.ExtKeyUsage = append(template.ExtKeyUsage, x509.ExtKeyUsageServerAuth)

		IPs := make([]net.IP, 0, len(c.StringSlice("ip")))
		for _, ipStr := range c.StringSlice("ip") {
			if i := net.ParseIP(ipStr); i != nil {
				IPs = append(IPs, i)
			}
		}
		template.IPAddresses = IPs
		template.DNSNames = c.StringSlice("dns")
	}
	err := easypki.GenerateCertifcate(c.GlobalString("root"), filename, template)
	if err != nil {
		log.Fatal(err)
	}
}
Example #5
0
// cmdScriptRun serviced script run filename
func (c *ServicedCli) cmdScriptRun(ctx *cli.Context) {
	args := ctx.Args()
	if len(args) != 1 {
		fmt.Fprintln(os.Stderr, "Incorrect Usage.\n\n")
		if !ctx.Bool("help") {
			fmt.Fprintf(os.Stderr, "Incorrect Usage.\n\n")
		}
		cli.ShowSubcommandHelp(ctx)
		return
	}

	var svc *service.Service
	if svcID := ctx.String("service"); svcID != "" {
		//verify service or translate to ID
		var err error
		svc, err = c.searchForService(svcID)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			c.exit(1)
			return
		}
		if svc == nil {
			fmt.Fprintf(os.Stderr, "service %s not found\n", svcID)
			c.exit(1)
			return
		}
	}

	fileName := args[0]
	config := &script.Config{}
	if svc != nil {
		config.ServiceID = svc.ID
	}

	// exec unix script command to log output
	if isWithin := os.Getenv("IS_WITHIN_UNIX_SCRIPT"); isWithin != "TRUE" {
		os.Setenv("IS_WITHIN_UNIX_SCRIPT", "TRUE") // prevent inception problem

		// DO NOT EXIT ON ANY ERRORS - continue without logging
		logdir := utils.ServicedLogDir()
		if userrec, err := user.Current(); err != nil {
			fmt.Fprintf(os.Stderr, "Unable to retrieve userid to log output: %s", err)
		} else {
			logfile := time.Now().Format(fmt.Sprintf("%s/script-2006-01-02-150405-%s.log", logdir, userrec.Username))

			// unix exec ourselves
			cmd := []string{"/usr/bin/script", "--append", "--return", "--flush",
				"-c", strings.Join(os.Args, " "), logfile}

			fmt.Fprintf(os.Stderr, "Logging to logfile: %s\n", logfile)
			glog.V(1).Infof("syscall.exec unix script with command: %+v", cmd)
			if err := syscall.Exec(cmd[0], cmd[0:], os.Environ()); err != nil {
				fmt.Fprintf(os.Stderr, "Unable to log output with command:%+v err:%s\n", cmd, err)
			}
		}
	}

	glog.V(1).Infof("runScript filename:%s %+v\n", fileName, config)
	runScript(c, ctx, fileName, config)
}
Example #6
0
func secretAdd(c *cli.Context) error {

	repo := c.Args().First()
	owner, name, err := parseRepo(repo)
	if err != nil {
		return err
	}

	tail := c.Args().Tail()
	if len(tail) != 2 {
		cli.ShowSubcommandHelp(c)
		return nil
	}

	secret := &model.Secret{}
	secret.Name = tail[0]
	secret.Value = tail[1]
	secret.Images = c.StringSlice("image")
	secret.Events = c.StringSlice("event")

	if len(secret.Images) == 0 {
		return fmt.Errorf("Please specify the --image parameter")
	}

	client, err := newClient(c)
	if err != nil {
		return err
	}

	return client.SecretPost(owner, name, secret)
}
Example #7
0
// Create a pastie.
func createPastie(c *cli.Context) {
	fn := strings.TrimSpace(c.Args().First())
	if fn == "" {
		cli.ShowSubcommandHelp(c)
		return
	}

	content, err := ioutil.ReadFile(fn)
	if err != nil {
		fmt.Printf("Can't read '%s'\n", fn)
		return
	}

	pastie, resp, _ := pst.Create(string(content), c.String("lang"), c.Bool("restricted"))

	if resp.StatusCode != http.StatusOK {
		fmt.Println(resp.Status)
	}

	shortURL, err := isgd.Short(pastie)
	if err != nil {
		panic(err)
	}

	fmt.Printf("File: %s\nPastie URL: %s\nShort URL: %s\n",
		fn, pastie, shortURL)

}
Example #8
0
func echo_command(cfg *watch.Config, action func(*watch.Config)) cli.Command {
	return cli.Command{
		Name:      "echo",
		Usage:     "echo the full filepath",
		ArgsUsage: "DIR",
		Action: func(c *cli.Context) {

			args := c.Args()

			bail := func() {
				cli.ShowSubcommandHelp(c)
				os.Exit(1)
			}

			if !args.Present() {
				bail()
			}

			cfg.Actions = []watch.Action{
				&watch.EchoAction{},
			}
			cfg.Dir = args.First()
			action(cfg)
		},
	}
}
Example #9
0
func zoneInfo(c *cli.Context) {
	if err := checkEnv(); err != nil {
		fmt.Println(err)
		return
	}
	var zone string
	if len(c.Args()) > 0 {
		zone = c.Args()[0]
	} else if c.String("zone") != "" {
		zone = c.String("zone")
	} else {
		cli.ShowSubcommandHelp(c)
		return
	}
	zones, err := api.ListZones(zone)
	if err != nil {
		fmt.Println(err)
		return
	}
	var output []table
	for _, z := range zones {
		output = append(output, table{
			"ID":           z.ID,
			"Zone":         z.Name,
			"Plan":         z.Plan.LegacyID,
			"Status":       z.Status,
			"Name Servers": strings.Join(z.NameServers, ", "),
			"Paused":       fmt.Sprintf("%t", z.Paused),
			"Type":         z.Type,
		})
	}
	makeTable(output, "ID", "Zone", "Plan", "Status", "Name Servers", "Paused", "Type")
}
Example #10
0
func cloud_list(c *cli.Context) {
	args := c.Args()
	L := len(args)
	if L != 0 {
		fmt.Println("Error: bad args to 'cloud list'")
		cli.ShowSubcommandHelp(c)
		return
	}
	appname := APPCFG.Name

	// get a directory listing
	finfos, err := ioutil.ReadDir(APPCFG.SourcePath + "/clouds")
	if err != nil {
		fmt.Println("while reading clouds directory: ", err)
	}

	fmt.Printf("\n%-16s %-15s %-12s   %s\n", "Name", "Host", "Status", "Master:Worker counts")
	for _, fi := range finfos {
		if fi.IsDir() {
			continue
		}
		cloudname := strings.Replace(fi.Name(), ".yaml", "", -1)
		cloudcfg, err := readCloudConfig(appname, cloudname)
		if err != nil {
			fmt.Println("while reading cloud config: ", err)
		}

		fmt.Printf("%-16s %-15s %-12s   %d:%d\n", cloudcfg.Name, cloudcfg.URI, cloudcfg.Status, cloudcfg.NumMaster, cloudcfg.NumWorker)
	}
}
Example #11
0
func cloud_status(c *cli.Context) {
	args := c.Args()
	L := len(args)
	if L != 1 {
		fmt.Println("Error: bad args to 'cloud status <cloudname>'")
		cli.ShowSubcommandHelp(c)
		return
	}

	appname := APPCFG.Name
	cloudname := args[0]

	cloudcfg, err := readCloudConfig(appname, cloudname)
	if err != nil {
		fmt.Println("while reading cloud config: ", err)
		return
	}

	// print status known in the config file
	fmt.Printf("\n%-16s %-15s %-12s   %s\n", "Name", "Host", "Status", "Master:Worker counts")
	fmt.Printf("%-16s %-15s %-12s   %d:%d\n\n", cloudcfg.Name, cloudcfg.URI, cloudcfg.Status, cloudcfg.NumMaster, cloudcfg.NumWorker)

	// print status from mesos

	providers.CloudStatus(cloudcfg)

	// print status for the app

	// print status from mesosphere ? or is the service status

}
Example #12
0
func secretAdd(c *cli.Context) error {
	repo := c.Args().First()
	owner, name, err := parseRepo(repo)
	if err != nil {
		return err
	}

	tail := c.Args().Tail()
	if len(tail) != 2 {
		cli.ShowSubcommandHelp(c)
		return nil
	}

	secret, err := secretParseCmd(tail[0], tail[1], c)
	if err != nil {
		return err
	}

	client, err := newClient(c)
	if err != nil {
		return err
	}

	return client.SecretPost(owner, name, secret)
}
Example #13
0
func checkArgCount(c *cli.Context, num int) error {
	args := c.Args()
	if len(args) < num {
		if c.App != nil { // may be nill during tests, can cause panic
			cli.ShowSubcommandHelp(c)
		}
		return fmt.Errorf("Insufficient arguments: expected %d, provided %d", num, len(args))
	}
	if len(args) > num {
		if c.App != nil { // may be nill during tests, can cause panic
			cli.ShowSubcommandHelp(c)
		}
		return fmt.Errorf("Unknown arguments: %v", args[num:])
	}
	return nil
}
Example #14
0
func nodeName(c *cli.Context) string {
	name := c.String(nodeFlag.Name)
	if name == "" {
		cli.ShowSubcommandHelp(c)
		log.Fatal("node is required")
	}
	return name
}
Example #15
0
func db_import(c *cli.Context) {
	if len(c.Args()) != 0 {
		fmt.Println("Error: bad args to 'db import' !!!")
		cli.ShowSubcommandHelp(c)
		return
	}
	fmt.Println("Not implemented yet...")
}
Example #16
0
func config_app(c *cli.Context) {
	if len(c.Args()) != 0 {
		fmt.Println("Error: bad args to 'config app'")
		cli.ShowSubcommandHelp(c)
		return
	}
	fmt.Println("Zaha! ", APPCFG.Name, "config.")
}
Example #17
0
func CmdLsTree(c *cli.Context) {
	repo, err := git4go.OpenRepositoryExtended(".")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if len(c.Args()) == 0 {
		cli.ShowSubcommandHelp(c)
	} else {
		var tree *git4go.Tree
		var commit *git4go.Commit

		oid, err := git4go.NewOid(c.Args().First())

		if err == nil {
			obj, err := repo.Lookup(oid)
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			if obj.Type() == git4go.ObjectTree {
				tree = obj.(*git4go.Tree)
			} else if obj.Type() == git4go.ObjectCommit {
				commit = obj.(*git4go.Commit)
			} else {
				os.Stderr.WriteString("fatal: not a tree object")
				os.Exit(1)
			}
		} else {
			ref, err := repo.DwimReference(c.Args().First())
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			resolved, err := ref.Resolve()
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			commit, err = repo.LookupCommit(resolved.Target())
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
		}
		if commit != nil {
			tree, err = commit.Tree()
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
		}
		for _, entry := range tree.Entries {
			fileMode := fmt.Sprintf("%06o", int(entry.Filemode))
			fmt.Printf("%s %s %s\t%s\n", fileMode, entry.Type.String(), entry.Id.String(), entry.Name)
		}
	}
}
Example #18
0
// serviced service shell [--saveas SAVEAS]  [--interactive, -i] SERVICEID [COMMAND]
func (c *ServicedCli) cmdServiceShell(ctx *cli.Context) error {
	args := ctx.Args()
	if len(args) < 1 {
		if !ctx.Bool("help") {
			fmt.Fprintf(os.Stderr, "Incorrect Usage.\n\n")
		}
		cli.ShowSubcommandHelp(ctx)
		return c.exit(1)
	}

	var (
		command string
		argv    []string
		isTTY   bool
	)

	svc, err := c.searchForService(args[0])
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return c.exit(1)
	}

	if len(args) < 2 {
		command = "/bin/bash"
		isTTY = true
	} else {
		command = args[1]
		isTTY = ctx.GlobalBool("interactive")
	}

	if len(args) > 2 {
		argv = args[2:]
	}

	config := api.ShellConfig{
		ServiceID:        svc.ID,
		Command:          command,
		Args:             argv,
		SaveAs:           ctx.GlobalString("saveas"),
		IsTTY:            isTTY,
		Mounts:           ctx.GlobalStringSlice("mount"),
		ServicedEndpoint: fmt.Sprintf("localhost:%s", api.GetOptionsRPCPort()),
	}

	if err := c.driver.StartShell(config); err != nil {
		fmt.Fprintln(os.Stderr, err)
		if exitErr, ok := err.(*exec.ExitError); ok {
			if exitErr != nil && exitErr.ProcessState != nil && exitErr.ProcessState.Sys() != nil {
				if status, ok := exitErr.ProcessState.Sys().(syscall.WaitStatus); ok {
					return c.exit(status.ExitStatus())
				}
			}
		}
		return c.exit(1)
	} else {
		return c.exit(0)
	}
}
Example #19
0
func zoneRecords(c *cli.Context) {
	var zone string
	if len(c.Args()) > 0 {
		zone = c.Args()[0]
	} else if c.String("zone") != "" {
		zone = c.String("zone")
	} else {
		cli.ShowSubcommandHelp(c)
		return
	}
	// Create a an empty record for searching for records
	rr := cloudflare.DNSRecord{}
	var records []cloudflare.DNSRecord
	if c.String("id") != "" {
		rec, err := api.DNSRecord(zone, c.String("id"))
		if err != nil {
			fmt.Println(err)
			return
		}
		records = append(records, rec)
	} else {
		if c.String("name") != "" {
			rr.Name = c.String("name")
		}
		if c.String("content") != "" {
			rr.Name = c.String("content")
		}
		var err error
		records, err = api.DNSRecords(zone, rr)
		if err != nil {
			fmt.Println(err)
			return
		}
	}
	var output []table
	for _, r := range records {
		switch r.Type {
		case "MX":
			r.Content = fmt.Sprintf("%d %s", r.Priority, r.Content)
		case "SRV":
			dp := reflect.ValueOf(r.Data).Interface().(map[string]interface{})
			r.Content = fmt.Sprintf("%.f %s", dp["priority"], r.Content)
			// CloudFlare's API, annoyingly, automatically prepends the weight
			// and port into content, separated by tabs.
			// XXX: File this as a bug. LOC doesn't do this.
			r.Content = strings.Replace(r.Content, "\t", " ", -1)
		}
		output = append(output, table{
			"ID":      r.ID,
			"Type":    r.Type,
			"Name":    r.Name,
			"Content": r.Content,
			"Proxied": fmt.Sprintf("%t", r.Proxied),
			"TTL":     fmt.Sprintf("%d", r.TTL),
		})
	}
	makeTable(output, "ID", "Type", "Name", "Content", "Proxied", "TTL")
}
Example #20
0
// serviced service run SERVICEID [COMMAND [ARGS ...]]
func (c *ServicedCli) cmdServiceRun(ctx *cli.Context) error {
	args := ctx.Args()
	if len(args) < 1 {
		if !ctx.Bool("help") {
			fmt.Fprintf(os.Stderr, "Incorrect Usage.\n\n")
		}
		cli.ShowSubcommandHelp(ctx)
		return c.exit(1)
	}

	if len(args) < 2 {
		for _, s := range c.serviceRuns(args[0]) {
			fmt.Println(s)
		}
		fmt.Fprintf(os.Stderr, "serviced service run")
		return c.exit(1)
	}

	var (
		command string
		argv    []string
	)

	svc, err := c.searchForService(args[0])
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return c.exit(1)
	}

	command = args[1]
	if len(args) > 2 {
		argv = args[2:]
	}

	config := api.ShellConfig{
		ServiceID:        svc.ID,
		Command:          command,
		Username:         ctx.GlobalString("user"),
		Args:             argv,
		SaveAs:           dfs.NewLabel(svc.ID),
		IsTTY:            ctx.GlobalBool("interactive"),
		Mounts:           ctx.GlobalStringSlice("mount"),
		ServicedEndpoint: fmt.Sprintf("localhost:%s", api.GetOptionsRPCPort()),
		LogToStderr:      ctx.GlobalBool("logtostderr"),
	}

	config.LogStash.Enable = ctx.GlobalBool("logstash")
	config.LogStash.SettleTime = ctx.GlobalString("logstash-settle-time")
	config.LogStash.IdleFlushTime = ctx.GlobalString("logstash-idle-flush-time")

	if err := c.driver.RunShell(config); err != nil {
		fmt.Fprintln(os.Stderr, err)
		return c.exit(1)
	}

	return c.exit(0)
}
Example #21
0
// usage throws out an error is required and prints the usage menu
func usage(context *cli.Context, message string) {
	cli.ShowSubcommandHelp(context)
	if message != "" {
		fmt.Printf("\n[error]: %s\n", message)
		os.Exit(1)
	}

	os.Exit(0)
}
Example #22
0
// Utility function to check if CLI flags were given.
func checkFlags(c *cli.Context, flags ...string) error {
	for _, flag := range flags {
		if c.String(flag) == "" {
			cli.ShowSubcommandHelp(c)
			return fmt.Errorf("%s not specified", flag)
		}
	}
	return nil
}
Example #23
0
func (s SpreadCli) Git() *cli.Command {
	return &cli.Command{
		Name:  "git",
		Usage: "Allows access to git commands while Spread is build out",
		Action: func(c *cli.Context) {
			cli.ShowSubcommandHelp(c)
		},
	}
}
Example #24
0
func config_show(c *cli.Context) {
	if len(c.Args()) != 0 {
		fmt.Println("Error: bad args to 'config show'")
		cli.ShowSubcommandHelp(c)
		return
	}
	printZahaConfig()
	printAppConfig(APPCFG)
}
Example #25
0
func dev(c *cli.Context) {
	if len(c.Args()) != 1 {
		fmt.Println("Error: bad args to 'dev' !!!")
		cli.ShowSubcommandHelp(c)
		return
	}
	fmt.Println("Not Implemented")

}
Example #26
0
func checkFilepathArgument(c *cli.Context) (os.FileInfo, string) {
	if len(c.Args()) != 1 {
		cli.ShowSubcommandHelp(c)
		return nil, ""
	}

	filepath := c.Args()[0]
	return getFileOfType(filepath, true, "target")
}
Example #27
0
func db_migrate(c *cli.Context) {
	if len(c.Args()) != 0 {
		fmt.Println("Error: bad args to 'db migrate' !!!")
		cli.ShowSubcommandHelp(c)
		return
	}
	// migrate_cmd := "db migrate"
	// upgrade_cmd := "db upgrade"
	fmt.Println("Not implemented yet...")
}
Example #28
0
func errExit(ctx *cli.Context, exitCode int, err string, showHelp bool) {
	if err != "" {
		logrus.Error(err)
	}

	if showHelp {
		cli.ShowSubcommandHelp(ctx)
	}

	os.Exit(exitCode)
}
Example #29
0
// serviced service logs { SERVICEID | SERVICENAME | DOCKERID | POOL/...PARENTNAME.../SERVICENAME/INSTANCE }
func (c *ServicedCli) cmdServiceLogs(ctx *cli.Context) error {
	// verify args
	args := ctx.Args()
	if len(args) < 1 {
		if !ctx.Bool("help") {
			fmt.Fprintf(os.Stderr, "Incorrect Usage.\n\n")
		}
		cli.ShowSubcommandHelp(ctx)
		return nil
	}

	rs, err := c.searchForRunningService(args[0])
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return err
	}

	// docker logs on remote host if service is running on remote
	myHostID, err := utils.HostID()
	if err != nil {
		return err
	}

	if rs.HostID != myHostID {
		hosts, err := c.driver.GetHosts()
		if err != nil {
			return err
		}
		hostmap := make(map[string]host.Host)
		for _, host := range hosts {
			hostmap[host.ID] = host
		}

		cmd := []string{"/usr/bin/ssh", "-t", hostmap[rs.HostID].IPAddr, "--", "serviced", "--endpoint", api.GetOptionsRPCEndpoint(), "service", "logs", args[0]}
		if len(args) > 1 {
			cmd = append(cmd, args[1:]...)
		}

		glog.V(1).Infof("outputting remote logs with: %s\n", cmd)
		return syscall.Exec(cmd[0], cmd[0:], os.Environ())
	}

	// docker logs on local host if service is running locally
	var argv []string
	if len(args) > 2 {
		argv = args[2:]
	}

	if err := dockerclient.Logs(rs.DockerID, argv); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	return fmt.Errorf("serviced service logs")
}
Example #30
0
func CmdCatFile(c *cli.Context) {
	repo, err := git4go.OpenRepositoryExtended(".")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if len(c.Args()) < 2 {
		cli.ShowSubcommandHelp(c)
	} else {
		objType := git4go.TypeString2Type(c.Args().First())
		if objType == git4go.ObjectBad {
			fmt.Fprintln(os.Stderr, `fatal: invalid object type "bad"`)
			os.Exit(1)
		}
		odb, err := repo.Odb()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		oid, err := git4go.NewOid(c.Args()[1])
		if err != nil {
			ref, err := repo.DwimReference(c.Args()[1])
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			resolved, err := ref.Resolve()
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
			oid = resolved.Target()
		}
		obj, err := odb.Read(oid)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		if obj.Type == git4go.ObjectCommit && objType == git4go.ObjectTree {
			commit, _ := repo.LookupCommit(oid)
			obj, err = odb.Read(commit.TreeId())
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
		}
		if obj.Type != objType {
			fmt.Fprintf(os.Stderr, "fatal: got cat-file: %s: bad file\n", c.Args()[1])
			os.Exit(1)
		}
		os.Stdout.Write(obj.Data)
	}
}