| @@ -5,7 +5,7 @@ Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language. | |||
| Since we choose to use pure Go implmentation of Git manipulation, Gogs certainly supports **ALL platforms** that Go supports, including Linux, Max OS X, and Windows with **ZERO** dependency. | |||
| ##### Current version: 0.0.8 Alpha | |||
| ##### Current version: 0.0.9 Alpha | |||
| ## Purpose | |||
| @@ -12,7 +12,8 @@ | |||
| "models": "", | |||
| "others": [ | |||
| "modules", | |||
| "$GOPATH/src/github.com/gogits/binding" | |||
| "$GOPATH/src/github.com/gogits/binding", | |||
| "$GOPATH/src/github.com/gogits/git" | |||
| ] | |||
| }, | |||
| "cmd_args": [ | |||
| @@ -20,7 +20,7 @@ import ( | |||
| // Test that go1.1 tag above is included in builds. main.go refers to this definition. | |||
| const go11tag = true | |||
| const APP_VER = "0.0.9.0316.1" | |||
| const APP_VER = "0.0.9.0317.1" | |||
| func init() { | |||
| base.AppVer = APP_VER | |||
| @@ -6,11 +6,22 @@ package models | |||
| import ( | |||
| "path" | |||
| "strings" | |||
| "time" | |||
| git "github.com/gogits/git" | |||
| "github.com/Unknwon/com" | |||
| "github.com/gogits/git" | |||
| ) | |||
| type Commit struct { | |||
| Author string | |||
| Email string | |||
| Date time.Time | |||
| SHA string | |||
| Message string | |||
| } | |||
| type RepoFile struct { | |||
| *git.TreeEntry | |||
| Path string | |||
| @@ -19,10 +30,26 @@ type RepoFile struct { | |||
| Size int64 | |||
| } | |||
| func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) { | |||
| f := RepoPath(userName, reposName) | |||
| func GetBranches(userName, reposName string) ([]string, error) { | |||
| repo, err := git.OpenRepository(RepoPath(userName, reposName)) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| repo, err := git.OpenRepository(f) | |||
| refs, err := repo.AllReferences() | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| brs := make([]string, len(refs)) | |||
| for i, ref := range refs { | |||
| brs[i] = ref.Name | |||
| } | |||
| return brs, nil | |||
| } | |||
| func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) { | |||
| repo, err := git.OpenRepository(RepoPath(userName, reposName)) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| @@ -69,3 +96,33 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, | |||
| return append(repodirs, repofiles...), nil | |||
| } | |||
| func GetLastestCommit(userName, repoName string) (*Commit, error) { | |||
| stdout, _, err := com.ExecCmd("git", "--git-dir="+RepoPath(userName, repoName), "log", "-1") | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| commit := new(Commit) | |||
| for _, line := range strings.Split(stdout, "\n") { | |||
| if len(line) == 0 { | |||
| continue | |||
| } | |||
| switch { | |||
| case line[0] == 'c': | |||
| commit.SHA = line[7:] | |||
| case line[0] == 'A': | |||
| infos := strings.SplitN(line, " ", 3) | |||
| commit.Author = infos[1] | |||
| commit.Email = infos[2][1 : len(infos[2])-1] | |||
| case line[0] == 'D': | |||
| commit.Date, err = time.Parse("Mon Jan 02 15:04:05 2006 -0700", line[8:]) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| case line[:4] == " ": | |||
| commit.Message = line[4:] | |||
| } | |||
| } | |||
| return commit, nil | |||
| } | |||
| @@ -19,6 +19,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ | |||
| "AppVer": func() string { | |||
| return AppVer | |||
| }, | |||
| "AvatarLink": AvatarLink, | |||
| "str2html": Str2html, | |||
| "TimeSince": TimeSince, | |||
| "FileSize": FileSize, | |||
| @@ -22,6 +22,11 @@ func EncodeMd5(str string) string { | |||
| return hex.EncodeToString(m.Sum(nil)) | |||
| } | |||
| // AvatarLink returns avatar link by given e-mail. | |||
| func AvatarLink(email string) string { | |||
| return "http://1.gravatar.com/avatar/" + EncodeMd5(email) | |||
| } | |||
| // Seconds-based time units | |||
| const ( | |||
| Minute = 60 | |||
| @@ -33,6 +33,13 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| ctx.Data["Reponame"] = params["reponame"] | |||
| ctx.Data["Branchname"] = params["branchname"] | |||
| brs, err := models.GetBranches(params["username"], params["reponame"]) | |||
| if err != nil { | |||
| ctx.Handle(200, "repo.Single", err) | |||
| return | |||
| } | |||
| ctx.Data["Branches"] = brs | |||
| var treenames []string | |||
| Paths := make([]string, 0) | |||
| @@ -43,6 +50,13 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| } | |||
| } | |||
| commit, err := models.GetLastestCommit(params["username"], params["reponame"]) | |||
| if err != nil { | |||
| ctx.Handle(200, "repo.Single", err) | |||
| return | |||
| } | |||
| ctx.Data["LatestCommit"] = commit | |||
| ctx.Data["Paths"] = Paths | |||
| ctx.Data["Treenames"] = treenames | |||
| ctx.Data["IsRepoToolbarSource"] = true | |||
| @@ -5,21 +5,23 @@ | |||
| <div id="gogs-body" class="container"> | |||
| <div id="gogs-source"> | |||
| <div class="source-toolbar"> | |||
| {{ $username := .Username}} | |||
| {{ $reponame := .Reponame}} | |||
| {{ $branchname := .Branchname}} | |||
| {{ $treenames := .Treenames}} | |||
| {{ $repoLink := .RepositoryLink}} | |||
| {{ $n := len $treenames}} | |||
| <button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button> | |||
| <div class="dropdown branch-switch"> | |||
| <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>master | |||
| <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>{{$branchname}} | |||
| <b class="caret"></b></a> | |||
| <ul class="dropdown-menu"> | |||
| <li><a class="current" href="/{{.RepositoryLink}}/tree/master">master</a></li> | |||
| <li><a href="/{{.RepositoryLink}}/tree/develop">develop</a></li> | |||
| {{range .Branches}} | |||
| <li><a {{if eq . $branchname}}class="current" {{end}}href="/{{$repoLink}}/tree/{{.}}">{{.}}</a></li> | |||
| {{end}} | |||
| </ul> | |||
| </div> | |||
| {{$paths := .Paths}} | |||
| {{ $username := .Username}} | |||
| {{ $reponame := .Reponame}} | |||
| {{ $branchname := .Branchname}} | |||
| {{ $treenames := .Treenames}} | |||
| {{ $n := len $treenames}} | |||
| {{ $l := Subtract $n 1}} | |||
| <ol class="breadcrumb"> | |||
| <li class="root dir"><a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}">{{.Repository.Name}}</a></li> | |||
| @@ -34,10 +36,10 @@ | |||
| </div> | |||
| <div class="panel panel-default info-box"> | |||
| <div class="panel-heading info-head"> | |||
| Merge branch 'release/1.1.1' | |||
| <a href="/{{$username}}/{{$reponame}}/commit/{{.LatestCommit.SHA}}">{{.LatestCommit.Message}}</a> | |||
| </div> | |||
| <div class="panel-body info-content"> | |||
| slene authored 4 days ago | |||
| <a href="/user/{{.LatestCommit.Author}}">{{.LatestCommit.Author}}</a> <span class="text-muted">{{TimeSince .LatestCommit.Date}}</span> | |||
| </div> | |||
| <table class="panel-footer table file-list"> | |||
| <thead class="hidden"> | |||