Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: common/system/filesystem/filesystem.go

Issue 2963503003: [errors] Greatly simplify common/errors package. (Closed)
Patch Set: fix nits Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « common/runtime/profiling/profiler.go ('k') | common/system/filesystem/filesystem_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The LUCI Authors. All rights reserved. 1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package filesystem 5 package filesystem
6 6
7 import ( 7 import (
8 "os" 8 "os"
9 "path/filepath" 9 "path/filepath"
10 "time" 10 "time"
11 11
12 "github.com/luci/luci-go/common/errors" 12 "github.com/luci/luci-go/common/errors"
13 ) 13 )
14 14
15 // IsNotExist calls os.IsNotExist on the unwrapped err. 15 // IsNotExist calls os.IsNotExist on the unwrapped err.
16 func IsNotExist(err error) bool { return os.IsNotExist(errors.Unwrap(err)) } 16 func IsNotExist(err error) bool { return os.IsNotExist(errors.Unwrap(err)) }
17 17
18 // MakeDirs is a convenience wrapper around os.MkdirAll that applies a 0755 18 // MakeDirs is a convenience wrapper around os.MkdirAll that applies a 0755
19 // mask to all created directories. 19 // mask to all created directories.
20 func MakeDirs(path string) error { 20 func MakeDirs(path string) error {
21 if err := os.MkdirAll(path, 0755); err != nil { 21 if err := os.MkdirAll(path, 0755); err != nil {
22 » » return errors.Annotate(err).Err() 22 » » return errors.Annotate(err, "").Err()
23 } 23 }
24 return nil 24 return nil
25 } 25 }
26 26
27 // AbsPath is a convenience wrapper around filepath.Abs that accepts a string 27 // AbsPath is a convenience wrapper around filepath.Abs that accepts a string
28 // pointer, base, and updates it on successful resolution. 28 // pointer, base, and updates it on successful resolution.
29 func AbsPath(base *string) error { 29 func AbsPath(base *string) error {
30 v, err := filepath.Abs(*base) 30 v, err := filepath.Abs(*base)
31 if err != nil { 31 if err != nil {
32 » » return errors.Annotate(err).Reason("unable to resolve absolute p ath"). 32 » » return errors.Annotate(err, "unable to resolve absolute path").
33 » » » D("base", *base). 33 » » » InternalReason("base(%q)", *base).Err()
34 » » » Err()
35 } 34 }
36 *base = v 35 *base = v
37 return nil 36 return nil
38 } 37 }
39 38
40 // Touch creates a new, empty file at the specified path. 39 // Touch creates a new, empty file at the specified path.
41 // 40 //
42 // If when is zero-value, time.Now will be used. 41 // If when is zero-value, time.Now will be used.
43 func Touch(path string, when time.Time, mode os.FileMode) error { 42 func Touch(path string, when time.Time, mode os.FileMode) error {
44 // Try and create a file at the target path. 43 // Try and create a file at the target path.
45 fd, err := os.OpenFile(path, (os.O_CREATE | os.O_RDWR), mode) 44 fd, err := os.OpenFile(path, (os.O_CREATE | os.O_RDWR), mode)
46 if err == nil { 45 if err == nil {
47 if err := fd.Close(); err != nil { 46 if err := fd.Close(); err != nil {
48 » » » return errors.Annotate(err).Reason("failed to close new file").Err() 47 » » » return errors.Annotate(err, "failed to close new file"). Err()
49 } 48 }
50 if when.IsZero() { 49 if when.IsZero() {
51 // If "now" was specified, and we created a new file, th en its times will 50 // If "now" was specified, and we created a new file, th en its times will
52 // be now by default. 51 // be now by default.
53 return nil 52 return nil
54 } 53 }
55 } 54 }
56 55
57 // Couldn't create a new file. Either it exists already, it is a directo ry, 56 // Couldn't create a new file. Either it exists already, it is a directo ry,
58 // or there was an OS-level failure. Since we can't really distinguish 57 // or there was an OS-level failure. Since we can't really distinguish
59 // between these cases, try opening for write (update timestamp) and err or 58 // between these cases, try opening for write (update timestamp) and err or
60 // if this fails. 59 // if this fails.
61 if when.IsZero() { 60 if when.IsZero() {
62 when = time.Now() 61 when = time.Now()
63 } 62 }
64 if err := os.Chtimes(path, when, when); err != nil { 63 if err := os.Chtimes(path, when, when); err != nil {
65 » » return errors.Annotate(err).Reason("failed to Chtimes"). 64 » » return errors.Annotate(err, "failed to Chtimes").InternalReason( "path(%q)", path).Err()
66 » » » D("path", path).
67 » » » Err()
68 } 65 }
69 66
70 return nil 67 return nil
71 } 68 }
72 69
73 // RemoveAll is a wrapper around os.RemoveAll which makes sure all files are 70 // RemoveAll is a wrapper around os.RemoveAll which makes sure all files are
74 // writeable (recursively) prior to removing them. 71 // writeable (recursively) prior to removing them.
75 func RemoveAll(path string) error { 72 func RemoveAll(path string) error {
76 err := removeAllImpl(path, func(path string, fi os.FileInfo) error { 73 err := removeAllImpl(path, func(path string, fi os.FileInfo) error {
77 // If we aren't handed a FileInfo, use Lstat to get one. 74 // If we aren't handed a FileInfo, use Lstat to get one.
78 if fi == nil { 75 if fi == nil {
79 var err error 76 var err error
80 if fi, err = os.Lstat(path); err != nil { 77 if fi, err = os.Lstat(path); err != nil {
81 » » » » return errors.Annotate(err).Reason("could not Ls tat path"). 78 » » » » return errors.Annotate(err, "could not Lstat pat h").InternalReason("path(%q)", path).Err()
82 » » » » » D("path", path).
83 » » » » » Err()
84 } 79 }
85 } 80 }
86 81
87 // Make user-writable, if it's not already. 82 // Make user-writable, if it's not already.
88 mode := fi.Mode() 83 mode := fi.Mode()
89 if (mode & 0200) == 0 { 84 if (mode & 0200) == 0 {
90 mode |= 0200 85 mode |= 0200
91 if err := os.Chmod(path, mode); err != nil { 86 if err := os.Chmod(path, mode); err != nil {
92 » » » » return errors.Annotate(err).Reason("could not Ch mod path"). 87 » » » » return errors.Annotate(err, "could not Chmod pat h").InternalReason("mode(%#o)/path(%q)", mode, path).Err()
93 » » » » » D("mode", mode).
94 » » » » » D("path", path).
95 » » » » » Err()
96 } 88 }
97 } 89 }
98 90
99 if err := os.Remove(path); err != nil { 91 if err := os.Remove(path); err != nil {
100 » » » return errors.Annotate(err).Reason("failed to remove pat h"). 92 » » » return errors.Annotate(err, "failed to remove path").Int ernalReason("path(%q)", path).Err()
101 » » » » D("path", path).
102 » » » » Err()
103 } 93 }
104 return nil 94 return nil
105 }) 95 })
106 if err != nil { 96 if err != nil {
107 » » return errors.Annotate(err).Reason("failed to recurisvely remove path"). 97 » » return errors.Annotate(err, "failed to recurisvely remove path") .InternalReason("path(%q)", path).Err()
108 » » » D("path", path).
109 » » » Err()
110 } 98 }
111 return nil 99 return nil
112 } 100 }
113 101
114 // MakeReadOnly recursively iterates through all of the files and directories 102 // MakeReadOnly recursively iterates through all of the files and directories
115 // starting at path and marks them read-only. 103 // starting at path and marks them read-only.
116 func MakeReadOnly(path string, filter func(string) bool) error { 104 func MakeReadOnly(path string, filter func(string) bool) error {
117 return recursiveChmod(path, filter, func(mode os.FileMode) os.FileMode { 105 return recursiveChmod(path, filter, func(mode os.FileMode) os.FileMode {
118 return mode & (^os.FileMode(0222)) 106 return mode & (^os.FileMode(0222))
119 }) 107 })
120 } 108 }
121 109
122 func recursiveChmod(path string, filter func(string) bool, chmod func(mode os.Fi leMode) os.FileMode) error { 110 func recursiveChmod(path string, filter func(string) bool, chmod func(mode os.Fi leMode) os.FileMode) error {
123 if filter == nil { 111 if filter == nil {
124 filter = func(string) bool { return true } 112 filter = func(string) bool { return true }
125 } 113 }
126 114
127 err := filepath.Walk(path, func(path string, info os.FileInfo, err error ) error { 115 err := filepath.Walk(path, func(path string, info os.FileInfo, err error ) error {
128 if err != nil { 116 if err != nil {
129 » » » return errors.Annotate(err).Err() 117 » » » return errors.Annotate(err, "").Err()
130 } 118 }
131 119
132 mode := info.Mode() 120 mode := info.Mode()
133 if (mode.IsRegular() || mode.IsDir()) && filter(path) { 121 if (mode.IsRegular() || mode.IsDir()) && filter(path) {
134 if newMode := chmod(mode); newMode != mode { 122 if newMode := chmod(mode); newMode != mode {
135 if err := os.Chmod(path, newMode); err != nil { 123 if err := os.Chmod(path, newMode); err != nil {
136 » » » » » return errors.Annotate(err).Reason("fail ed to Chmod"). 124 » » » » » return errors.Annotate(err, "failed to C hmod").InternalReason("path(%q)", path).Err()
137 » » » » » » D("path", path).
138 » » » » » » Err()
139 } 125 }
140 } 126 }
141 } 127 }
142 return nil 128 return nil
143 }) 129 })
144 if err != nil { 130 if err != nil {
145 » » return errors.Annotate(err).Err() 131 » » return errors.Annotate(err, "").Err()
146 } 132 }
147 return nil 133 return nil
148 } 134 }
OLDNEW
« no previous file with comments | « common/runtime/profiling/profiler.go ('k') | common/system/filesystem/filesystem_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698