forked from Masterminds/vcs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bzr.go
155 lines (131 loc) · 4 KB
/
bzr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package vcs
import (
"os"
"os/exec"
"regexp"
"strings"
"time"
)
var bzrDetectURL = regexp.MustCompile("parent branch: (?P<foo>.+)\n")
// NewBzrRepo creates a new instance of BzrRepo. The remote and local directories
// need to be passed in.
func NewBzrRepo(remote, local string) (*BzrRepo, error) {
ltype, err := DetectVcsFromFS(local)
// Found a VCS other than Bzr. Need to report an error.
if err == nil && ltype != Bzr {
return nil, ErrWrongVCS
}
r := &BzrRepo{}
r.setRemote(remote)
r.setLocalPath(local)
r.Logger = Logger
// With the other VCS we can check if the endpoint locally is different
// from the one configured internally. But, with Bzr you can't. For example,
// if you do `bzr branch https://launchpad.net/govcstestbzrrepo` and then
// use `bzr info` to get the parent branch you'll find it set to
// http://bazaar.launchpad.net/~mattfarina/govcstestbzrrepo/trunk/. Notice
// the change from https to http and the path chance.
// Here we set the remote to be the local one if none is passed in.
if err == nil && r.CheckLocal() == true && remote == "" {
c := exec.Command("bzr", "info")
c.Dir = local
c.Env = envForDir(c.Dir)
out, err := c.CombinedOutput()
if err != nil {
return nil, err
}
m := bzrDetectURL.FindStringSubmatch(string(out))
// If no remote was passed in but one is configured for the locally
// checked out Bzr repo use that one.
if m[1] != "" {
r.setRemote(m[1])
}
}
return r, nil
}
// BzrRepo implements the Repo interface for the Bzr source control.
type BzrRepo struct {
base
}
// Vcs retrieves the underlying VCS being implemented.
func (s BzrRepo) Vcs() Type {
return Bzr
}
// Get is used to perform an initial clone of a repository.
func (s *BzrRepo) Get() error {
_, err := s.run("bzr", "branch", s.Remote(), s.LocalPath())
return err
}
// Update performs a Bzr pull and update to an existing checkout.
func (s *BzrRepo) Update() error {
_, err := s.runFromDir("bzr", "pull")
if err != nil {
return err
}
_, err = s.runFromDir("bzr", "update")
return err
}
// UpdateVersion sets the version of a package currently checked out via Bzr.
func (s *BzrRepo) UpdateVersion(version string) error {
_, err := s.runFromDir("bzr", "update", "-r", version)
return err
}
// Version retrieves the current version.
func (s *BzrRepo) Version() (string, error) {
out, err := s.runFromDir("bzr", "revno", "--tree")
if err != nil {
return "", err
}
return strings.TrimSpace(string(out)), nil
}
// Date retrieves the date on the latest commit.
func (s *BzrRepo) Date() (time.Time, error) {
out, err := s.runFromDir("bzr", "version-info", "--custom", "--template={date}")
if err != nil {
return time.Time{}, err
}
t, err := time.Parse(longForm, string(out))
if err != nil {
return time.Time{}, err
}
return t, nil
}
// CheckLocal verifies the local location is a Bzr repo.
func (s *BzrRepo) CheckLocal() bool {
if _, err := os.Stat(s.LocalPath() + "/.bzr"); err == nil {
return true
}
return false
}
// Branches returns a list of available branches on the repository.
// In Bazaar (Bzr) clones and branches are the same. A different branch will
// have a different URL location which we cannot detect from the repo. This
// is a little different from other VCS.
func (s *BzrRepo) Branches() ([]string, error) {
var branches []string
return branches, nil
}
// Tags returns a list of available tags on the repository.
func (s *BzrRepo) Tags() ([]string, error) {
out, err := s.runFromDir("bzr", "tags")
if err != nil {
return []string{}, err
}
tags := s.referenceList(string(out), `(?m-s)^(\S+)`)
return tags, nil
}
// IsReference returns if a string is a reference. A reference can be a
// commit id or tag.
func (s *BzrRepo) IsReference(r string) bool {
_, err := s.runFromDir("bzr", "revno", "-r", r)
if err == nil {
return true
}
return false
}
// IsDirty returns if the checkout has been modified from the checked
// out reference.
func (s *BzrRepo) IsDirty() bool {
out, err := s.runFromDir("bzr", "diff")
return err != nil || len(out) != 0
}