github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/kbfsgit/start.go (about) 1 // Copyright 2017 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 kbfsgit 6 7 import ( 8 "context" 9 "io" 10 11 "github.com/keybase/client/go/kbfs/libfs" 12 "github.com/keybase/client/go/kbfs/libgit" 13 "github.com/keybase/client/go/kbfs/libkbfs" 14 ) 15 16 // StartOptions are options for starting up. 17 type StartOptions struct { 18 KbfsParams libkbfs.InitParams 19 // Remote is the name that the caller's repo (on local disk) has 20 // assigned to the KBFS-based repo. 21 Remote string 22 // Repo is the URL the caller's repo (on local disk) is trying to 23 // access, in the form "keybase://private/user/reponame". 24 Repo string 25 // GitDir is the filepath leading to the .git directory of the 26 // caller's local on-disk repo. 27 GitDir string 28 // LFS indicates whether we should listen for LFS commands instead 29 // of normal git commands. 30 LFS bool 31 } 32 33 // Start starts the kbfsgit logic, and begins listening for git 34 // commands from `input` and responding to them via `output`. 35 func Start(ctx context.Context, options StartOptions, 36 kbCtx libkbfs.Context, defaultLogPath string, 37 input io.Reader, output io.Writer, errput io.Writer) ( 38 retErr *libfs.Error) { 39 // Ideally we wouldn't print this if the verbosity is 0, but we 40 // don't know that until we start parsing options. TODO: get rid 41 // of this once we integrate with the kbfs daemon. 42 _, err := errput.Write([]byte("Initializing Keybase... ")) 43 if err != nil { 44 return libfs.InitError(err.Error()) 45 } 46 ctx, config, err := libgit.Init( 47 ctx, options.KbfsParams, kbCtx, nil, defaultLogPath, 48 kbCtx.GetVDebugSetting()) 49 if err != nil { 50 return libfs.InitError(err.Error()) 51 } 52 defer func() { 53 shutdownErr := config.Shutdown(ctx) 54 if retErr == nil && shutdownErr != nil { 55 retErr = libfs.InitError(shutdownErr.Error()) 56 } 57 }() 58 59 config.MakeLogger("").CDebugf( 60 ctx, "Running Git remote helper: remote=%s, repo=%s, storageRoot=%s", 61 options.Remote, options.Repo, options.KbfsParams.StorageRoot) 62 _, err = errput.Write([]byte("done.\n")) 63 if err != nil { 64 return libfs.InitError(err.Error()) 65 } 66 67 t := processGit 68 if options.LFS { 69 t = processLFS 70 } 71 r, err := newRunnerWithType( 72 ctx, config, options.Remote, options.Repo, options.GitDir, 73 input, output, errput, t) 74 if err != nil { 75 return libfs.InitError(err.Error()) 76 } 77 78 errCh := make(chan error, 1) 79 go func() { 80 errCh <- r.processCommands(ctx) 81 }() 82 83 select { 84 case err := <-errCh: 85 if err != nil { 86 return libfs.InitError(err.Error()) 87 } 88 return nil 89 case <-ctx.Done(): 90 return libfs.InitError(ctx.Err().Error()) 91 } 92 }