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