func CloneNodeCode(e *parsecli.Env, isNew, onlyConfig bool, appConfig parsecli.AppConfig) (bool, error) { cloneTemplate := false if !isNew && !onlyConfig { authToken, err := appConfig.GetApplicationAuth(e) if err != nil { return false, err } herokuAppConfig, ok := appConfig.(*parsecli.HerokuAppConfig) if !ok { return false, stackerr.New("invalid heroku app config") } var gitURL string g := &gitInfo{} herokuAppName, err := parsecli.FetchHerokuAppName(herokuAppConfig.HerokuAppID, e) if err != nil { return false, err } gitURL = fmt.Sprintf("https://:%[email protected]/%s.git", authToken, herokuAppName) err = g.clone(gitURL, e.Root) if err != nil { fmt.Fprintf(e.Err, `Failed to fetch the latest deployed code from Heroku. Please try "git clone %s %s". Currently cloning the template project. `, gitURL, e.Root, ) cloneTemplate = true } else { isEmpty, err := g.isEmptyRepository(e.Root) if err != nil { return false, err } if isEmpty { if err := os.RemoveAll(e.Root); err != nil { return false, stackerr.Wrap(err) } cloneTemplate = true } } } cloneTemplate = (isNew || cloneTemplate) && !onlyConfig return cloneTemplate, setupNodeSample(e, cloneTemplate) }
func (h *downloadCmd) run(e *parsecli.Env, ctx *parsecli.Context) error { appConfig, ok := ctx.AppConfig.(*parsecli.HerokuAppConfig) if !ok { return stackerr.New("expected heroku project config type") } authToken, err := appConfig.GetApplicationAuth(e) if err != nil { return err } herokuAppName, err := parsecli.FetchHerokuAppName(appConfig.HerokuAppID, e) if err != nil { return err } gitURL := fmt.Sprintf("https://:%[email protected]/%s.git", authToken, herokuAppName) return (&gitInfo{}).pull(e, gitURL) }
func (h *herokuLink) herokuAppNames(ids []string, e *parsecli.Env) (nameIDs, []string, error) { var wg errgroup.Group wg.Add(len(ids)) maxParallel := make(chan struct{}, maxRequests) var ( ret nameIDs deletedLinks []string retMutex sync.Mutex deletedLinksMutex sync.Mutex ) getAppName := func(id string) { defer func() { wg.Done() <-maxParallel }() appName, err := parsecli.FetchHerokuAppName(id, e) if err != nil { if stackerr.HasUnderlying(err, stackerr.MatcherFunc(parsecli.HerokuAppNotFound)) { deletedLinksMutex.Lock() defer deletedLinksMutex.Unlock() deletedLinks = append(deletedLinks, id) return } wg.Error(err) // ignore error if corresponding heroku app was deleted return } retMutex.Lock() defer retMutex.Unlock() ret = append(ret, nameID{id: id, name: appName}) } for _, id := range ids { go getAppName(id) } err := wg.Wait() sort.Sort(ret) return ret, deletedLinks, stackerr.Wrap(err) }