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}