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}