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