go.tools/go/vcs: add logging functionality and create/log at revision

Add support for logging commands for Mercurial and Subversion as well as the ability to create/log a repo at a certain revision.

- Exported Cmd.LogCmd
- Exported Cmd.CreateAtRev
- Exported Cmd.Log
- Exported Cmd.LogAtRev

R=adg
CC=golang-dev
https://golang.org/cl/13060044
This commit is contained in:
Chris Manghane 2013-08-20 20:10:15 -07:00
parent de72360261
commit d64ad45594
1 changed files with 41 additions and 1 deletions

View File

@ -14,6 +14,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
) )
@ -37,6 +38,8 @@ type Cmd struct {
TagSyncCmd string // command to sync to specific tag TagSyncCmd string // command to sync to specific tag
TagSyncDefault string // command to sync to default tag TagSyncDefault string // command to sync to default tag
LogCmd string // command to list repository changelogs in an XML format
Scheme []string Scheme []string
PingCmd string PingCmd string
} }
@ -87,6 +90,8 @@ var vcsHg = &Cmd{
TagSyncCmd: "update -r {tag}", TagSyncCmd: "update -r {tag}",
TagSyncDefault: "update default", TagSyncDefault: "update default",
LogCmd: "log --encoding=utf-8 --limit={limit} --template={template}",
Scheme: []string{"https", "http", "ssh"}, Scheme: []string{"https", "http", "ssh"},
PingCmd: "identify {scheme}://{repo}", PingCmd: "identify {scheme}://{repo}",
} }
@ -144,6 +149,8 @@ var vcsSvn = &Cmd{
// There is no tag command in subversion. // There is no tag command in subversion.
// The branch information is all in the path names. // The branch information is all in the path names.
LogCmd: "log --xml --limit={limit}",
Scheme: []string{"https", "http", "svn", "svn+ssh"}, Scheme: []string{"https", "http", "svn", "svn+ssh"},
PingCmd: "info {scheme}://{repo}", PingCmd: "info {scheme}://{repo}",
} }
@ -216,7 +223,7 @@ func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([
return out, nil return out, nil
} }
// Ping pings the repo to determine if scheme used if valid. // Ping pings the repo to determine if scheme used is valid.
// This repo must be pingable with this scheme and VCS. // This repo must be pingable with this scheme and VCS.
func (v *Cmd) Ping(scheme, repo string) error { func (v *Cmd) Ping(scheme, repo string) error {
return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo) return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo)
@ -228,6 +235,15 @@ func (v *Cmd) Create(dir, repo string) error {
return v.run(".", v.CreateCmd, "dir", dir, "repo", repo) return v.run(".", v.CreateCmd, "dir", dir, "repo", repo)
} }
// CreateAtRev creates a new copy of repo in dir at revision rev.
// The parent of dir must exist; dir must not.
// rev must be a valid revision in repo.
func (v *Cmd) CreateAtRev(dir, repo, rev string) error {
// Append revision flag to CreateCmd
createAtRevCmd := v.CreateCmd + " --rev=" + rev
return v.run(".", createAtRevCmd, "dir", dir, "repo", repo)
}
// Download downloads any new changes for the repo in dir. // Download downloads any new changes for the repo in dir.
// dir must be a valid VCS repo compatible with v. // dir must be a valid VCS repo compatible with v.
func (v *Cmd) Download(dir string) error { func (v *Cmd) Download(dir string) error {
@ -278,6 +294,30 @@ func (v *Cmd) TagSync(dir, tag string) error {
return v.run(dir, v.TagSyncCmd, "tag", tag) return v.run(dir, v.TagSyncCmd, "tag", tag)
} }
// Log logs the changes for the repo in dir.
// dir must be a valid VCS repo compatible with v.
func (v *Cmd) Log(dir, logTemplate string) ([]byte, error) {
if err := v.Download(dir); err != nil {
return []byte{}, err
}
const N = 50 // how many revisions to grab
return v.runOutput(dir, v.LogCmd, "limit", strconv.Itoa(N), "template", logTemplate)
}
// LogAtRev logs the change for repo in dir at the rev revision.
// dir must be a valid VCS repo compatible with v.
// rev must be a valid revision for the repo in dir.
func (v *Cmd) LogAtRev(dir, rev, logTemplate string) ([]byte, error) {
if err := v.Download(dir); err != nil {
return []byte{}, err
}
// Append revision flag to LogCmd.
logAtRevCmd := v.LogCmd + " --rev=" + rev
return v.runOutput(dir, logAtRevCmd, "limit", strconv.Itoa(1), "template", logTemplate)
}
// A vcsPath describes how to convert an import path into a // A vcsPath describes how to convert an import path into a
// version control system and repository name. // version control system and repository name.
type vcsPath struct { type vcsPath struct {