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