forked from git-lfs/git-lfs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommand_pointer.go
177 lines (150 loc) · 4.25 KB
/
command_pointer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package commands
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"github.com/git-lfs/git-lfs/v3/git"
"github.com/git-lfs/git-lfs/v3/lfs"
"github.com/git-lfs/git-lfs/v3/tr"
"github.com/spf13/cobra"
)
var (
pointerFile string
pointerCompare string
pointerStdin bool
pointerCheck bool
pointerStrict bool
pointerNoStrict bool
)
func pointerCommand(cmd *cobra.Command, args []string) {
comparing := false
something := false
buildOid := ""
compareOid := ""
if pointerCheck {
var r io.ReadCloser
var err error
if pointerStrict && pointerNoStrict {
ExitWithError(errors.New(tr.Tr.Get("Cannot combine --strict with --no-strict")))
}
if len(pointerCompare) > 0 {
ExitWithError(errors.New(tr.Tr.Get("Cannot combine --check with --compare")))
}
if len(pointerFile) > 0 {
if pointerStdin {
ExitWithError(errors.New(tr.Tr.Get("With --check, --file cannot be combined with --stdin")))
}
r, err = os.Open(pointerFile)
if err != nil {
ExitWithError(err)
}
} else if pointerStdin {
r = io.NopCloser(os.Stdin)
} else {
ExitWithError(errors.New(tr.Tr.Get("Must specify either --file or --stdin with --compare")))
}
p, err := lfs.DecodePointer(r)
if err != nil {
os.Exit(1)
}
if pointerStrict && !p.Canonical {
os.Exit(2)
}
r.Close()
return
}
if len(pointerCompare) > 0 || pointerStdin {
comparing = true
}
if len(pointerFile) > 0 {
something = true
buildFile, err := os.Open(pointerFile)
if err != nil {
Error(err.Error())
os.Exit(1)
}
oidHash := sha256.New()
size, err := io.Copy(oidHash, buildFile)
buildFile.Close()
if err != nil {
Error(err.Error())
os.Exit(1)
}
ptr := lfs.NewPointer(hex.EncodeToString(oidHash.Sum(nil)), size, nil)
fmt.Fprint(os.Stderr, tr.Tr.Get("Git LFS pointer for %s", pointerFile), "\n\n")
buf := &bytes.Buffer{}
lfs.EncodePointer(io.MultiWriter(os.Stdout, buf), ptr)
if comparing {
buildOid, err = git.HashObject(bytes.NewReader(buf.Bytes()))
if err != nil {
Error(err.Error())
os.Exit(1)
}
fmt.Fprint(os.Stderr, "\n", tr.Tr.Get("Git blob OID: %s", buildOid), "\n\n")
}
} else {
comparing = false
}
if len(pointerCompare) > 0 || pointerStdin {
something = true
compFile, err := pointerReader()
if err != nil {
Error(err.Error())
os.Exit(1)
}
buf := &bytes.Buffer{}
tee := io.TeeReader(compFile, buf)
_, err = lfs.DecodePointer(tee)
compFile.Close()
pointerName := "STDIN"
if !pointerStdin {
pointerName = pointerCompare
}
fmt.Fprint(os.Stderr, tr.Tr.Get("Pointer from %s", pointerName), "\n\n")
if err != nil {
Error(err.Error())
os.Exit(1)
}
fmt.Fprintf(os.Stderr, buf.String())
if comparing {
compareOid, err = git.HashObject(bytes.NewReader(buf.Bytes()))
if err != nil {
Error(err.Error())
os.Exit(1)
}
fmt.Fprint(os.Stderr, "\n", tr.Tr.Get("Git blob OID: %s", compareOid), "\n")
}
}
if comparing && buildOid != compareOid {
fmt.Fprint(os.Stderr, "\n", tr.Tr.Get("Pointers do not match"), "\n")
os.Exit(1)
}
if !something {
Error(tr.Tr.Get("Nothing to do!"))
os.Exit(1)
}
}
func pointerReader() (io.ReadCloser, error) {
if len(pointerCompare) > 0 {
if pointerStdin {
return nil, errors.New(tr.Tr.Get("cannot read from STDIN and --pointer"))
}
return os.Open(pointerCompare)
}
requireStdin(tr.Tr.Get("The --stdin flag expects a pointer file from STDIN."))
return os.Stdin, nil
}
func init() {
RegisterCommand("pointer", pointerCommand, func(cmd *cobra.Command) {
cmd.Flags().StringVarP(&pointerFile, "file", "f", "", "Path to a local file to generate the pointer from.")
cmd.Flags().StringVarP(&pointerCompare, "pointer", "p", "", "Path to a local file containing a pointer built by another Git LFS implementation.")
cmd.Flags().BoolVarP(&pointerStdin, "stdin", "", false, "Read a pointer built by another Git LFS implementation through STDIN.")
cmd.Flags().BoolVarP(&pointerCheck, "check", "", false, "Check whether the given file is a Git LFS pointer.")
cmd.Flags().BoolVarP(&pointerStrict, "strict", "", false, "Check whether the given Git LFS pointer is canonical.")
cmd.Flags().BoolVarP(&pointerNoStrict, "no-strict", "", false, "Don't check whether the given Git LFS pointer is canonical.")
})
}