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

Side by Side Diff: deploytool/managedfs/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 | « deploytool/cmd/luci_deploy/work.go ('k') | deploytool/managedfs/util.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 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 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 managedfs offers a managed filesystem. A managed filesystem assumes 5 // Package managedfs offers a managed filesystem. A managed filesystem assumes
6 // that it has ownership of a specified directory and all of that directory's 6 // that it has ownership of a specified directory and all of that directory's
7 // contents, and tracks directory and creation. 7 // contents, and tracks directory and creation.
8 // 8 //
9 // This is useful in enabling the reuse of managed directories. In between uses, 9 // This is useful in enabling the reuse of managed directories. In between uses,
10 // new files may be added and old files may be deleted. A managed filesystem 10 // new files may be added and old files may be deleted. A managed filesystem
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 root *Dir 57 root *Dir
58 } 58 }
59 59
60 // New creates a new managed filesystem rooted at the target directory. 60 // New creates a new managed filesystem rooted at the target directory.
61 // 61 //
62 // The filesystem will create rootDir if it does not exist, and assumes total 62 // The filesystem will create rootDir if it does not exist, and assumes total
63 // ownership of its contents. 63 // ownership of its contents.
64 func New(rootDir string) (*Filesystem, error) { 64 func New(rootDir string) (*Filesystem, error) {
65 rootDir = filepath.Clean(rootDir) 65 rootDir = filepath.Clean(rootDir)
66 if err := ensureDirectory(rootDir); err != nil { 66 if err := ensureDirectory(rootDir); err != nil {
67 » » return nil, errors.Annotate(err).Reason("failed to create root d irectory").Err() 67 » » return nil, errors.Annotate(err, "failed to create root director y").Err()
68 } 68 }
69 fs := Filesystem{ 69 fs := Filesystem{
70 rootDir: rootDir, 70 rootDir: rootDir,
71 } 71 }
72 fs.root = &Dir{ 72 fs.root = &Dir{
73 fs: &fs, 73 fs: &fs,
74 relPath: "", 74 relPath: "",
75 elem: "", 75 elem: "",
76 } 76 }
77 return &fs, nil 77 return &fs, nil
(...skipping 30 matching lines...) Expand all
108 return filepath.Join(d.fs.rootDir, d.relPath) 108 return filepath.Join(d.fs.rootDir, d.relPath)
109 } 109 }
110 110
111 // RelPath returns the path of this Dir relative to its filesystem root. 111 // RelPath returns the path of this Dir relative to its filesystem root.
112 func (d *Dir) RelPath() string { return d.relPath } 112 func (d *Dir) RelPath() string { return d.relPath }
113 113
114 // RelPathFrom returns the relative path from d to targpath. It also asserts 114 // RelPathFrom returns the relative path from d to targpath. It also asserts
115 // that targpath is under the Filesystem root. 115 // that targpath is under the Filesystem root.
116 func (d *Dir) RelPathFrom(targpath string) (string, error) { 116 func (d *Dir) RelPathFrom(targpath string) (string, error) {
117 if !isSubpath(d.fs.rootDir, targpath) { 117 if !isSubpath(d.fs.rootDir, targpath) {
118 » » return "", errors.Reason("[%(path)s] is not a subpath of [%(root )s]"). 118 » » return "", errors.Reason("[%s] is not a subpath of [%s]", targpa th, d.fs.rootDir).Err()
119 » » » D("path", targpath).D("root", d.fs.rootDir).Err()
120 } 119 }
121 120
122 rel, err := filepath.Rel(d.String(), targpath) 121 rel, err := filepath.Rel(d.String(), targpath)
123 if err != nil { 122 if err != nil {
124 » » return "", errors.Annotate(err).Reason("could not calculate rela tive path from [%(dir)s] to [%(path)s]"). 123 » » return "", errors.Annotate(err, "could not calculate relative pa th from [%s] to [%s]",
125 » » » D("dir", d.String()).D("path", targpath).Err() 124 » » » d.String(), targpath).Err()
126 } 125 }
127 return rel, nil 126 return rel, nil
128 } 127 }
129 128
130 // Ignore configures d to be marked as ignored. This causes it and all of its 129 // Ignore configures d to be marked as ignored. This causes it and all of its
131 // contents to be exempt from cleanup. 130 // contents to be exempt from cleanup.
132 func (d *Dir) Ignore() { 131 func (d *Dir) Ignore() {
133 d.fs.lock.Lock() 132 d.fs.lock.Lock()
134 defer d.fs.lock.Unlock() 133 defer d.fs.lock.Unlock()
135 d.ignored = true 134 d.ignored = true
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 d.subdirs[elem] = subDir 179 d.subdirs[elem] = subDir
181 return 180 return
182 } 181 }
183 182
184 // EnsureDirectory returns a managed sub-directory composed by joining all of 183 // EnsureDirectory returns a managed sub-directory composed by joining all of
185 // the specified elements together. 184 // the specified elements together.
186 // 185 //
187 // If the described directory doesn't exist, it will be created. 186 // If the described directory doesn't exist, it will be created.
188 func (d *Dir) EnsureDirectory(elem string, elems ...string) (*Dir, error) { 187 func (d *Dir) EnsureDirectory(elem string, elems ...string) (*Dir, error) {
189 if !isValidSinglePathComponent(elem) { 188 if !isValidSinglePathComponent(elem) {
190 » » return nil, errors.Reason("invalid path component #0: %(comp)q") . 189 » » return nil, errors.Reason("invalid path component #0: %q", elem) .Err()
191 » » » D("comp", elem).Err()
192 } 190 }
193 191
194 // No element may have a path separator in it. 192 // No element may have a path separator in it.
195 components := make([]string, 0, len(elems)+2) 193 components := make([]string, 0, len(elems)+2)
196 components = append(components, d.String()) 194 components = append(components, d.String())
197 components = append(components, elem) 195 components = append(components, elem)
198 for i, comp := range elems { 196 for i, comp := range elems {
199 if !isValidSinglePathComponent(comp) { 197 if !isValidSinglePathComponent(comp) {
200 » » » return nil, errors.Reason("invalid path component #%(ind ex)d: %(comp)q"). 198 » » » return nil, errors.Reason("invalid path component #%d: % q", i+1, comp).Err()
201 » » » » D("index", i+1).D("comp", comp).Err()
202 } 199 }
203 components = append(components, comp) 200 components = append(components, comp)
204 } 201 }
205 202
206 // Make the full subdirectory path. 203 // Make the full subdirectory path.
207 fullPath := filepath.Join(components...) 204 fullPath := filepath.Join(components...)
208 if err := ensureDirectory(fullPath); err != nil { 205 if err := ensureDirectory(fullPath); err != nil {
209 » » return nil, errors.Annotate(err).Reason("failed to create direct ory [%(path)s]").D("path", fullPath).Err() 206 » » return nil, errors.Annotate(err, "failed to create directory [%s ]", fullPath).Err()
210 } 207 }
211 208
212 // Return the last managed directory node. 209 // Return the last managed directory node.
213 return d.GetSubDirectory(elem, elems...), nil 210 return d.GetSubDirectory(elem, elems...), nil
214 } 211 }
215 212
216 // ShallowSymlinkFrom creates one symlink under d per regular file in dir. 213 // ShallowSymlinkFrom creates one symlink under d per regular file in dir.
217 func (d *Dir) ShallowSymlinkFrom(dir string, rel bool) error { 214 func (d *Dir) ShallowSymlinkFrom(dir string, rel bool) error {
218 fis, err := ioutil.ReadDir(dir) 215 fis, err := ioutil.ReadDir(dir)
219 if err != nil { 216 if err != nil {
220 » » return errors.Annotate(err).Reason("failed to read directory [%( path)s]").D("path", dir).Err() 217 » » return errors.Annotate(err, "failed to read directory [%s]", dir ).Err()
221 } 218 }
222 219
223 for _, fi := range fis { 220 for _, fi := range fis {
224 if fi.IsDir() { 221 if fi.IsDir() {
225 continue 222 continue
226 } 223 }
227 224
228 f := d.File(fi.Name()) 225 f := d.File(fi.Name())
229 if err := f.SymlinkFrom(filepath.Join(dir, fi.Name()), rel); err != nil { 226 if err := f.SymlinkFrom(filepath.Join(dir, fi.Name()), rel); err != nil {
230 return err 227 return err
231 } 228 }
232 } 229 }
233 230
234 return nil 231 return nil
235 } 232 }
236 233
237 // File creates a new managed File immediately within d. 234 // File creates a new managed File immediately within d.
238 func (d *Dir) File(name string) *File { 235 func (d *Dir) File(name string) *File {
239 if !isValidSinglePathComponent(name) { 236 if !isValidSinglePathComponent(name) {
240 » » panic(errors.Reason("invalid path component: %(name)q").D("name" , name).Err()) 237 » » panic(errors.Reason("invalid path component: %q", name).Err())
241 } 238 }
242 239
243 // Register this file with its managed directory. 240 // Register this file with its managed directory.
244 return d.registerFile(name) 241 return d.registerFile(name)
245 } 242 }
246 243
247 func (d *Dir) registerFile(name string) *File { 244 func (d *Dir) registerFile(name string) *File {
248 d.fs.lock.RLock() 245 d.fs.lock.RLock()
249 _, registered := d.files[name] 246 _, registered := d.files[name]
250 d.fs.lock.RUnlock() 247 d.fs.lock.RUnlock()
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 } 281 }
285 282
286 func (d *Dir) cleanupLocked() error { 283 func (d *Dir) cleanupLocked() error {
287 if d.ignored { 284 if d.ignored {
288 return nil 285 return nil
289 } 286 }
290 287
291 // List the contents of this directory. 288 // List the contents of this directory.
292 fis, err := ioutil.ReadDir(d.String()) 289 fis, err := ioutil.ReadDir(d.String())
293 if err != nil { 290 if err != nil {
294 » » return errors.Annotate(err).Reason("failed to read directory %(d ir)q").D("dir", d.String()).Err() 291 » » return errors.Annotate(err, "failed to read directory %q", d.Str ing()).Err()
295 } 292 }
296 293
297 for _, fi := range fis { 294 for _, fi := range fis {
298 name := fi.Name() 295 name := fi.Name()
299 if fi.IsDir() { 296 if fi.IsDir() {
300 if subD := d.subdirs[name]; subD != nil { 297 if subD := d.subdirs[name]; subD != nil {
301 // Cleanup our subdirectory. 298 // Cleanup our subdirectory.
302 if err := subD.cleanupLocked(); err != nil { 299 if err := subD.cleanupLocked(); err != nil {
303 return err 300 return err
304 } 301 }
305 continue 302 continue
306 } 303 }
307 } else { 304 } else {
308 // This is a file/symlink/etc. Delete it if it's not man aged. 305 // This is a file/symlink/etc. Delete it if it's not man aged.
309 if _, ok := d.files[name]; ok { 306 if _, ok := d.files[name]; ok {
310 continue 307 continue
311 } 308 }
312 } 309 }
313 310
314 // This is unmanaged. Delete it. 311 // This is unmanaged. Delete it.
315 fiPath := filepath.Join(d.String(), name) 312 fiPath := filepath.Join(d.String(), name)
316 313
317 // Safety / sanity check, the path under consideration for delet ion MUST be 314 // Safety / sanity check, the path under consideration for delet ion MUST be
318 // underneath of our filesystem's root. 315 // underneath of our filesystem's root.
319 if !isSubpath(d.fs.rootDir, fiPath) { 316 if !isSubpath(d.fs.rootDir, fiPath) {
320 » » » panic(errors.Reason("about to delete [%(path)q], which i s not a subdirectory of [%(root)q]"). 317 » » » panic(errors.Reason("about to delete [%q], which is not a subdirectory of [%q]",
321 » » » » D("path", fiPath).D("root", d.fs.rootDir).Err()) 318 » » » » fiPath, d.fs.rootDir).Err())
322 } 319 }
323 320
324 if err := os.RemoveAll(fiPath); err != nil { 321 if err := os.RemoveAll(fiPath); err != nil {
325 » » » return errors.Annotate(err).Reason("failed to delete unm anaged [%(path)q]").D("path", fiPath).Err() 322 » » » return errors.Annotate(err, "failed to delete unmanaged [%q]", fiPath).Err()
326 } 323 }
327 } 324 }
328 return nil 325 return nil
329 } 326 }
330 327
331 // File is a managed file within a managed Dir. 328 // File is a managed file within a managed Dir.
332 type File struct { 329 type File struct {
333 dir *Dir 330 dir *Dir
334 331
335 name string 332 name string
(...skipping 12 matching lines...) Expand all
348 345
349 // SymlinkFrom writes a symlink from the specified path to f's location. 346 // SymlinkFrom writes a symlink from the specified path to f's location.
350 // 347 //
351 // If rel is true, the symlink's target will be "from" relative to the managed 348 // If rel is true, the symlink's target will be "from" relative to the managed
352 // filesystem's root. If it goes above the root, it is an error. 349 // filesystem's root. If it goes above the root, it is an error.
353 func (f *File) SymlinkFrom(from string, rel bool) error { 350 func (f *File) SymlinkFrom(from string, rel bool) error {
354 to := f.String() 351 to := f.String()
355 352
356 // Assert that our "from" field exists. 353 // Assert that our "from" field exists.
357 if _, err := os.Stat(from); err != nil { 354 if _, err := os.Stat(from); err != nil {
358 » » return errors.Annotate(err).Reason("failed to stat symlink from [%(path)s]"). 355 » » return errors.Annotate(err, "failed to stat symlink from [%s]", from).Err()
359 » » » D("path", from).Err()
360 } 356 }
361 357
362 // "from" must be a path under the filesystem base. 358 // "from" must be a path under the filesystem base.
363 if rel { 359 if rel {
364 var err error 360 var err error
365 if from, err = f.dir.RelPathFrom(from); err != nil { 361 if from, err = f.dir.RelPathFrom(from); err != nil {
366 » » » return errors.Annotate(err).Reason("failed to calculate relative path").Err() 362 » » » return errors.Annotate(err, "failed to calculate relativ e path").Err()
367 } 363 }
368 } 364 }
369 365
370 if st, err := os.Lstat(to); err == nil { 366 if st, err := os.Lstat(to); err == nil {
371 if st.Mode()&os.ModeSymlink != 0 { 367 if st.Mode()&os.ModeSymlink != 0 {
372 // to is a symlink. Is it a symlink to "from"? 368 // to is a symlink. Is it a symlink to "from"?
373 currentFrom, err := os.Readlink(to) 369 currentFrom, err := os.Readlink(to)
374 if err == nil && currentFrom == from { 370 if err == nil && currentFrom == from {
375 // The symlink already exists! 371 // The symlink already exists!
376 return nil 372 return nil
377 } 373 }
378 } 374 }
379 375
380 // The file exists, but is not a symlink to "from". Try to delet e it. 376 // The file exists, but is not a symlink to "from". Try to delet e it.
381 if err := os.Remove(to); err != nil { 377 if err := os.Remove(to); err != nil {
382 return err 378 return err
383 } 379 }
384 } 380 }
385 381
386 if err := os.Symlink(from, to); err != nil { 382 if err := os.Symlink(from, to); err != nil {
387 » » return errors.Annotate(err).Reason("failed to symlink [%(from)s] => [%(to)s]"). 383 » » return errors.Annotate(err, "failed to symlink [%s] => [%s]", fr om, to).Err()
388 » » » D("from", from).D("to", to).Err()
389 } 384 }
390 return nil 385 return nil
391 } 386 }
392 387
393 // CopyFrom copies contents from the specified path to f's location. 388 // CopyFrom copies contents from the specified path to f's location.
394 func (f *File) CopyFrom(src string) (rerr error) { 389 func (f *File) CopyFrom(src string) (rerr error) {
395 dst := f.String() 390 dst := f.String()
396 391
397 s, err := os.Open(src) 392 s, err := os.Open(src)
398 if err != nil { 393 if err != nil {
399 » » return errors.Annotate(err).Reason("failed to open [%(source)s]" ). 394 » » return errors.Annotate(err, "failed to open [%s]", src).Err()
400 » » » D("source", src).Err()
401 } 395 }
402 defer func() { 396 defer func() {
403 cerr := s.Close() 397 cerr := s.Close()
404 if rerr == nil && cerr != nil { 398 if rerr == nil && cerr != nil {
405 rerr = cerr 399 rerr = cerr
406 } 400 }
407 }() 401 }()
408 402
409 d, err := createFile(dst) 403 d, err := createFile(dst)
410 if err != nil { 404 if err != nil {
411 » » return errors.Annotate(err).Reason("failed to create [%(dest)s]" ). 405 » » return errors.Annotate(err, "failed to create [%s]", dst).Err()
412 » » » D("dest", dst).Err()
413 } 406 }
414 defer func() { 407 defer func() {
415 cerr := d.Close() 408 cerr := d.Close()
416 if rerr == nil && cerr != nil { 409 if rerr == nil && cerr != nil {
417 rerr = cerr 410 rerr = cerr
418 } 411 }
419 }() 412 }()
420 413
421 withBuffer(func(buf []byte) { 414 withBuffer(func(buf []byte) {
422 _, err = io.CopyBuffer(d, s, buf) 415 _, err = io.CopyBuffer(d, s, buf)
423 }) 416 })
424 if err != nil { 417 if err != nil {
425 » » return errors.Annotate(err).Reason("failed to copy from [%(sourc e)s] => [%(dest)s]"). 418 » » return errors.Annotate(err, "failed to copy from [%s] => [%s]", src, dst).Err()
426 » » » D("source", src).D("dest", dst).Err()
427 } 419 }
428 return nil 420 return nil
429 } 421 }
430 422
431 // SameAs returns true if the spceified path is the exact same file as the 423 // SameAs returns true if the spceified path is the exact same file as the
432 // file at f's location. 424 // file at f's location.
433 func (f *File) SameAs(other string) (bool, error) { 425 func (f *File) SameAs(other string) (bool, error) {
434 // Stat each file and check if they are the same. 426 // Stat each file and check if they are the same.
435 myPath := f.String() 427 myPath := f.String()
436 myStat, err := os.Lstat(myPath) 428 myStat, err := os.Lstat(myPath)
437 if err != nil { 429 if err != nil {
438 if isNotExist(err) { 430 if isNotExist(err) {
439 return false, nil 431 return false, nil
440 } 432 }
441 » » return false, errors.Annotate(err).Reason("failed to stat [%(sel f)s]"). 433 » » return false, errors.Annotate(err, "failed to stat [%s]", myPath ).Err()
442 » » » D("self", myPath).Err()
443 } 434 }
444 435
445 otherStat, err := os.Lstat(other) 436 otherStat, err := os.Lstat(other)
446 if err != nil { 437 if err != nil {
447 if isNotExist(err) { 438 if isNotExist(err) {
448 return false, nil 439 return false, nil
449 } 440 }
450 » » return false, errors.Annotate(err).Reason("failed to stat [%(oth er)s]"). 441 » » return false, errors.Annotate(err, "failed to stat [%s]", other) .Err()
451 » » » D("other", other).Err()
452 } 442 }
453 443
454 if os.SameFile(myStat, otherStat) { 444 if os.SameFile(myStat, otherStat) {
455 return true, nil 445 return true, nil
456 } 446 }
457 447
458 // Not the same file, and both exist, so let's compare byte-for-byte. 448 // Not the same file, and both exist, so let's compare byte-for-byte.
459 myFD, err := os.Open(f.String()) 449 myFD, err := os.Open(f.String())
460 if err != nil { 450 if err != nil {
461 » » return false, errors.Annotate(err).Reason("failed to open [%(sel f)s]"). 451 » » return false, errors.Annotate(err, "failed to open [%s]", myPath ).Err()
462 » » » D("self", myPath).Err()
463 } 452 }
464 defer myFD.Close() 453 defer myFD.Close()
465 454
466 otherFD, err := os.Open(other) 455 otherFD, err := os.Open(other)
467 if err != nil { 456 if err != nil {
468 » » return false, errors.Annotate(err).Reason("failed to option [%(o ther)s]"). 457 » » return false, errors.Annotate(err, "failed to option [%s]", othe r).Err()
469 » » » D("other", other).Err()
470 } 458 }
471 defer otherFD.Close() 459 defer otherFD.Close()
472 460
473 same := false 461 same := false
474 withBuffer(func(myBuf []byte) { 462 withBuffer(func(myBuf []byte) {
475 withBuffer(func(otherBuf []byte) { 463 withBuffer(func(otherBuf []byte) {
476 same, err = byteCompare(myFD, otherFD, myBuf, otherBuf) 464 same, err = byteCompare(myFD, otherFD, myBuf, otherBuf)
477 }) 465 })
478 }) 466 })
479 if err != nil { 467 if err != nil {
480 » » return false, errors.Annotate(err).Reason("failed to compare fil es [%(self)s] to [$(other)s]"). 468 » » return false, errors.Annotate(err, "failed to compare files [%s] to [%s]", myPath, other).Err()
481 » » » D("self", myPath).D("other", other).Err()
482 } 469 }
483 return same, nil 470 return same, nil
484 } 471 }
485 472
486 // GenerateTextProto writes the specified object as rendered text protobuf to 473 // GenerateTextProto writes the specified object as rendered text protobuf to
487 // f's location. 474 // f's location.
488 func (f *File) GenerateTextProto(c context.Context, msg proto.Message) error { 475 func (f *File) GenerateTextProto(c context.Context, msg proto.Message) error {
489 return f.WriteDataFrom(func(fd io.Writer) error { 476 return f.WriteDataFrom(func(fd io.Writer) error {
490 if gh := f.dir.fs.GenHeader; len(gh) > 0 { 477 if gh := f.dir.fs.GenHeader; len(gh) > 0 {
491 for _, h := range gh { 478 for _, h := range gh {
(...skipping 12 matching lines...) Expand all
504 491
505 if gn := f.dir.fs.GenName; gn != "" { 492 if gn := f.dir.fs.GenName; gn != "" {
506 genNote := fmt.Sprintf("# GENERATED by %q at: %s\n\n", g n, clock.Now(c)) 493 genNote := fmt.Sprintf("# GENERATED by %q at: %s\n\n", g n, clock.Now(c))
507 if _, err := fmt.Fprint(fd, genNote); err != nil { 494 if _, err := fmt.Fprint(fd, genNote); err != nil {
508 return err 495 return err
509 } 496 }
510 } 497 }
511 498
512 // Write YAML contents. 499 // Write YAML contents.
513 if err := proto.MarshalText(fd, msg); err != nil { 500 if err := proto.MarshalText(fd, msg); err != nil {
514 » » » return errors.Annotate(err).Err() 501 » » » return errors.Annotate(err, "").Err()
515 } 502 }
516 return nil 503 return nil
517 }) 504 })
518 } 505 }
519 506
520 // GenerateYAML writes the specified object as a YAML file to f's location. 507 // GenerateYAML writes the specified object as a YAML file to f's location.
521 func (f *File) GenerateYAML(c context.Context, obj interface{}) error { 508 func (f *File) GenerateYAML(c context.Context, obj interface{}) error {
522 d, err := yaml.Marshal(obj) 509 d, err := yaml.Marshal(obj)
523 if err != nil { 510 if err != nil {
524 return err 511 return err
(...skipping 17 matching lines...) Expand all
542 529
543 if gn := f.dir.fs.GenName; gn != "" { 530 if gn := f.dir.fs.GenName; gn != "" {
544 genNote := fmt.Sprintf("# GENERATED by %q at: %s\n\n", g n, clock.Now(c)) 531 genNote := fmt.Sprintf("# GENERATED by %q at: %s\n\n", g n, clock.Now(c))
545 if _, err := fmt.Fprint(fd, genNote); err != nil { 532 if _, err := fmt.Fprint(fd, genNote); err != nil {
546 return err 533 return err
547 } 534 }
548 } 535 }
549 536
550 // Write YAML contents. 537 // Write YAML contents.
551 if _, err := fd.Write(d); err != nil { 538 if _, err := fd.Write(d); err != nil {
552 » » » return errors.Annotate(err).Err() 539 » » » return errors.Annotate(err, "").Err()
553 } 540 }
554 return nil 541 return nil
555 }) 542 })
556 } 543 }
557 544
558 // GenerateGo writes Go contents to the supplied filesystem. 545 // GenerateGo writes Go contents to the supplied filesystem.
559 func (f *File) GenerateGo(c context.Context, content string) error { 546 func (f *File) GenerateGo(c context.Context, content string) error {
560 return f.WriteDataFrom(func(fd io.Writer) error { 547 return f.WriteDataFrom(func(fd io.Writer) error {
561 if gh := f.dir.fs.GenHeader; len(gh) > 0 { 548 if gh := f.dir.fs.GenHeader; len(gh) > 0 {
562 for _, h := range gh { 549 for _, h := range gh {
(...skipping 12 matching lines...) Expand all
575 562
576 if gn := f.dir.fs.GenName; gn != "" { 563 if gn := f.dir.fs.GenName; gn != "" {
577 genNote := fmt.Sprintf("// GENERATED by %q at: %s\n\n", gn, clock.Now(c)) 564 genNote := fmt.Sprintf("// GENERATED by %q at: %s\n\n", gn, clock.Now(c))
578 if _, err := fmt.Fprint(fd, genNote); err != nil { 565 if _, err := fmt.Fprint(fd, genNote); err != nil {
579 return err 566 return err
580 } 567 }
581 } 568 }
582 569
583 // Write Go content. 570 // Write Go content.
584 if _, err := fmt.Fprint(fd, content); err != nil { 571 if _, err := fmt.Fprint(fd, content); err != nil {
585 » » » return errors.Annotate(err).Err() 572 » » » return errors.Annotate(err, "").Err()
586 } 573 }
587 return nil 574 return nil
588 }) 575 })
589 } 576 }
590 577
591 // ReadAll reads the contents of the file at f's location. 578 // ReadAll reads the contents of the file at f's location.
592 func (f *File) ReadAll() ([]byte, error) { 579 func (f *File) ReadAll() ([]byte, error) {
593 return ioutil.ReadFile(f.String()) 580 return ioutil.ReadFile(f.String())
594 } 581 }
595 582
(...skipping 14 matching lines...) Expand all
610 } 597 }
611 defer func() { 598 defer func() {
612 if closeErr := fd.Close(); err == nil { 599 if closeErr := fd.Close(); err == nil {
613 err = closeErr 600 err = closeErr
614 } 601 }
615 }() 602 }()
616 603
617 err = fn(fd) 604 err = fn(fd)
618 return 605 return
619 } 606 }
OLDNEW
« no previous file with comments | « deploytool/cmd/luci_deploy/work.go ('k') | deploytool/managedfs/util.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698