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

Side by Side Diff: vpython/filesystem/filesystem.go

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

Powered by Google App Engine
This is Rietveld 408576698