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