porting all github actions from bluesky-social/indigo to tangled CI
at main 2.6 kB view raw
1package main 2 3import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "os" 9 "path/filepath" 10 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 "github.com/bluesky-social/indigo/repo" 13 14 "github.com/ipfs/go-cid" 15 cli "github.com/urfave/cli/v2" 16) 17 18var carCmd = &cli.Command{ 19 Name: "car", 20 Usage: "sub-commands to work with CAR files on local disk", 21 Subcommands: []*cli.Command{ 22 carUnpackCmd, 23 }, 24} 25 26var carUnpackCmd = &cli.Command{ 27 Name: "unpack", 28 Usage: "read all records from repo export CAR file, write as JSON files in directories", 29 Flags: []cli.Flag{ 30 &cli.BoolFlag{ 31 Name: "cbor", 32 Usage: "output CBOR files instead of JSON", 33 }, 34 &cli.StringFlag{ 35 Name: "out-dir", 36 Usage: "directory to write files to", 37 }, 38 }, 39 ArgsUsage: `<car-file>`, 40 Action: func(cctx *cli.Context) error { 41 ctx := context.Background() 42 arg := cctx.Args().First() 43 if arg == "" { 44 return fmt.Errorf("CAR file path arg is required") 45 } 46 47 fi, err := os.Open(arg) 48 if err != nil { 49 return err 50 } 51 52 r, err := repo.ReadRepoFromCar(ctx, fi) 53 if err != nil { 54 return err 55 } 56 57 sc := r.SignedCommit() 58 did, err := syntax.ParseDID(sc.Did) 59 if err != nil { 60 return err 61 } 62 63 topDir := cctx.String("out-dir") 64 if topDir == "" { 65 topDir = did.String() 66 } 67 log.Info("writing output", "topDir", topDir) 68 69 commitPath := topDir + "/_commit" 70 os.MkdirAll(filepath.Dir(commitPath), os.ModePerm) 71 if cctx.Bool("cbor") { 72 cborBytes := new(bytes.Buffer) 73 err = sc.MarshalCBOR(cborBytes) 74 if err := os.WriteFile(commitPath+".cbor", cborBytes.Bytes(), 0666); err != nil { 75 return err 76 } 77 } else { 78 recJson, err := json.MarshalIndent(sc, "", " ") 79 if err != nil { 80 return err 81 } 82 if err := os.WriteFile(commitPath+".json", recJson, 0666); err != nil { 83 return err 84 } 85 } 86 87 err = r.ForEach(ctx, "", func(k string, v cid.Cid) error { 88 89 _, rec, err := r.GetRecord(ctx, k) 90 if err != nil { 91 return err 92 } 93 log.Debug("processing record", "rec", k) 94 95 // TODO: check if path is safe more carefully 96 recPath := topDir + "/" + k 97 os.MkdirAll(filepath.Dir(recPath), os.ModePerm) 98 if err != nil { 99 return err 100 } 101 if cctx.Bool("cbor") { 102 cborBytes := new(bytes.Buffer) 103 err = rec.MarshalCBOR(cborBytes) 104 if err := os.WriteFile(recPath+".cbor", cborBytes.Bytes(), 0666); err != nil { 105 return err 106 } 107 } else { 108 recJson, err := json.MarshalIndent(rec, "", " ") 109 if err != nil { 110 return err 111 } 112 if err := os.WriteFile(recPath+".json", recJson, 0666); err != nil { 113 return err 114 } 115 } 116 117 return nil 118 }) 119 if err != nil { 120 return err 121 } 122 123 return nil 124 }, 125}