github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/pkg/cmdutil/run.go (about)

     1  package cmdutil
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os/exec"
     7  	"strconv"
     8  
     9  	"github.com/cli/cli/git"
    10  )
    11  
    12  type Runnable interface {
    13  	Run() error
    14  	Output() ([]byte, error)
    15  	OutputCombined() ([]byte, error)
    16  }
    17  
    18  type run struct {
    19  	cmd *exec.Cmd
    20  }
    21  
    22  func (run *run) Run() error {
    23  	var stdout, stderr bytes.Buffer
    24  	run.cmd.Stdout = &stdout
    25  	run.cmd.Stderr = &stderr
    26  
    27  	err := run.cmd.Run()
    28  	if err != nil {
    29  		return CmdError{
    30  			Stderr: &stderr,
    31  			Args:   run.cmd.Args,
    32  			Err:    err,
    33  		}
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  func (run *run) Output() ([]byte, error) {
    40  	var stderr bytes.Buffer
    41  	run.cmd.Stderr = &stderr
    42  
    43  	output, err := run.cmd.Output()
    44  
    45  	if err != nil {
    46  		return nil, CmdError{
    47  			Stderr: &stderr,
    48  			Args:   run.cmd.Args,
    49  			Err:    err,
    50  		}
    51  	}
    52  
    53  	return output, nil
    54  }
    55  
    56  func (run *run) OutputCombined() ([]byte, error) {
    57  	var b bytes.Buffer
    58  	run.cmd.Stdout = &b
    59  	run.cmd.Stderr = &b
    60  
    61  	err := run.cmd.Run()
    62  	if err != nil {
    63  		return nil, CmdError{
    64  			Stderr: &b,
    65  			Args:   run.cmd.Args,
    66  			Err:    err,
    67  		}
    68  	}
    69  
    70  	return b.Bytes(), nil
    71  }
    72  
    73  // gitprepare inits git cmd with `root` as the working dir.
    74  func gitprepare(root string, args ...string) (r Runnable, _ error) {
    75  	cmd, err := git.GitCommand(args...)
    76  	if err != nil {
    77  		return r, fmt.Errorf("failed to make git command: %w", err)
    78  	}
    79  
    80  	cmd.Dir = root
    81  
    82  	return &run{cmd}, nil
    83  }
    84  
    85  func RunGit(root string, args ...string) error {
    86  	r, err := gitprepare(root, args...)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	return r.Run()
    91  }
    92  
    93  func RunGitWithOutput(root string, args ...string) ([]byte, error) {
    94  	r, err := gitprepare(root, args...)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	return r.OutputCombined()
    99  }
   100  
   101  func GitStatus(root string) ([]byte, error) {
   102  	r, err := gitprepare(root, "status", "--porcelain")
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  	return r.Output()
   107  }
   108  
   109  func GitDryCommit(root string, message string) ([]byte, error) {
   110  	r, err := gitprepare(root, "commit", "-m", strconv.Quote(message), "--dry-run", "--porcelain")
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  	return r.Output()
   115  }
   116  
   117  func GitCommit(root string, message string) ([]byte, error) {
   118  	r, err := gitprepare(root, "commit", "-m", strconv.Quote(message))
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	return r.OutputCombined()
   123  }
   124  
   125  func GitAddDry(root string, targetDir string) ([]byte, error) {
   126  	r, err := gitprepare(root, "add", targetDir, "--dry-run")
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	return r.Output()
   132  }
   133  
   134  func GitAdd(root string, targetDir string) error {
   135  	r, err := gitprepare(root, "add", targetDir)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	return r.Run()
   141  }