func()

in snapshot/cli/cli.go [216:302]


func (c *createGitBundleCommand) run(db snapshot.DB, _ *cobra.Command, _ []string) error {
	if c.basis == "" || c.ref == "" {
		return fmt.Errorf("Create bundle command requires a basis and reference")
	}
	validOutput := false
	for _, o := range outputTypes {
		if o == c.outputType {
			validOutput = true
			break
		}
	}
	if !validOutput {
		return fmt.Errorf("Output type must be one of: %q", outputTypes)
	}

	wd, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("cannot get working directory: wd")
	}

	ingestRepo, err := repo.NewRepository(wd)
	if err != nil {
		return fmt.Errorf("not a valid repo dir: %v, %v", wd, err)
	}

	gdb, ok := db.(*gitdb.DB)
	if !ok {
		return fmt.Errorf("create bundle requires a gitdb.DB snapshot.DB")
	}

	td, err := ioutil.TempDir("", "")
	if err != nil {
		return fmt.Errorf("Couldn't create temp dir: %v", err)
	}
	defer func() {
		os.RemoveAll(td)
	}()

	// Don't use commit sha as bundle name as it could collide with other bundles.
	// Use the rev-list for the given basis/ref to generate a unique sha
	// Use this non-commit sha as bundleKey for a snapshot, but still parse
	// commit sha of provided ref to use as snapshot sha.
	// TODO (dgassaway): this would be better off in a proper library package

	revList := fmt.Sprintf("%s..%s", c.basis, c.ref)
	revData, err := ingestRepo.Run("rev-list", revList)
	if err != nil {
		return fmt.Errorf("Couldn't get rev-list for %s: %v", revList, err)
	}
	log.Infof("Using rev-list for %s:\n%s\n", revList, revData)
	commit, err := ingestRepo.Run("rev-parse", c.ref)
	if err != nil {
		return fmt.Errorf("Couldn't rev-parse ref %s: %v", c.ref, err)
	}
	commit = strings.TrimSpace(commit)

	// Add ref name to the rev-list we are bundling - otherwise we can create collisions
	// where a bundle with the same commit content but different ref name can get the same sha1
	revData += c.ref

	revSha1 := fmt.Sprintf("%x", sha1.Sum([]byte(revData)))
	bundleFilename := path.Join(td, fmt.Sprintf("bs-%s.bundle", revSha1))

	if _, err := ingestRepo.Run("-c",
		"core.packobjectedgesonlyshallow=0",
		"bundle",
		"create",
		bundleFilename,
		revList); err != nil {
		return err
	}

	ttlP := &store.TTLValue{TTL: time.Now().Add(c.ttld), TTLKey: store.DefaultTTLKey}
	location, err := gdb.UploadFile(bundleFilename, ttlP)
	if err != nil {
		return err
	}

	if c.outputType == outputTypeLocation {
		fmt.Println(location)
	} else if c.outputType == outputTypeSnapshotID {
		// Create a bundlestoreSnapshot to be able to return a valid snapshot ID
		bs := gitdb.CreateBundlestoreSnapshot(commit, gitdb.KindGitCommitSnapshot, revSha1, gdb.StreamName())
		fmt.Println(bs.ID())
	}
	return nil
}