%d neuen Zei
diff.bin=BIN
diff.view_file=Datei anzeigen
+release.releases=Releases
+release.new_release=Neues Release
+release.draft=Entwurf
+release.prerelease=Pre-Release
+release.stable=Endversion
+release.edit=bearbeiten
+release.ahead=%d Commits zu %s seit diesem Release
+release.source_code=Quelltext
+release.tag_name=Tag-Name
+release.target=Ziel
+release.tag_helper=Wähle ein neues Tag oder erstelle ein Tag beim Veröffentlichen.
+release.release_title=Release-Titel
+release.content_with_md=Inhalt mit Markdown
+release.write=Schreiben
+release.preview=Vorschau
+release.content_placeholder=Schreibe hier etwas
+release.loading=Laden…
+release.prerelease_desc=Dies ist eine Pre-Release-Version
+release.prerelease_helper=Wir möchten darauf hinweisen, dass dieses Release nicht für den produktiven Einsatz gedacht ist.
+release.publish=Release veröffentlichen
+release.save_draft=Entwurf speichern
+release.edit_release=Release bearbeiten
+release.tag_name_already_exist=Ein Release mit diesem Tag existiert bereits.
+
[org]
org_name_holder=Name der Organisation
org_name_helper=Gute Namen von Organisationen sind kurz und einprägsam.
@@ -476,8 +500,8 @@ dashboard.delete_inactivate_accounts=inaktive Konten löschen
dashboard.delete_inactivate_accounts_success=Alle inaktiven Konten wurden erfolgreich gelöscht.
dashboard.delete_repo_archives=Alle Repository-Archive löschen
dashboard.delete_repo_archives_success=Alle Repositoriy-Archive wurden gelöscht.
-dashboard.git_gc_repos=Führe Garbage Collection auf Repositorys aus
-dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositorys erfolgreich ausgeführt.
+dashboard.git_gc_repos=Führe Garbage Collection auf Repositories aus
+dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt.
dashboard.server_uptime=Server-Uptime
dashboard.current_goroutine=Aktuelle Goroutines
dashboard.current_memory_usage=Aktuelle Speichernutzung
diff --git a/gogs.go b/gogs.go
index de76ca722..88cc03a87 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-const APP_VER = "0.5.8.1211 Beta"
+const APP_VER = "0.5.8.1212 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/models/org.go b/models/org.go
index 41611f811..5431a111c 100644
--- a/models/org.go
+++ b/models/org.go
@@ -25,8 +25,8 @@ var (
ErrLastOrgOwner = errors.New("The user to remove is the last member in owner team")
)
-// IsOrgOwner returns true if given user is in the owner team.
-func (org *User) IsOrgOwner(uid int64) bool {
+// IsOwnedBy returns true if given user is in the owner team.
+func (org *User) IsOwnedBy(uid int64) bool {
return IsOrganizationOwner(org.Id, uid)
}
@@ -170,6 +170,24 @@ func CreateOrganization(org, owner *User) (*User, error) {
return org, sess.Commit()
}
+// GetOrgByName returns organization by given name.
+func GetOrgByName(name string) (*User, error) {
+ if len(name) == 0 {
+ return nil, ErrOrgNotExist
+ }
+ u := &User{
+ LowerName: strings.ToLower(name),
+ Type: ORGANIZATION,
+ }
+ has, err := x.Get(u)
+ if err != nil {
+ return nil, err
+ } else if !has {
+ return nil, ErrOrgNotExist
+ }
+ return u, nil
+}
+
// CountOrganizations returns number of organizations.
func CountOrganizations() int64 {
count, _ := x.Where("type=1").Count(new(User))
diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go
index 41c0217a9..36e62f04f 100644
--- a/modules/auth/repo_form.go
+++ b/modules/auth/repo_form.go
@@ -21,9 +21,9 @@ type CreateRepoForm struct {
RepoName string `form:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(255)"`
+ AutoInit bool `form:"auto_init"`
Gitignore string `form:"gitignore"`
License string `form:"license"`
- InitReadme bool `form:"init_readme"`
}
func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
diff --git a/modules/middleware/org.go b/modules/middleware/org.go
index be1029899..e68725861 100644
--- a/modules/middleware/org.go
+++ b/modules/middleware/org.go
@@ -48,7 +48,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Data["Org"] = org
if ctx.IsSigned {
- ctx.Org.IsOwner = org.IsOrgOwner(ctx.User.Id)
+ ctx.Org.IsOwner = org.IsOwnedBy(ctx.User.Id)
if ctx.Org.IsOwner {
ctx.Org.IsMember = true
ctx.Org.IsAdminTeam = true
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index 8b0f0c59f..171619492 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -55,7 +55,7 @@ func ApiRepoAssignment() macaron.Handler {
ctx.Repo.Owner = u
// Organization owner team members are true owners as well.
- if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgOwner(ctx.User.Id) {
+ if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
ctx.Repo.IsTrueOwner = true
}
@@ -280,7 +280,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
ctx.Repo.Owner = u
// Organization owner team members are true owners as well.
- if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgOwner(ctx.User.Id) {
+ if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
ctx.Repo.IsTrueOwner = true
}
diff --git a/routers/api/v1/repo.go b/routers/api/v1/repo.go
index 33e3b05a4..6f2372316 100644
--- a/routers/api/v1/repo.go
+++ b/routers/api/v1/repo.go
@@ -21,6 +21,26 @@ import (
"github.com/gogits/gogs/modules/setting"
)
+// ToApiRepository converts repository to API format.
+func ToApiRepository(owner *models.User, repo *models.Repository, permission api.Permission) *api.Repository {
+ sshUrlFmt := "%s@%s:%s/%s.git"
+ if setting.SshPort != 22 {
+ sshUrlFmt = "ssh://%s@%s:%d/%s/%s.git"
+ }
+ htmlUrl := setting.AppUrl + owner.Name + "/" + repo.Name
+ return &api.Repository{
+ Id: repo.Id,
+ Owner: *ToApiUser(owner),
+ FullName: owner.Name + "/" + repo.Name,
+ Private: repo.IsPrivate,
+ Fork: repo.IsFork,
+ HtmlUrl: htmlUrl,
+ SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, owner.LowerName, repo.LowerName),
+ CloneUrl: htmlUrl + ".git",
+ Permissions: permission,
+ }
+}
+
func SearchRepos(ctx *middleware.Context) {
opt := models.SearchOption{
Keyword: path.Base(ctx.Query("q")),
@@ -44,7 +64,7 @@ func SearchRepos(ctx *middleware.Context) {
})
return
}
- if u.IsOrganization() && u.IsOrgOwner(ctx.User.Id) {
+ if u.IsOrganization() && u.IsOwnedBy(ctx.User.Id) {
opt.Private = true
}
// FIXME: how about collaborators?
@@ -75,13 +95,66 @@ func SearchRepos(ctx *middleware.Context) {
}
}
- ctx.Render.JSON(200, map[string]interface{}{
+ ctx.JSON(200, map[string]interface{}{
"ok": true,
"data": results,
})
}
-func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) {
+func createRepo(ctx *middleware.Context, owner *models.User, opt api.CreateRepoOption) {
+ repo, err := models.CreateRepository(owner, opt.Name, opt.Description,
+ opt.Gitignore, opt.License, opt.Private, false, opt.AutoInit)
+ if err != nil {
+ if err == models.ErrRepoAlreadyExist ||
+ err == models.ErrRepoNameIllegal {
+ ctx.JSON(422, &base.ApiJsonErr{err.Error(), base.DOC_URL})
+ } else {
+ log.Error(4, "CreateRepository: %v", err)
+ if repo != nil {
+ if err = models.DeleteRepository(ctx.User.Id, repo.Id, ctx.User.Name); err != nil {
+ log.Error(4, "DeleteRepository: %v", err)
+ }
+ }
+ ctx.Error(500)
+ }
+ return
+ }
+
+ ctx.JSON(200, ToApiRepository(owner, repo, api.Permission{true, true, true}))
+}
+
+// POST /user/repos
+// https://developer.github.com/v3/repos/#create
+func CreateRepo(ctx *middleware.Context, opt api.CreateRepoOption) {
+ // Shouldn't reach this condition, but just in case.
+ if ctx.User.IsOrganization() {
+ ctx.JSON(422, "not allowed creating repository for organization")
+ return
+ }
+ createRepo(ctx, ctx.User, opt)
+}
+
+// POST /orgs/:org/repos
+// https://developer.github.com/v3/repos/#create
+func CreateOrgRepo(ctx *middleware.Context, opt api.CreateRepoOption) {
+ org, err := models.GetOrgByName(ctx.Params(":org"))
+ if err != nil {
+ if err == models.ErrUserNotExist {
+ ctx.Error(404)
+ } else {
+ ctx.Error(500)
+ }
+ return
+ }
+
+ if !org.IsOwnedBy(ctx.User.Id) {
+ ctx.Error(403)
+ return
+ }
+ createRepo(ctx, org, opt)
+}
+
+func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
u, err := models.GetUserByName(ctx.Query("username"))
if err != nil {
ctx.JSON(500, map[string]interface{}{
@@ -103,17 +176,15 @@ func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) {
if form.Uid != u.Id {
org, err := models.GetUserById(form.Uid)
if err != nil {
- ctx.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
+ log.Error(4, "GetUserById: %v", err)
+ ctx.Error(500)
return
}
ctxUser = org
}
if ctx.HasError() {
- ctx.JSON(500, map[string]interface{}{
+ ctx.JSON(422, map[string]interface{}{
"ok": false,
"error": ctx.GetErrMsg(),
})
@@ -122,7 +193,7 @@ func Migrate(ctx *middleware.Context, form auth.MigrateRepoForm) {
if ctxUser.IsOrganization() {
// Check ownership of organization.
- if !ctxUser.IsOrgOwner(u.Id) {
+ if !ctxUser.IsOwnedBy(u.Id) {
ctx.JSON(403, map[string]interface{}{
"ok": false,
"error": "given user is not owner of organization",
@@ -173,29 +244,9 @@ func ListMyRepos(ctx *middleware.Context) {
return
}
- sshUrlFmt := "%s@%s:%s/%s.git"
- if setting.SshPort != 22 {
- sshUrlFmt = "ssh://%s@%s:%d/%s/%s.git"
- }
-
repos := make([]*api.Repository, numOwnRepos+len(collaRepos))
- // FIXME: make only one loop
for i := range ownRepos {
- repos[i] = &api.Repository{
- Id: ownRepos[i].Id,
- Owner: api.User{
- Id: ctx.User.Id,
- UserName: ctx.User.Name,
- AvatarUrl: string(setting.Protocol) + ctx.User.AvatarLink(),
- },
- FullName: ctx.User.Name + "/" + ownRepos[i].Name,
- Private: ownRepos[i].IsPrivate,
- Fork: ownRepos[i].IsFork,
- HtmlUrl: setting.AppUrl + ctx.User.Name + "/" + ownRepos[i].Name,
- SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, ctx.User.LowerName, ownRepos[i].LowerName),
- Permissions: api.Permission{true, true, true},
- }
- repos[i].CloneUrl = repos[i].HtmlUrl + ".git"
+ repos[i] = ToApiRepository(ctx.User, ownRepos[i], api.Permission{true, true, true})
}
for i := range collaRepos {
if err = collaRepos[i].GetOwner(); err != nil {
@@ -203,24 +254,10 @@ func ListMyRepos(ctx *middleware.Context) {
return
}
j := i + numOwnRepos
- repos[j] = &api.Repository{
- Id: collaRepos[i].Id,
- Owner: api.User{
- Id: collaRepos[i].Owner.Id,
- UserName: collaRepos[i].Owner.Name,
- AvatarUrl: string(setting.Protocol) + collaRepos[i].Owner.AvatarLink(),
- },
- FullName: collaRepos[i].Owner.Name + "/" + collaRepos[i].Name,
- Private: collaRepos[i].IsPrivate,
- Fork: collaRepos[i].IsFork,
- HtmlUrl: setting.AppUrl + collaRepos[i].Owner.Name + "/" + collaRepos[i].Name,
- SshUrl: fmt.Sprintf(sshUrlFmt, setting.RunUser, setting.Domain, collaRepos[i].Owner.LowerName, collaRepos[i].LowerName),
- Permissions: api.Permission{false, collaRepos[i].CanPush, true},
- }
- repos[j].CloneUrl = repos[j].HtmlUrl + ".git"
+ repos[j] = ToApiRepository(collaRepos[i].Owner, collaRepos[i].Repository, api.Permission{false, collaRepos[i].CanPush, true})
// FIXME: cache result to reduce DB query?
- if collaRepos[i].Owner.IsOrganization() && collaRepos[i].Owner.IsOrgOwner(ctx.User.Id) {
+ if collaRepos[i].Owner.IsOrganization() && collaRepos[i].Owner.IsOwnedBy(ctx.User.Id) {
repos[j].Permissions.Admin = true
}
}
diff --git a/routers/api/v1/repo_hooks.go b/routers/api/v1/repo_hooks.go
index 5dddbc5a3..afe18a005 100644
--- a/routers/api/v1/repo_hooks.go
+++ b/routers/api/v1/repo_hooks.go
@@ -48,15 +48,9 @@ func ListRepoHooks(ctx *middleware.Context) {
ctx.JSON(200, &apiHooks)
}
-type CreateRepoHookForm struct {
- Type string `json:"type" binding:"Required"`
- Config map[string]string `json:"config" binding:"Required"`
- Active bool `json:"active"`
-}
-
// POST /repos/:username/:reponame/hooks
// https://developer.github.com/v3/repos/hooks/#create-a-hook
-func CreateRepoHook(ctx *middleware.Context, form CreateRepoHookForm) {
+func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
if !models.IsValidHookTaskType(form.Type) {
ctx.JSON(422, &base.ApiJsonErr{"invalid hook type", base.DOC_URL})
return
@@ -124,14 +118,9 @@ func CreateRepoHook(ctx *middleware.Context, form CreateRepoHookForm) {
ctx.JSON(201, apiHook)
}
-type EditRepoHookForm struct {
- Config map[string]string `json:"config"`
- Active *bool `json:"active"`
-}
-
// PATCH /repos/:username/:reponame/hooks/:id
// https://developer.github.com/v3/repos/hooks/#edit-a-hook
-func EditRepoHook(ctx *middleware.Context, form EditRepoHookForm) {
+func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
w, err := models.GetWebhookById(ctx.ParamsInt64(":id"))
if err != nil {
ctx.JSON(500, &base.ApiJsonErr{"GetWebhookById: " + err.Error(), base.DOC_URL})
diff --git a/routers/api/v1/user.go b/routers/api/v1/user.go
index 15c423f72..e9ba615fc 100644
--- a/routers/api/v1/user.go
+++ b/routers/api/v1/user.go
@@ -12,8 +12,18 @@ import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/middleware"
+ "github.com/gogits/gogs/modules/setting"
)
+// ToApiUser converts user to API format.
+func ToApiUser(u *models.User) *api.User {
+ return &api.User{
+ Id: u.Id,
+ UserName: u.Name,
+ AvatarUrl: string(setting.Protocol) + u.AvatarLink(),
+ }
+}
+
func SearchUsers(ctx *middleware.Context) {
opt := models.SearchOption{
Keyword: ctx.Query("q"),
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 8e4ace994..70b0c05ec 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -97,14 +97,14 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
if ctxUser.IsOrganization() {
// Check ownership of organization.
- if !ctxUser.IsOrgOwner(ctx.User.Id) {
+ if !ctxUser.IsOwnedBy(ctx.User.Id) {
ctx.Error(403)
return
}
}
repo, err := models.CreateRepository(ctxUser, form.RepoName, form.Description,
- form.Gitignore, form.License, form.Private, false, form.InitReadme)
+ form.Gitignore, form.License, form.Private, false, form.AutoInit)
if err == nil {
log.Trace("Repository created: %s/%s", ctxUser.Name, repo.Name)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
@@ -174,7 +174,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
if ctxUser.IsOrganization() {
// Check ownership of organization.
- if !ctxUser.IsOrgOwner(ctx.User.Id) {
+ if !ctxUser.IsOwnedBy(ctx.User.Id) {
ctx.Error(403)
return
}
@@ -292,7 +292,7 @@ func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) {
if ctxUser.IsOrganization() {
// Check ownership of organization.
- if !ctxUser.IsOrgOwner(ctx.User.Id) {
+ if !ctxUser.IsOwnedBy(ctx.User.Id) {
ctx.Error(403)
return
}
diff --git a/routers/repo/setting.go b/routers/repo/setting.go
index 94c642b2b..aec79aa43 100644
--- a/routers/repo/setting.go
+++ b/routers/repo/setting.go
@@ -137,7 +137,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
if ctx.Repo.Owner.IsOrganization() {
- if !ctx.Repo.Owner.IsOrgOwner(ctx.User.Id) {
+ if !ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
ctx.Error(404)
return
}
diff --git a/templates/.VERSION b/templates/.VERSION
index f69ca6c4b..e5ab0b331 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.5.8.1211 Beta
\ No newline at end of file
+0.5.8.1212 Beta
\ No newline at end of file
diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl
index 5d0c9b0f1..8b60b5685 100644
--- a/templates/repo/create.tmpl
+++ b/templates/repo/create.tmpl
@@ -69,7 +69,7 @@
-
+
{{.i18n.Tr "repo.init_readme"}}