forked from distribution/distribution
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
129 lines (106 loc) · 2.45 KB
/
main.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
package main
import (
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strings"
"github.com/docker/distribution/digest"
"github.com/docker/distribution/version"
"github.com/docker/docker/pkg/tarsum"
)
var (
algorithm = digest.Canonical
showVersion bool
)
type job struct {
name string
reader io.Reader
}
func init() {
flag.Var(&algorithm, "a", "select the digest algorithm (shorthand)")
flag.Var(&algorithm, "algorithm", "select the digest algorithm")
flag.BoolVar(&showVersion, "version", false, "show the version and exit")
log.SetFlags(0)
log.SetPrefix(os.Args[0] + ": ")
}
func usage() {
fmt.Fprintf(os.Stderr, "usage: %s [files...]\n", os.Args[0])
fmt.Fprintf(os.Stderr, `
Calculate the digest of one or more input files, emitting the result
to standard out. If no files are provided, the digest of stdin will
be calculated.
`)
flag.PrintDefaults()
}
func unsupported() {
log.Fatalf("unsupported digest algorithm: %v", algorithm)
}
func main() {
var jobs []job
flag.Usage = usage
flag.Parse()
if showVersion {
version.PrintVersion()
return
}
var fail bool // if we fail on one item, foul the exit code
if flag.NArg() > 0 {
for _, path := range flag.Args() {
fp, err := os.Open(path)
if err != nil {
log.Printf("%s: %v", path, err)
fail = true
continue
}
defer fp.Close()
jobs = append(jobs, job{name: path, reader: fp})
}
} else {
// just read stdin
jobs = append(jobs, job{name: "-", reader: os.Stdin})
}
digestFn := algorithm.FromReader
if !algorithm.Available() {
// we cannot digest if is not available. An exception is made for
// tarsum.
if !strings.HasPrefix(algorithm.String(), "tarsum") {
unsupported()
}
var version tarsum.Version
if algorithm == "tarsum" {
// small hack: if we just have tarsum, use latest
version = tarsum.Version1
} else {
var err error
version, err = tarsum.GetVersionFromTarsum(algorithm.String())
if err != nil {
unsupported()
}
}
digestFn = func(rd io.Reader) (digest.Digest, error) {
ts, err := tarsum.NewTarSum(rd, true, version)
if err != nil {
return "", err
}
if _, err := io.Copy(ioutil.Discard, ts); err != nil {
return "", err
}
return digest.Digest(ts.Sum(nil)), nil
}
}
for _, job := range jobs {
dgst, err := digestFn(job.reader)
if err != nil {
log.Printf("%s: %v", job.name, err)
fail = true
continue
}
fmt.Printf("%v\t%s\n", dgst, job.name)
}
if fail {
os.Exit(1)
}
}