1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package dirhash defines hashes over directory trees.
21 var DefaultHash
= Hash1
23 type Hash
func(files
[]string, open
func(string) (io
.ReadCloser
, error
)) (string, error
)
25 func Hash1(files
[]string, open
func(string) (io
.ReadCloser
, error
)) (string, error
) {
27 files
= append([]string(nil), files
...)
29 for _
, file
:= range files
{
30 if strings
.Contains(file
, "\n") {
31 return "", errors
.New("filenames with newlines are not supported")
38 _
, err
= io
.Copy(hf
, r
)
43 fmt
.Fprintf(h
, "%x %s\n", hf
.Sum(nil), file
)
45 return "h1:" + base64
.StdEncoding
.EncodeToString(h
.Sum(nil)), nil
48 func HashDir(dir
, prefix
string, hash Hash
) (string, error
) {
49 files
, err
:= DirFiles(dir
, prefix
)
53 osOpen
:= func(name
string) (io
.ReadCloser
, error
) {
54 return os
.Open(filepath
.Join(dir
, strings
.TrimPrefix(name
, prefix
)))
56 return hash(files
, osOpen
)
59 func DirFiles(dir
, prefix
string) ([]string, error
) {
61 dir
= filepath
.Clean(dir
)
62 err
:= filepath
.Walk(dir
, func(file
string, info os
.FileInfo
, err error
) error
{
71 rel
= file
[len(dir
)+1:]
73 f
:= filepath
.Join(prefix
, rel
)
74 files
= append(files
, filepath
.ToSlash(f
))
83 func HashZip(zipfile
string, hash Hash
) (string, error
) {
84 z
, err
:= zip
.OpenReader(zipfile
)
90 zfiles
:= make(map[string]*zip
.File
)
91 for _
, file
:= range z
.File
{
92 files
= append(files
, file
.Name
)
93 zfiles
[file
.Name
] = file
95 zipOpen
:= func(name
string) (io
.ReadCloser
, error
) {
98 return nil, fmt
.Errorf("file %q not found in zip", name
) // should never happen
102 return hash(files
, zipOpen
)