Merge branch 'dev' of github.com:gogits/gogs into dev

release/v1.15
Lunny Xiao 2014-04-30 10:24:00 +08:00
commit a85f242030
41 changed files with 231 additions and 228 deletions

View File

@ -19,6 +19,7 @@ github.com/lib/pq =
github.com/nfnt/resize =
github.com/qiniu/log =
github.com/robfig/cron =
github.com/juju2013/goldap =
[res]
include = templates|public|conf

View File

@ -10,6 +10,8 @@ Want to hack on Gogs? Awesome! Here are instructions to get you started. They ar
### Pull requests are always welcome
**ALL PULL REQUESTS MUST SEND TO `DEV` BRANCH**
We are always thrilled to receive pull requests, and do our best to process them as fast as possible. Not sure if that typo is worth a pull request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be discouraged! If there's a problem with the implementation, hopefully you received feedback on what to improve.

View File

@ -5,7 +5,7 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language
![Demo](http://gowalker.org/public/gogs_demo.gif)
##### Current version: 0.3.0 Alpha
##### Current version: 0.3.1 Alpha
### NOTICES
@ -42,6 +42,11 @@ More importantly, Gogs only needs one binary to setup your own project hosting o
- Supports MySQL, PostgreSQL and SQLite3.
- Social account login(GitHub, Google, QQ, Weibo)
## System Requirements
- A cheap Raspberry Pi is powerful enough to match the minimal requirement.
- 4 CPU Cores and 1GB RAM would be the baseline for teamwork.
## Installation
Make sure you install [Prerequirements](https://github.com/gogits/gogs/wiki/Prerequirements) first.

View File

@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。
![Demo](http://gowalker.org/public/gogs_demo.gif)
##### 当前版本0.3.0 Alpha
##### 当前版本0.3.1 Alpha
## 开发目的
@ -33,6 +33,12 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依
- 支持 MySQL、PostgreSQL 以及 SQLite3 数据库
- 社交帐号登录GitHub、Google、QQ、微博
## 系统要求
- 最低的系统硬件要求为一个廉价的树莓派
- 如果用于团队项目,建议使用 4 核 CPU 及 1GB 内存
## 安装部署
在安装 Gogs 之前,您需要先安装 [基本环境](https://github.com/gogits/gogs/wiki/Prerequirements)。

View File

@ -16,6 +16,8 @@ LICENSES = Apache v2 License|GPL v2|MIT License|Affero GPL|Artistic License 2.0|
PROTOCOL = http
DOMAIN = localhost
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
; Disable CDN even in "prod" mode
OFFLINE_MODE = false
HTTP_ADDR =
HTTP_PORT = 3000
; Generate steps:

View File

@ -18,8 +18,8 @@
### install the gogs
- mkdir gogs
- cd gogs
- curl -L http://gobuild.io/github.com/gogits/gogs/v0.2.0/linux/amd64 -o v0.2.0.zip
- unzip v0.2.0.zip
- curl -L http://gobuild.io/github.com/gogits/gogs/v0.3.0/linux/amd64 -o v0.3.0.zip
- unzip v0.3.0.zip
- ./start.sh
> The up-to-date binary could be found at

View File

@ -13,7 +13,7 @@ ENV GOROOT /usr/local/go
ENV GOPATH /go
RUN apt-get update && apt-get install --yes --force-yes curl git mercurial zip wget ca-certificates build-essential
RUN apt-get install -yq vim
RUN apt-get install -yq vim sudo
RUN curl -s http://docker.u.qiniudn.com/go1.2.1.src.tar.gz | tar -v -C /usr/local -xz
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1

View File

@ -9,7 +9,8 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B97B0AFCAA
# Add PostgreSQL's repository. It contains the most recent stable release
# of PostgreSQL, ``9.3``.
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
# See http://apt.postgresql.org/pub/repos/apt/README
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
# Update the Ubuntu and PostgreSQL repository indexes
RUN apt-get update

View File

@ -19,7 +19,7 @@ import (
// Test that go1.2 tag above is included in builds. main.go refers to this definition.
const go12tag = true
const APP_VER = "0.3.0.0422 Alpha"
const APP_VER = "0.3.1.0427 Alpha"
func init() {
base.AppVer = APP_VER

View File

@ -77,12 +77,12 @@ func init() {
// PublicKey represents a SSH key of user.
type PublicKey struct {
Id int64
OwnerId int64 `xorm:"unique(s) index not null"`
Name string `xorm:"unique(s) not null"`
OwnerId int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"UNIQUE(s) NOT NULL"`
Fingerprint string
Content string `xorm:"TEXT not null"`
Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"`
Content string `xorm:"TEXT NOT NULL"`
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
}
// GenAuthorizedKey returns formatted public key string.
@ -107,9 +107,9 @@ func AddPublicKey(key *PublicKey) (err error) {
if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
return err
}
stdout, _, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
stdout, stderr, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
if err != nil {
return err
return errors.New("ssh-keygen -l -f: " + stderr)
} else if len(stdout) < 2 {
return errors.New("Not enough output for calculating fingerprint")
}

View File

@ -159,9 +159,7 @@ func MirrorUpdate() {
repoPath := filepath.Join(base.RepoRootPath, m.RepoName+".git")
_, stderr, err := com.ExecCmdDir(repoPath, "git", "remote", "update")
if err != nil {
return err
} else if strings.Contains(stderr, "fatal:") {
return errors.New(stderr)
return errors.New("git remote update: " + stderr)
} else if err = git.UnpackRefs(repoPath); err != nil {
return err
}
@ -177,9 +175,7 @@ func MirrorUpdate() {
func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) error {
_, stderr, err := com.ExecCmd("git", "clone", "--mirror", url, repoPath)
if err != nil {
return err
} else if strings.Contains(stderr, "fatal:") {
return errors.New(stderr)
return errors.New("git clone --mirror: " + stderr)
}
if _, err = orm.InsertOne(&Mirror{
@ -219,23 +215,17 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url
// Clone from local repository.
_, stderr, err := com.ExecCmd("git", "clone", repoPath, tmpDir)
if err != nil {
return repo, err
} else if strings.Contains(stderr, "fatal:") {
return repo, errors.New("git clone: " + stderr)
}
// Pull data from source.
_, stderr, err = com.ExecCmdDir(tmpDir, "git", "pull", url)
if err != nil {
return repo, err
} else if strings.Contains(stderr, "fatal:") {
return repo, errors.New("git pull: " + stderr)
}
// Push data to local repository.
if _, stderr, err = com.ExecCmdDir(tmpDir, "git", "push", "origin", "master"); err != nil {
return repo, err
} else if strings.Contains(stderr, "fatal:") {
return repo, errors.New("git push: " + stderr)
}
@ -403,10 +393,11 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
return err
}
rp := strings.NewReplacer("\\", "/", " ", "\\ ")
// hook/post-update
if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
fmt.Sprintf("#!/usr/bin/env %s\n%s update $1 $2 $3\n", base.ScriptType,
strings.Replace(appPath, "\\", "/", -1))); err != nil {
rp.Replace(appPath))); err != nil {
return err
}
@ -428,8 +419,6 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
_, stderr, err := com.ExecCmd("git", "clone", repoPath, tmpDir)
if err != nil {
return err
} else if strings.Contains(stderr, "fatal:") {
return errors.New("git clone: " + stderr)
}

View File

@ -1,3 +1,7 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
@ -5,9 +9,11 @@ import (
"os/exec"
"strings"
"github.com/gogits/git"
"github.com/gogits/gogs/modules/base"
qlog "github.com/qiniu/log"
"github.com/gogits/git"
"github.com/gogits/gogs/modules/base"
)
func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId int64) {

View File

@ -410,21 +410,27 @@ func GetUserByEmail(email string) (*User, error) {
}
// LoginUserPlain validates user by raw user name and password.
func LoginUserPlain(name, passwd string) (*User, error) {
user := User{LowerName: strings.ToLower(name)}
has, err := orm.Get(&user)
func LoginUserPlain(uname, passwd string) (*User, error) {
var u *User
if strings.Contains(uname, "@") {
u = &User{Email: uname}
} else {
u = &User{LowerName: strings.ToLower(uname)}
}
has, err := orm.Get(u)
if err != nil {
return nil, err
} else if !has {
return nil, ErrUserNotExist
}
newUser := &User{Passwd: passwd, Salt: user.Salt}
newUser := &User{Passwd: passwd, Salt: u.Salt}
newUser.EncodePasswd()
if user.Passwd != newUser.Passwd {
if u.Passwd != newUser.Passwd {
return nil, ErrUserNotExist
}
return &user, nil
return u, nil
}
// Follow is connection request for receiving user notifycation.

View File

@ -57,7 +57,7 @@ func (f *RegisterForm) Validate(errors *base.BindingErrors, req *http.Request, c
}
type LogInForm struct {
UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"`
UserName string `form:"username" binding:"Required;MaxSize(35)"`
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
Remember string `form:"remember"`
}

View File

@ -45,15 +45,15 @@ type Oauther struct {
}
var (
AppVer string
AppName string
AppLogo string
AppUrl string
IsProdMode bool
Domain string
SecretKey string
RunUser string
LdapAuth bool
AppVer string
AppName string
AppLogo string
AppUrl string
OfflineMode bool
ProdMode bool
Domain string
SecretKey string
RunUser string
RepoRootPath string
ScriptType string
@ -93,6 +93,7 @@ var Service struct {
NotifyMail bool
ActiveCodeLives int
ResetPwdCodeLives int
LdapAuth bool
}
func ExecDir() (string, error) {
@ -178,6 +179,36 @@ func newLogService() {
log.Info("Log Mode: %s(%s)", strings.Title(LogMode), levelName)
}
func newLdapService() {
Service.LdapAuth = Cfg.MustBool("security", "LDAP_AUTH", false)
if !Service.LdapAuth {
return
}
nbsrc := 0
for _, v := range Cfg.GetSectionList() {
if matched, _ := regexp.MatchString("(?i)^LDAPSOURCE.*", v); matched {
ldapname := Cfg.MustValue(v, "name", v)
ldaphost := Cfg.MustValue(v, "host")
ldapport := Cfg.MustInt(v, "port", 389)
ldapbasedn := Cfg.MustValue(v, "basedn", "dc=*,dc=*")
ldapattribute := Cfg.MustValue(v, "attribute", "mail")
ldapfilter := Cfg.MustValue(v, "filter", "(*)")
ldapmsadsaformat := Cfg.MustValue(v, "MSADSAFORMAT", "%s")
ldap.AddSource(ldapname, ldaphost, ldapport, ldapbasedn, ldapattribute, ldapfilter, ldapmsadsaformat)
nbsrc++
log.Debug("%s added as LDAP source", ldapname)
}
}
if nbsrc == 0 {
log.Warn("No valide LDAP found, LDAP Authentication NOT enabled")
Service.LdapAuth = false
return
}
log.Info("LDAP Authentication Enabled")
}
func newCacheService() {
CacheAdapter = Cfg.MustValue("cache", "ADAPTER", "memory")
if EnableRedis {
@ -295,6 +326,7 @@ func NewConfigContext() {
AppLogo = Cfg.MustValue("", "APP_LOGO", "img/favicon.png")
AppUrl = Cfg.MustValue("server", "ROOT_URL")
Domain = Cfg.MustValue("server", "DOMAIN")
OfflineMode = Cfg.MustBool("server", "OFFLINE_MODE", false)
SecretKey = Cfg.MustValue("security", "SECRET_KEY")
InstallLock = Cfg.MustBool("security", "INSTALL_LOCK", false)
@ -312,34 +344,6 @@ func NewConfigContext() {
LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS")
CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME")
CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME")
// load LDAP authentication configuration if present
LdapAuth = Cfg.MustBool("security", "LDAP_AUTH", false)
if LdapAuth {
qlog.Debug("LDAP AUTHENTICATION activated")
nbsrc := 0
for _, v := range Cfg.GetSectionList() {
if matched, _ := regexp.MatchString("(?i)^LDAPSOURCE.*", v); matched {
ldapname := Cfg.MustValue(v, "name", v)
ldaphost := Cfg.MustValue(v, "host")
ldapport := Cfg.MustInt(v, "port", 389)
ldapbasedn := Cfg.MustValue(v, "basedn", "dc=*,dc=*")
ldapattribute := Cfg.MustValue(v, "attribute", "mail")
ldapfilter := Cfg.MustValue(v, "filter", "(*)")
ldapmsadsaformat := Cfg.MustValue(v, "MSADSAFORMAT", "%s")
ldap.AddSource(ldapname, ldaphost, ldapport, ldapbasedn, ldapattribute, ldapfilter, ldapmsadsaformat)
nbsrc += 1
qlog.Debug("%s added as LDAP source", ldapname)
}
}
if nbsrc == 0 {
qlog.Debug("No valide LDAP found, LDAP AUTHENTICATION NOT activated")
LdapAuth = false
}
} else {
qlog.Debug("LDAP AUTHENTICATION NOT activated")
}
PictureService = Cfg.MustValue("picture", "SERVICE")
// Determine and create root git reposiroty path.
@ -357,6 +361,7 @@ func NewConfigContext() {
func NewBaseServices() {
newService()
newLogService()
newLdapService()
newCacheService()
newSessionService()
newMailService()

View File

@ -56,8 +56,8 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
"AppDomain": func() string {
return Domain
},
"IsProdMode": func() bool {
return IsProdMode
"CdnMode": func() bool {
return ProdMode && !OfflineMode
},
"LoadTimes": func(startTime time.Time) string {
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
@ -124,11 +124,11 @@ func ActionIcon(opType int) string {
const (
TPL_CREATE_REPO = `<a href="/user/%s">%s</a> created repository <a href="/%s">%s</a>`
TPL_COMMIT_REPO = `<a href="/user/%s">%s</a> pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>%s`
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="/%s/commit/%s">%s</a> %s</div>`
TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="/%s/commit/%s" rel="nofollow">%s</a> %s</div>`
TPL_CREATE_ISSUE = `<a href="/user/%s">%s</a> opened issue <a href="/%s/issues/%s">%s#%s</a>
<div><img src="%s?s=16" alt="user-avatar"/> %s</div>`
TPL_TRANSFER_REPO = `<a href="/user/%s">%s</a> transfered repository <code>%s</code> to <a href="/%s">%s</a>`
TPL_PUSH_TAG = `<a href="/user/%s">%s</a> pushed tag <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a>`
TPL_PUSH_TAG = `<a href="/user/%s">%s</a> pushed tag <a href="/%s/src/%s" rel="nofollow">%s</a> at <a href="/%s">%s</a>`
)
type PushCommit struct {
@ -165,7 +165,7 @@ func ActionDesc(act Actioner) string {
buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n")
}
if push.Len > 3 {
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
buf.WriteString(fmt.Sprintf(`<div><a href="/%s/%s/commits/%s" rel="nofollow">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len))
}
return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink,
buf.String())

View File

@ -26,11 +26,14 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
var displayBare bool
if len(args) >= 1 {
validBranch = args[0]
// Note: argument has wrong value in Go1.3 martini.
// validBranch = args[0]
validBranch = true
}
if len(args) >= 2 {
displayBare = args[1]
// displayBare = args[1]
displayBare = true
}
var (

BIN
public/img/favicon.bak.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -468,13 +468,28 @@ function initRepository() {
function initInstall() {
// database type change
(function () {
var mysql_default = '127.0.0.1:3306'
var postgres_default = '127.0.0.1:5432'
$('#install-database').on("change", function () {
var val = $(this).val();
if (val != "sqlite") {
if (val != "SQLite3") {
$('.server-sql').show();
$('.sqlite-setting').addClass("hide");
if (val == "pgsql") {
if (val == "PostgreSQL") {
$('.pgsql-setting').removeClass("hide");
// Change the host value to the Postgres default, but only
// if the user hasn't already changed it from the MySQL
// default.
if ($('#database-host').val() == mysql_default) {
$('#database-host').val(postgres_default);
}
} else if (val == 'MySQL') {
$('.pgsql-setting').addClass("hide");
if ($('#database-host').val() == postgres_default) {
$('#database-host').val(mysql_default);
}
} else {
$('.pgsql-setting').addClass("hide");
}

View File

@ -139,9 +139,11 @@ func Config(ctx *middleware.Context) {
ctx.Data["AppUrl"] = base.AppUrl
ctx.Data["Domain"] = base.Domain
ctx.Data["OfflineMode"] = base.OfflineMode
ctx.Data["RunUser"] = base.RunUser
ctx.Data["RunMode"] = strings.Title(martini.Env)
ctx.Data["RepoRootPath"] = base.RepoRootPath
ctx.Data["ScriptType"] = base.ScriptType
ctx.Data["Service"] = base.Service

View File

@ -30,7 +30,7 @@ func checkRunMode() {
switch base.Cfg.MustValue("", "RUN_MODE") {
case "prod":
martini.Env = martini.Prod
base.IsProdMode = true
base.ProdMode = true
case "test":
martini.Env = martini.Test
}
@ -65,6 +65,10 @@ func GlobalInit() {
checkRunMode()
}
func renderDbOption(ctx *middleware.Context) {
ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"}
}
func Install(ctx *middleware.Context, form auth.InstallForm) {
if base.InstallLock {
ctx.Handle(404, "install.Install", errors.New("Installation is prohibited"))
@ -104,6 +108,13 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
form.AppUrl = base.AppUrl
}
renderDbOption(ctx)
curDbValue := ""
if models.EnableSQLite3 {
curDbValue = "SQLite3" // Default when enabled.
}
ctx.Data["CurDbValue"] = curDbValue
auth.AssignForm(form, ctx.Data)
ctx.HTML(200, "install")
}
@ -117,6 +128,9 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
ctx.Data["Title"] = "Install"
ctx.Data["PageIsInstall"] = true
renderDbOption(ctx)
ctx.Data["CurDbValue"] = form.Database
if ctx.HasError() {
ctx.HTML(200, "install")
return
@ -129,7 +143,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
// Pass basic check, now test configuration.
// Test database setting.
dbTypes := map[string]string{"mysql": "mysql", "pgsql": "postgres", "sqlite": "sqlite3"}
dbTypes := map[string]string{"MySQL": "mysql", "PostgreSQL": "postgres", "SQLite3": "sqlite3"}
models.DbCfg.Type = dbTypes[form.Database]
models.DbCfg.Host = form.Host
models.DbCfg.User = form.User

View File

@ -91,10 +91,23 @@ func Diff(ctx *middleware.Context, params martini.Params) {
return isImage
}
parents := make([]string, commit.ParentCount())
for i := 0; i < commit.ParentCount(); i++ {
sha, err := commit.ParentId(i)
parents[i] = sha.String()
if err != nil {
ctx.Handle(404, "repo.Diff", err)
return
}
}
ctx.Data["Username"] = userName
ctx.Data["Reponame"] = repoName
ctx.Data["IsImageFile"] = isImageFile
ctx.Data["Title"] = commit.Message() + " · " + base.ShortSha(commitId)
ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitId)
ctx.Data["Commit"] = commit
ctx.Data["Diff"] = diff
ctx.Data["Parents"] = parents
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
ctx.Data["IsRepoToolbarCommits"] = true
ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", commitId)

View File

@ -166,7 +166,8 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {
return
}
k := &models.PublicKey{OwnerId: ctx.User.Id,
k := &models.PublicKey{
OwnerId: ctx.User.Id,
Name: form.KeyName,
Content: form.KeyContent,
}

View File

@ -91,12 +91,14 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
var user *models.User
var err error
// try to login against LDAP if defined
if base.LdapAuth {
if base.Service.LdapAuth {
user, err = models.LoginUserLdap(form.UserName, form.Password)
if err != nil {
log.Error("Fail to login through LDAP: %v", err)
}
}
// try local if not LDAP or it's failed
if (!base.LdapAuth) || (err != nil) {
if !base.Service.LdapAuth || err != nil {
user, err = models.LoginUserPlain(form.UserName, form.Password)
}
if err != nil {
@ -142,27 +144,6 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
ctx.Redirect("/")
}
func oauthSignInPost(ctx *middleware.Context, sid int64) {
ctx.Data["Title"] = "OAuth Sign Up"
ctx.Data["PageIsSignUp"] = true
if _, err := models.GetOauth2ById(sid); err != nil {
if err == models.ErrOauth2RecordNotExist {
ctx.Handle(404, "user.oauthSignUp(GetOauth2ById)", err)
} else {
ctx.Handle(500, "user.oauthSignUp(GetOauth2ById)", err)
}
return
}
ctx.Data["IsSocialLogin"] = true
ctx.Data["username"] = ctx.Session.Get("socialName")
ctx.Data["email"] = ctx.Session.Get("socialEmail")
log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId"))
ctx.HTML(200, "user/signup")
}
func SignOut(ctx *middleware.Context) {
ctx.Session.Delete("userId")
ctx.Session.Delete("userName")

View File

@ -18,6 +18,8 @@
<dd>{{.AppUrl}}</dd>
<dt>Domain</dt>
<dd>{{.Domain}}</dd>
<dt>Offline Mode</dt>
<dd><i class="fa fa{{if .OfflineMode}}-check{{end}}-square-o"></i></dd>
<hr/>
<dt>Run User</dt>
<dd>{{.RunUser}}</dd>
@ -26,6 +28,8 @@
<hr/>
<dt>Repository Root Path</dt>
<dd>{{.RepoRootPath}}</dd>
<dt>Script Type</dt>
<dd>{{.ScriptType}}</dd>
</dl>
</div>
</div>

View File

@ -13,7 +13,10 @@
<div class="col-md-1" style="margin: -5px;">
<a target="_blank" href="https://github.com/gogits/gogs"><i class="fa fa-github fa-2x"></i></a>
</div>
<p class="desc"></p>
<div class="col-md-5">
<p class="desc"></p>
</div>
</div>
</div>
</footer>

View File

@ -12,7 +12,7 @@
{{if .Repository.IsGoget}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}}
<!-- Stylesheets -->
{{if IsProdMode}}
{{if CdnMode}}
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">

View File

@ -3,7 +3,7 @@
<nav class="nav">
<a id="nav-logo" class="nav-item pull-left{{if .PageIsHome}} active{{end}}" href="/"><img src="/img/favicon.png" alt="Gogs Logo" id="logo"></a>
<a class="nav-item pull-left{{if .PageIsUserDashboard}} active{{end}}" href="/">Dashboard</a>
<a class="nav-item pull-left{{if .PageIsHelp}} active{{end}}" href="https://github.com/gogits/gogs/wiki">Help</a>{{if .IsSigned}}
<a class="nav-item pull-left{{if .PageIsHelp}} active{{end}}" target="_blank" href="https://github.com/gogits/gogs/wiki">Help</a>{{if .IsSigned}}
{{if .HasAccess}}<!-- <form class="nav-item pull-left{{if .PageIsNewRepo}} active{{end}}" id="nav-search-form">
<div class="input-group">
<div class="input-group-btn">
@ -33,8 +33,8 @@
</ul>
</div>
</div>
{{else}}<a id="nav-signin" class="nav-item navbar-right navbar-btn btn btn-danger" href="/user/login/">Sign In</a>
<a id="nav-signup" class="nav-item navbar-right" href="/user/sign_up/">Sign Up</a>{{end}}
{{else}}<a id="nav-signin" class="nav-item navbar-right navbar-btn btn btn-danger" href="/user/login/" rel="nofollow">Sign In</a>
<a id="nav-signup" class="nav-item navbar-right" href="/user/sign_up/" rel="nofollow">Sign Up</a>{{end}}
</nav>
</div>
</div>

View File

@ -9,18 +9,19 @@
<label class="col-md-3 control-label">Database Type: </label>
<div class="col-md-8">
<select name="database" id="install-database" class="form-control">
<option value="mysql">MySQL</option>
<option value="pgsql">PostgreSQL</option>
<option value="sqlite">SQLite3</option>
{{if .CurDbValue}}<option value="{{.CurDbValue}}">{{.CurDbValue}}</option>{{end}}
{{range .DbOptions}}
{{if not (eq $.CurDbValue .)}}<option value="{{.}}">{{.}}</option>{{end}}
{{end}}
</select>
</div>
</div>
<div class="server-sql">
<div class="server-sql {{if eq .CurDbValue "SQLite3"}}hide{{end}}">
<div class="form-group">
<label class="col-md-3 control-label">Host: </label>
<div class="col-md-8">
<input name="host" class="form-control" placeholder="Type database server host" value="{{.host}}">
<input name="host" id="database-host" class="form-control" placeholder="Type database server host" value="{{.host}}">
</div>
</div>
@ -49,7 +50,7 @@
</div>
</div>
<div class="form-group pgsql-setting hide">
<div class="form-group pgsql-setting {{if not (eq .CurDbValue "PostgreSQL")}}hide{{end}}">
<label class="col-md-3 control-label">SSL Mode: </label>
<div class="col-md-8">
<select name="ssl_mode" class="form-control">
@ -61,7 +62,7 @@
</div>
</div>
<div class="sqlite-setting hide">
<div class="sqlite-setting {{if not (eq .CurDbValue "SQLite3")}}hide{{end}}">
<div class="form-group">
<label class="col-md-3 control-label">Path: </label>

View File

@ -15,8 +15,8 @@
{{if .PublisherId}}
<div class="col-md-2 text-right">
{{if .IsPrerelease}}<span class="btn btn-warning status pre-release">Pre-Release</span>{{else}}<span class="btn btn-success status stable">Stable</span>{{end}}
<a class="tag" href="{{$.RepoLink}}/src/{{.TagName}}"><i class="fa fa-tag"></i>{{.TagName}}</a>
<a class="commit" href="{{$.RepoLink}}/src/{{.SHA1}}"><i class="fa fa-code"></i>{{ShortSha .SHA1}}</a>
<a class="tag" href="{{$.RepoLink}}/src/{{.TagName}}" rel="nofollow"><i class="fa fa-tag"></i>{{.TagName}}</a>
<a class="commit" href="{{$.RepoLink}}/src/{{.SHA1}}" rel="nofollow"><i class="fa fa-code"></i>{{ShortSha .SHA1}}</a>
</div>
<div class="col-md-10">
<h4 class="title"><a href="{{$.RepoLink}}/src/{{.TagName}}">{{.Title}}</a></h4>
@ -30,19 +30,19 @@
{{str2html .Note}}
</div>
<p class="download">
<a class="btn btn-default" href="{{$.RepoLink}}/archive/{{.TagName}}/{{$.Repository.Name}}.zip"><i class="fa fa-download"></i>Source Code (ZIP)</a>
<a class="btn btn-default" href="{{$.RepoLink}}/archive/{{.TagName}}/{{$.Repository.Name}}.zip" rel="nofollow"><i class="fa fa-download"></i>Source Code (ZIP)</a>
<!-- <a class="btn btn-default" href="{release_download_link}"><i class="fa fa-download"></i>Source Code (TAR.GZ)</a> -->
</p>
<span class="dot">&nbsp;</span>
</div>
{{else}}
<div class="col-md-2 text-right">
<a class="commit" href="{{$.RepoLink}}/src/{{.SHA1}}"><i class="fa fa-code"></i>{{ShortSha .SHA1}}</a>
<a class="commit" href="{{$.RepoLink}}/src/{{.SHA1}}" rel="nofollow"><i class="fa fa-code"></i>{{ShortSha .SHA1}}</a>
</div>
<div class="col-md-10">
<h5 class="title"><a href="{{$.RepoLink}}/src/{{.TagName}}">{{.TagName}}</a><i class="fa fa-tag"></i></h5>
<h5 class="title"><a href="{{$.RepoLink}}/src/{{.TagName}}" rel="nofollow">{{.TagName}}</a><i class="fa fa-tag"></i></h5>
<p class="download">
<a class="download-link" href="{{$.RepoLink}}/archive/{{.TagName}}/{{$.Repository.Name}}.zip"><i class="fa fa-download"></i>zip</a>
<a class="download-link" href="{{$.RepoLink}}/archive/{{.TagName}}/{{$.Repository.Name}}.zip" rel="nofollow"><i class="fa fa-download"></i>zip</a>
<!-- <a class="download-link" href="{release_download_link}"><i class="fa fa-download"></i>tar.gz</a> -->
</p>
<span class="dot">&nbsp;</span>
@ -50,30 +50,6 @@
{{end}}
</li>
{{end}}
<!-- <li class="release-item clearfix" id="release-{release_id}">
<div class="col-md-2 text-right">
<span class="btn btn-warning status pre-release">Pre-Release</span>
<a class="tag" href="{commit_link}"><i class="fa fa-tag"></i>release tag</a>
<a class="commit" href="{commit_link}"><i class="fa fa-code"></i>commit-sha</a>
</div>
<div class="col-md-10">
<h4 class="title"><a href="{release_single_link}">Release Title</a></h4>
<p class="info">
<span class="author"><img class="avatar" src="http://1.gravatar.com/avatar/f72f7454ce9d710baa506394f68f4132" alt="" width="20">&nbsp;&nbsp;
<a href="/user/fuxiaohei">fuxiaohei</a></span>
<span class="time">1 week ago</span>
<span class="ahead"><strong>0</strong> commits since this tag</span>
</p>
<div class="markdown desc">
release descriptions, support markdown content
</div>
<p class="download">
<a class="btn btn-default" href="{release_download_link}"><i class="fa fa-download"></i>Source Code (ZIP)</a>
<a class="btn btn-default" href="{release_download_link}"><i class="fa fa-download"></i>Source Code (TAR.GZ)</a>
</p>
<span class="dot">&nbsp;</span>
</div>
</li> -->
</ul>
</div>
</div>

View File

@ -33,7 +33,7 @@
<tr>
<td class="author"><img class="avatar" src="{{AvatarLink .Author.Email}}" alt=""/><a href="/user/email2user?email={{.Author.Email}}">{{.Author.Name}}</a></td>
<td class="sha"><a rel="nofollow" class="label label-success" href="/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td>
<td class="message">{{.Message}} </td>
<td class="message">{{.Summary}} </td>
<td class="date">{{TimeSince .Author.When}}</td>
</tr>
{{end}}
@ -41,8 +41,8 @@
</table>
</div>
{{if not .IsSearchPage}}<ul class="pagination" id="commits-pager">
{{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.LastPageNum}}">&laquo; Newer</a></li>{{end}}
{{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.NextPageNum}}">&raquo; Older</a></li>{{end}}
{{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.LastPageNum}}" rel="nofollow">&laquo; Newer</a></li>{{end}}
{{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.NextPageNum}}" rel="nofollow">&raquo; Older</a></li>{{end}}
</ul>{{end}}
</div>
</div>

View File

@ -10,7 +10,12 @@
</div>
<div class="panel-body">
<span class="pull-right">
commit <span class="label label-default sha">{{ShortSha .CommitId}}</span>
<ul class="list-unstyled">
{{range .Parents}}
<li>parent <a href="{{$.RepoLink}}/commit/{{.}}"><span class="label label-default sha">{{ShortSha .}}</span></a></li>
{{end}}
<li>commit <span class="label label-default sha">{{ShortSha .CommitId}}</span></li>
</ul>
</span>
<p class="author">
<img class="avatar" src="{{AvatarLink .Commit.Author.Email}}" alt=""/>

View File

@ -23,10 +23,10 @@
<button class="btn btn-default" type="button" data-toggle="tooltip" title="copy to clipboard" data-placement="top" data-init="copy" data-copy-val="val" data-copy-from="#repo-clone-ipt"><i class="fa fa-copy"></i></button>
</span>
</div>
<p class="help-block text-center">Need help cloning? Visit <a href="#">Help</a>!</p>
<p class="help-block text-center">Need help cloning? Visit <a target="_blank" href="https://help.github.com/articles/fork-a-repo">Help</a>!</p>
<hr/>
<div class="clone-zip text-center">
<a class="btn btn-success btn-lg" href="{{.RepoLink}}/archive/{{.BranchName}}/{{.Repository.Name}}.zip"><i class="fa fa-suitcase"></i>Download ZIP</a>
<a class="btn btn-success btn-lg" href="{{.RepoLink}}/archive/{{.BranchName}}/{{.Repository.Name}}.zip" rel="nofollow"><i class="fa fa-suitcase"></i>Download ZIP</a>
</div>
</div>
</div>

View File

@ -14,37 +14,38 @@
{{if not .ReadmeInSingle}}
<div class="btn-group pull-right">
<a class="btn btn-default hidden" href="#">Edit</a>
<a class="btn btn-default" href="{{.FileLink}}">Raw</a>
<a class="btn btn-default" href="{{.FileLink}}" rel="nofollow">Raw</a>
<a class="btn btn-default hidden" href="#">Blame</a>
<a class="btn btn-default hidden" href="#">History</a>
<a class="btn btn-danger hidden" href="#">Delete</a>
</div>
{{end}}
</div>
{{if not .FileIsText}}
<div class="panel-footer text-center">
{{if .IsImageFile}}
<img src="{{.FileLink}}">
{{else}}
<a href="{{.FileLink}}" class="btn btn-default">View Raw</a>
{{end}}
</div>
{{else}}
{{if .ReadmeExist}}
<div class="panel-body file-body markdown">
{{.FileContent|str2html}}
</div>
<div class="panel-body file-body file-code code-view">
{{if .IsImageFile}}
<img src="{{.FileLink}}">
{{else}}
<div class="panel-body file-body file-code code-view">
<table>
<tbody>
<tr>
<td class="lines-num"></td>
<td class="lines-code markdown"><pre class="prettyprint linenums{{if .FileExt}} lang-{{.FileExt}}{{end}}">{{.FileContent}}</pre></td>
</tr>
</tbody>
</table>
</div>
<a href="{{.FileLink}}" rel="nofollow" class="btn btn-default">View Raw</a>
{{end}}
</div>
{{else}}
{{if .ReadmeExist}}
<div class="panel-body file-body markdown">
{{.FileContent|str2html}}
</div>
{{else}}
<div class="panel-body file-body file-code code-view">
<table>
<tbody>
<tr>
<td class="lines-num"></td>
<td class="lines-code markdown"><pre class="prettyprint linenums{{if .FileExt}} lang-{{.FileExt}}{{end}}">{{.FileContent}}</pre></td>
</tr>
</tbody>
</table>
</div>
{{end}}
{{end}}
</div>

View File

@ -1,6 +1,6 @@
<div class="panel panel-default info-box">
<div class="panel-heading info-head">
<a href="/{{.Username}}/{{.Reponame}}/commit/{{.LastCommit.Id}}">{{.LastCommit.Message}}</a>
<a href="/{{.Username}}/{{.Reponame}}/commit/{{.LastCommit.Id}}" rel="nofollow">{{.LastCommit.Summary}}</a>
</div>
<div class="panel-body info-content">
<a href="/user/{{.LastCommit.Author.Name}}">{{.LastCommit.Author.Name}}</a> <span class="text-muted">{{TimeSince .LastCommit.Author.When}}</span>
@ -36,7 +36,7 @@
</span>
</td>
<td class="text">
<span class="wrap"><a rel="nofollow" href="/{{$.Username}}/{{$.Reponame}}/commit/{{$commit.Id}}">{{$commit.Message}}</a></span>
<span class="wrap"><a rel="nofollow" href="/{{$.Username}}/{{$.Reponame}}/commit/{{$commit.Id}}">{{$commit.Summary}}</a></span>
</td>
<td class="date">
<span class="wrap">{{TimeSince $commit.Committer.When}}</span>

View File

@ -11,13 +11,13 @@
<div class="profile-info">
<ul class="list-group">
{{if .Owner.Location}}
<li class="list-group-item"><i class="fa fa-thumb-tack"></i>{{.Owner.Location}}</li>
<li class="list-group-item"><i class="fa fa-thumb-tack"></i>{{.Owner.Location}}</li>
{{end}}
{{if .Owner.Email}}
<li class="list-group-item"><i class="fa fa-envelope"></i><a href="mailto:{{.Owner.Email}}">{{.Owner.Email}}</a></li>
<li class="list-group-item"><i class="fa fa-envelope"></i><a href="mailto:{{.Owner.Email}}" rel="nofollow">{{.Owner.Email}}</a></li>
{{end}}
{{if .Owner.Website}}
<li class="list-group-item"><i class="fa fa-link"></i><a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li>
<li class="list-group-item"><i class="fa fa-link"></i><a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li>
{{end}}
<li class="list-group-item"><i class="fa fa-clock-o"></i>Joined on {{DateFormat .Owner.Created "M d, Y"}}</li>
<!-- <hr> -->

View File

@ -10,7 +10,7 @@
{{end}}
{{template "base/alert" .}}
<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
<label class="col-md-4 control-label">Username: </label>
<label class="col-md-4 control-label">Username or e-mail: </label>
<div class="col-md-6">
<input name="username" class="form-control" placeholder="Type your username" value="{{.username}}" required="required">
</div>

View File

@ -1,9 +0,0 @@
command: go test -v {}
include: ^.+_test\.go$
path: ./
depth: 1
verbose: true
timeout: 1m
reload: false
html: test.html
notify: []

View File

@ -1,13 +0,0 @@
## Gogs Test
This is for developers.
## Prepare Environment
go get -u github.com/shxsun/travelexec
# start gogs server
gogs web
## Start Testing
travelexec

View File

@ -1,17 +0,0 @@
package test
import (
"net/http"
"testing"
)
func TestMain(t *testing.T) {
r, err := http.Get("http://localhost:3000/")
if err != nil {
t.Fatal(err)
}
defer r.Body.Close()
if r.StatusCode != http.StatusOK {
t.Error(r.StatusCode)
}
}