func getAndPourSkeleton(skeleton string) error { // Get or update given skeleton. task := fmt.Sprintf("Get or update skeleton '%v'", skeleton) log.Run(task) if err := getOrUpdateSkeleton(flagSkeleton); err != nil { return errs.NewError(task, err) } // Move the skeleton files into place. task = "Copy the skeleton into the configuration directory" log.Go(task) localConfigDir, err := config.LocalConfigDirectoryAbsolutePath() if err != nil { return errs.NewError(task, err) } log.NewLine("") if err := pourSkeleton(flagSkeleton, localConfigDir); err != nil { return errs.NewError(task, err) } log.NewLine("") log.Ok(task) return nil }
func downloadAndInstallAsset(assetName, assetURL, dstDir string) error { // Download the asset. task := "Download " + assetName log.Run(task) resp, err := http.Get(assetURL) if err != nil { return errs.NewError(task, err) } defer resp.Body.Close() // Unpack the asset (in-memory). // We keep the asset in the memory since it is never going to be that big. task = "Read the asset into an internal buffer" var capacity = resp.ContentLength if capacity == -1 { capacity = 0 } bodyBuffer := bytes.NewBuffer(make([]byte, 0, capacity)) _, err = io.Copy(bodyBuffer, resp.Body) if err != nil { return errs.NewError(task, err) } task = "Replace SalsaFlow executables" archive, err := zip.NewReader(bytes.NewReader(bodyBuffer.Bytes()), int64(bodyBuffer.Len())) if err != nil { return errs.NewError(task, err) } var numThreads int errCh := make(chan errs.Err, len(archive.File)) // Uncompress all the executables in the archive and move them into place. // This part replaces the current executables with new ones just downloaded. for _, file := range archive.File { if file.CompressedSize64 == 0 { continue } numThreads++ go func(file *zip.File) { baseName := filepath.Base(file.Name) task := fmt.Sprintf("Uncompress executable '%v'", baseName) log.Go(task) src, err := file.Open() if err != nil { errCh <- errs.NewError(task, err) return } task = fmt.Sprintf("Move executable '%v' into place", baseName) log.Go(task) if err := replaceExecutable(src, dstDir, baseName); err != nil { src.Close() errCh <- errs.NewError(task, err) return } src.Close() errCh <- nil }(file) } task = "install given SalsaFlow package" var ex error for i := 0; i < numThreads; i++ { if err := <-errCh; err != nil { errs.Log(err) ex = errs.NewError(task, ErrInstallationFailed) } } return ex }