Skip to content

Commit 25725f4

Browse files
authored
v1.0.0-beta.3 (#46)
* Add some methods * Add more methods * Make it compile * Add more tests
1 parent cfb8e9a commit 25725f4

10 files changed

+189
-60
lines changed

command.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (c *Command) RunInDirPipelineWithTimeout(timeout time.Duration, stdout, std
118118
}()
119119

120120
cmd := exec.CommandContext(ctx, c.name, c.args...)
121-
if c.envs != nil {
121+
if len(c.envs) > 0 {
122122
cmd.Env = append(os.Environ(), c.envs...)
123123
}
124124
cmd.Dir = dir

repo.go

+54-18
Original file line numberDiff line numberDiff line change
@@ -221,17 +221,25 @@ type PushOptions struct {
221221
Timeout time.Duration
222222
}
223223

224-
// Push pushs local changes to given remote and branch for the repository.
225-
func (r *Repository) Push(remote, branch string, opts ...PushOptions) error {
224+
// RepoPush pushs local changes to given remote and branch for the repository
225+
// in given path.
226+
func RepoPush(repoPath, remote, branch string, opts ...PushOptions) error {
226227
var opt PushOptions
227228
if len(opts) > 0 {
228229
opt = opts[0]
229230
}
230231

231-
_, err := NewCommand("push", remote, branch).AddEnvs(opt.Envs...).RunInDirWithTimeout(opt.Timeout, r.path)
232+
_, err := NewCommand("push", remote, branch).
233+
AddEnvs(opt.Envs...).
234+
RunInDirWithTimeout(opt.Timeout, repoPath)
232235
return err
233236
}
234237

238+
// Push pushs local changes to given remote and branch for the repository.
239+
func (r *Repository) Push(remote, branch string, opts ...PushOptions) error {
240+
return RepoPush(r.path, remote, branch, opts...)
241+
}
242+
235243
// CheckoutOptions contains optional arguments for checking out to a branch.
236244
// Docs: https://git-scm.com/docs/git-checkout
237245
type CheckoutOptions struct {
@@ -242,8 +250,8 @@ type CheckoutOptions struct {
242250
Timeout time.Duration
243251
}
244252

245-
// Checkout checks out to given branch for the repository.
246-
func (r *Repository) Checkout(branch string, opts ...CheckoutOptions) error {
253+
// Checkout checks out to given branch for the repository in given path.
254+
func RepoCheckout(repoPath, branch string, opts ...CheckoutOptions) error {
247255
var opt CheckoutOptions
248256
if len(opts) > 0 {
249257
opt = opts[0]
@@ -258,10 +266,15 @@ func (r *Repository) Checkout(branch string, opts ...CheckoutOptions) error {
258266
cmd.AddArgs(opt.BaseBranch)
259267
}
260268

261-
_, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
269+
_, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
262270
return err
263271
}
264272

273+
// Checkout checks out to given branch for the repository.
274+
func (r *Repository) Checkout(branch string, opts ...CheckoutOptions) error {
275+
return RepoCheckout(r.path, branch, opts...)
276+
}
277+
265278
// ResetOptions contains optional arguments for resetting a branch.
266279
// Docs: https://git-scm.com/docs/git-reset
267280
type ResetOptions struct {
@@ -272,8 +285,8 @@ type ResetOptions struct {
272285
Timeout time.Duration
273286
}
274287

275-
// Reset resets working tree to given revision for the repository.
276-
func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
288+
// RepoReset resets working tree to given revision for the repository in given path.
289+
func RepoReset(repoPath, rev string, opts ...ResetOptions) error {
277290
var opt ResetOptions
278291
if len(opts) > 0 {
279292
opt = opts[0]
@@ -284,10 +297,15 @@ func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
284297
cmd.AddArgs("--hard")
285298
}
286299

287-
_, err := cmd.AddArgs(rev).RunInDir(r.path)
300+
_, err := cmd.AddArgs(rev).RunInDir(repoPath)
288301
return err
289302
}
290303

304+
// Reset resets working tree to given revision for the repository.
305+
func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
306+
return RepoReset(r.path, rev, opts...)
307+
}
308+
291309
// MoveOptions contains optional arguments for moving a file, a directory, or a symlink.
292310
// Docs: https://git-scm.com/docs/git-mv
293311
type MoveOptions struct {
@@ -296,17 +314,24 @@ type MoveOptions struct {
296314
Timeout time.Duration
297315
}
298316

299-
// Move moves a file, a directory, or a symlink file or directory from source to destination.
300-
func (r *Repository) Move(src, dst string, opts ...MoveOptions) error {
317+
// RepoMove moves a file, a directory, or a symlink file or directory from source to
318+
// destination for the repository in given path.
319+
func RepoMove(repoPath, src, dst string, opts ...MoveOptions) error {
301320
var opt MoveOptions
302321
if len(opts) > 0 {
303322
opt = opts[0]
304323
}
305324

306-
_, err := NewCommand("mv", src, dst).RunInDirWithTimeout(opt.Timeout, r.path)
325+
_, err := NewCommand("mv", src, dst).RunInDirWithTimeout(opt.Timeout, repoPath)
307326
return err
308327
}
309328

329+
// Move moves a file, a directory, or a symlink file or directory from source to destination
330+
// for the repository.
331+
func (r *Repository) Move(src, dst string, opts ...MoveOptions) error {
332+
return RepoMove(r.path, src, dst, opts...)
333+
}
334+
310335
// AddOptions contains optional arguments for adding local changes.
311336
// Docs: https://git-scm.com/docs/git-add
312337
type AddOptions struct {
@@ -319,8 +344,8 @@ type AddOptions struct {
319344
Timeout time.Duration
320345
}
321346

322-
// Add adds local changes to index for the repository.
323-
func (r *Repository) Add(opts ...AddOptions) error {
347+
// RepoAdd adds local changes to index for the repository in given path.
348+
func RepoAdd(repoPath string, opts ...AddOptions) error {
324349
var opt AddOptions
325350
if len(opts) > 0 {
326351
opt = opts[0]
@@ -334,10 +359,15 @@ func (r *Repository) Add(opts ...AddOptions) error {
334359
cmd.AddArgs("--")
335360
cmd.AddArgs(opt.Pathsepcs...)
336361
}
337-
_, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
362+
_, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
338363
return err
339364
}
340365

366+
// Add adds local changes to index for the repository.
367+
func (r *Repository) Add(opts ...AddOptions) error {
368+
return RepoAdd(r.path, opts...)
369+
}
370+
341371
// CommitOptions contains optional arguments to commit changes.
342372
// Docs: https://git-scm.com/docs/git-commit
343373
type CommitOptions struct {
@@ -348,8 +378,9 @@ type CommitOptions struct {
348378
Timeout time.Duration
349379
}
350380

351-
// Commit commits local changes with given author, committer and message for the repository.
352-
func (r *Repository) Commit(committer *Signature, message string, opts ...CommitOptions) error {
381+
// RepoCommit commits local changes with given author, committer and message for the
382+
// repository in given path.
383+
func RepoCommit(repoPath string, committer *Signature, message string, opts ...CommitOptions) error {
353384
var opt CommitOptions
354385
if len(opts) > 0 {
355386
opt = opts[0]
@@ -363,14 +394,19 @@ func (r *Repository) Commit(committer *Signature, message string, opts ...Commit
363394
}
364395
cmd.AddArgs("-m", message)
365396

366-
_, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
397+
_, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
367398
// No stderr but exit status 1 means nothing to commit.
368399
if err != nil && err.Error() == "exit status 1" {
369400
return nil
370401
}
371402
return err
372403
}
373404

405+
// Commit commits local changes with given author, committer and message for the repository.
406+
func (r *Repository) Commit(committer *Signature, message string, opts ...CommitOptions) error {
407+
return RepoCommit(r.path, committer, message, opts...)
408+
}
409+
374410
// NameStatus contains name status of a commit.
375411
type NameStatus struct {
376412
Added []string

repo_commit.go

+24-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package git
77
import (
88
"bytes"
99
"errors"
10+
"fmt"
1011
"strconv"
1112
"strings"
1213
"time"
@@ -139,8 +140,19 @@ func escapePath(path string) string {
139140
return path
140141
}
141142

142-
// Log returns a list of commits in the state of given revision. The returned list is in reverse
143-
// chronological order.
143+
// RepoLog returns a list of commits in the state of given revision of the repository
144+
// in given path. The returned list is in reverse chronological order.
145+
func RepoLog(repoPath, rev string, opts ...LogOptions) ([]*Commit, error) {
146+
r, err := Open(repoPath)
147+
if err != nil {
148+
return nil, fmt.Errorf("open: %v", err)
149+
}
150+
151+
return r.Log(rev, opts...)
152+
}
153+
154+
// Log returns a list of commits in the state of given revision of the repository.
155+
// The returned list is in reverse chronological order.
144156
func (r *Repository) Log(rev string, opts ...LogOptions) ([]*Commit, error) {
145157
var opt LogOptions
146158
if len(opts) > 0 {
@@ -300,8 +312,9 @@ type DiffNameOnlyOptions struct {
300312
Timeout time.Duration
301313
}
302314

303-
// DiffNameOnly returns a list of changed files between base and head revisions of the repository.
304-
func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions) ([]string, error) {
315+
// RepoDiffNameOnly returns a list of changed files between base and head revisions of
316+
// the repository in given path.
317+
func RepoDiffNameOnly(repoPath, base, head string, opts ...DiffNameOnlyOptions) ([]string, error) {
305318
var opt DiffNameOnlyOptions
306319
if len(opts) > 0 {
307320
opt = opts[0]
@@ -318,7 +331,7 @@ func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions
318331
cmd.AddArgs(escapePath(opt.Path))
319332
}
320333

321-
stdout, err := cmd.RunInDirWithTimeout(opt.Timeout, r.path)
334+
stdout, err := cmd.RunInDirWithTimeout(opt.Timeout, repoPath)
322335
if err != nil {
323336
return nil, err
324337
}
@@ -335,6 +348,12 @@ func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions
335348
return names, nil
336349
}
337350

351+
// DiffNameOnly returns a list of changed files between base and head revisions of the
352+
// repository.
353+
func (r *Repository) DiffNameOnly(base, head string, opts ...DiffNameOnlyOptions) ([]string, error) {
354+
return RepoDiffNameOnly(r.path, base, head, opts...)
355+
}
356+
338357
// RevListCountOptions contains optional arguments for counting commits.
339358
// Docs: https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt---count
340359
type RevListCountOptions struct {

repo_commit_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ func TestRepository_Log(t *testing.T) {
7777
}
7878

7979
assert.Equal(t, test.expCommitIDs, commitsToIDs(commits))
80+
81+
commits, err = RepoLog(testrepo.path, test.rev, test.opt)
82+
if err != nil {
83+
t.Fatal(err)
84+
}
85+
86+
assert.Equal(t, test.expCommitIDs, commitsToIDs(commits))
8087
})
8188
}
8289
}

repo_hook.go

+13-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package git
77
import (
88
"io/ioutil"
99
"os"
10-
"path"
1110
"path/filepath"
1211
)
1312

@@ -23,11 +22,15 @@ func (r *Repository) NewHook(name HookName) *Hook {
2322
}
2423
}
2524

26-
// Hook returns a Git hook by given name in the repository. It returns an os.ErrNotExist
27-
// if both active and sample hook do not exist.
28-
func (r *Repository) Hook(name HookName) (*Hook, error) {
25+
// Hook returns a Git hook by given name in the repository. Giving empty directory
26+
// will use the default directory.It returns an os.ErrNotExist if both active and
27+
// sample hook do not exist.
28+
func (r *Repository) Hook(dir string, name HookName) (*Hook, error) {
29+
if dir == "" {
30+
dir = DefaultHooksDir
31+
}
2932
// 1. Check if there is an active hook.
30-
fpath := filepath.Join(r.path, DefaultHooksDir, string(name))
33+
fpath := filepath.Join(r.path, dir, string(name))
3134
if isFile(fpath) {
3235
p, err := ioutil.ReadFile(fpath)
3336
if err != nil {
@@ -41,7 +44,7 @@ func (r *Repository) Hook(name HookName) (*Hook, error) {
4144
}
4245

4346
// 2. Check if a sample file exists.
44-
spath := fpath + ".sample"
47+
spath := filepath.Join(r.path, DefaultHooksDir, string(name)+".sample")
4548
if isFile(spath) {
4649
p, err := ioutil.ReadFile(spath)
4750
if err != nil {
@@ -58,16 +61,12 @@ func (r *Repository) Hook(name HookName) (*Hook, error) {
5861
return nil, os.ErrNotExist
5962
}
6063

61-
// Hooks returns a list of Git hooks found in the repository. It may return an empty slice
62-
// when no hooks found.
63-
func (r *Repository) Hooks() ([]*Hook, error) {
64-
if !isDir(path.Join(r.path, DefaultHooksDir)) {
65-
return []*Hook{}, nil
66-
}
67-
64+
// Hooks returns a list of Git hooks found in the repository. Giving empty directory
65+
// will use the default directory. It may return an empty slice when no hooks found.
66+
func (r *Repository) Hooks(dir string) ([]*Hook, error) {
6867
hooks := make([]*Hook, 0, len(ServerSideHooks))
6968
for _, name := range ServerSideHooks {
70-
h, err := r.Hook(name)
69+
h, err := r.Hook(dir, name)
7170
if err != nil {
7271
if err == os.ErrNotExist {
7372
continue

repo_hook_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
func TestRepository_Hooks(t *testing.T) {
1616
t.Run("invalid hook", func(t *testing.T) {
17-
h, err := testrepo.Hook("bad_hook")
17+
h, err := testrepo.Hook("", "bad_hook")
1818
assert.Equal(t, os.ErrNotExist, err)
1919
assert.Nil(t, h)
2020
})
@@ -30,7 +30,7 @@ func TestRepository_Hooks(t *testing.T) {
3030
t.Fatal(err)
3131
}
3232

33-
hooks, err := r.Hooks()
33+
hooks, err := r.Hooks("")
3434
if err != nil {
3535
t.Fatal(err)
3636
}
@@ -57,7 +57,7 @@ func TestRepository_Hooks(t *testing.T) {
5757
_ = os.RemoveAll(dir)
5858
}()
5959

60-
hooks, err := r.Hooks()
60+
hooks, err := r.Hooks("")
6161
if err != nil {
6262
t.Fatal(err)
6363
}
@@ -75,7 +75,7 @@ func TestRepository_Hooks(t *testing.T) {
7575
t.Fatal(err)
7676
}
7777

78-
hooks, err := testrepo.Hooks()
78+
hooks, err := testrepo.Hooks("")
7979
if err != nil {
8080
t.Fatal(err)
8181
}

repo_pull.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ type MergeBaseOptions struct {
1717
Timeout time.Duration
1818
}
1919

20-
// MergeBase returns merge base between base and head revisions.
21-
func (r *Repository) MergeBase(base, head string, opts ...MergeBaseOptions) (string, error) {
20+
// RepoMergeBase returns merge base between base and head revisions of the repository
21+
// in given path.
22+
func RepoMergeBase(repoPath, base, head string, opts ...MergeBaseOptions) (string, error) {
2223
var opt MergeBaseOptions
2324
if len(opts) > 0 {
2425
opt = opts[0]
2526
}
2627

27-
stdout, err := NewCommand("merge-base", base, head).RunInDirWithTimeout(opt.Timeout, r.path)
28+
stdout, err := NewCommand("merge-base", base, head).RunInDirWithTimeout(opt.Timeout, repoPath)
2829
if err != nil {
2930
if strings.Contains(err.Error(), "exit status 1") {
3031
return "", ErrNoMergeBase
@@ -33,3 +34,8 @@ func (r *Repository) MergeBase(base, head string, opts ...MergeBaseOptions) (str
3334
}
3435
return strings.TrimSpace(string(stdout)), nil
3536
}
37+
38+
// MergeBase returns merge base between base and head revisions of the repository.
39+
func (r *Repository) MergeBase(base, head string, opts ...MergeBaseOptions) (string, error) {
40+
return RepoMergeBase(r.path, base, head, opts...)
41+
}

0 commit comments

Comments
 (0)