github.com/git-lfs/git-lfs@v2.5.2+incompatible/commands/command_pointer.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"encoding/hex"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  
    12  	"github.com/git-lfs/git-lfs/git"
    13  	"github.com/git-lfs/git-lfs/lfs"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  var (
    18  	pointerFile    string
    19  	pointerCompare string
    20  	pointerStdin   bool
    21  )
    22  
    23  func pointerCommand(cmd *cobra.Command, args []string) {
    24  	comparing := false
    25  	something := false
    26  	buildOid := ""
    27  	compareOid := ""
    28  
    29  	if len(pointerCompare) > 0 || pointerStdin {
    30  		comparing = true
    31  	}
    32  
    33  	if len(pointerFile) > 0 {
    34  		something = true
    35  		buildFile, err := os.Open(pointerFile)
    36  		if err != nil {
    37  			Error(err.Error())
    38  			os.Exit(1)
    39  		}
    40  
    41  		oidHash := sha256.New()
    42  		size, err := io.Copy(oidHash, buildFile)
    43  		buildFile.Close()
    44  
    45  		if err != nil {
    46  			Error(err.Error())
    47  			os.Exit(1)
    48  		}
    49  
    50  		ptr := lfs.NewPointer(hex.EncodeToString(oidHash.Sum(nil)), size, nil)
    51  		fmt.Fprintf(os.Stderr, "Git LFS pointer for %s\n\n", pointerFile)
    52  		buf := &bytes.Buffer{}
    53  		lfs.EncodePointer(io.MultiWriter(os.Stdout, buf), ptr)
    54  
    55  		if comparing {
    56  			buildOid, err = git.HashObject(bytes.NewReader(buf.Bytes()))
    57  			if err != nil {
    58  				Error(err.Error())
    59  				os.Exit(1)
    60  			}
    61  			fmt.Fprintf(os.Stderr, "\nGit blob OID: %s\n\n", buildOid)
    62  		}
    63  	} else {
    64  		comparing = false
    65  	}
    66  
    67  	if len(pointerCompare) > 0 || pointerStdin {
    68  		something = true
    69  		compFile, err := pointerReader()
    70  		if err != nil {
    71  			Error(err.Error())
    72  			os.Exit(1)
    73  		}
    74  
    75  		buf := &bytes.Buffer{}
    76  		tee := io.TeeReader(compFile, buf)
    77  		_, err = lfs.DecodePointer(tee)
    78  		compFile.Close()
    79  
    80  		pointerName := "STDIN"
    81  		if !pointerStdin {
    82  			pointerName = pointerCompare
    83  		}
    84  		fmt.Fprintf(os.Stderr, "Pointer from %s\n\n", pointerName)
    85  
    86  		if err != nil {
    87  			Error(err.Error())
    88  			os.Exit(1)
    89  		}
    90  
    91  		fmt.Fprintf(os.Stderr, buf.String())
    92  		if comparing {
    93  			compareOid, err = git.HashObject(bytes.NewReader(buf.Bytes()))
    94  			if err != nil {
    95  				Error(err.Error())
    96  				os.Exit(1)
    97  			}
    98  			fmt.Fprintf(os.Stderr, "\nGit blob OID: %s\n", compareOid)
    99  		}
   100  	}
   101  
   102  	if comparing && buildOid != compareOid {
   103  		fmt.Fprintf(os.Stderr, "\nPointers do not match\n")
   104  		os.Exit(1)
   105  	}
   106  
   107  	if !something {
   108  		Error("Nothing to do!")
   109  		os.Exit(1)
   110  	}
   111  }
   112  
   113  func pointerReader() (io.ReadCloser, error) {
   114  	if len(pointerCompare) > 0 {
   115  		if pointerStdin {
   116  			return nil, errors.New("Cannot read from STDIN and --pointer.")
   117  		}
   118  
   119  		return os.Open(pointerCompare)
   120  	}
   121  
   122  	requireStdin("The --stdin flag expects a pointer file from STDIN.")
   123  
   124  	return os.Stdin, nil
   125  }
   126  
   127  func init() {
   128  	RegisterCommand("pointer", pointerCommand, func(cmd *cobra.Command) {
   129  		cmd.Flags().StringVarP(&pointerFile, "file", "f", "", "Path to a local file to generate the pointer from.")
   130  		cmd.Flags().StringVarP(&pointerCompare, "pointer", "p", "", "Path to a local file containing a pointer built by another Git LFS implementation.")
   131  		cmd.Flags().BoolVarP(&pointerStdin, "stdin", "", false, "Read a pointer built by another Git LFS implementation through STDIN.")
   132  	})
   133  }