github.com/rumpl/mod@v1.1.0/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"strings"
     9  
    10  	"github.com/github/hub/github"
    11  	"github.com/pkg/errors"
    12  	"github.com/sirupsen/logrus"
    13  	"github.com/urfave/cli/v2"
    14  )
    15  
    16  const (
    17  	gitignore = `# Binaries for programs and plugins
    18  *.exe
    19  *.exe~
    20  *.dll
    21  *.so
    22  *.dylib
    23  
    24  cov
    25  
    26  # Test binary, built with "go test -c\"
    27  *.test
    28  
    29  # Output of the go coverage tool, specifically when used with LiteIDE
    30  *.out
    31  # The binary
    32  ./%s
    33  `
    34  	readme = `# %s
    35  `
    36  	makefile = `all: cli
    37  
    38  cli:
    39  	@go build .
    40  
    41  .PHONY: cli
    42  `
    43  	mainfile = `package main
    44  
    45  import (
    46  	"fmt"
    47  	"log"
    48  )
    49  
    50  func main() {
    51  	if err := run(); err != nil {
    52  		log.Fatal(err)
    53  	}
    54  }
    55  
    56  func run() error {
    57  	fmt.Println("Hello world")
    58  
    59  	return nil
    60  }
    61  `
    62  )
    63  
    64  func main() {
    65  	app := cli.App{
    66  		Usage: "mod",
    67  		Flags: []cli.Flag{
    68  			&cli.BoolFlag{
    69  				Name:    "debug",
    70  				Aliases: []string{"d"},
    71  			},
    72  		},
    73  		Before: func(ctx *cli.Context) error {
    74  			if ctx.Bool("debug") {
    75  				logrus.SetLevel(logrus.DebugLevel)
    76  			}
    77  			return nil
    78  		},
    79  		Commands: []*cli.Command{
    80  			{
    81  				Name: "init",
    82  				Action: func(ctx *cli.Context) error {
    83  					repo := ctx.Args().First()
    84  					if repo == "" {
    85  						return errors.New("please provide a repo name")
    86  					}
    87  					return run(repo)
    88  				},
    89  			},
    90  		},
    91  	}
    92  
    93  	if err := app.Run(os.Args); err != nil {
    94  		fmt.Println(err)
    95  		os.Exit(1)
    96  	}
    97  }
    98  
    99  func run(repo string) error {
   100  	if _, err := os.Stat(repo); !os.IsNotExist(err) {
   101  		return errors.New("directory already exists")
   102  	}
   103  
   104  	cc := github.CurrentConfig()
   105  	user := cc.PromptForUser("github.com")
   106  
   107  	if user == "" {
   108  		host, err := cc.PromptForHost("github.com")
   109  		if err != nil {
   110  			return err
   111  		}
   112  		user = host.User
   113  	}
   114  
   115  	inits := []initFunc{
   116  		mkdir,
   117  		chdir,
   118  		modInit,
   119  		gitInit,
   120  	}
   121  
   122  	for _, init := range inits {
   123  		if err := init(user, repo); err != nil {
   124  			return err
   125  		}
   126  	}
   127  
   128  	if err := addFiles(repo); err != nil {
   129  		return err
   130  	}
   131  
   132  	fmt.Println("All done, happy hacking!")
   133  
   134  	return nil
   135  }
   136  
   137  type initFunc func(string, string) error
   138  
   139  func mkdir(user string, repo string) error {
   140  	return os.Mkdir(repo, 0755)
   141  }
   142  
   143  func chdir(user string, repo string) error {
   144  	return os.Chdir(repo)
   145  }
   146  
   147  func modInit(user string, repo string) error {
   148  	return execute("go", "mod", "init", fmt.Sprintf("github.com/%s/%s", user, repo))
   149  }
   150  
   151  func gitInit(_ string, _ string) error {
   152  	return execute("git", "init")
   153  }
   154  
   155  func execute(args ...string) error {
   156  	logrus.Debugf("Executing %s", strings.Join(args, " "))
   157  	out, err := exec.Command(args[0], args[1:]...).Output()
   158  	if err != nil {
   159  		return errors.Wrap(err, string(out))
   160  	}
   161  	return nil
   162  }
   163  
   164  func addFiles(repo string) error {
   165  	actions := []action{
   166  		writeGitIgnore,
   167  		writeMainGo,
   168  		writeMakefile,
   169  		writeReadme,
   170  	}
   171  
   172  	for _, action := range actions {
   173  		if err := action(repo); err != nil {
   174  			return err
   175  		}
   176  	}
   177  
   178  	return nil
   179  }
   180  
   181  type action func(string) error
   182  
   183  func writeGitIgnore(repo string) error {
   184  	return writeFile(".gitignore", []byte(fmt.Sprintf(gitignore, repo)))
   185  }
   186  
   187  func writeMainGo(_ string) error {
   188  	return writeFile("main.go", []byte(mainfile))
   189  }
   190  
   191  func writeMakefile(_ string) error {
   192  	return writeFile("Makefile", []byte(makefile))
   193  }
   194  
   195  func writeReadme(repo string) error {
   196  	return writeFile("README.md", []byte(fmt.Sprintf(readme, repo)))
   197  }
   198  
   199  func writeFile(file string, contents []byte) error {
   200  	logrus.Debugf("Writing file %s", file)
   201  	return ioutil.WriteFile(file, contents, 0644)
   202  }