109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"github.com/urfave/cli/v2"
|
||
|
"go.jolheiser.com/beaver"
|
||
|
"net/http"
|
||
|
"os"
|
||
|
"os/exec"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var Version = "develop"
|
||
|
|
||
|
func main() {
|
||
|
app := cli.NewApp()
|
||
|
app.Name = "git-import"
|
||
|
app.Usage = "Import from vanity git URLs"
|
||
|
app.Version = Version
|
||
|
app.Flags = []cli.Flag{
|
||
|
&cli.BoolFlag{
|
||
|
Name: "display",
|
||
|
Aliases: []string{"d"},
|
||
|
Usage: "Display URL instead of cloning",
|
||
|
},
|
||
|
&cli.BoolFlag{
|
||
|
Name: "ssh",
|
||
|
Aliases: []string{"s"},
|
||
|
Usage: "Use SSH if available",
|
||
|
},
|
||
|
}
|
||
|
app.UseShortOptionHandling = true
|
||
|
app.EnableBashCompletion = true
|
||
|
app.Action = doImport
|
||
|
err := app.Run(os.Args)
|
||
|
if err != nil {
|
||
|
beaver.Error(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func doImport(ctx *cli.Context) error {
|
||
|
if ctx.NArg() < 1 {
|
||
|
return errors.New("must specify an import URL")
|
||
|
}
|
||
|
importURL := ctx.Args().First()
|
||
|
if !strings.HasPrefix(importURL, "https") {
|
||
|
importURL = fmt.Sprintf("http://%s", importURL)
|
||
|
}
|
||
|
|
||
|
res, err := http.Get(importURL)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("could not request URL `%s`: %v", importURL, err)
|
||
|
}
|
||
|
defer res.Body.Close()
|
||
|
|
||
|
gitImport, err := parseMetaGitImport(res.Body)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("could not parse: %v", err)
|
||
|
}
|
||
|
|
||
|
if ctx.Bool("display") {
|
||
|
if ctx.Bool("ssh") {
|
||
|
fmt.Println(gitImport.SSH)
|
||
|
return nil
|
||
|
}
|
||
|
fmt.Println(gitImport.HTTPS)
|
||
|
return nil
|
||
|
}
|
||
|
return doClone(ctx, gitImport)
|
||
|
}
|
||
|
|
||
|
func doClone(ctx *cli.Context, gitImport GitImport) error {
|
||
|
projectName := gitImport.ProjectName
|
||
|
if ctx.NArg() > 1 {
|
||
|
projectName = ctx.Args().Get(1)
|
||
|
}
|
||
|
|
||
|
cmd := exec.Command("git", "clone", gitImport.HTTPS, projectName)
|
||
|
if ctx.Bool("ssh") {
|
||
|
if gitImport.SSH == "" {
|
||
|
return errors.New("SSH was not provided by git-import")
|
||
|
}
|
||
|
if os.Getenv("GIT_SSH_COMMAND") == "" {
|
||
|
return errors.New("no environment variable found for GIT_SSH_COMMAND")
|
||
|
}
|
||
|
cmd = exec.Command("git", "clone", gitImport.SSH, projectName)
|
||
|
}
|
||
|
cmd.Stdout = os.Stdout
|
||
|
cmd.Stderr = os.Stderr
|
||
|
|
||
|
if err := cmd.Run(); err != nil {
|
||
|
return fmt.Errorf("could not clone: %v", err)
|
||
|
}
|
||
|
|
||
|
if ctx.Bool("ssh") {
|
||
|
if err := os.Chdir(projectName); err != nil {
|
||
|
return fmt.Errorf("could not change to `%s` directory. Git config will not store SSH command", projectName)
|
||
|
}
|
||
|
cmd := exec.Command("git", "config", "--local", "core.sshCommand", os.Getenv("GIT_SSH_COMMAND"))
|
||
|
cmd.Stdout = os.Stdout
|
||
|
cmd.Stderr = os.Stderr
|
||
|
if err := cmd.Run(); err != nil {
|
||
|
return fmt.Errorf("could not configure SSH: %v", err)
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|