github.com/npaton/distribution@v2.3.1-rc.0+incompatible/cmd/digest/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  
    10  	"github.com/docker/distribution/digest"
    11  	"github.com/docker/distribution/version"
    12  )
    13  
    14  var (
    15  	algorithm   = digest.Canonical
    16  	showVersion bool
    17  )
    18  
    19  type job struct {
    20  	name   string
    21  	reader io.Reader
    22  }
    23  
    24  func init() {
    25  	flag.Var(&algorithm, "a", "select the digest algorithm (shorthand)")
    26  	flag.Var(&algorithm, "algorithm", "select the digest algorithm")
    27  	flag.BoolVar(&showVersion, "version", false, "show the version and exit")
    28  
    29  	log.SetFlags(0)
    30  	log.SetPrefix(os.Args[0] + ": ")
    31  }
    32  
    33  func usage() {
    34  	fmt.Fprintf(os.Stderr, "usage: %s [files...]\n", os.Args[0])
    35  	fmt.Fprintf(os.Stderr, `
    36  Calculate the digest of one or more input files, emitting the result
    37  to standard out. If no files are provided, the digest of stdin will
    38  be calculated.
    39  
    40  `)
    41  	flag.PrintDefaults()
    42  }
    43  
    44  func unsupported() {
    45  	log.Fatalf("unsupported digest algorithm: %v", algorithm)
    46  }
    47  
    48  func main() {
    49  	var jobs []job
    50  
    51  	flag.Usage = usage
    52  	flag.Parse()
    53  	if showVersion {
    54  		version.PrintVersion()
    55  		return
    56  	}
    57  
    58  	var fail bool // if we fail on one item, foul the exit code
    59  	if flag.NArg() > 0 {
    60  		for _, path := range flag.Args() {
    61  			fp, err := os.Open(path)
    62  
    63  			if err != nil {
    64  				log.Printf("%s: %v", path, err)
    65  				fail = true
    66  				continue
    67  			}
    68  			defer fp.Close()
    69  
    70  			jobs = append(jobs, job{name: path, reader: fp})
    71  		}
    72  	} else {
    73  		// just read stdin
    74  		jobs = append(jobs, job{name: "-", reader: os.Stdin})
    75  	}
    76  
    77  	digestFn := algorithm.FromReader
    78  
    79  	if !algorithm.Available() {
    80  		unsupported()
    81  	}
    82  
    83  	for _, job := range jobs {
    84  		dgst, err := digestFn(job.reader)
    85  		if err != nil {
    86  			log.Printf("%s: %v", job.name, err)
    87  			fail = true
    88  			continue
    89  		}
    90  
    91  		fmt.Printf("%v\t%s\n", dgst, job.name)
    92  	}
    93  
    94  	if fail {
    95  		os.Exit(1)
    96  	}
    97  }