| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. | 1 // Copyright 2015 The LUCI Authors. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 package archiver | 15 package archiver |
| 16 | 16 |
| 17 import ( | 17 import ( |
| 18 "bytes" | 18 "bytes" |
| 19 "encoding/json" | 19 "encoding/json" |
| 20 "fmt" | 20 "fmt" |
| 21 "log" | 21 "log" |
| 22 "os" | 22 "os" |
| 23 "path/filepath" | 23 "path/filepath" |
| 24 "strings" | |
| 25 | 24 |
| 26 "github.com/luci/luci-go/common/isolated" | 25 "github.com/luci/luci-go/common/isolated" |
| 27 "github.com/luci/luci-go/common/isolatedclient" | 26 "github.com/luci/luci-go/common/isolatedclient" |
| 28 "github.com/luci/luci-go/common/runtime/tracer" | 27 "github.com/luci/luci-go/common/runtime/tracer" |
| 29 ) | 28 ) |
| 30 | 29 |
| 31 type walkItem struct { | 30 type walkItem struct { |
| 32 fullPath string | 31 fullPath string |
| 33 relPath string | 32 relPath string |
| 34 info os.FileInfo | 33 info os.FileInfo |
| (...skipping 30 matching lines...) Expand all Loading... |
| 65 end := tracer.Span(root, "walk:"+filepath.Base(root), nil) | 64 end := tracer.Span(root, "walk:"+filepath.Base(root), nil) |
| 66 defer func() { end(tracer.Args{"root": root, "total": total}) }() | 65 defer func() { end(tracer.Args{"root": root, "total": total}) }() |
| 67 // Check patterns upfront, so it has consistent behavior w.r.t. bad glob | 66 // Check patterns upfront, so it has consistent behavior w.r.t. bad glob |
| 68 // patterns. | 67 // patterns. |
| 69 for _, b := range blacklist { | 68 for _, b := range blacklist { |
| 70 if _, err := filepath.Match(b, b); err != nil { | 69 if _, err := filepath.Match(b, b); err != nil { |
| 71 c <- &walkItem{err: fmt.Errorf("bad blacklist pattern \"
%s\"", b)} | 70 c <- &walkItem{err: fmt.Errorf("bad blacklist pattern \"
%s\"", b)} |
| 72 return | 71 return |
| 73 } | 72 } |
| 74 } | 73 } |
| 75 if strings.HasSuffix(root, string(filepath.Separator)) { | |
| 76 root = root[:len(root)-1] | |
| 77 } | |
| 78 rootLen := len(root) + 1 | |
| 79 err := filepath.Walk(root, func(p string, info os.FileInfo, err error) e
rror { | 74 err := filepath.Walk(root, func(p string, info os.FileInfo, err error) e
rror { |
| 80 total++ | 75 total++ |
| 81 if err != nil { | 76 if err != nil { |
| 82 return fmt.Errorf("walk(%q): %v", p, err) | 77 return fmt.Errorf("walk(%q): %v", p, err) |
| 83 } | 78 } |
| 84 » » if len(p) <= rootLen { | 79 |
| 85 » » » // Root directory. | 80 » » relPath, err := filepath.Rel(root, p) |
| 86 » » » return nil | 81 » » if err != nil { |
| 82 » » » return fmt.Errorf("walk: calculating relative path(%q):
%v", p, err) |
| 87 } | 83 } |
| 88 » » relPath := p[rootLen:] | 84 |
| 85 » » // filepath.Rel is documented to call filepath.Clean on its resu
lt before returning it, |
| 86 » » // which results in "." for an empty relative path. |
| 87 » » if relPath == "." { |
| 88 » » » return nil // Root directory. |
| 89 » » } |
| 90 |
| 89 for _, b := range blacklist { | 91 for _, b := range blacklist { |
| 90 matched, _ := filepath.Match(b, relPath) | 92 matched, _ := filepath.Match(b, relPath) |
| 91 if !matched { | 93 if !matched { |
| 92 // Also check at the base file name. | 94 // Also check at the base file name. |
| 93 matched, _ = filepath.Match(b, filepath.Base(rel
Path)) | 95 matched, _ = filepath.Match(b, filepath.Base(rel
Path)) |
| 94 } | 96 } |
| 95 if matched { | 97 if matched { |
| 96 // Must not return io.SkipDir for file, filepath
.walk() handles this | 98 // Must not return io.SkipDir for file, filepath
.walk() handles this |
| 97 // badly. | 99 // badly. |
| 98 if info.IsDir() { | 100 if info.IsDir() { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 } | 203 } |
| 202 } | 204 } |
| 203 } | 205 } |
| 204 } | 206 } |
| 205 if err != nil { | 207 if err != nil { |
| 206 s.SetErr(err) | 208 s.SetErr(err) |
| 207 } | 209 } |
| 208 }() | 210 }() |
| 209 return s | 211 return s |
| 210 } | 212 } |
| OLD | NEW |