Skip to content

Commit 4cc1cbb

Browse files
committed
complete migration from gogs module
1 parent d14b1e8 commit 4cc1cbb

17 files changed

+977
-45
lines changed

commit.go

Lines changed: 137 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
package git
66

77
import (
8+
"bufio"
9+
"container/list"
810
"fmt"
11+
"net/http"
912
"strconv"
1013
"strings"
1114

@@ -20,8 +23,18 @@ type Commit struct {
2023
Committer *Signature
2124
CommitMessage string
2225

23-
parents []sha1 // SHA1 strings
24-
// submodules map[string]*SubModule
26+
parents []sha1 // SHA1 strings
27+
submodules map[string]*SubModule
28+
}
29+
30+
// Message returns the commit message. Same as retrieving CommitMessage directly.
31+
func (c *Commit) Message() string {
32+
return c.CommitMessage
33+
}
34+
35+
// Summary returns first line of commit message.
36+
func (c *Commit) Summary() string {
37+
return strings.Split(c.CommitMessage, "\n")[0]
2538
}
2639

2740
// ParentID returns oid of n-th parent (0-based index).
@@ -47,14 +60,41 @@ func (c *Commit) Parent(n int) (*Commit, error) {
4760
}
4861

4962
// ParentCount returns number of parents of the commit.
50-
// 0 if this is the root commit, otherwise 1,2, etc.
63+
// 0 if this is the root commit, otherwise 1,2, etc.
5164
func (c *Commit) ParentCount() int {
5265
return len(c.parents)
5366
}
5467

55-
// GetCommitOfRelPath return the commit of relative path object.
56-
func (c *Commit) GetCommitOfRelPath(relpath string) (*Commit, error) {
57-
return c.repo.getCommitOfRelPath(c.ID, relpath)
68+
func isImageFile(data []byte) (string, bool) {
69+
contentType := http.DetectContentType(data)
70+
if strings.Index(contentType, "image/") != -1 {
71+
return contentType, true
72+
}
73+
return contentType, false
74+
}
75+
76+
func (c *Commit) IsImageFile(name string) bool {
77+
blob, err := c.GetBlobByPath(name)
78+
if err != nil {
79+
return false
80+
}
81+
82+
dataRc, err := blob.Data()
83+
if err != nil {
84+
return false
85+
}
86+
buf := make([]byte, 1024)
87+
n, _ := dataRc.Read(buf)
88+
if n > 0 {
89+
buf = buf[:n]
90+
}
91+
_, isImage := isImageFile(buf)
92+
return isImage
93+
}
94+
95+
// GetCommitByPath return the commit of relative path object.
96+
func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) {
97+
return c.repo.getCommitByPathWithID(c.ID, relpath)
5898
}
5999

60100
// AddAllChanges marks local changes to be ready for commit.
@@ -82,19 +122,102 @@ func CommitChanges(repoPath, message string, author *Signature) error {
82122
return err
83123
}
84124

85-
// CommitsCount returns number of total commits of until given revision.
86-
func CommitsCount(repoPath, revision string) (int64, error) {
125+
func commitsCount(repoPath, revision, relpath string) (int64, error) {
126+
var cmd *Command
127+
isFallback := false
87128
if version.Compare(gitVersion, "1.8.0", "<") {
88-
stdout, err := NewCommand("log", "--pretty=format:''", revision).RunInDir(repoPath)
89-
if err != nil {
90-
return 0, err
91-
}
92-
return int64(len(strings.Split(stdout, "\n"))), nil
129+
isFallback = true
130+
cmd = NewCommand("log", "--pretty=format:''")
131+
} else {
132+
cmd = NewCommand("rev-list", "--count")
133+
}
134+
cmd.AddArguments(revision)
135+
if len(relpath) > 0 {
136+
cmd.AddArguments("--", relpath)
93137
}
94138

95-
stdout, err := NewCommand("rev-list", "--count", revision).RunInDir(repoPath)
139+
stdout, err := cmd.RunInDir(repoPath)
96140
if err != nil {
97141
return 0, err
98142
}
143+
144+
if isFallback {
145+
return int64(len(strings.Split(stdout, "\n"))), nil
146+
}
99147
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
100148
}
149+
150+
// CommitsCount returns number of total commits of until given revision.
151+
func CommitsCount(repoPath, revision string) (int64, error) {
152+
return commitsCount(repoPath, revision, "")
153+
}
154+
155+
func (c *Commit) CommitsCount() (int64, error) {
156+
return CommitsCount(c.repo.Path, c.ID.String())
157+
}
158+
159+
func (c *Commit) CommitsByRange(page int) (*list.List, error) {
160+
return c.repo.commitsByRange(c.ID, page)
161+
}
162+
163+
func (c *Commit) CommitsBefore() (*list.List, error) {
164+
return c.repo.getCommitsBefore(c.ID)
165+
}
166+
167+
func (c *Commit) CommitsBeforeUntil(commitID string) (*list.List, error) {
168+
endCommit, err := c.repo.GetCommit(commitID)
169+
if err != nil {
170+
return nil, err
171+
}
172+
return c.repo.CommitsBetween(c, endCommit)
173+
}
174+
175+
func (c *Commit) SearchCommits(keyword string) (*list.List, error) {
176+
return c.repo.searchCommits(c.ID, keyword)
177+
}
178+
179+
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
180+
modules, err := c.GetSubModules()
181+
if err != nil {
182+
return nil, err
183+
}
184+
return modules[entryname], nil
185+
}
186+
187+
func (c *Commit) GetSubModules() (map[string]*SubModule, error) {
188+
if c.submodules != nil {
189+
return c.submodules, nil
190+
}
191+
192+
entry, err := c.GetTreeEntryByPath(".gitmodules")
193+
if err != nil {
194+
return nil, err
195+
}
196+
rd, err := entry.Blob().Data()
197+
if err != nil {
198+
return nil, err
199+
}
200+
201+
scanner := bufio.NewScanner(rd)
202+
c.submodules = make(map[string]*SubModule)
203+
var ismodule bool
204+
var path string
205+
for scanner.Scan() {
206+
if strings.HasPrefix(scanner.Text(), "[submodule") {
207+
ismodule = true
208+
continue
209+
}
210+
if ismodule {
211+
fields := strings.Split(scanner.Text(), "=")
212+
k := strings.TrimSpace(fields[0])
213+
if k == "path" {
214+
path = strings.TrimSpace(fields[1])
215+
} else if k == "url" {
216+
c.submodules[path] = &SubModule{path, strings.TrimSpace(fields[1])}
217+
ismodule = false
218+
}
219+
}
220+
}
221+
222+
return c.submodules, nil
223+
}

commit_archive.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2015 The Gogs Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package git
6+
7+
import "fmt"
8+
9+
type ArchiveType int
10+
11+
const (
12+
ZIP ArchiveType = iota + 1
13+
TARGZ
14+
)
15+
16+
func (c *Commit) CreateArchive(path string, archiveType ArchiveType) error {
17+
var format string
18+
switch archiveType {
19+
case ZIP:
20+
format = "zip"
21+
case TARGZ:
22+
format = "tar.gz"
23+
default:
24+
return fmt.Errorf("unknown format: %v", archiveType)
25+
}
26+
27+
_, err := NewCommand("archive", "--format="+format, "-o", path, c.ID.String()).RunInDir(c.repo.Path)
28+
return err
29+
}

error.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,16 @@ func IsErrNotExist(err error) bool {
3535
func (err ErrNotExist) Error() string {
3636
return fmt.Sprintf("object does not exist [id: %s, rel_path: %s]", err.ID, err.RelPath)
3737
}
38+
39+
type ErrUnsupportedVersion struct {
40+
Required string
41+
}
42+
43+
func IsErrUnsupportedVersion(err error) bool {
44+
_, ok := err.(ErrUnsupportedVersion)
45+
return ok
46+
}
47+
48+
func (err ErrUnsupportedVersion) Error() string {
49+
return fmt.Sprintf("Operation requires higher version [required: %s]", err.Required)
50+
}

git.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ import (
1010
"time"
1111
)
1212

13+
const _VERSION = "0.1.0"
14+
15+
func Version() string {
16+
return _VERSION
17+
}
18+
1319
var (
1420
// Debug enables verbose logging on everything.
1521
// This should be false in case Gogs starts in SSH mode.
@@ -33,7 +39,7 @@ func log(format string, args ...interface{}) {
3339
var gitVersion string
3440

3541
// Version returns current Git version from shell.
36-
func Version() (string, error) {
42+
func BinVersion() (string, error) {
3743
if len(gitVersion) > 0 {
3844
return gitVersion, nil
3945
}
@@ -53,7 +59,7 @@ func Version() (string, error) {
5359
}
5460

5561
func init() {
56-
Version()
62+
BinVersion()
5763
}
5864

5965
// Fsck verifies the connectivity and validity of the objects in the database

hook.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright 2015 The Gogs Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package git
6+
7+
import (
8+
"errors"
9+
"io/ioutil"
10+
"os"
11+
"path"
12+
"strings"
13+
)
14+
15+
// hookNames is a list of Git hooks' name that are supported.
16+
var hookNames = []string{
17+
"applypatch-msg",
18+
"pre-applypatch",
19+
"post-applypatch",
20+
"pre-commit",
21+
"prepare-commit-msg",
22+
"commit-msg",
23+
"post-commit",
24+
"pre-rebase",
25+
"post-checkout",
26+
"post-merge",
27+
"pre-push",
28+
"pre-receive",
29+
// "update",
30+
"post-receive",
31+
"post-update",
32+
"push-to-checkout",
33+
"pre-auto-gc",
34+
"post-rewrite",
35+
}
36+
37+
var (
38+
ErrNotValidHook = errors.New("not a valid Git hook")
39+
)
40+
41+
// IsValidHookName returns true if given name is a valid Git hook.
42+
func IsValidHookName(name string) bool {
43+
for _, hn := range hookNames {
44+
if hn == name {
45+
return true
46+
}
47+
}
48+
return false
49+
}
50+
51+
// Hook represents a Git hook.
52+
type Hook struct {
53+
name string
54+
IsActive bool // Indicates whether repository has this hook.
55+
Content string // Content of hook if it's active.
56+
Sample string // Sample content from Git.
57+
path string // Hook file path.
58+
}
59+
60+
// GetHook returns a Git hook by given name and repository.
61+
func GetHook(repoPath, name string) (*Hook, error) {
62+
if !IsValidHookName(name) {
63+
return nil, ErrNotValidHook
64+
}
65+
h := &Hook{
66+
name: name,
67+
path: path.Join(repoPath, "hooks", name),
68+
}
69+
if isFile(h.path) {
70+
data, err := ioutil.ReadFile(h.path)
71+
if err != nil {
72+
return nil, err
73+
}
74+
h.IsActive = true
75+
h.Content = string(data)
76+
} else if isFile(h.path + ".sample") {
77+
data, err := ioutil.ReadFile(h.path + ".sample")
78+
if err != nil {
79+
return nil, err
80+
}
81+
h.Sample = string(data)
82+
}
83+
return h, nil
84+
}
85+
86+
func (h *Hook) Name() string {
87+
return h.name
88+
}
89+
90+
// Update updates hook settings.
91+
func (h *Hook) Update() error {
92+
if len(strings.TrimSpace(h.Content)) == 0 {
93+
if isExist(h.path) {
94+
return os.Remove(h.path)
95+
}
96+
return nil
97+
}
98+
return ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm)
99+
}
100+
101+
// ListHooks returns a list of Git hooks of given repository.
102+
func ListHooks(repoPath string) (_ []*Hook, err error) {
103+
if !isDir(path.Join(repoPath, "hooks")) {
104+
return nil, errors.New("hooks path does not exist")
105+
}
106+
107+
hooks := make([]*Hook, len(hookNames))
108+
for i, name := range hookNames {
109+
hooks[i], err = GetHook(repoPath, name)
110+
if err != nil {
111+
return nil, err
112+
}
113+
}
114+
return hooks, nil
115+
}
116+
117+
const (
118+
HOOK_PATH_UPDATE = "hooks/update"
119+
)
120+
121+
// SetUpdateHook writes given content to update hook of the reposiotry.
122+
func SetUpdateHook(repoPath, content string) error {
123+
log("Setting update hook: %s", repoPath)
124+
hookPath := path.Join(repoPath, HOOK_PATH_UPDATE)
125+
os.MkdirAll(path.Dir(hookPath), os.ModePerm)
126+
return ioutil.WriteFile(hookPath, []byte(content), 0777)
127+
}

0 commit comments

Comments
 (0)