func parseSIProgress(pb progress.Meter, stdout io.Reader) error { if pb == nil { pb = &progress.NullProgress{} } scanner := bufio.NewScanner(stdout) // s-i is funny, total changes during the runs total := 0.0 pb.Start("ubuntu-core", 100) for scanner.Scan() { if os.Getenv("SNAPPY_DEBUG") != "" { fmt.Println(scanner.Text()) } jsonStream := strings.NewReader(scanner.Text()) dec := json.NewDecoder(jsonStream) var genericData genericJSON if err := dec.Decode(&genericData); err != nil { // we ignore invalid json here and continue // the parsing if s-i-cli or ubuntu-core-upgrader // output something unexpected (like stray debug // output or whatnot) continue } switch { case genericData.Type == "spinner": pb.Spin(genericData.Message) case genericData.Type == "error": return fmt.Errorf("error from %s: %s", systemImageCli, genericData.Message) case genericData.Type == "progress": if total != genericData.Total { total = genericData.Total pb.SetTotal(total) } pb.Set(genericData.Now) } } // ugly: avoid Spin() artifacts pb.Notify("\nApply done") if err := scanner.Err(); err != nil { return err } return nil }