/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/kbfs/kbfstool/write.go
172 строки
3 KB
zoom-ua
modernize error handling with errors.As/Is (#29350)
25 июн 2026, 17:41
Не верифицирован
25 июн 2026, 17:41
e09e254
Код
Авторство
О чём код?
// Copyright 2016 Keybase Inc. All rights reserved. // Use of this source code is governed by a BSD // license that can be found in the LICENSE file. package main import ( "context" "errors" "flag" "fmt" "io" "os" "github.com/keybase/client/go/kbfs/fsrpc" "github.com/keybase/client/go/kbfs/idutil" "github.com/keybase/client/go/kbfs/libkbfs" ) type nodeWriter struct { ctx context.Context kbfsOps libkbfs.KBFSOps node libkbfs.Node off int64 verbose bool } var _ io.Writer = (*nodeWriter)(nil) func (nw *nodeWriter) Write(p []byte) (n int, err error) { if nw.verbose { fmt.Fprintf(os.Stderr, "Writing %s at offset %d\n", byteCountStr(len(p)), nw.off) } err = nw.kbfsOps.Write(nw.ctx, nw.node, p, nw.off) if err == nil { n = len(p) nw.off += int64(n) } return } func writeHelper(ctx context.Context, config libkbfs.Config, args []string) (err error) { flags := flag.NewFlagSet("kbfs write", flag.ContinueOnError) appendMode := flags.Bool("a", false, "Append to an existing file instead of truncating it.") verbose := flags.Bool("v", false, "Print extra status output.") err = flags.Parse(args) if err != nil { return err } if flags.NArg() != 1 { return errExactlyOnePath } filePathStr := flags.Arg(0) defer func() { if err != nil { if _, ok := err.(cannotWriteErr); !ok { err = cannotWriteErr{filePathStr, err} } } }() p, err := fsrpc.NewPath(filePathStr) if err != nil { return } if p.PathType != fsrpc.TLFPathType { err = cannotWriteErr{filePathStr, nil} return } dir, filename, err := p.DirAndBasename() if err != nil { return } if dir.PathType != fsrpc.TLFPathType { err = cannotWriteErr{filePathStr, nil} return } parentNode, err := dir.GetDirNode(ctx, config) if err != nil { return err } kbfsOps := config.KBFSOps() noSuchFileErr := idutil.NoSuchNameError{Name: filename} // The operations below are racy, but that is inherent to a // distributed FS. filenamePPS := parentNode.ChildName(filename) fileNode, de, err := kbfsOps.Lookup(ctx, parentNode, filenamePPS) if err != nil && !errors.Is(err, noSuchFileErr) { return err } needSync := false var off int64 if errors.Is(err, noSuchFileErr) { if *verbose { fmt.Fprintf(os.Stderr, "Creating %s\n", p) } fileNode, _, err = kbfsOps.CreateFile( ctx, parentNode, filenamePPS, false, libkbfs.NoExcl) if err != nil { return err } } else { if *appendMode { if *verbose { fmt.Fprintf(os.Stderr, "Appending to %s\n", p) } off = int64(de.Size) //nolint:gosec // G115: File sizes are bounded by filesystem limits } else { if *verbose { fmt.Fprintf(os.Stderr, "Truncating %s\n", p) } err = kbfsOps.Truncate(ctx, fileNode, 0) if err != nil { return err } needSync = true } } nw := nodeWriter{ ctx: ctx, kbfsOps: kbfsOps, node: fileNode, off: off, verbose: *verbose, } written, err := io.Copy(&nw, os.Stdin) if err != nil { return err } if written > 0 { needSync = true } if needSync { if *verbose { fmt.Fprintf(os.Stderr, "Syncing %s\n", p) } err := kbfsOps.SyncAll(ctx, fileNode.GetFolderBranch()) if err != nil { return err } } return nil } func write(ctx context.Context, config libkbfs.Config, args []string) (exitStatus int) { err := writeHelper(ctx, config, args) if err != nil { printError("write", err) exitStatus = 1 } return }