git-lfs/client/credentials.go

87 lines
1.6 KiB
Go

package gitmediaclient
import (
"bytes"
"fmt"
"net/url"
"os/exec"
"strings"
)
func credentials(u *url.URL) (Creds, error) {
creds := Creds{"protocol": u.Scheme, "host": u.Host}
cmd, err := execCreds(creds, "fill")
if err != nil {
return nil, err
}
return cmd.Credentials(), nil
}
func execCreds(input Creds, subCommand string) (*CredentialCmd, error) {
cmd := NewCommand(input, subCommand)
err := cmd.Start()
if err == nil {
err = cmd.Wait()
}
if err != nil {
return cmd, fmt.Errorf("'git credential %s' error: %s\n%s", cmd.SubCommand, err.Error(), cmd.StderrString())
}
return cmd, nil
}
type CredentialCmd struct {
output *bytes.Buffer
err *bytes.Buffer
SubCommand string
*exec.Cmd
}
func NewCommand(input Creds, subCommand string) *CredentialCmd {
buf1 := new(bytes.Buffer)
buf2 := new(bytes.Buffer)
cmd := exec.Command("git", "credential", subCommand)
cmd.Stdin = input.Buffer()
cmd.Stdout = buf1
cmd.Stderr = buf2
return &CredentialCmd{buf1, buf2, subCommand, cmd}
}
func (c *CredentialCmd) StderrString() string {
return c.err.String()
}
func (c *CredentialCmd) StdoutString() string {
return c.output.String()
}
func (c *CredentialCmd) Credentials() Creds {
creds := make(Creds)
for _, line := range strings.Split(c.StdoutString(), "\n") {
pieces := strings.SplitN(line, "=", 2)
if len(pieces) < 2 {
continue
}
creds[pieces[0]] = pieces[1]
}
return creds
}
type Creds map[string]string
func (c Creds) Buffer() *bytes.Buffer {
buf := new(bytes.Buffer)
for k, v := range c {
buf.Write([]byte(k))
buf.Write([]byte("="))
buf.Write([]byte(v))
buf.Write([]byte("\n"))
}
return buf
}