github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/kbfstool/main.go (about)

     1  // Copyright 2016 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"os"
    11  
    12  	"golang.org/x/net/context"
    13  
    14  	"github.com/keybase/client/go/kbfs/env"
    15  	"github.com/keybase/client/go/kbfs/libkbfs"
    16  	"github.com/keybase/client/go/logger"
    17  )
    18  
    19  var version = flag.Bool("version", false, "Print version")
    20  
    21  const usageFormatStr = `Usage:
    22    kbfstool -version
    23  
    24  To run against remote KBFS servers:
    25    kbfstool
    26  %s
    27      <command> [<args>]
    28  
    29  To run in a local testing environment:
    30    kbfstool
    31  %s
    32      <command> [<args>]
    33  
    34  Defaults:
    35  %s
    36  
    37  The possible commands are:
    38    stat		Display file status
    39    ls		List directory contents
    40    mkdir		Make directories
    41    read		Dump file to stdout
    42    write		Write stdin to file
    43    md            Operate on metadata objects
    44    git           Operate on git repositories
    45  
    46  `
    47  
    48  func getUsageString(ctx libkbfs.Context) string {
    49  	remoteUsageStr := libkbfs.GetRemoteUsageString()
    50  	localUsageStr := libkbfs.GetLocalUsageString()
    51  	defaultUsageStr := libkbfs.GetDefaultsUsageString(ctx)
    52  	return fmt.Sprintf(usageFormatStr, remoteUsageStr,
    53  		localUsageStr, defaultUsageStr)
    54  }
    55  
    56  // Define this so deferred functions get executed before exit.
    57  func realMain() (exitStatus int) {
    58  	kbCtx := env.NewContext()
    59  	kbfsParams := libkbfs.AddFlags(flag.CommandLine, kbCtx)
    60  
    61  	flag.Parse()
    62  
    63  	if *version {
    64  		fmt.Printf("%s\n", libkbfs.VersionString())
    65  		return 0
    66  	}
    67  
    68  	if len(flag.Args()) < 1 {
    69  		fmt.Print(getUsageString(kbCtx))
    70  		return 1
    71  	}
    72  
    73  	log := logger.New("")
    74  
    75  	tempDir, err := os.MkdirTemp(kbCtx.GetDataDir(), "kbfstool")
    76  	if err != nil {
    77  		panic(err.Error())
    78  	}
    79  	defer func() {
    80  		rmErr := os.RemoveAll(tempDir)
    81  		if rmErr != nil {
    82  			fmt.Fprintf(os.Stderr,
    83  				"Error cleaning storage dir %s: %+v\n", tempDir, rmErr)
    84  		}
    85  	}()
    86  
    87  	// Turn these off, and use a temp dir for the storage root, to not
    88  	// interfere with a running kbfs daemon.
    89  	kbfsParams.EnableJournal = false
    90  	kbfsParams.DiskCacheMode = libkbfs.DiskCacheModeOff
    91  	kbfsParams.Mode = libkbfs.InitSingleOpString
    92  	kbfsParams.StorageRoot = tempDir
    93  
    94  	ctx := context.Background()
    95  	config, err := libkbfs.Init(ctx, kbCtx, *kbfsParams, nil, nil, log)
    96  	if err != nil {
    97  		printError("kbfs", err)
    98  		return 1
    99  	}
   100  
   101  	defer libkbfs.Shutdown()
   102  
   103  	// TODO: Make the logging level WARNING instead of INFO, or
   104  	// figure out some other way to log the full folder-branch
   105  	// name for kbfsfuse but not for kbfs.
   106  
   107  	cmd := flag.Arg(0)
   108  	args := flag.Args()[1:]
   109  
   110  	switch cmd {
   111  	case "stat":
   112  		return stat(ctx, config, args)
   113  	case "ls":
   114  		return ls(ctx, config, args)
   115  	case "mkdir":
   116  		return mkdir(ctx, config, args)
   117  	case "read":
   118  		return read(ctx, config, args)
   119  	case "write":
   120  		return write(ctx, config, args)
   121  	case "md":
   122  		return mdMain(ctx, config, args)
   123  	case "git":
   124  		return gitMain(ctx, config, args)
   125  	default:
   126  		printError("kbfs", fmt.Errorf("unknown command %q", cmd))
   127  		return 1
   128  	}
   129  }
   130  
   131  func main() {
   132  	os.Exit(realMain())
   133  }