1package cmd
2
3import (
4 "fmt"
5
6 "github.com/charmbracelet/soft-serve/git"
7 "github.com/charmbracelet/soft-serve/pkg/backend"
8 "github.com/charmbracelet/soft-serve/pkg/ui/common"
9 "github.com/charmbracelet/soft-serve/pkg/ui/styles"
10 "github.com/spf13/cobra"
11)
12
13// blobCommand returns a command that prints the contents of a file.
14func blobCommand() *cobra.Command {
15 var linenumber bool
16 var color bool
17 var raw bool
18
19 styles := styles.DefaultStyles()
20 cmd := &cobra.Command{
21 Use: "blob REPOSITORY [REFERENCE] [PATH]",
22 Aliases: []string{"cat", "show"},
23 Short: "Print out the contents of file at path",
24 Args: cobra.RangeArgs(1, 3),
25 PersistentPreRunE: checkIfReadable,
26 RunE: func(cmd *cobra.Command, args []string) error {
27 ctx := cmd.Context()
28 be := backend.FromContext(ctx)
29 rn := args[0]
30 ref := ""
31 fp := ""
32 switch len(args) {
33 case 2:
34 fp = args[1]
35 case 3:
36 ref = args[1]
37 fp = args[2]
38 }
39
40 repo, err := be.Repository(ctx, rn)
41 if err != nil {
42 return err
43 }
44
45 r, err := repo.Open()
46 if err != nil {
47 return err
48 }
49
50 if ref == "" {
51 head, err := r.HEAD()
52 if err != nil {
53 return err
54 }
55 ref = head.ID
56 }
57
58 tree, err := r.LsTree(ref)
59 if err != nil {
60 return err
61 }
62
63 te, err := tree.TreeEntry(fp)
64 if err != nil {
65 return err
66 }
67
68 if te.Type() != "blob" {
69 return git.ErrFileNotFound
70 }
71
72 bts, err := te.Contents()
73 if err != nil {
74 return err
75 }
76
77 c := string(bts)
78 isBin, _ := te.File().IsBinary()
79 if isBin {
80 if raw {
81 cmd.Println(c)
82 } else {
83 return fmt.Errorf("binary file: use --raw to print")
84 }
85 } else {
86 if color {
87 c, err = common.FormatHighlight(fp, c)
88 if err != nil {
89 return err
90 }
91 }
92
93 if linenumber {
94 c, _ = common.FormatLineNumber(styles, c, color)
95 }
96
97 cmd.Println(c)
98 }
99 return nil
100 },
101 }
102
103 cmd.Flags().BoolVarP(&raw, "raw", "r", false, "Print raw contents")
104 cmd.Flags().BoolVarP(&linenumber, "linenumber", "l", false, "Print line numbers")
105 cmd.Flags().BoolVarP(&color, "color", "c", false, "Colorize output")
106
107 return cmd
108}