2020-02-21 14:21:07 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2020-09-12 19:53:28 +00:00
|
|
|
"net/url"
|
2020-02-21 14:21:07 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
2020-09-12 19:53:28 +00:00
|
|
|
|
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
"go.jolheiser.com/beaver"
|
2020-02-21 14:21:07 +00:00
|
|
|
)
|
|
|
|
|
2020-09-12 19:53:28 +00:00
|
|
|
var (
|
|
|
|
Version = "develop"
|
|
|
|
|
2021-02-21 20:20:28 +00:00
|
|
|
output string
|
|
|
|
author string
|
|
|
|
email string
|
|
|
|
gpg string
|
|
|
|
display bool
|
|
|
|
ssh bool
|
|
|
|
insecure bool
|
|
|
|
debug bool
|
2020-09-12 19:53:28 +00:00
|
|
|
)
|
2020-02-21 14:21:07 +00:00
|
|
|
|
|
|
|
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{
|
2020-09-12 19:53:28 +00:00
|
|
|
Name: "display",
|
|
|
|
Aliases: []string{"d"},
|
|
|
|
Usage: "Display URL instead of cloning",
|
|
|
|
Destination: &display,
|
2020-02-21 14:21:07 +00:00
|
|
|
},
|
|
|
|
&cli.BoolFlag{
|
2020-09-12 19:53:28 +00:00
|
|
|
Name: "ssh",
|
|
|
|
Aliases: []string{"s"},
|
|
|
|
Usage: "Use SSH if available",
|
|
|
|
Destination: &ssh,
|
|
|
|
},
|
|
|
|
&cli.StringFlag{
|
|
|
|
Name: "output",
|
|
|
|
Aliases: []string{"o"},
|
|
|
|
Usage: "Path to output (default: git-import name)",
|
|
|
|
Destination: &output,
|
|
|
|
},
|
|
|
|
&cli.StringFlag{
|
|
|
|
Name: "author",
|
|
|
|
Aliases: []string{"a"},
|
|
|
|
Usage: "Signature author",
|
|
|
|
Destination: &author,
|
|
|
|
},
|
|
|
|
&cli.StringFlag{
|
|
|
|
Name: "email",
|
|
|
|
Aliases: []string{"e"},
|
|
|
|
Usage: "Signature email",
|
|
|
|
Destination: &email,
|
|
|
|
},
|
|
|
|
&cli.StringFlag{
|
|
|
|
Name: "gpg",
|
|
|
|
Aliases: []string{"g"},
|
|
|
|
Usage: "GPG key to sign with",
|
|
|
|
Destination: &gpg,
|
|
|
|
},
|
2021-02-21 20:20:28 +00:00
|
|
|
&cli.BoolFlag{
|
|
|
|
Name: "insecure",
|
|
|
|
Usage: "Use HTTP instead of HTTPS by default",
|
|
|
|
Destination: &insecure,
|
|
|
|
},
|
2020-09-12 19:53:28 +00:00
|
|
|
&cli.BoolFlag{
|
|
|
|
Name: "debug",
|
|
|
|
Usage: "Enable debug logging",
|
|
|
|
Destination: &debug,
|
2020-02-21 14:21:07 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
app.Action = doImport
|
2020-09-12 19:53:28 +00:00
|
|
|
|
|
|
|
if err := app.Run(os.Args); err != nil {
|
2020-02-21 14:21:07 +00:00
|
|
|
beaver.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func doImport(ctx *cli.Context) error {
|
|
|
|
if ctx.NArg() < 1 {
|
|
|
|
return errors.New("must specify an import URL")
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
|
|
|
|
if debug {
|
|
|
|
beaver.Console.Level = beaver.DEBUG
|
|
|
|
}
|
|
|
|
|
2020-02-21 14:21:07 +00:00
|
|
|
importURL := ctx.Args().First()
|
2020-09-12 19:53:28 +00:00
|
|
|
u, err := url.Parse(importURL)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if u.Scheme == "" {
|
2021-02-21 20:20:28 +00:00
|
|
|
u.Scheme = "https"
|
|
|
|
if insecure {
|
|
|
|
u.Scheme = "http"
|
|
|
|
}
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
2021-02-21 20:20:28 +00:00
|
|
|
u.RawQuery = "git-import=1"
|
2020-02-21 14:21:07 +00:00
|
|
|
|
2020-09-12 19:53:28 +00:00
|
|
|
beaver.Debugf("Getting git-import from %s", u.String())
|
|
|
|
res, err := http.Get(u.String())
|
2020-02-21 14:21:07 +00:00
|
|
|
if err != nil {
|
2020-09-12 19:53:28 +00:00
|
|
|
return fmt.Errorf("could not request URL `%s`: %v", u.String(), err)
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
gitImport, err := parseMetaGitImport(res.Body)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not parse: %v", err)
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
beaver.Debug(gitImport)
|
2020-02-21 14:21:07 +00:00
|
|
|
|
2020-09-12 19:53:28 +00:00
|
|
|
if display {
|
|
|
|
if ssh {
|
2020-02-21 14:21:07 +00:00
|
|
|
fmt.Println(gitImport.SSH)
|
|
|
|
return nil
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
fmt.Println(gitImport.HTTP)
|
2020-02-21 14:21:07 +00:00
|
|
|
return nil
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
return doClone(gitImport)
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
|
|
|
|
2020-09-12 19:53:28 +00:00
|
|
|
func doClone(gitImport GitImport) error {
|
|
|
|
if output == "" {
|
|
|
|
output = gitImport.Name
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
|
|
|
|
2020-09-12 19:53:28 +00:00
|
|
|
cmd := exec.Command("git", "clone", gitImport.HTTP, output)
|
|
|
|
if ssh {
|
2020-02-21 14:21:07 +00:00
|
|
|
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")
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
cmd = exec.Command("git", "clone", gitImport.SSH, output)
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return fmt.Errorf("could not clone: %v", err)
|
|
|
|
}
|
|
|
|
|
2020-09-12 19:53:28 +00:00
|
|
|
if ssh {
|
|
|
|
if err := os.Chdir(output); err != nil {
|
|
|
|
return fmt.Errorf("could not change to `%s` directory. Git config will not store SSH command", output)
|
|
|
|
}
|
|
|
|
if err := gitConfig("core.sshCommand", os.Getenv("GIT_SSH_COMMAND")); err != nil {
|
|
|
|
beaver.Errorf("could not configure SSH: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if author != "" {
|
|
|
|
if err := gitConfig("user.name", author); err != nil {
|
|
|
|
beaver.Errorf("could not configure author: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if email != "" {
|
|
|
|
if err := gitConfig("user.email", email); err != nil {
|
|
|
|
beaver.Errorf("could not configure email: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if gpg != "" {
|
|
|
|
if err := gitConfig("user.signingkey", gpg); err != nil {
|
|
|
|
beaver.Errorf("could not configure GPG key: %v", err)
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
if err := gitConfig("commit.gpgsign", "true"); err != nil {
|
|
|
|
beaver.Errorf("could not configure GPG signing: %v", err)
|
2020-02-21 14:21:07 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
|
2020-02-21 14:21:07 +00:00
|
|
|
return nil
|
|
|
|
}
|
2020-09-12 19:53:28 +00:00
|
|
|
|
|
|
|
func gitConfig(key, value string) error {
|
|
|
|
cmd := exec.Command("git", "config", "--local", key, value)
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
return cmd.Run()
|
|
|
|
}
|