diff options
41 files changed, 230 insertions, 227 deletions
@@ -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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cfc6c14f21..6cc88515f7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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. @@ -5,7 +5,7 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language  -##### 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. diff --git a/README_ZH.md b/README_ZH.md index 6d7553a684..b827822357 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。  -##### 当前版本: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)。 diff --git a/conf/app.ini b/conf/app.ini index 25fd41091f..e7174e2251 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -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: diff --git a/doc/install_gogs_from_binary_on_ubuntu.md b/doc/install_gogs_from_binary_on_ubuntu.md index 6d004106cf..3b406b3643 100644 --- a/doc/install_gogs_from_binary_on_ubuntu.md +++ b/doc/install_gogs_from_binary_on_ubuntu.md @@ -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 diff --git a/dockerfiles/images/gogits/Dockerfile b/dockerfiles/images/gogits/Dockerfile index 25d1dd5e5c..7f1514efeb 100644 --- a/dockerfiles/images/gogits/Dockerfile +++ b/dockerfiles/images/gogits/Dockerfile @@ -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 diff --git a/dockerfiles/images/postgres/Dockerfile b/dockerfiles/images/postgres/Dockerfile index 44e82b7d88..0188dd78fb 100644 --- a/dockerfiles/images/postgres/Dockerfile +++ b/dockerfiles/images/postgres/Dockerfile @@ -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 @@ -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 diff --git a/models/publickey.go b/models/publickey.go index ed47ff209d..b80412812b 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -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") } diff --git a/models/repo.go b/models/repo.go index 2011ed7de1..5f66bca86d 100644 --- a/models/repo.go +++ b/models/repo.go @@ -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) } diff --git a/models/update.go b/models/update.go index 2f59547b72..648c45f160 100644 --- a/models/update.go +++ b/models/update.go @@ -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" + qlog "github.com/qiniu/log" + "github.com/gogits/git" + "github.com/gogits/gogs/modules/base" - qlog "github.com/qiniu/log" ) func Update(refName, oldCommitId, newCommitId, userName, repoName string, userId int64) { diff --git a/models/user.go b/models/user.go index df1eb985c2..661eff2fdd 100644 --- a/models/user.go +++ b/models/user.go @@ -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. diff --git a/modules/auth/auth.go b/modules/auth/auth.go index 350ef4fcbf..e493faefe7 100644 --- a/modules/auth/auth.go +++ b/modules/auth/auth.go @@ -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"` } diff --git a/modules/base/conf.go b/modules/base/conf.go index 04c1245774..cfc85ff51e 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -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() diff --git a/modules/base/template.go b/modules/base/template.go index 79aeeb9d77..dd98df75b1 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -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()) diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index 34144fe3d8..2d2778cb00 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -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 ( diff --git a/public/img/favicon.bak.png b/public/img/favicon.bak.png Binary files differnew file mode 100644 index 0000000000..ba9bd03756 --- /dev/null +++ b/public/img/favicon.bak.png diff --git a/public/img/favicon.png b/public/img/favicon.png Binary files differindex ba9bd03756..87282f9a78 100644 --- a/public/img/favicon.png +++ b/public/img/favicon.png diff --git a/public/js/app.js b/public/js/app.js index a5c79a3987..30e9d5d0bb 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -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"); } diff --git a/routers/admin/admin.go b/routers/admin/admin.go index d0f737e645..fddd830185 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -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 diff --git a/routers/install.go b/routers/install.go index 12182ad300..38bf896f4e 100644 --- a/routers/install.go +++ b/routers/install.go @@ -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 diff --git a/routers/repo/commit.go b/routers/repo/commit.go index 6e20a7b7f4..bc33fe4473 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -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) diff --git a/routers/user/setting.go b/routers/user/setting.go index 019044c53d..a55e617f44 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -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, } diff --git a/routers/user/user.go b/routers/user/user.go index 75314237dd..9cce4e719d 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -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") diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index d25d40275a..b2b25e90f6 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -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> diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl index 6c2da63e5d..30f068913c 100644 --- a/templates/base/footer.tmpl +++ b/templates/base/footer.tmpl @@ -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> diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 68231391c0..6794b0171e 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -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"> diff --git a/templates/base/navbar.tmpl b/templates/base/navbar.tmpl index 932cae36d4..b8cba5faa6 100644 --- a/templates/base/navbar.tmpl +++ b/templates/base/navbar.tmpl @@ -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> diff --git a/templates/install.tmpl b/templates/install.tmpl index 2ed7e569d1..eb6327d205 100644 --- a/templates/install.tmpl +++ b/templates/install.tmpl @@ -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> diff --git a/templates/release/list.tmpl b/templates/release/list.tmpl index dd37e9c1a2..11f96aa548 100644 --- a/templates/release/list.tmpl +++ b/templates/release/list.tmpl @@ -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"> </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"> </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"> - <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"> </span> - </div> - </li> --> </ul> </div> </div> diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index b14c6bc8c6..74b03074bc 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -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}}">« Newer</a></li>{{end}} - {{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.NextPageNum}}">» Older</a></li>{{end}} + {{if .LastPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.LastPageNum}}" rel="nofollow">« Newer</a></li>{{end}} + {{if .NextPageNum}}<li><a href="{{.RepoLink}}/commits/{{.BranchName}}?p={{.NextPageNum}}" rel="nofollow">» Older</a></li>{{end}} </ul>{{end}} </div> </div> diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl index 0dce405337..0b6d4f722e 100644 --- a/templates/repo/diff.tmpl +++ b/templates/repo/diff.tmpl @@ -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=""/> diff --git a/templates/repo/nav.tmpl b/templates/repo/nav.tmpl index ce9c112b8d..48fe31a619 100644 --- a/templates/repo/nav.tmpl +++ b/templates/repo/nav.tmpl @@ -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> diff --git a/templates/repo/single_file.tmpl b/templates/repo/single_file.tmpl index 9199ca91f7..95c41b7017 100644 --- a/templates/repo/single_file.tmpl +++ b/templates/repo/single_file.tmpl @@ -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> diff --git a/templates/repo/single_list.tmpl b/templates/repo/single_list.tmpl index 7b6c6e5e9c..640f7f0901 100644 --- a/templates/repo/single_list.tmpl +++ b/templates/repo/single_list.tmpl @@ -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> diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index 0319f46c2e..15d2a0bd5a 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -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> --> diff --git a/templates/user/signin.tmpl b/templates/user/signin.tmpl index 955c82f430..09ce249f7f 100644 --- a/templates/user/signin.tmpl +++ b/templates/user/signin.tmpl @@ -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> diff --git a/tests/.travel.yml b/tests/.travel.yml deleted file mode 100644 index 09a5752bfb..0000000000 --- a/tests/.travel.yml +++ /dev/null @@ -1,9 +0,0 @@ -command: go test -v {} -include: ^.+_test\.go$ -path: ./ -depth: 1 -verbose: true -timeout: 1m -reload: false -html: test.html -notify: [] diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index e51b251037..0000000000 --- a/tests/README.md +++ /dev/null @@ -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 diff --git a/tests/default_test.go b/tests/default_test.go deleted file mode 100644 index d6f3a03be6..0000000000 --- a/tests/default_test.go +++ /dev/null @@ -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) - } -} |