From 6c189876cbe38fab51143ce34c200053130a706b Mon Sep 17 00:00:00 2001 From: Unknwon Date: Thu, 26 Nov 2015 17:34:02 -0500 Subject: [PATCH] initial command --- command.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ error.go | 16 +++++++++++ git.go | 51 +++++++++++++++++++++++++++++++++++ repo.go | 21 +++++++++++++++ signature.go | 16 +++++++++++ 5 files changed, 180 insertions(+) create mode 100644 command.go create mode 100644 error.go create mode 100644 git.go create mode 100644 repo.go create mode 100644 signature.go diff --git a/command.go b/command.go new file mode 100644 index 0000000..58fd7fc --- /dev/null +++ b/command.go @@ -0,0 +1,76 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package git + +import ( + "bytes" + "fmt" + "os/exec" + "strings" +) + +// Command represents a command with its subcommands or arguments. +type Command struct { + name string + args []string +} + +func (c *Command) String() string { + if len(c.args) == 0 { + return c.name + } + return fmt.Sprintf("%s %s", c.name, strings.Join(c.args, " ")) +} + +// NewCommand creates and returns a new Git Command based on given command and arguments. +func NewCommand(args ...string) *Command { + return &Command{ + name: "git", + args: args, + } +} + +// AddArguments adds new argument(s) to the command. +func (c *Command) AddArguments(args ...string) *Command { + c.args = append(c.args, args...) + return c +} + +func (c *Command) run(dir string) (string, error) { + stdout := new(bytes.Buffer) + stderr := new(bytes.Buffer) + + cmd := exec.Command(c.name, c.args...) + cmd.Dir = dir + cmd.Stdout = stdout + cmd.Stderr = stderr + + if len(dir) == 0 { + log(c.String()) + } else { + log("%s: %v", dir, c) + } + + if err := cmd.Run(); err != nil { + return stdout.String(), concatenateError(err, stderr.String()) + } + if stdout.Len() > 0 { + log("stdout:\n%s", stdout) + } + + return stdout.String(), nil +} + +// Run executes the command in defualt working directory +// and returns stdout and error (combined with stderr). +func (c *Command) Run() (string, error) { + return c.run("") +} + +// RunInDir executes the command in given directory +// and returns stdout and error (combined with stderr). +func (c *Command) RunInDir(dir string) (string, error) { + return c.run(dir) +} diff --git a/error.go b/error.go new file mode 100644 index 0000000..08efd29 --- /dev/null +++ b/error.go @@ -0,0 +1,16 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package git + +import ( + "fmt" +) + +func concatenateError(err error, stderr string) error { + if len(stderr) == 0 { + return err + } + return fmt.Errorf("%v - %s", err, stderr) +} diff --git a/git.go b/git.go new file mode 100644 index 0000000..28bd263 --- /dev/null +++ b/git.go @@ -0,0 +1,51 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package git + +import ( + "fmt" + "strings" +) + +var ( + // Debug enables verbose logging on everything. + Debug = true + Prefix = "[git-shell] " +) + +func log(format string, args ...interface{}) { + if !Debug { + return + } + + fmt.Print(Prefix) + if len(args) == 0 { + fmt.Println(format) + } else { + fmt.Printf(format+"\n", args...) + } +} + +var gitVersion string + +// Version returns current Git version from shell. +func Version() (string, error) { + if len(gitVersion) > 0 { + return gitVersion, nil + } + + stdout, err := NewCommand("version").Run() + if err != nil { + return "", err + } + + fields := strings.Fields(stdout) + if len(fields) < 3 { + return "", fmt.Errorf("not enough output: %s", stdout) + } + + gitVersion = fields[2] + return gitVersion, nil +} diff --git a/repo.go b/repo.go new file mode 100644 index 0000000..b3b9bc6 --- /dev/null +++ b/repo.go @@ -0,0 +1,21 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package git + +import ( + "os" +) + +// InitRepository initializes a new Git repository in choice of bare or not. +func InitRepository(repoPath string, bare bool) error { + os.MkdirAll(repoPath, os.ModePerm) + + cmd := NewCommand("init") + if bare { + cmd.AddArguments("--bare") + } + _, err := cmd.RunInDir(repoPath) + return err +} diff --git a/signature.go b/signature.go new file mode 100644 index 0000000..9343f29 --- /dev/null +++ b/signature.go @@ -0,0 +1,16 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package git + +import ( + "time" +) + +// Signature represents the Author or Committer information. +type Signature struct { + Email string + Name string + When time.Time +}