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  }