@@ -30,7 +30,7 @@ More importantly, Gogs only needs one binary to setup your own project hosting o | |||||
- User profile page. | - User profile page. | ||||
- Repository viewer. | - Repository viewer. | ||||
- Gravatar and cache support. | - Gravatar and cache support. | ||||
- Mail service(register). | |||||
- Mail service(register, issue). | |||||
- Administration panel. | - Administration panel. | ||||
- Supports MySQL, PostgreSQL and SQLite3(binary release only). | - Supports MySQL, PostgreSQL and SQLite3(binary release only). | ||||
@@ -29,7 +29,7 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依 | |||||
- 用户个人信息页面 | - 用户个人信息页面 | ||||
- 仓库浏览器 | - 仓库浏览器 | ||||
- Gravatar 以及缓存支持 | - Gravatar 以及缓存支持 | ||||
- 邮件服务(注册) | |||||
- 邮件服务(注册、Issue) | |||||
- 管理员面板 | - 管理员面板 | ||||
- 支持 MySQL、PostgreSQL 以及 SQLite3(仅限二进制版本) | - 支持 MySQL、PostgreSQL 以及 SQLite3(仅限二进制版本) | ||||
@@ -19,7 +19,7 @@ import ( | |||||
// Test that go1.2 tag above is included in builds. main.go refers to this definition. | // Test that go1.2 tag above is included in builds. main.go refers to this definition. | ||||
const go12tag = true | const go12tag = true | ||||
const APP_VER = "0.1.8.0326" | |||||
const APP_VER = "0.1.8.0326 Alpha" | |||||
func init() { | func init() { | ||||
base.AppVer = APP_VER | base.AppVer = APP_VER | ||||
@@ -235,6 +235,18 @@ func initRepoCommit(tmpPath string, sig *git.Signature) (err error) { | |||||
return nil | return nil | ||||
} | } | ||||
func createHookUpdate(hookPath, content string) error { | |||||
pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
defer pu.Close() | |||||
if _, err = pu.WriteString(content); err != nil { | |||||
return err | |||||
} | |||||
return nil | |||||
} | |||||
// InitRepository initializes README and .gitignore if needed. | // InitRepository initializes README and .gitignore if needed. | ||||
func initRepository(f string, user *User, repo *Repository, initReadme bool, repoLang, license string) error { | func initRepository(f string, user *User, repo *Repository, initReadme bool, repoLang, license string) error { | ||||
repoPath := RepoPath(user.Name, repo.Name) | repoPath := RepoPath(user.Name, repo.Name) | ||||
@@ -245,13 +257,9 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep | |||||
} | } | ||||
// hook/post-update | // hook/post-update | ||||
pu, err := os.OpenFile(filepath.Join(repoPath, "hooks", "update"), os.O_CREATE|os.O_WRONLY, 0777) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
defer pu.Close() | |||||
// TODO: Windows .bat | |||||
if _, err = pu.WriteString(fmt.Sprintf("#!/usr/bin/env bash\n%s update $1 $2 $3\n", appPath)); err != nil { | |||||
if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"), | |||||
fmt.Sprintf("#!/usr/bin/env bash\n%s update $1 $2 $3\n", | |||||
strings.Replace(appPath, "\\", "/", -1))); err != nil { | |||||
return err | return err | ||||
} | } | ||||
@@ -9,7 +9,7 @@ It is recommend to use this way | |||||
cacheDir := "./cache" | cacheDir := "./cache" | ||||
defaultImg := "./default.jpg" | defaultImg := "./default.jpg" | ||||
http.Handle("/avatar/", avatar.HttpHandler(cacheDir, defaultImg)) | |||||
http.Handle("/avatar/", avatar.CacheServer(cacheDir, defaultImg)) | |||||
*/ | */ | ||||
package avatar | package avatar | ||||
@@ -135,12 +135,12 @@ func (this *Avatar) UpdateTimeout(timeout time.Duration) error { | |||||
return err | return err | ||||
} | } | ||||
type avatarHandler struct { | |||||
type service struct { | |||||
cacheDir string | cacheDir string | ||||
altImage string | altImage string | ||||
} | } | ||||
func (this *avatarHandler) mustInt(r *http.Request, defaultValue int, keys ...string) int { | |||||
func (this *service) mustInt(r *http.Request, defaultValue int, keys ...string) int { | |||||
var v int | var v int | ||||
for _, k := range keys { | for _, k := range keys { | ||||
if _, err := fmt.Sscanf(r.FormValue(k), "%d", &v); err == nil { | if _, err := fmt.Sscanf(r.FormValue(k), "%d", &v); err == nil { | ||||
@@ -150,7 +150,7 @@ func (this *avatarHandler) mustInt(r *http.Request, defaultValue int, keys ...st | |||||
return defaultValue | return defaultValue | ||||
} | } | ||||
func (this *avatarHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||
func (this *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||
urlPath := r.URL.Path | urlPath := r.URL.Path | ||||
hash := urlPath[strings.LastIndex(urlPath, "/")+1:] | hash := urlPath[strings.LastIndex(urlPath, "/")+1:] | ||||
size := this.mustInt(r, 80, "s", "size") // default size = 80*80 | size := this.mustInt(r, 80, "s", "size") // default size = 80*80 | ||||
@@ -183,9 +183,9 @@ func (this *avatarHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||
} | } | ||||
} | } | ||||
// http.Handle("/avatar/", avatar.HttpHandler("./cache")) | |||||
func HttpHandler(cacheDir string, defaultImgPath string) http.Handler { | |||||
return &avatarHandler{ | |||||
// http.Handle("/avatar/", avatar.CacheServer("./cache")) | |||||
func CacheServer(cacheDir string, defaultImgPath string) http.Handler { | |||||
return &service{ | |||||
cacheDir: cacheDir, | cacheDir: cacheDir, | ||||
altImage: defaultImgPath, | altImage: defaultImgPath, | ||||
} | } | ||||
@@ -51,7 +51,7 @@ func TestFetchMany(t *testing.T) { | |||||
// wget http://www.artsjournal.com/artfulmanager/wp/wp-content/uploads/2013/12/200x200xmirror_cat.jpg.pagespeed.ic.GOZSv6v1_H.jpg -O default.jpg | // wget http://www.artsjournal.com/artfulmanager/wp/wp-content/uploads/2013/12/200x200xmirror_cat.jpg.pagespeed.ic.GOZSv6v1_H.jpg -O default.jpg | ||||
/* | /* | ||||
func TestHttp(t *testing.T) { | func TestHttp(t *testing.T) { | ||||
http.Handle("/", avatar.HttpHandler("./", "default.jpg")) | |||||
http.Handle("/", avatar.CacheServer("./", "default.jpg")) | |||||
http.ListenAndServe(":8001", nil) | http.ListenAndServe(":8001", nil) | ||||
} | } | ||||
*/ | */ | ||||
@@ -80,7 +80,7 @@ func ExecDir() (string, error) { | |||||
if err != nil { | if err != nil { | ||||
return "", err | return "", err | ||||
} | } | ||||
return path.Dir(p), nil | |||||
return path.Dir(strings.Replace(p, "\\", "/", -1)), nil | |||||
} | } | ||||
var logLevels = map[string]string{ | var logLevels = map[string]string{ | ||||
@@ -5,18 +5,18 @@ | |||||
package main | package main | ||||
import ( | import ( | ||||
"os" | |||||
"os/exec" | |||||
"strings" | |||||
"strconv" | |||||
"container/list" | |||||
"github.com/codegangsta/cli" | |||||
//"github.com/gogits/gogs/modules/log" | |||||
"github.com/gogits/gogs/models" | |||||
"github.com/gogits/gogs/modules/base" | |||||
"github.com/qiniu/log" | |||||
"github.com/gogits/git" | |||||
"container/list" | |||||
"os" | |||||
"os/exec" | |||||
"strconv" | |||||
"strings" | |||||
"github.com/codegangsta/cli" | |||||
//"github.com/gogits/gogs/modules/log" | |||||
"github.com/gogits/git" | |||||
"github.com/gogits/gogs/models" | |||||
"github.com/gogits/gogs/modules/base" | |||||
"github.com/qiniu/log" | |||||
) | ) | ||||
var CmdUpdate = cli.Command{ | var CmdUpdate = cli.Command{ | ||||
@@ -103,7 +103,7 @@ func runUpdate(c *cli.Context) { | |||||
// if a new branch | // if a new branch | ||||
if strings.HasPrefix(oldCommitId, "0000000") { | if strings.HasPrefix(oldCommitId, "0000000") { | ||||
l, err = ref.AllCommits() | l, err = ref.AllCommits() | ||||
} else { | } else { | ||||
l = ref.CommitsBetween(newCommit, oldCommit) | l = ref.CommitsBetween(newCommit, oldCommit) | ||||
} | } | ||||
@@ -96,8 +96,8 @@ func runWeb(*cli.Context) { | |||||
m.Get("/stars", reqSignIn, user.Stars) | m.Get("/stars", reqSignIn, user.Stars) | ||||
m.Get("/help", routers.Help) | m.Get("/help", routers.Help) | ||||
avatarCache := avatar.HttpHandler("public/img/avatar/", "public/img/avatar_default.jpg") | |||||
m.Get("/avatar/:hash", avatarCache.ServeHTTP) | |||||
avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg") | |||||
m.Get("/avatar/:hash", avt.ServeHTTP) | |||||
m.Group("/user", func(r martini.Router) { | m.Group("/user", func(r martini.Router) { | ||||
r.Any("/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn) | r.Any("/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn) | ||||