func unpackIndex(ctx context.Context, pack *indexpack.Archive, dir string) error { fetcher := pack.Fetcher(ctx) return pack.ReadUnits(ctx, formatKey, func(u interface{}) error { unit, ok := u.(*apb.CompilationUnit) if !ok { return fmt.Errorf("%T is not a CompilationUnit", u) } idx, err := kindex.FromUnit(unit, fetcher) if err != nil { return fmt.Errorf("error creating kindex: %v", err) } path := kindexPath(dir, idx) if !*quiet { log.Println("Writing compilation unit to", path) } f, err := vfs.Create(ctx, path) if err != nil { return fmt.Errorf("error creating output file: %v", err) } if _, err := idx.WriteTo(f); err != nil { f.Close() // try to close file before returning return fmt.Errorf("error writing output file: %v", err) } return f.Close() }) }
func main() { flag.Parse() if *toArchive != "" && *fromArchive != "" { fmt.Fprintln(os.Stderr, "ERROR: --to_archive and --from_archive are mutually exclusive") flag.Usage() } else if *toArchive != "" && *viewArchive != "" { fmt.Fprintln(os.Stderr, "ERROR: --to_archive and --view_archive are mutually exclusive") flag.Usage() } else if *fromArchive != "" && *viewArchive != "" { fmt.Fprintln(os.Stderr, "ERROR: --from_archive and --view_archive are mutually exclusive") flag.Usage() } else if *toArchive == "" && *fromArchive == "" && *viewArchive == "" { fmt.Fprintln(os.Stderr, "ERROR: One of [--to_archive --from_archive --view_archive] must be specified") flag.Usage() } archiveRoot := *toArchive if archiveRoot == "" { archiveRoot = *fromArchive } if archiveRoot == "" { archiveRoot = *viewArchive } ctx := context.Background() var err error opts := []indexpack.Option{indexpack.UnitType(apb.CompilationUnit{})} if strings.HasPrefix(archiveRoot, "gs://") { path := strings.Trim(strings.TrimPrefix(archiveRoot, "gs://"), "/") parts := strings.SplitN(path, "/", 2) ctx, err = oauth2Config.Context(ctx) if err != nil { log.Fatal(err) } opts = append(opts, indexpack.FS(gcs.FS{parts[0]})) if len(parts) == 2 { archiveRoot = parts[1] } else { archiveRoot = "/" } } pack, err := indexpack.CreateOrOpen(ctx, archiveRoot, opts...) if err != nil { log.Fatalf("Error opening indexpack at %q: %v", archiveRoot, err) } if *toArchive != "" { if len(flag.Args()) == 0 { log.Println("WARNING: no kindex file paths given") } for _, path := range flag.Args() { kindex, err := kindex.Open(ctx, path) if err != nil { log.Fatalf("Error opening kindex at %q: %v", path, err) } if err := packIndex(ctx, pack, kindex); err != nil { log.Fatalf("Error packing kindex at %q into %q: %v", path, pack.Root(), err) } } } else if *fromArchive != "" { var dir string if len(flag.Args()) > 1 { fmt.Fprintf(os.Stderr, "ERROR: Too many positional arguments for --from_archive: %v\n", flag.Args()) flag.Usage() } else if len(flag.Args()) == 1 { dir = flag.Arg(0) if err := os.MkdirAll(dir, os.ModePerm); err != nil { log.Fatalf("Error creating directory %q: %v", dir, err) } } if err := unpackIndex(ctx, pack, dir); err != nil { log.Fatalf("Error unpacking compilation units at %q: %v", pack.Root(), err) } } else { en := json.NewEncoder(os.Stdout) fetcher := pack.Fetcher(ctx) displayCompilation := func(i interface{}) error { cu := i.(*apb.CompilationUnit) if *printFiles { idx, err := kindex.FromUnit(cu, fetcher) if err != nil { return fmt.Errorf("error reading files for compilation: %v", err) } return en.Encode(idx) } return en.Encode(cu) } if len(flag.Args()) == 0 { if err := pack.ReadUnits(ctx, formatKey, displayCompilation); err != nil { log.Fatal(err) } } else { for _, digest := range flag.Args() { if err := pack.ReadUnit(ctx, formatKey, digest, displayCompilation); err != nil { log.Fatal(err) } } } } }