blob.go

  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}