mirror of
https://github.com/gogs/gogs.git
synced 2026-02-28 09:10:57 +01:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f54bcba339 | ||
|
|
f0209ac2f6 | ||
|
|
e1dcd11051 | ||
|
|
24734a33e7 | ||
|
|
1df54ea0cd | ||
|
|
e6df2259ab | ||
|
|
96ae0129ef | ||
|
|
aaadc61ee8 | ||
|
|
44a6b63316 | ||
|
|
5f058c3f07 | ||
|
|
b116dc506b | ||
|
|
bf58f26305 | ||
|
|
601f174ea0 | ||
|
|
a34c21cde3 | ||
|
|
bb19bb601e | ||
|
|
05dbd3f7d7 | ||
|
|
dee76e4189 | ||
|
|
b615d670b3 | ||
|
|
b9bb4a62d6 | ||
|
|
61e2bff757 | ||
|
|
9713016637 | ||
|
|
5c7cb1594b | ||
|
|
3eb57370a6 | ||
|
|
ac8b1e595f | ||
|
|
31c55213ff | ||
|
|
23da90e25d | ||
|
|
60ee79363d | ||
|
|
8fa6d0d302 | ||
|
|
a534f9f9b6 | ||
|
|
aa99e805c8 | ||
|
|
0049c80cd9 | ||
|
|
ebc0943713 | ||
|
|
451aef7a1c | ||
|
|
22882d7c04 | ||
|
|
c3cde864f8 | ||
|
|
f860ddbbb7 | ||
|
|
89cc6aa430 | ||
|
|
c93731339f | ||
|
|
bab448681d | ||
|
|
de2d3e3fd8 | ||
|
|
295d251232 | ||
|
|
83f6b8e847 | ||
|
|
e38fef0009 | ||
|
|
6c3424dc3f | ||
|
|
d1f0bc48ce | ||
|
|
bb005f3f9a | ||
|
|
e6dbfd918c | ||
|
|
c2f0711db0 | ||
|
|
92153fd898 | ||
|
|
a9d2480c7f | ||
|
|
fd70d503e0 | ||
|
|
8b73c8076f | ||
|
|
971a96a962 | ||
|
|
e9838a83ce | ||
|
|
837fc9847d | ||
|
|
7e883f891a | ||
|
|
e19a69442d | ||
|
|
ebd95dd082 | ||
|
|
f7b7d008b6 | ||
|
|
b39454ca16 | ||
|
|
00943a025f | ||
|
|
600f748cb0 | ||
|
|
038b107c3d | ||
|
|
c6e08d76fd | ||
|
|
6daac151b8 | ||
|
|
e08161a302 | ||
|
|
341eafcf04 | ||
|
|
dd649eb4cc | ||
|
|
d43f5f17fd | ||
|
|
193cc3ba9a | ||
|
|
fd667ca1d8 | ||
|
|
9d40b8a83c | ||
|
|
b0169ba064 | ||
|
|
9ace35ee8b | ||
|
|
ca2cfaf71e | ||
|
|
b06f299748 | ||
|
|
beea014343 | ||
|
|
70072e2842 | ||
|
|
f0086e66ae | ||
|
|
7fe13e72d8 | ||
|
|
87f0ce793d | ||
|
|
25cf755f30 | ||
|
|
c7a8051a71 | ||
|
|
a47553b7aa | ||
|
|
d7954014a4 | ||
|
|
429345b9df | ||
|
|
eaab01fa49 | ||
|
|
4f9c5981a9 |
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -5,7 +5,7 @@ public/plugins/* linguist-vendored
|
||||
public/plugins/* linguist-vendored
|
||||
public/css/themes/* linguist-vendored
|
||||
public/css/github.min.css linguist-vendored
|
||||
public/css/semantic-2.2.9.min.css linguist-vendored
|
||||
public/css/semantic-2.2.7.min.css linguist-vendored
|
||||
public/js/libs/* linguist-vendored
|
||||
public/js/jquery-1.11.3.min.js linguist-vendored
|
||||
public/js/semantic-2.2.9.min.js linguist-vendored
|
||||
public/js/semantic-2.2.7.min.js linguist-vendored
|
||||
1
.github/ISSUE_TEMPLATE.md
vendored
1
.github/ISSUE_TEMPLATE.md
vendored
@@ -13,6 +13,7 @@ The issue will be closed without any reasons if it does not satisfy any of follo
|
||||
- Database (use `[x]`):
|
||||
- [ ] PostgreSQL
|
||||
- [ ] MySQL
|
||||
- [ ] MSSQL
|
||||
- [ ] SQLite
|
||||
- Can you reproduce the bug at https://try.gogs.io:
|
||||
- [ ] Yes (provide example URL)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
FROM aarch64/alpine:3.5
|
||||
MAINTAINER atzoum@gmail.com
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-arm64 /usr/sbin/gosu
|
||||
@@ -8,9 +7,12 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
COPY . /app/gogs/
|
||||
WORKDIR /app/gogs/
|
||||
RUN ./docker/build.sh
|
||||
COPY . /app/gogs/build
|
||||
WORKDIR /app/gogs/build
|
||||
|
||||
RUN ./docker/build-go.sh \
|
||||
&& ./docker/build.sh \
|
||||
&& ./docker/finalize.sh
|
||||
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
@@ -18,5 +20,5 @@ COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data"]
|
||||
EXPOSE 22 3000
|
||||
ENTRYPOINT ["docker/start.sh"]
|
||||
ENTRYPOINT ["/app/gogs/docker/start.sh"]
|
||||
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
|
||||
@@ -16,7 +16,7 @@ Gogs [](http
|
||||
1. **YOU MUST READ [Contributing Code](https://github.com/gogits/gogs/wiki/Contributing-Code) BEFORE STARTING TO WORK ON A PULL REQUEST**.
|
||||
2. Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) was reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
3. The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
|
||||
4. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
|
||||
4. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**, and the name you want to be credited as. Thanks!
|
||||
5. If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
|
||||
6. If your team/company is using Gogs and would like to put your logo on [our website](https://gogs.io), contact us by any means.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
CmdAdmin = cli.Command{
|
||||
Admin = cli.Command{
|
||||
Name: "admin",
|
||||
Usage: "Preform admin operations on command line",
|
||||
Description: `Allow using internal logic of Gogs without hacking into the source code
|
||||
|
||||
135
cmd/backup.go
Normal file
135
cmd/backup.go
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright 2017 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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/cae/zip"
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/urfave/cli"
|
||||
log "gopkg.in/clog.v1"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var Backup = cli.Command{
|
||||
Name: "backup",
|
||||
Usage: "Backup files and database",
|
||||
Description: `Backup dumps and compresses all related files and database into zip file,
|
||||
which can be used for migrating Gogs to another server. The output format is meant to be
|
||||
portable among all supported database engines.`,
|
||||
Action: runBackup,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary directory path"),
|
||||
stringFlag("target", "./", "Target directory path to save backup archive"),
|
||||
boolFlag("database-only", "Only dump database"),
|
||||
boolFlag("exclude-repos", "Exclude repositories"),
|
||||
},
|
||||
}
|
||||
|
||||
const _ARCHIVE_ROOT_DIR = "gogs-backup"
|
||||
|
||||
func runBackup(c *cli.Context) error {
|
||||
zip.Verbose = c.Bool("verbose")
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
}
|
||||
setting.NewContext()
|
||||
models.LoadConfigs()
|
||||
models.SetEngine()
|
||||
|
||||
tmpDir := c.String("tempdir")
|
||||
if !com.IsExist(tmpDir) {
|
||||
log.Fatal(0, "'--tempdir' does not exist: %s", tmpDir)
|
||||
}
|
||||
rootDir, err := ioutil.TempDir(tmpDir, "gogs-backup-")
|
||||
if err != nil {
|
||||
log.Fatal(0, "Fail to create backup root directory '%s': %v", rootDir, err)
|
||||
}
|
||||
log.Info("Backup root directory: %s", rootDir)
|
||||
|
||||
// Metadata
|
||||
metaFile := path.Join(rootDir, "metadata.ini")
|
||||
metadata := ini.Empty()
|
||||
metadata.Section("").Key("VERSION").SetValue("1")
|
||||
metadata.Section("").Key("DATE_TIME").SetValue(time.Now().String())
|
||||
metadata.Section("").Key("GOGS_VERSION").SetValue(setting.AppVer)
|
||||
if err = metadata.SaveTo(metaFile); err != nil {
|
||||
log.Fatal(0, "Fail to save metadata '%s': %v", metaFile, err)
|
||||
}
|
||||
|
||||
archiveName := path.Join(c.String("target"), fmt.Sprintf("gogs-backup-%d.zip", time.Now().Unix()))
|
||||
log.Info("Packing backup files to: %s", archiveName)
|
||||
|
||||
z, err := zip.Create(archiveName)
|
||||
if err != nil {
|
||||
log.Fatal(0, "Fail to create backup archive '%s': %v", archiveName, err)
|
||||
}
|
||||
if err = z.AddFile(_ARCHIVE_ROOT_DIR+"/metadata.ini", metaFile); err != nil {
|
||||
log.Fatal(0, "Fail to include 'metadata.ini': %v", err)
|
||||
}
|
||||
|
||||
// Database
|
||||
dbDir := path.Join(rootDir, "db")
|
||||
if err = models.DumpDatabase(dbDir); err != nil {
|
||||
log.Fatal(0, "Fail to dump database: %v", err)
|
||||
}
|
||||
if err = z.AddDir(_ARCHIVE_ROOT_DIR+"/db", dbDir); err != nil {
|
||||
log.Fatal(0, "Fail to include 'db': %v", err)
|
||||
}
|
||||
|
||||
// Custom files
|
||||
if !c.Bool("database-only") {
|
||||
if err = z.AddDir(_ARCHIVE_ROOT_DIR+"/custom", setting.CustomPath); err != nil {
|
||||
log.Fatal(0, "Fail to include 'custom': %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Data files
|
||||
if !c.Bool("database-only") {
|
||||
for _, dir := range []string{"attachments", "avatars"} {
|
||||
dirPath := path.Join(setting.AppDataPath, dir)
|
||||
if !com.IsDir(dirPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = z.AddDir(path.Join(_ARCHIVE_ROOT_DIR+"/data", dir), dirPath); err != nil {
|
||||
log.Fatal(0, "Fail to include 'data': %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repositories
|
||||
if !c.Bool("exclude-repos") && !c.Bool("database-only") {
|
||||
reposDump := path.Join(rootDir, "repositories.zip")
|
||||
log.Info("Dumping repositories in '%s'", setting.RepoRootPath)
|
||||
if err = zip.PackTo(setting.RepoRootPath, reposDump, true); err != nil {
|
||||
log.Fatal(0, "Fail to dump repositories: %v", err)
|
||||
}
|
||||
log.Info("Repositories dumped to: %s", reposDump)
|
||||
|
||||
if err = z.AddFile(_ARCHIVE_ROOT_DIR+"/repositories.zip", reposDump); err != nil {
|
||||
log.Fatal(0, "Fail to include 'repositories.zip': %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = z.Close(); err != nil {
|
||||
log.Fatal(0, "Fail to save backup archive '%s': %v", archiveName, err)
|
||||
}
|
||||
|
||||
os.RemoveAll(rootDir)
|
||||
log.Info("Backup succeed! Archive is located at: %s", archiveName)
|
||||
log.Shutdown()
|
||||
return nil
|
||||
}
|
||||
@@ -25,10 +25,10 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var CmdCert = cli.Command{
|
||||
var Cert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
|
||||
Action: runCert,
|
||||
Flags: []cli.Flag{
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var CmdCert = cli.Command{
|
||||
var Cert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Please use build tags "cert" to rebuild Gogs in order to have this ability`,
|
||||
|
||||
122
cmd/dump.go
122
cmd/dump.go
@@ -1,122 +0,0 @@
|
||||
// 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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/Unknwon/cae/zip"
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var CmdDump = cli.Command{
|
||||
Name: "dump",
|
||||
Usage: "Dump Gogs files and database",
|
||||
Description: `Dump compresses all related files and database into zip file.
|
||||
It can be used for backup and capture Gogs server image to send to maintainer`,
|
||||
Action: runDump,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary dir path"),
|
||||
},
|
||||
}
|
||||
|
||||
func runDump(ctx *cli.Context) error {
|
||||
if ctx.IsSet("config") {
|
||||
setting.CustomConf = ctx.String("config")
|
||||
}
|
||||
setting.NewContext()
|
||||
models.LoadConfigs()
|
||||
models.SetEngine()
|
||||
|
||||
tmpDir := ctx.String("tempdir")
|
||||
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
||||
log.Fatalf("Path does not exist: %s", tmpDir)
|
||||
}
|
||||
TmpWorkDir, err := ioutil.TempDir(tmpDir, "gogs-dump-")
|
||||
if err != nil {
|
||||
log.Fatalf("Fail to create tmp work directory: %v", err)
|
||||
}
|
||||
log.Printf("Creating tmp work dir: %s", TmpWorkDir)
|
||||
|
||||
reposDump := path.Join(TmpWorkDir, "gogs-repo.zip")
|
||||
dbDump := path.Join(TmpWorkDir, "gogs-db.sql")
|
||||
|
||||
log.Printf("Dumping local repositories...%s", setting.RepoRootPath)
|
||||
zip.Verbose = ctx.Bool("verbose")
|
||||
if err := zip.PackTo(setting.RepoRootPath, reposDump, true); err != nil {
|
||||
log.Fatalf("Fail to dump local repositories: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Dumping database...")
|
||||
if err := models.DumpDatabase(dbDump); err != nil {
|
||||
log.Fatalf("Fail to dump database: %v", err)
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("gogs-dump-%d.zip", time.Now().Unix())
|
||||
log.Printf("Packing dump files...")
|
||||
z, err := zip.Create(fileName)
|
||||
if err != nil {
|
||||
os.Remove(fileName)
|
||||
log.Fatalf("Fail to create %s: %v", fileName, err)
|
||||
}
|
||||
|
||||
if err := z.AddFile("gogs-repo.zip", reposDump); err != nil {
|
||||
log.Fatalf("Fail to include gogs-repo.zip: %v", err)
|
||||
}
|
||||
if err := z.AddFile("gogs-db.sql", dbDump); err != nil {
|
||||
log.Fatalf("Fail to include gogs-db.sql: %v", err)
|
||||
}
|
||||
customDir, err := os.Stat(setting.CustomPath)
|
||||
if err == nil && customDir.IsDir() {
|
||||
if err := z.AddDir("custom", setting.CustomPath); err != nil {
|
||||
log.Fatalf("Fail to include custom: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
||||
}
|
||||
|
||||
if err := z.AddDir("log", setting.LogRootPath); err != nil {
|
||||
log.Fatalf("Fail to include log: %v", err)
|
||||
}
|
||||
|
||||
for _, dir := range []string{"attachments", "avatars"} {
|
||||
dirPath := path.Join(setting.AppDataPath, dir)
|
||||
if !com.IsDir(dirPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := z.AddDir(path.Join("data", dir), dirPath); err != nil {
|
||||
log.Fatalf("Fail to include '%s': %v", dirPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: SSH key file.
|
||||
if err = z.Close(); err != nil {
|
||||
os.Remove(fileName)
|
||||
log.Fatalf("Fail to save %s: %v", fileName, err)
|
||||
}
|
||||
|
||||
if err := os.Chmod(fileName, 0600); err != nil {
|
||||
log.Printf("Can't change file access permissions mask to 0600: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Removing tmp work dir: %s", TmpWorkDir)
|
||||
os.RemoveAll(TmpWorkDir)
|
||||
log.Printf("Finish dumping in file %s", fileName)
|
||||
|
||||
return nil
|
||||
}
|
||||
23
cmd/hook.go
23
cmd/hook.go
@@ -27,7 +27,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
CmdHook = cli.Command{
|
||||
Hook = cli.Command{
|
||||
Name: "hook",
|
||||
Usage: "Delegate commands to corresponding Git hooks",
|
||||
Description: "All sub-commands should only be called by Git",
|
||||
@@ -100,14 +100,21 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if whitelist is enabled
|
||||
// Whitelist users can bypass require pull request check
|
||||
bypassRequirePullRequest := false
|
||||
|
||||
// Check if user is in whitelist when enabled
|
||||
userID := com.StrTo(os.Getenv(http.ENV_AUTH_USER_ID)).MustInt64()
|
||||
if protectBranch.EnableWhitelist && !models.IsUserInProtectBranchWhitelist(repoID, userID, branchName) {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected and you are not in the push whitelist", branchName), "")
|
||||
if protectBranch.EnableWhitelist {
|
||||
if !models.IsUserInProtectBranchWhitelist(repoID, userID, branchName) {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected and you are not in the push whitelist", branchName), "")
|
||||
}
|
||||
|
||||
bypassRequirePullRequest = true
|
||||
}
|
||||
|
||||
// Check if branch allows direct push
|
||||
if protectBranch.RequirePullRequest {
|
||||
if !bypassRequirePullRequest && protectBranch.RequirePullRequest {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected and commits must be merged through pull request", branchName), "")
|
||||
}
|
||||
|
||||
@@ -117,7 +124,8 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
}
|
||||
|
||||
// Check force push
|
||||
output, err := git.NewCommand("rev-list", oldCommitID, "^"+newCommitID).Run()
|
||||
output, err := git.NewCommand("rev-list", oldCommitID, "^"+newCommitID).
|
||||
RunInDir(models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME)))
|
||||
if err != nil {
|
||||
fail("Internal error", "Fail to detect force push: %v", err)
|
||||
} else if len(output) > 0 {
|
||||
@@ -131,6 +139,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
}
|
||||
|
||||
hookCmd := exec.Command(customHooksPath)
|
||||
hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
|
||||
hookCmd.Stdout = os.Stdout
|
||||
hookCmd.Stdin = buf
|
||||
hookCmd.Stderr = os.Stderr
|
||||
@@ -159,6 +168,7 @@ func runHookUpdate(c *cli.Context) error {
|
||||
}
|
||||
|
||||
hookCmd := exec.Command(customHooksPath, args...)
|
||||
hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
|
||||
hookCmd.Stdout = os.Stdout
|
||||
hookCmd.Stdin = os.Stdin
|
||||
hookCmd.Stderr = os.Stderr
|
||||
@@ -231,6 +241,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||
}
|
||||
|
||||
hookCmd := exec.Command(customHooksPath)
|
||||
hookCmd.Dir = models.RepoPath(os.Getenv(http.ENV_REPO_OWNER_NAME), os.Getenv(http.ENV_REPO_NAME))
|
||||
hookCmd.Stdout = os.Stdout
|
||||
hookCmd.Stdin = buf
|
||||
hookCmd.Stderr = os.Stderr
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
CmdImport = cli.Command{
|
||||
Import = cli.Command{
|
||||
Name: "import",
|
||||
Usage: "Import portable data as local Gogs data",
|
||||
Description: `Allow user import data from other Gogs installations to local instance
|
||||
|
||||
129
cmd/restore.go
Normal file
129
cmd/restore.go
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2017 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 cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/Unknwon/cae/zip"
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/mcuadros/go-version"
|
||||
"github.com/urfave/cli"
|
||||
log "gopkg.in/clog.v1"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var Restore = cli.Command{
|
||||
Name: "restore",
|
||||
Usage: "Restore files and database from backup",
|
||||
Description: `Restore imports all related files and database from a backup archive.
|
||||
The backup version must lower or equal to current Gogs version. You can also import
|
||||
backup from other database engines, which is useful for database migrating.
|
||||
|
||||
If corresponding files or database tables are not presented in the archive, they will
|
||||
be skipped and remian unchanged.`,
|
||||
Action: runRestore,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary directory path"),
|
||||
stringFlag("from", "", "Path to backup archive"),
|
||||
boolFlag("database-only", "Only import database"),
|
||||
boolFlag("exclude-repos", "Exclude repositories"),
|
||||
},
|
||||
}
|
||||
|
||||
func runRestore(c *cli.Context) error {
|
||||
zip.Verbose = c.Bool("verbose")
|
||||
|
||||
tmpDir := c.String("tempdir")
|
||||
if !com.IsExist(tmpDir) {
|
||||
log.Fatal(0, "'--tempdir' does not exist: %s", tmpDir)
|
||||
}
|
||||
|
||||
log.Info("Restore backup from: %s", c.String("from"))
|
||||
if err := zip.ExtractTo(c.String("from"), tmpDir); err != nil {
|
||||
log.Fatal(0, "Fail to extract backup archive: %v", err)
|
||||
}
|
||||
archivePath := path.Join(tmpDir, _ARCHIVE_ROOT_DIR)
|
||||
|
||||
// Check backup version
|
||||
metaFile := path.Join(archivePath, "metadata.ini")
|
||||
if !com.IsExist(metaFile) {
|
||||
log.Fatal(0, "File 'metadata.ini' is missing")
|
||||
}
|
||||
metadata, err := ini.Load(metaFile)
|
||||
if err != nil {
|
||||
log.Fatal(0, "Fail to load metadata '%s': %v", metaFile, err)
|
||||
}
|
||||
backupVersion := metadata.Section("").Key("GOGS_VERSION").MustString("999.0")
|
||||
if version.Compare(setting.AppVer, backupVersion, "<") {
|
||||
log.Fatal(0, "Current Gogs version is lower than backup version: %s < %s", setting.AppVer, backupVersion)
|
||||
}
|
||||
|
||||
// If config file is not present in backup, user must set this file via flag.
|
||||
// Otherwise, it's optional to set config file flag.
|
||||
configFile := path.Join(archivePath, "custom/conf/app.ini")
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
} else if !com.IsExist(configFile) {
|
||||
log.Fatal(0, "'--config' is not specified and custom config file is not found in backup")
|
||||
} else {
|
||||
setting.CustomConf = configFile
|
||||
}
|
||||
setting.NewContext()
|
||||
models.LoadConfigs()
|
||||
models.SetEngine()
|
||||
|
||||
// Database
|
||||
dbDir := path.Join(archivePath, "db")
|
||||
if err = models.ImportDatabase(dbDir); err != nil {
|
||||
log.Fatal(0, "Fail to import database: %v", err)
|
||||
}
|
||||
|
||||
// Custom files
|
||||
if !c.Bool("database-only") {
|
||||
if com.IsExist(setting.CustomPath) {
|
||||
if err = os.Rename(setting.CustomPath, setting.CustomPath+".bak"); err != nil {
|
||||
log.Fatal(0, "Fail to backup current 'custom': %v", err)
|
||||
}
|
||||
}
|
||||
if err = os.Rename(path.Join(archivePath, "custom"), setting.CustomPath); err != nil {
|
||||
log.Fatal(0, "Fail to import 'custom': %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Data files
|
||||
if !c.Bool("database-only") {
|
||||
for _, dir := range []string{"attachments", "avatars"} {
|
||||
dirPath := path.Join(setting.AppDataPath, dir)
|
||||
if com.IsExist(dirPath) {
|
||||
if err = os.Rename(dirPath, dirPath+".bak"); err != nil {
|
||||
log.Fatal(0, "Fail to backup current 'data': %v", err)
|
||||
}
|
||||
}
|
||||
if err = os.Rename(path.Join(archivePath, "data", dir), dirPath); err != nil {
|
||||
log.Fatal(0, "Fail to import 'data': %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repositories
|
||||
reposPath := path.Join(archivePath, "repositories.zip")
|
||||
if !c.Bool("exclude-repos") && !c.Bool("database-only") && com.IsExist(reposPath) {
|
||||
if err := zip.ExtractTo(reposPath, path.Dir(setting.RepoRootPath)); err != nil {
|
||||
log.Fatal(0, "Fail to extract 'repositories.zip': %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
os.RemoveAll(path.Join(tmpDir, _ARCHIVE_ROOT_DIR))
|
||||
log.Info("Restore succeed!")
|
||||
log.Shutdown()
|
||||
return nil
|
||||
}
|
||||
154
cmd/web.go
154
cmd/web.go
@@ -15,6 +15,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-macaron/binding"
|
||||
"github.com/go-macaron/cache"
|
||||
"github.com/go-macaron/captcha"
|
||||
@@ -34,9 +35,9 @@ import (
|
||||
"github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/bindata"
|
||||
"github.com/gogits/gogs/modules/context"
|
||||
"github.com/gogits/gogs/modules/form"
|
||||
"github.com/gogits/gogs/modules/mailer"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/gogits/gogs/modules/template"
|
||||
@@ -49,9 +50,9 @@ import (
|
||||
"github.com/gogits/gogs/routers/user"
|
||||
)
|
||||
|
||||
var CmdWeb = cli.Command{
|
||||
var Web = cli.Command{
|
||||
Name: "web",
|
||||
Usage: "Start Gogs web server",
|
||||
Usage: "Start web server",
|
||||
Description: `Gogs web server is the only thing you need to run,
|
||||
and it takes care of all the other things for you`,
|
||||
Action: runWeb,
|
||||
@@ -219,35 +220,35 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Get("/organizations", routers.ExploreOrganizations)
|
||||
}, ignSignIn)
|
||||
m.Combo("/install", routers.InstallInit).Get(routers.Install).
|
||||
Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost)
|
||||
Post(bindIgnErr(form.Install{}), routers.InstallPost)
|
||||
m.Get("/^:type(issues|pulls)$", reqSignIn, user.Issues)
|
||||
|
||||
// ***** START: User *****
|
||||
m.Group("/user", func() {
|
||||
m.Get("/login", user.SignIn)
|
||||
m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)
|
||||
m.Post("/login", bindIgnErr(form.SignIn{}), user.SignInPost)
|
||||
m.Get("/sign_up", user.SignUp)
|
||||
m.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
|
||||
m.Post("/sign_up", bindIgnErr(form.Register{}), user.SignUpPost)
|
||||
m.Get("/reset_password", user.ResetPasswd)
|
||||
m.Post("/reset_password", user.ResetPasswdPost)
|
||||
}, reqSignOut)
|
||||
|
||||
m.Group("/user/settings", func() {
|
||||
m.Get("", user.Settings)
|
||||
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
|
||||
m.Post("", bindIgnErr(form.UpdateProfile{}), user.SettingsPost)
|
||||
m.Combo("/avatar").Get(user.SettingsAvatar).
|
||||
Post(binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost)
|
||||
Post(binding.MultipartForm(form.Avatar{}), user.SettingsAvatarPost)
|
||||
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
|
||||
m.Combo("/email").Get(user.SettingsEmails).
|
||||
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
|
||||
Post(bindIgnErr(form.AddEmail{}), user.SettingsEmailPost)
|
||||
m.Post("/email/delete", user.DeleteEmail)
|
||||
m.Get("/password", user.SettingsPassword)
|
||||
m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
|
||||
m.Post("/password", bindIgnErr(form.ChangePassword{}), user.SettingsPasswordPost)
|
||||
m.Combo("/ssh").Get(user.SettingsSSHKeys).
|
||||
Post(bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
|
||||
Post(bindIgnErr(form.AddSSHKey{}), user.SettingsSSHKeysPost)
|
||||
m.Post("/ssh/delete", user.DeleteSSHKey)
|
||||
m.Combo("/applications").Get(user.SettingsApplications).
|
||||
Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
|
||||
Post(bindIgnErr(form.NewAccessToken{}), user.SettingsApplicationsPost)
|
||||
m.Post("/applications/delete", user.SettingsDeleteApplication)
|
||||
|
||||
m.Group("/organizations", func() {
|
||||
@@ -261,7 +262,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
})
|
||||
|
||||
m.Group("/user", func() {
|
||||
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
|
||||
// r.Get("/feeds", binding.Bind(form.Feeds{}), user.Feeds)
|
||||
m.Any("/activate", user.Activate)
|
||||
m.Any("/activate_email", user.ActivateEmail)
|
||||
m.Get("/email2user", user.Email2User)
|
||||
@@ -282,8 +283,8 @@ func runWeb(ctx *cli.Context) error {
|
||||
|
||||
m.Group("/users", func() {
|
||||
m.Get("", admin.Users)
|
||||
m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(auth.AdminCrateUserForm{}), admin.NewUserPost)
|
||||
m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost)
|
||||
m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(form.AdminCrateUser{}), admin.NewUserPost)
|
||||
m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(form.AdminEditUser{}), admin.EditUserPost)
|
||||
m.Post("/:userid/delete", admin.DeleteUser)
|
||||
})
|
||||
|
||||
@@ -298,9 +299,9 @@ func runWeb(ctx *cli.Context) error {
|
||||
|
||||
m.Group("/auths", func() {
|
||||
m.Get("", admin.Authentications)
|
||||
m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost)
|
||||
m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(form.Authentication{}), admin.NewAuthSourcePost)
|
||||
m.Combo("/:authid").Get(admin.EditAuthSource).
|
||||
Post(bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost)
|
||||
Post(bindIgnErr(form.Authentication{}), admin.EditAuthSourcePost)
|
||||
m.Post("/:authid/delete", admin.DeleteAuthSource)
|
||||
})
|
||||
|
||||
@@ -323,11 +324,10 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Get("/attachments/:uuid", func(ctx *context.Context) {
|
||||
attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid"))
|
||||
if err != nil {
|
||||
if models.IsErrAttachmentNotExist(err) {
|
||||
ctx.Error(404)
|
||||
} else {
|
||||
ctx.Handle(500, "GetAttachmentByUUID", err)
|
||||
}
|
||||
ctx.NotFoundOrServerError("GetAttachmentByUUID", models.IsErrAttachmentNotExist, err)
|
||||
return
|
||||
} else if !com.IsFile(attach.LocalPath()) {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -339,15 +339,15 @@ func runWeb(ctx *cli.Context) error {
|
||||
defer fr.Close()
|
||||
|
||||
ctx.Header().Set("Cache-Control", "public,max-age=86400")
|
||||
fmt.Println("attach.Name:", attach.Name)
|
||||
ctx.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name))
|
||||
// Fix #312. Attachments with , in their name are not handled correctly by Google Chrome.
|
||||
// We must put the name in " manually.
|
||||
if err = repo.ServeData(ctx, "\""+attach.Name+"\"", fr); err != nil {
|
||||
if err = repo.ServeData(ctx, attach.Name, fr); err != nil {
|
||||
ctx.Handle(500, "ServeData", err)
|
||||
return
|
||||
}
|
||||
})
|
||||
m.Post("/issues/attachments", repo.UploadIssueAttachment)
|
||||
m.Post("/releases/attachments", repo.UploadReleaseAttachment)
|
||||
}, ignSignIn)
|
||||
|
||||
m.Group("/:username", func() {
|
||||
@@ -365,7 +365,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Group("/org", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/create", org.Create)
|
||||
m.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost)
|
||||
m.Post("/create", bindIgnErr(form.CreateOrg{}), org.CreatePost)
|
||||
}, func(ctx *context.Context) {
|
||||
if !ctx.User.CanCreateOrganization() {
|
||||
ctx.NotFound()
|
||||
@@ -390,28 +390,28 @@ func runWeb(ctx *cli.Context) error {
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/teams/new", org.NewTeam)
|
||||
m.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
|
||||
m.Post("/teams/new", bindIgnErr(form.CreateTeam{}), org.NewTeamPost)
|
||||
m.Get("/teams/:team/edit", org.EditTeam)
|
||||
m.Post("/teams/:team/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost)
|
||||
m.Post("/teams/:team/edit", bindIgnErr(form.CreateTeam{}), org.EditTeamPost)
|
||||
m.Post("/teams/:team/delete", org.DeleteTeam)
|
||||
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(org.Settings).
|
||||
Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), org.SettingsAvatar)
|
||||
Post(bindIgnErr(form.UpdateOrgSetting{}), org.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(form.Avatar{}), org.SettingsAvatar)
|
||||
m.Post("/avatar/delete", org.SettingsDeleteAvatar)
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", org.Webhooks)
|
||||
m.Post("/delete", org.DeleteWebhook)
|
||||
m.Get("/:type/new", repo.WebhooksNew)
|
||||
m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
|
||||
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost)
|
||||
m.Post("/gogs/new", bindIgnErr(form.NewWebhook{}), repo.WebHooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(form.NewSlackHook{}), repo.SlackHooksNewPost)
|
||||
m.Post("/discord/new", bindIgnErr(form.NewDiscordHook{}), repo.DiscordHooksNewPost)
|
||||
m.Get("/:id", repo.WebHooksEdit)
|
||||
m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
||||
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
||||
m.Post("/gogs/:id", bindIgnErr(form.NewWebhook{}), repo.WebHooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(form.NewSlackHook{}), repo.SlackHooksEditPost)
|
||||
m.Post("/discord/:id", bindIgnErr(form.NewDiscordHook{}), repo.DiscordHooksEditPost)
|
||||
})
|
||||
|
||||
m.Route("/delete", "GET,POST", org.SettingsDelete)
|
||||
@@ -425,17 +425,17 @@ func runWeb(ctx *cli.Context) error {
|
||||
// ***** START: Repository *****
|
||||
m.Group("/repo", func() {
|
||||
m.Get("/create", repo.Create)
|
||||
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
|
||||
m.Post("/create", bindIgnErr(form.CreateRepo{}), repo.CreatePost)
|
||||
m.Get("/migrate", repo.Migrate)
|
||||
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
|
||||
m.Post("/migrate", bindIgnErr(form.MigrateRepo{}), repo.MigratePost)
|
||||
m.Combo("/fork/:repoid").Get(repo.Fork).
|
||||
Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
|
||||
Post(bindIgnErr(form.CreateRepo{}), repo.ForkPost)
|
||||
}, reqSignIn)
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(repo.Settings).
|
||||
Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
|
||||
Post(bindIgnErr(form.RepoSetting{}), repo.SettingsPost)
|
||||
m.Group("/collaboration", func() {
|
||||
m.Combo("").Get(repo.SettingsCollaboration).Post(repo.SettingsCollaborationPost)
|
||||
m.Post("/access_mode", repo.ChangeCollaborationAccessMode)
|
||||
@@ -445,7 +445,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Get("", repo.SettingsBranches)
|
||||
m.Post("/default_branch", repo.UpdateDefaultBranch)
|
||||
m.Combo("/*").Get(repo.SettingsProtectedBranch).
|
||||
Post(bindIgnErr(auth.ProtectBranchForm{}), repo.SettingsProtectedBranchPost)
|
||||
Post(bindIgnErr(form.ProtectBranch{}), repo.SettingsProtectedBranchPost)
|
||||
}, func(ctx *context.Context) {
|
||||
if ctx.Repo.Repository.IsMirror {
|
||||
ctx.NotFound()
|
||||
@@ -457,14 +457,14 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Get("", repo.Webhooks)
|
||||
m.Post("/delete", repo.DeleteWebhook)
|
||||
m.Get("/:type/new", repo.WebhooksNew)
|
||||
m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
|
||||
m.Post("/discord/new", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksNewPost)
|
||||
m.Post("/gogs/new", bindIgnErr(form.NewWebhook{}), repo.WebHooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(form.NewSlackHook{}), repo.SlackHooksNewPost)
|
||||
m.Post("/discord/new", bindIgnErr(form.NewDiscordHook{}), repo.DiscordHooksNewPost)
|
||||
m.Get("/:id", repo.WebHooksEdit)
|
||||
m.Post("/:id/test", repo.TestWebhook)
|
||||
m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
||||
m.Post("/discord/:id", bindIgnErr(auth.NewDiscordHookForm{}), repo.DiscordHooksEditPost)
|
||||
m.Post("/gogs/:id", bindIgnErr(form.NewWebhook{}), repo.WebHooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(form.NewSlackHook{}), repo.SlackHooksEditPost)
|
||||
m.Post("/discord/:id", bindIgnErr(form.NewDiscordHook{}), repo.DiscordHooksEditPost)
|
||||
|
||||
m.Group("/git", func() {
|
||||
m.Get("", repo.SettingsGitHooks)
|
||||
@@ -475,7 +475,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo.SettingsDeployKeys).
|
||||
Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.SettingsDeployKeysPost)
|
||||
Post(bindIgnErr(form.AddSSHKey{}), repo.SettingsDeployKeysPost)
|
||||
m.Post("/delete", repo.DeleteDeployKey)
|
||||
})
|
||||
|
||||
@@ -490,7 +490,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
||||
Post(bindIgnErr(form.NewIssue{}), repo.NewIssuePost)
|
||||
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/label", repo.UpdateIssueLabel)
|
||||
@@ -501,7 +501,7 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/title", repo.UpdateIssueTitle)
|
||||
m.Post("/content", repo.UpdateIssueContent)
|
||||
m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
||||
m.Combo("/comments").Post(bindIgnErr(form.CreateComment{}), repo.NewComment)
|
||||
})
|
||||
})
|
||||
m.Group("/comments/:id", func() {
|
||||
@@ -509,49 +509,51 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Post("/delete", repo.DeleteComment)
|
||||
})
|
||||
m.Group("/labels", func() {
|
||||
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
|
||||
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
|
||||
m.Post("/new", bindIgnErr(form.CreateLabel{}), repo.NewLabel)
|
||||
m.Post("/edit", bindIgnErr(form.CreateLabel{}), repo.UpdateLabel)
|
||||
m.Post("/delete", repo.DeleteLabel)
|
||||
m.Post("/initialize", bindIgnErr(auth.InitializeLabelsForm{}), repo.InitializeLabels)
|
||||
m.Post("/initialize", bindIgnErr(form.InitializeLabels{}), repo.InitializeLabels)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
m.Group("/milestones", func() {
|
||||
m.Combo("/new").Get(repo.NewMilestone).
|
||||
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
|
||||
Post(bindIgnErr(form.CreateMilestone{}), repo.NewMilestonePost)
|
||||
m.Get("/:id/edit", repo.EditMilestone)
|
||||
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
|
||||
m.Post("/:id/edit", bindIgnErr(form.CreateMilestone{}), repo.EditMilestonePost)
|
||||
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
||||
m.Post("/delete", repo.DeleteMilestone)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/new", repo.NewRelease)
|
||||
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
|
||||
m.Post("/new", bindIgnErr(form.NewRelease{}), repo.NewReleasePost)
|
||||
m.Post("/delete", repo.DeleteRelease)
|
||||
m.Get("/edit/*", repo.EditRelease)
|
||||
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
m.Post("/edit/*", bindIgnErr(form.EditRelease{}), repo.EditReleasePost)
|
||||
}, reqRepoWriter, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
})
|
||||
|
||||
// FIXME: Should use ctx.Repo.PullRequest to unify template, currently we have inconsistent URL
|
||||
// for PR in same repository. After select branch on the page, the URL contains redundant head user name.
|
||||
// e.g. /org1/test-repo/compare/master...org1:develop
|
||||
// which should be /org1/test-repo/compare/master...develop
|
||||
m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
|
||||
Post(bindIgnErr(form.NewIssue{}), repo.CompareAndPullRequestPost)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_edit/*").Get(repo.EditFile).
|
||||
Post(bindIgnErr(auth.EditRepoFileForm{}), repo.EditFilePost)
|
||||
Post(bindIgnErr(form.EditRepoFile{}), repo.EditFilePost)
|
||||
m.Combo("/_new/*").Get(repo.NewFile).
|
||||
Post(bindIgnErr(auth.EditRepoFileForm{}), repo.NewFilePost)
|
||||
m.Post("/_preview/*", bindIgnErr(auth.EditPreviewDiffForm{}), repo.DiffPreviewPost)
|
||||
Post(bindIgnErr(form.EditRepoFile{}), repo.NewFilePost)
|
||||
m.Post("/_preview/*", bindIgnErr(form.EditPreviewDiff{}), repo.DiffPreviewPost)
|
||||
m.Combo("/_delete/*").Get(repo.DeleteFile).
|
||||
Post(bindIgnErr(auth.DeleteRepoFileForm{}), repo.DeleteFilePost)
|
||||
Post(bindIgnErr(form.DeleteRepoFile{}), repo.DeleteFilePost)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_upload/*").Get(repo.UploadFile).
|
||||
Post(bindIgnErr(auth.UploadRepoFileForm{}), repo.UploadFilePost)
|
||||
Post(bindIgnErr(form.UploadRepoFile{}), repo.UploadFilePost)
|
||||
m.Post("/upload-file", repo.UploadFileToServer)
|
||||
m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
|
||||
m.Post("/upload-remove", bindIgnErr(form.RemoveUploadFile{}), repo.RemoveUploadFileFromServer)
|
||||
}, func(ctx *context.Context) {
|
||||
if !setting.Repository.Upload.Enabled {
|
||||
ctx.NotFound()
|
||||
@@ -575,8 +577,13 @@ func runWeb(ctx *cli.Context) error {
|
||||
m.Get("/milestones", repo.Milestones)
|
||||
}, context.RepoRef())
|
||||
|
||||
// m.Get("/branches", repo.Branches)
|
||||
m.Post("/branches/delete/*", reqSignIn, reqRepoWriter, repo.DeleteBranchPost)
|
||||
m.Group("/branches", func() {
|
||||
m.Get("", repo.Branches)
|
||||
m.Get("/all", repo.AllBranches)
|
||||
m.Post("/delete/*", reqSignIn, reqRepoWriter, repo.DeleteBranchPost)
|
||||
}, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
})
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
m.Get("/?:page", repo.Wiki)
|
||||
@@ -584,9 +591,9 @@ func runWeb(ctx *cli.Context) error {
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_new").Get(repo.NewWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
|
||||
Post(bindIgnErr(form.NewWiki{}), repo.NewWikiPost)
|
||||
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
|
||||
Post(bindIgnErr(form.NewWiki{}), repo.EditWikiPost)
|
||||
m.Post("/:page/delete", repo.DeleteWikiPagePost)
|
||||
}, reqSignIn, reqRepoWriter)
|
||||
}, repo.MustEnableWiki, context.RepoRef())
|
||||
@@ -616,18 +623,19 @@ func runWeb(ctx *cli.Context) error {
|
||||
}, ignSignIn, context.RepoAssignment(), context.RepoRef())
|
||||
|
||||
m.Group("/:username", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/:reponame", repo.Home)
|
||||
}, ignSignIn, context.RepoAssignment(true), context.RepoRef())
|
||||
m.Get("/:reponame", ignSignIn, context.RepoAssignment(true), context.RepoRef(), repo.Home)
|
||||
|
||||
m.Group("/:reponame", func() {
|
||||
m.Head("/tasks/trigger", repo.TriggerTask)
|
||||
})
|
||||
// Use the regexp to match the repository name validation
|
||||
// Use the regexp to match the repository name
|
||||
// Duplicated routes to enable different ways of accessing same set of URLs,
|
||||
// e.g. with or without ".git" suffix.
|
||||
m.Group("/:reponame([\\d\\w-_\\.]+\\.git$)", func() {
|
||||
m.Get("", ignSignIn, context.RepoAssignment(true), context.RepoRef(), repo.Home)
|
||||
m.Route("/*", "GET,POST", ignSignInAndCsrf, repo.HTTPContexter(), repo.HTTP)
|
||||
})
|
||||
m.Route("/:reponame/*", "GET,POST", ignSignInAndCsrf, repo.HTTPContexter(), repo.HTTP)
|
||||
})
|
||||
// ***** END: Repository *****
|
||||
|
||||
|
||||
29
conf/app.ini
29
conf/app.ini
@@ -114,6 +114,19 @@ FILE_MAX_SIZE = 3
|
||||
; Maximum number of files per upload
|
||||
MAX_FILES = 5
|
||||
|
||||
; Attachment settings for releases
|
||||
[release.attachment]
|
||||
; Whether attachments are enabled. Defaults to `true`
|
||||
ENABLED = true
|
||||
; Path for attachments. Defaults to `data/attachments`
|
||||
PATH = data/attachments
|
||||
; One or more allowed types, e.g. image/jpeg|image/png
|
||||
ALLOWED_TYPES = */*
|
||||
; Max size of each file. Defaults to 32MB
|
||||
MAX_SIZE = 32
|
||||
; Max number of files per upload. Defaults to 10
|
||||
MAX_FILES = 10
|
||||
|
||||
[markdown]
|
||||
; Enable hard line break extension
|
||||
ENABLE_HARD_LINE_BREAK = false
|
||||
@@ -124,6 +137,13 @@ CUSTOM_URL_SCHEMES =
|
||||
; Separate extensions with a comma. To render files w/o extension as markdown, just put a comma
|
||||
FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
||||
|
||||
[smartypants]
|
||||
ENABLED = false
|
||||
FRACTIONS = true
|
||||
DASHES = true
|
||||
LATEX_DASHES = true
|
||||
ANGLED_QUOTES = true
|
||||
|
||||
[http]
|
||||
; Value for Access-Control-Allow-Origin header, default is not to present
|
||||
ACCESS_CONTROL_ALLOW_ORIGIN =
|
||||
@@ -218,8 +238,8 @@ FROM =
|
||||
; Mailer user name and password
|
||||
USER =
|
||||
PASSWD =
|
||||
; Use text/html as alternative format of content
|
||||
ENABLE_HTML_ALTERNATIVE = false
|
||||
; Use text/plain as format of content
|
||||
USE_PLAIN_TEXT = false
|
||||
|
||||
[cache]
|
||||
; Either "memory", "redis", or "memcache", default is "memory"
|
||||
@@ -266,6 +286,7 @@ DISABLE_GRAVATAR = false
|
||||
; This value will be forced to be false in offline mode or Gravatar is disbaled.
|
||||
ENABLE_FEDERATED_AVATAR = true
|
||||
|
||||
; Attachment settings for issues
|
||||
[attachment]
|
||||
; Whether attachments are enabled. Defaults to `true`
|
||||
ENABLE = true
|
||||
@@ -273,9 +294,9 @@ ENABLE = true
|
||||
PATH = data/attachments
|
||||
; One or more allowed types, e.g. image/jpeg|image/png
|
||||
ALLOWED_TYPES = image/jpeg|image/png
|
||||
; Max size of each file. Defaults to 32MB
|
||||
; Max size of each file. Defaults to 4MB
|
||||
MAX_SIZE = 4
|
||||
; Max number of files per upload. Defaults to 10
|
||||
; Max number of files per upload. Defaults to 5
|
||||
MAX_FILES = 5
|
||||
|
||||
[time]
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
@@ -18,6 +18,8 @@ Antoine GIRARD <sapk AT sapk DOT fr>
|
||||
Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
|
||||
Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
|
||||
Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
|
||||
Bo-Yi Wu <appleboy DOT tw AT gmail DOT com>
|
||||
Breton Corentin <contact AT neodarz DOT net>
|
||||
Camille Baronnet <gogs AT camillebaronnet DOT fr>
|
||||
Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
|
||||
Cysioland
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Съдържание
|
||||
require_error=` не може да бъде празен.`
|
||||
alpha_dash_error=` трябва да e валидна буква, число или тире(-_).`
|
||||
alpha_dash_dot_error=` трябва да e валидна буква, число, тире(-_) или точка.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` трябва да е с размер %s.`
|
||||
min_size_error=` трябва да съдържа поне %s знака.`
|
||||
max_size_error=` трябва да съдържа най-много %s знака.`
|
||||
@@ -426,6 +427,7 @@ pulls=Заявки за сливане
|
||||
labels=Етикети
|
||||
milestones=Етапи
|
||||
commits=Ревизии
|
||||
git_branches=Branches
|
||||
releases=Версии
|
||||
file_raw=Директен файл
|
||||
file_history=История
|
||||
@@ -434,6 +436,13 @@ file_permalink=Постоянна връзка
|
||||
file_too_large=Този файл е твърде голям за да се визуализира
|
||||
video_not_supported_in_browser=Вашият браузър не поддържа HTML5 видео тагове.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Нов файл
|
||||
editor.upload_file=Качи файл
|
||||
editor.edit_file=Редактирай файл
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=При <strong>всички</strong> събити
|
||||
settings.event_choose=Нека избера от какво имам нужда.
|
||||
settings.event_create=Създаване
|
||||
settings.event_create_desc=Създаване на клон или маркер
|
||||
settings.event_pull_request=Заявка за сливане
|
||||
settings.event_pull_request_desc=Заявка за сливане е отворена, затворена, отворена повторно, редактирана, възложена, отменена, при модифициран етикет, при премахнат етикет или е синхронизирана.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Предаване
|
||||
settings.event_push_desc=Git предаване към хранилището
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Заявка за сливане
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Активна
|
||||
settings.active_helper=Подробности относно събитието, което е задействало куката, също ще бъдат изпратени.
|
||||
settings.add_hook_success=Новата уеб-кука е добавена успешно.
|
||||
@@ -803,7 +822,6 @@ release.releases=Версии
|
||||
release.new_release=Нова версия
|
||||
release.draft=Чернови
|
||||
release.prerelease=Предварителни
|
||||
release.stable=Стабилни
|
||||
release.edit=редактиране
|
||||
release.ahead=<strong>%d</strong> ревизии на %s след тази версия
|
||||
release.source_code=Изходен код
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Частно
|
||||
repos.watches=Наблюдавания
|
||||
repos.stars=Харесвания
|
||||
repos.issues=Задачи
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Управление на удостоверявания
|
||||
auths.new=Добави нов начин на удостоверяване
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Време за отказ при сливане
|
||||
config.git_gc_timeout=Време за отказ при GC
|
||||
|
||||
config.log_config=Конфигурация на журнал
|
||||
config.log_mode=Режим на журнал
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron задачи
|
||||
monitor.name=Име
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Системните съобщения са изтрит
|
||||
|
||||
[action]
|
||||
create_repo=създаде хранилище <a href="%s"> %s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=преименува хранилище от <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=предаде към <a href="%[1]s/src/%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Сравнение между тези %d ревизии
|
||||
transfer_repo=прехвърли хранилище <code>%s</code> към <a href="%s">%s</a>
|
||||
create_issue=`отвори задача <a href="%s/issues/%s">%s#%[2]s"</a>`
|
||||
close_issue=`затвори <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`повторно отвори <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`коментира задача <a href="%s/issues/%s">%s#%[2]s"</a>`
|
||||
create_pull_request=`създаде заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`затвори заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`повторно отвори заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`коментира задача <a href="%s/issues/%s">%s#%[2]s"</a>`
|
||||
merge_pull_request=`обедини заявка за сливане <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=прехвърли хранилище <code>%s</code> към <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=предаде маркер <a href="%s/src/%s">%[2]s</a> към <a href="%[1]s">[3]s</a>
|
||||
compare_commits=Сравнение между тези %d ревизии
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=преди
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Obsah
|
||||
require_error=` nemůže být prázdný.`
|
||||
alpha_dash_error=` musí být pouze písmena, číslice či znaky - a _ .`
|
||||
alpha_dash_dot_error=` musí být pouze písmena, číslice, tečka či znaky - a _ .`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` musí být minimálně velikosti %s.`
|
||||
min_size_error=` musí obsahovat nejméně %s znaků.`
|
||||
max_size_error=` musí obsahovat maximálně %s znaků.`
|
||||
@@ -426,6 +427,7 @@ pulls=Požadavky na natažení
|
||||
labels=Štítky
|
||||
milestones=Mezníky
|
||||
commits=Revize
|
||||
git_branches=Branches
|
||||
releases=Vydání
|
||||
file_raw=Surový
|
||||
file_history=Historie
|
||||
@@ -434,6 +436,13 @@ file_permalink=Trvalý odkaz
|
||||
file_too_large=Tento soubor je příliš velký pro zobrazení
|
||||
video_not_supported_in_browser=Váš prohlížeč nepodporuje tag pro HTML5 video.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Nový soubor
|
||||
editor.upload_file=Nahrát soubor
|
||||
editor.edit_file=Upravit soubor
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Potřebuji <strong>vše</strong>.
|
||||
settings.event_choose=Nech mne vybrat, co potřebuji.
|
||||
settings.event_create=Vytvořit
|
||||
settings.event_create_desc=Větev nebo značka byla vytvořena
|
||||
settings.event_pull_request=Požadavek na stažení
|
||||
settings.event_pull_request_desc=Pull request byl otevřen, uzavřen, znovu-otevřen, upraven, přiřazen, zrušeno přiřazení, popis upraven, smazán nebo synchronizován.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Nahrát
|
||||
settings.event_push_desc=Nahrání pomocí Gitu do repositáře
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Požadavek na stažení
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktivní
|
||||
settings.active_helper=Podrobnosti vztahující se k události, která spustila háček, budou doručeny taktéž.
|
||||
settings.add_hook_success=Nový webový háček byl přidán.
|
||||
@@ -803,7 +822,6 @@ release.releases=Vydání
|
||||
release.new_release=Nové vydání
|
||||
release.draft=Koncept
|
||||
release.prerelease=Předběžná verze
|
||||
release.stable=Stabilní
|
||||
release.edit=upravit
|
||||
release.ahead=<strong>%d</strong> revizí do větve %s od tohoto vydání
|
||||
release.source_code=Zdrojový kód
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Soukromý
|
||||
repos.watches=Sledovače
|
||||
repos.stars=Oblíbení
|
||||
repos.issues=Úkoly
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Panel správy způsobů ověřování
|
||||
auths.new=Přidat nový zdroj
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Časový limit operace stažení
|
||||
config.git_gc_timeout=Časový limit operace GC
|
||||
|
||||
config.log_config=Nastavení logů
|
||||
config.log_mode=Způsob logování
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Naplánované úlohy
|
||||
monitor.name=Název
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Systémová upozornění byla úspěšně smazána.
|
||||
|
||||
[action]
|
||||
create_repo=vytvořil repositář <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=přejmenoval repositář z <code>%[1]s</code> na <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=odeslal do <a href="%[1]s/src/%[2]s">%[3]s</a> v <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Zobrazit porovnání pro tyto %d revize
|
||||
transfer_repo=předal repositář <code>%s</code> uživateli/organizaci <a href="%s">%s</a>
|
||||
create_issue=`vytvořil úkol <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`uzavřel úkol <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`znovuotevřel úkol <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`přidal komentář k úkolu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`vytvořil požadavek na stažení <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`zavřel požadavek na stažení <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`znovuotevřel požadavek na stažení <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`přidal komentář k úkolu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`sloučil požadavek na stažení <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=předal repositář <code>%s</code> uživateli/organizaci <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=nahrál značku <a href="%s/src/%s">%[2]s</a> do <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Zobrazit porovnání pro tyto %d revize
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=před
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Inhalt
|
||||
require_error=` darf nicht leer sein.`
|
||||
alpha_dash_error=` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
|
||||
alpha_dash_dot_error=` kann ausschließlich alphanumerische Zeichen und ".-_" enthalten.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` muss die Größe %s haben.`
|
||||
min_size_error=` muss mindestens %s Zeichen enthalten.`
|
||||
max_size_error=` darf höchstens %s Zeichen enthalten.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull-Requests
|
||||
labels=Label
|
||||
milestones=Meilensteine
|
||||
commits=Commits
|
||||
git_branches=Branches
|
||||
releases=Releases
|
||||
file_raw=Originalformat
|
||||
file_history=Verlauf
|
||||
@@ -434,6 +436,13 @@ file_permalink=Permalink
|
||||
file_too_large=Diese Datei ist zu groß zum Anzeigen
|
||||
video_not_supported_in_browser=Ihr Browser unterstützt HTML5 Video-Tags nicht.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Neue Datei
|
||||
editor.upload_file=Datei hochladen
|
||||
editor.edit_file=Datei bearbeiten
|
||||
@@ -654,8 +663,8 @@ settings.protect_this_branch=Diesen Branch schützen
|
||||
settings.protect_this_branch_desc=Verhindere forcierte Pushes sowie Löschungen.
|
||||
settings.protect_require_pull_request=Verlange Pull-Request an Stelle von direkten Pushes
|
||||
settings.protect_require_pull_request_desc=Aktivieren Sie diese Option, um direktes Pushen in diesen Branch zu verhindern. Commits müssen in einen anderen, ungeschützten Branch gepusht werden und dann per Pull-Request in diesen Branch überführt werden.
|
||||
settings.protect_whitelist_committers=Fügt die Benutzer zu Whitelist hinzu, die in diesen Branch pushen dürfen
|
||||
settings.protect_whitelist_committers_desc=Benutzer oder Teams zur Whitelist hinzufügen.
|
||||
settings.protect_whitelist_committers=Hinzufügen von Benutzern oder Teams zur Whitelist, die in diesen Branch pushen dürfen
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Benutzer, die in diesen Branch pushen können
|
||||
settings.protect_whitelist_search_users=Benutzer suchen
|
||||
settings.protect_whitelist_teams=Teams, deren Mitglieder in diesen Branch pushen können
|
||||
@@ -688,7 +697,7 @@ settings.tracker_issue_style.alphanumeric=Alphanumerisch
|
||||
settings.tracker_url_format_desc=Sie können die Platzhalter <code>{user} {repo} {index}</code> für den Benutzernamen, den Namen des Repositories und die Issue-Nummer verwenden.
|
||||
settings.pulls_desc=Pull-Requests aktivieren, um öffentliche Mitwirkung zu ermöglichen
|
||||
settings.danger_zone=Gefahrenzone
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
settings.cannot_fork_to_same_owner=Besitzer kann das Repository nicht forken.
|
||||
settings.new_owner_has_same_repo=Der neue Eigentümer hat bereits ein Repository mit dem gleichen Namen. Bitte wählen Sie einen anderen Namen.
|
||||
settings.convert=In ein normales Repository umwandeln
|
||||
settings.convert_desc=Dieser Mirror kann in ein normales Repository umgewandelt werden. Dies kann nicht rückgängig gemacht werden.
|
||||
@@ -745,7 +754,7 @@ settings.add_webhook_desc=Gogs sendet einen <code>POST</code>-Request an die unt
|
||||
settings.payload_url=Payload URL
|
||||
settings.content_type=Inhaltstyp
|
||||
settings.secret=Secret
|
||||
settings.secret_desc=Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.secret_desc=Das Secret wird im <code>X-Gogs-Signature</code> Header als hexadezimalem SHA256 HMAC Stempel der Nutzlast.
|
||||
settings.slack_username=Benutzername
|
||||
settings.slack_icon_url=Icon URL
|
||||
settings.slack_color=Farbe
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Ich brauche <strong>alles</strong>.
|
||||
settings.event_choose=Lass mich auswählen, was ich brauche.
|
||||
settings.event_create=Erstellen
|
||||
settings.event_create_desc=Branch/Tag erstellt
|
||||
settings.event_pull_request=Pull-Request
|
||||
settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht oder synchronisiert.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push auf ein Repository
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull-Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktiv
|
||||
settings.active_helper=Details über das auslösende Ereignis des Webhooks werden ebenfalls mit gesendet
|
||||
settings.add_hook_success=Webhook hinzugefügt
|
||||
@@ -803,7 +822,6 @@ release.releases=Releases
|
||||
release.new_release=Neues Release
|
||||
release.draft=Entwurf
|
||||
release.prerelease=Pre-Release
|
||||
release.stable=Stabil
|
||||
release.edit=bearbeiten
|
||||
release.ahead=<strong>%d</strong> Commits zu %s seit diesem Release
|
||||
release.source_code=Quelltext
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privat
|
||||
repos.watches=Beobachtungen
|
||||
repos.stars=Favoriten
|
||||
repos.issues=Issues
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Authentifizierung
|
||||
auths.new=Neue Quelle hinzufügen
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Zeitlimit für Pull
|
||||
config.git_gc_timeout=Zeitlimit für GC
|
||||
|
||||
config.log_config=Konfiguration des Loggings
|
||||
config.log_mode=Log-Modus
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron-Tasks
|
||||
monitor.name=Name
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Systemmitteilungen wurden erfolgreich gelöscht.
|
||||
|
||||
[action]
|
||||
create_repo=hat das Repository <a href="%s">%s</a> erstellt
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=hat das Repository von <code>%[1]s</code> zu <a href="%[2]s">%[3]s</a> umbenannt
|
||||
commit_repo=hat auf <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a> gepusht
|
||||
compare_commits=Zeige Vergleich für diese %d Commits
|
||||
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="%s">%s</a>
|
||||
create_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> geöffnet`
|
||||
close_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> geschlossen`
|
||||
reopen_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> wieder geöffnet`
|
||||
comment_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> kommentiert`
|
||||
create_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> erstellt`
|
||||
close_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> geschlossen`
|
||||
reopen_pull_request=`hat den Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> wieder geöffnet`
|
||||
comment_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> kommentiert`
|
||||
merge_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> zuammengeführt`
|
||||
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=hat Tag <a href="%s/src/%s">%[2]s</a> auf <a href="%[1]s">%[3]s</a> gepusht
|
||||
compare_commits=Zeige Vergleich für diese %d Commits
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=vor
|
||||
|
||||
@@ -201,6 +201,7 @@ Content = Content
|
||||
require_error = ` cannot be empty.`
|
||||
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.`
|
||||
alpha_dash_dot_error = ` must be valid alpha or numeric or dash(-_) or dot characters.`
|
||||
alpha_dash_dot_slash_error = ` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error = ` must be size %s.`
|
||||
min_size_error = ` must contain at least %s characters.`
|
||||
max_size_error = ` must contain at most %s characters.`
|
||||
@@ -426,6 +427,7 @@ pulls = Pull Requests
|
||||
labels = Labels
|
||||
milestones = Milestones
|
||||
commits = Commits
|
||||
git_branches = Branches
|
||||
releases = Releases
|
||||
file_raw = Raw
|
||||
file_history = History
|
||||
@@ -434,6 +436,13 @@ file_permalink = Permalink
|
||||
file_too_large = This file is too large to be shown
|
||||
video_not_supported_in_browser = Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview = Overview
|
||||
branches.active_branches = Active Branches
|
||||
branches.stale_branches = Stale Branches
|
||||
branches.all = All Branches
|
||||
branches.updated_by = Updated %[1]s by %[2]s
|
||||
branches.change_default_branch = Change Default Branch
|
||||
|
||||
editor.new_file = New file
|
||||
editor.upload_file = Upload file
|
||||
editor.edit_file = Edit file
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc = Disable force pushes and prevent from deleti
|
||||
settings.protect_require_pull_request = Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc = Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers = Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc = Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc = Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users = Users who can push to this branch
|
||||
settings.protect_whitelist_search_users = Search users
|
||||
settings.protect_whitelist_teams = Teams for which members of them can push to this branch
|
||||
@@ -754,11 +763,21 @@ settings.event_push_only = Just the <code>push</code> event.
|
||||
settings.event_send_everything = I need <strong>everything</strong>.
|
||||
settings.event_choose = Let me choose what I need.
|
||||
settings.event_create = Create
|
||||
settings.event_create_desc = Branch, or tag created
|
||||
settings.event_pull_request = Pull Request
|
||||
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
|
||||
settings.event_create_desc = Branch or tag created
|
||||
settings.event_delete = Delete
|
||||
settings.event_delete_desc = Branch or tag deleted
|
||||
settings.event_fork = Fork
|
||||
settings.event_fork_desc = Repository forked
|
||||
settings.event_push = Push
|
||||
settings.event_push_desc = Git push to a repository
|
||||
settings.event_issues = Issues
|
||||
settings.event_issues_desc = Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment = Issue Comment
|
||||
settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request = Pull Request
|
||||
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release = Release
|
||||
settings.event_release_desc = Release published in a repository.
|
||||
settings.active = Active
|
||||
settings.active_helper = Details regarding the event which triggered the hook will be delivered as well.
|
||||
settings.add_hook_success = New webhook has been added.
|
||||
@@ -803,7 +822,6 @@ release.releases = Releases
|
||||
release.new_release = New Release
|
||||
release.draft = Draft
|
||||
release.prerelease = Pre-Release
|
||||
release.stable = Stable
|
||||
release.edit = edit
|
||||
release.ahead = <strong>%d</strong> commits to %s since this release
|
||||
release.source_code = Source Code
|
||||
@@ -1019,6 +1037,7 @@ repos.private = Private
|
||||
repos.watches = Watches
|
||||
repos.stars = Stars
|
||||
repos.issues = Issues
|
||||
repos.size = Size
|
||||
|
||||
auths.auth_manage_panel = Authentication Manage Panel
|
||||
auths.new = Add New Source
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout = Pull Operation Timeout
|
||||
config.git_gc_timeout = GC Operation Timeout
|
||||
|
||||
config.log_config = Log Configuration
|
||||
config.log_mode = Log Mode
|
||||
config.log_mode = Mode
|
||||
config.log_options = Options
|
||||
|
||||
monitor.cron = Cron Tasks
|
||||
monitor.name = Name
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success = System notices have been deleted successfully.
|
||||
|
||||
[action]
|
||||
create_repo = created repository <a href="%s">%s</a>
|
||||
fork_repo = forked a repository to <a href="%s">%s</a>
|
||||
rename_repo = renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a>
|
||||
commit_repo = pushed to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
compare_commits = View comparison for these %d commits
|
||||
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue = `closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue = `reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request = `created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request = `closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request = `reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request = `merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
create_branch = created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch = deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag = pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
|
||||
compare_commits = View comparison for these %d commits
|
||||
delete_tag = deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago = ago
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Contenido
|
||||
require_error=` no puede estar vacío.`
|
||||
alpha_dash_error=` los caracteres deben ser Alfanumericos o dash(-_).`
|
||||
alpha_dash_dot_error=` debe ser un caracter alfanumérivo válido, un guión alto o bajo (-_) o un signo de puntuación.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` debe ser de tamaño %s.`
|
||||
min_size_error=` debe contener al menos %s caracteres.`
|
||||
max_size_error=` debe contener como máximo %s caracteres.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull Requests
|
||||
labels=Etiquetas
|
||||
milestones=Milestones
|
||||
commits=Commits
|
||||
git_branches=Branches
|
||||
releases=Releases
|
||||
file_raw=Raw
|
||||
file_history=Histórico
|
||||
@@ -434,6 +436,13 @@ file_permalink=Permalink
|
||||
file_too_large=Este archivo es demasiado grande para ser mostrado
|
||||
video_not_supported_in_browser=Su navegador no soporta el tag video de HTML5.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Nuevo archivo
|
||||
editor.upload_file=Subir archivo
|
||||
editor.edit_file=Editar archivo
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Desactivar force pushes y evite la eliminació
|
||||
settings.protect_require_pull_request=Requiere una solicitud pull, en lugar de un push directo
|
||||
settings.protect_require_pull_request_desc=Active esta opción para deshabilitar un push directo a esta rama. Los commits tienen que ser empujados a otra rama no protegida y fusionados a esta rama a través de la solicitud pull.
|
||||
settings.protect_whitelist_committers=Lista blanca de quienes pueden empujar a esta rama
|
||||
settings.protect_whitelist_committers_desc=Añadir personas o equipos a la lista blanca de empuje directo a esta rama.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Necesito <strong>todo</strong>.
|
||||
settings.event_choose=Déjeme elegir lo que necesito.
|
||||
settings.event_create=Crear
|
||||
settings.event_create_desc=Rama o etiqueta creada
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request, abierta, cerrada, reabierta, editada, asignada, desasignada, con etiqueta actualizada, con etiqueta eliminada, o sincronizada.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push a un repositorio
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Activo
|
||||
settings.active_helper=Enviaremos detalles del evento cuando este hook se dispare.
|
||||
settings.add_hook_success=Se ha añadido un nuevo webhook.
|
||||
@@ -803,7 +822,6 @@ release.releases=Releases
|
||||
release.new_release=Nueva Release
|
||||
release.draft=Borrador
|
||||
release.prerelease=Pre-Release
|
||||
release.stable=Estable
|
||||
release.edit=editar
|
||||
release.ahead=<strong>%d</strong> commits en %s desde esta release
|
||||
release.source_code=Código Fuente
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privado
|
||||
repos.watches=Vigilantes
|
||||
repos.stars=Estrellas
|
||||
repos.issues=Incidencias
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Panel de administración de autenticación
|
||||
auths.new=Añadir nuevo origen
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Tiempo de espera de operación de pull
|
||||
config.git_gc_timeout=Tiempo de espera de operación de GC
|
||||
|
||||
config.log_config=Configuración del Log
|
||||
config.log_mode=Modo del Log
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Tareas de Cron
|
||||
monitor.name=Nombre
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Las notificaciones del sistema han sido eliminadas satisf
|
||||
|
||||
[action]
|
||||
create_repo=creó el repositorio <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=repositorio renombrado de <code>%[1]s</code> a <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=hizo push a <a href="%[1]s/src/%[2]s">%[3]s</a> en <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Ver comparación de estos %d commits
|
||||
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>
|
||||
create_issue=`incidencia abierta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`cerró la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reabrió la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`creado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`cerró el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reabrió el pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=hizo push del tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Ver comparación de estos %d commits
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=hace
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Sisältö
|
||||
require_error=` ei voi olla tyhjä.`
|
||||
alpha_dash_error=` täytyy olla kirjaimia tai numeroita tai väliviiva(-_) merkkejä.`
|
||||
alpha_dash_dot_error=` täytyy olla kirjaimia tai numeroita tai väliviiva(-_) tai piste merkkejä.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` täytyy olla kokoa %s.`
|
||||
min_size_error=` täytyy sisältää vähintään %s merkkiä.`
|
||||
max_size_error=` täytyy sisältää enintään %s merkkiä.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull-pyynnöt
|
||||
labels=Tunnisteet
|
||||
milestones=Merkkipaalut
|
||||
commits=Commitit
|
||||
git_branches=Branches
|
||||
releases=Julkaisut
|
||||
file_raw=Raaka
|
||||
file_history=Historia
|
||||
@@ -434,6 +436,13 @@ file_permalink=Pysyvä linkki
|
||||
file_too_large=Tämä tiedosto on liian suuri näytettäväksi
|
||||
video_not_supported_in_browser=Selaimesi ei tue HTML5 video-tagia.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Uusi tiedosto
|
||||
editor.upload_file=Liitä tiedosto
|
||||
editor.edit_file=Muokkaa tiedostoa
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Kiellä pakoteut push-operaatiot ja estä pois
|
||||
settings.protect_require_pull_request=Vaadi pull-pyyntö suoran push-operaation sijaan
|
||||
settings.protect_require_pull_request_desc=Estä suorat push-operaatiot tähän haaraan. Commitit täytyy pushata ei-suojattuun haaraan ja yhdistää tähän haaraan pull-pyynnön kautta.
|
||||
settings.protect_whitelist_committers=Lista sallituista, jotka voivat pushata tähän haaraan
|
||||
settings.protect_whitelist_committers_desc=Lisää ihmisiä tai tiimejä sallittujen listaan, jotka voivat pushata suoraan tähän haaraan.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Tarvitsen <strong>kaiken</strong>.
|
||||
settings.event_choose=Haluan valita, mitä tarvitsen.
|
||||
settings.event_create=Luo
|
||||
settings.event_create_desc=Branch, tai tagi luotu
|
||||
settings.event_pull_request=Pull-pyyntö
|
||||
settings.event_pull_request_desc=Pull-pyyntö avattu, suljettu, uudelleenavattu, muokattu, annettu, anto vedottu, tarra päivitetty, tarra poistettu tai synkronoitu.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push repoon
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull-pyyntö
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktiivinen
|
||||
settings.active_helper=Yksityiskohdat koskien tapahtumaa joka laukaisi koukun toimitetaan myös.
|
||||
settings.add_hook_success=Uusi webkoukku on lisätty.
|
||||
@@ -803,7 +822,6 @@ release.releases=Julkaisut
|
||||
release.new_release=Uusi julkaisu
|
||||
release.draft=Työversio
|
||||
release.prerelease=Esiversio
|
||||
release.stable=Vakaa
|
||||
release.edit=muokkaa
|
||||
release.ahead=<strong>%d</strong> committia kohteeseen %s version jälkeen
|
||||
release.source_code=Lähdekoodi
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Yksityinen
|
||||
repos.watches=Tarkkailijat
|
||||
repos.stars=Äänet
|
||||
repos.issues=Ongelmat
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Todennus hallintapaneeli
|
||||
auths.new=Lisää uusi lähde
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Pull-operaatio aikakatkaistiin
|
||||
config.git_gc_timeout=Roskienkeruu aikakatkaistiin
|
||||
|
||||
config.log_config=Loki asetukset
|
||||
config.log_mode=Loki tila
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron tehtävät
|
||||
monitor.name=Nimi
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Järjestelmän ilmoitukset on poistettu onnistuneesti.
|
||||
|
||||
[action]
|
||||
create_repo=luotu repo <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=uudelleennimetty repo <code>%[1]s</code> nimelle <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=pushattu kohteeseen <a href="%[1]s/src/%[2]s">%[3]s</a> paikassa <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Näytä vertailu näille %d commiteille
|
||||
transfer_repo=siirretty repo <code>%s</code> kohteeseen <a href="%s">%s</a>
|
||||
create_issue=`avasi ongelman <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`sulki ongelman <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`avasi uudelleen ongelman <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`kommentoi ongelmaa <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`luotu pull-pyyntö <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`sulki pull-pyynnön <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`avasi uudelleen pull-pyynnön <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`kommentoi ongelmaa <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`yhdistetty pull-pyyntö <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=siirretty repo <code>%s</code> kohteeseen <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=pushattu tagi <a href="%s/src/%s">%[2]s</a> kohteeseen <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Näytä vertailu näille %d commiteille
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=sitten
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Contenu
|
||||
require_error=` ne peut pas être vide.`
|
||||
alpha_dash_error=` doivent être des caractères alpha, numériques ou tirets (-_) valides.`
|
||||
alpha_dash_dot_error=` doivent être des caractères alpha, numériques, tirets (-_) valides ou des points.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` doit être à la taille de %s.`
|
||||
min_size_error=` %s caractères minimum `
|
||||
max_size_error=` %s caractères maximum `
|
||||
@@ -399,7 +400,7 @@ migrate.failed=Echec de migration: %v
|
||||
mirror_from=miroir de
|
||||
forked_from=forké depuis
|
||||
copy_link=Copier
|
||||
copy_link_success=Copié!
|
||||
copy_link_success=Copié !
|
||||
copy_link_error=Appuyez sur ⌘-C ou Ctrl-C pour copier
|
||||
copied=Copié
|
||||
unwatch=Ne plus suivre
|
||||
@@ -423,9 +424,10 @@ branches=Branches
|
||||
tags=Tags
|
||||
issues=Tickets
|
||||
pulls=Pull Requests
|
||||
labels=Etiquettes
|
||||
labels=Étiquettes
|
||||
milestones=Jalons
|
||||
commits=Commits
|
||||
git_branches=Branches
|
||||
releases=Publications
|
||||
file_raw=Raw
|
||||
file_history=Historique
|
||||
@@ -434,6 +436,13 @@ file_permalink=Lien permanent
|
||||
file_too_large=Ce fichier est trop gros pour être afficher
|
||||
video_not_supported_in_browser=Votre navigateur ne supporte pas la balise video HTML5.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Nouveau fichier
|
||||
editor.upload_file=Téléverser un fichier
|
||||
editor.edit_file=Modifier fichier
|
||||
@@ -484,7 +493,7 @@ commits.older=Précédemment
|
||||
commits.newer=Récemment
|
||||
|
||||
issues.new=Nouveau ticket
|
||||
issues.new.labels=Etiquettes
|
||||
issues.new.labels=Étiquettes
|
||||
issues.new.no_label=Pas d'étiquette
|
||||
issues.new.clear_labels=Effacer les étiquettes
|
||||
issues.new.milestone=Jalon
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Interdire les push forcés et empêcher la sup
|
||||
settings.protect_require_pull_request=Exiger une requête de fusion plutôt qu'un push immédiat
|
||||
settings.protect_require_pull_request_desc=Activez cette option pour empêcher la publication immédiate vers cette branche. Les commits devront être publiés vers une autre branche (non protégée) et fusionnée dans cette branche avec une requête de fusion.
|
||||
settings.protect_whitelist_committers=Liste blanche de personnes pouvant publier sur cette branche
|
||||
settings.protect_whitelist_committers_desc=Ajouter des personnes ou des équipes à la liste blanche de publication directe vers cette branche.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Utilisateurs qui peuvent pousser sur cette branche
|
||||
settings.protect_whitelist_search_users=Rechercher des utilisateurs
|
||||
settings.protect_whitelist_teams=Les équipes pour lesquelles les membres peuvent pousser sur cette branche
|
||||
@@ -688,7 +697,7 @@ settings.tracker_issue_style.alphanumeric=Alphanumérique
|
||||
settings.tracker_url_format_desc=Vous pouvez utiliser l'espace réservé <code>{user} {repo} {index}</code> pour le nom d'utilisateur, le nom du dépôt et le numéro de bug.
|
||||
settings.pulls_desc=Activer les pull requests pour accepter les contributions publiques
|
||||
settings.danger_zone=Zone de danger
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
settings.cannot_fork_to_same_owner=Vous ne pouvez par créer un fork d'un dépot à son propriétaire actuel.
|
||||
settings.new_owner_has_same_repo=Le nouveau propriétaire a déjà un dépôt nommé ainsi.
|
||||
settings.convert=Convertir en dépôt ordinaire
|
||||
settings.convert_desc=Vous pouvez convertir ce miroir en dépôt ordinaire. Cela ne peut pas être inversée.
|
||||
@@ -745,7 +754,7 @@ settings.add_webhook_desc=Une requête <code>POST</code> sera transmise vers l'U
|
||||
settings.payload_url=URL des Données Utiles
|
||||
settings.content_type=Type de contenu
|
||||
settings.secret=Confidentiel
|
||||
settings.secret_desc=Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.secret_desc=Le secret sera envoyé comme digest de payload SHA256 HMAC hex avec l'entête <code>X-Gogs-Signature</code>.
|
||||
settings.slack_username=Nom d'utilisateur
|
||||
settings.slack_icon_url=URL de l'icône
|
||||
settings.slack_color=Couleur
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=J'ai besoin de <strong>tout</strong>.
|
||||
settings.event_choose=Permettez-moi de choisir ce dont j'ai besoin.
|
||||
settings.event_create=Créer
|
||||
settings.event_create_desc=Branche, ou Tag créé
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request ouvert, fermé, rouvert, édité, attribuée, non attribuées, étiquette mise à jour, étiquette désactivée ou synchronisé.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push vers un dépôt
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Actif
|
||||
settings.active_helper=Les détails seront délivrés lorsque ce Hook sera déclenché.
|
||||
settings.add_hook_success=Nouveau Webhook ajouté.
|
||||
@@ -786,7 +805,7 @@ settings.deploy_key_deletion=Supprimer la Clé de Déploiement
|
||||
settings.deploy_key_deletion_desc=Supprimer cette clé de déploiement effacera tous les accès relatifs pour ce référentiel. Voulez-vous continuer ?
|
||||
settings.deploy_key_deletion_success=La clé de déploiement a été supprimée avec succès !
|
||||
|
||||
diff.browse_source=Parcourir la Source
|
||||
diff.browse_source=Parcourir la source
|
||||
diff.parent=Parent
|
||||
diff.commit=commit
|
||||
diff.data_not_available=Données Diff indisponibles.
|
||||
@@ -803,7 +822,6 @@ release.releases=Versions
|
||||
release.new_release=Nouvelle version
|
||||
release.draft=Brouillon
|
||||
release.prerelease=Pré-publication
|
||||
release.stable=Stable
|
||||
release.edit=Éditer
|
||||
release.ahead=<strong>%d</strong> commits jusqu'à %s depuis cette publication
|
||||
release.source_code=Code source
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privé
|
||||
repos.watches=Suivi par
|
||||
repos.stars=Votes
|
||||
repos.issues=Tickets
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Panel d'administration des authentifications
|
||||
auths.new=Ajouter une nouvelle source d'authentification
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Délai imparti pour l'opération "Pull"
|
||||
config.git_gc_timeout=Délai imparti pour l'opération "GC"
|
||||
|
||||
config.log_config=Configuration du Journal
|
||||
config.log_mode=Mode du journal
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Tâches Cron
|
||||
monitor.name=Nom
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Notifications système supprimées avec succès.
|
||||
|
||||
[action]
|
||||
create_repo=a créé le dépôt <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=a rebaptisé le dépôt de <code>%[1]s</code> vers <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=a commité dans <a href="%[1]s/src/%[2]s">%[3]s</a> sur <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Comparer ces %d commits
|
||||
transfer_repo=a transféré le dépôt <code>%s</code> à <a href="%s">%s</a>
|
||||
create_issue=`a ouvert un problème <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`tickets clos <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`tickets ré-ouverts <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`a commenté le problème <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`pull request créée le <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`pull request fermé <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`pull request ré-ouverte <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`a commenté le problème <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`pull request fusionné le <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=a transféré le dépôt <code>%s</code> à <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=a soumis le tag <a href="%s/src/%s">%[2]s</a> sur <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Comparer ces %d commits
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=il y a
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Contido
|
||||
require_error=` non pode estar baleiro.`
|
||||
alpha_dash_error=` os caracteres deben ser alfanuméricos ou dash(-_).`
|
||||
alpha_dash_dot_error=` debe ser un carácter alfanumérivo válido, un guión alto ou baixo (-_) ou un signo de puntuación.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` debe ser de tamaño %s.`
|
||||
min_size_error=` debe conter polo menos %s caracteres.`
|
||||
max_size_error=` debe conter como máximo %s caracteres.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull Requests
|
||||
labels=Etiquetas
|
||||
milestones=Fitos
|
||||
commits=Achegas
|
||||
git_branches=Branches
|
||||
releases=Lanzamentos
|
||||
file_raw=Raw
|
||||
file_history=Histórico
|
||||
@@ -434,6 +436,13 @@ file_permalink=Permalink
|
||||
file_too_large=Este arquivo é demasiado grande para ser mostrado
|
||||
video_not_supported_in_browser=O teu navegador non soporte a etiqueta video de HTML5.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Novo arquivo
|
||||
editor.upload_file=Subir arquivo
|
||||
editor.edit_file=Editar arquivo
|
||||
@@ -531,7 +540,7 @@ issues.next=Páxina seguinte
|
||||
issues.open_title=Aberta
|
||||
issues.closed_title=Cerrada
|
||||
issues.num_comments=%d comentarios
|
||||
issues.commented_at='comentado <a href="#%s"> %s'</a>
|
||||
issues.commented_at=`comentado <a href="#%s"> %s'</a>`
|
||||
issues.delete_comment_confirm=Seguro que desexas eliminar este comentario?
|
||||
issues.no_content=Aínda non existe contido.
|
||||
issues.close_issue=Cerrar
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Necesito <strong>todo</strong>.
|
||||
settings.event_choose=Déixeme elixir o que necesito.
|
||||
settings.event_create=Crear
|
||||
settings.event_create_desc=Rama ou etiqueta creada
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request aberto, cerrado, reaberto, editado, asignado, desasignado, etiqueta actualizada, etiqueta borrada, ou sincronizado.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push a un repositorio
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Activo
|
||||
settings.active_helper=Enviaremos detalles do evento cando este hook se dispare.
|
||||
settings.add_hook_success=Engadiuse un novo webhook.
|
||||
@@ -803,7 +822,6 @@ release.releases=Lanzamentos
|
||||
release.new_release=Novo lanzamento
|
||||
release.draft=Borrador=Borrador
|
||||
release.prerelease=Pre-Release=Pre-Lanzamento
|
||||
release.stable=Estable=Estable
|
||||
release.edit=editar=editar
|
||||
release.ahead=<strong>%d</strong> achegas en %s desde este release
|
||||
release.source_code=Código fonte
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privado
|
||||
repos.watches=Vixilantes
|
||||
repos.stars=Estrelas
|
||||
repos.issues=Incidencias
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Panel de administración de autenticación
|
||||
auths.new=Engadir nova orixe
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Tempo de espera de operación de pull
|
||||
config.git_gc_timeout=Tempo de espera de operación de GC
|
||||
|
||||
config.log_config=Configuración do log
|
||||
config.log_mode=Modo do log
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Tarefas de cron
|
||||
monitor.name=Nome
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=As notificacións do sistema foron eliminadas satisfactor
|
||||
|
||||
[action]
|
||||
create_repo=creou o repositorio <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=repositorio renomeado de <code>%[1]s</code> a <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=fixo push a <a href="%[1]s/src/%[2]s">%[3]s</a> en <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Ver comparación destas %d achegas
|
||||
transfer_repo=transferiu o repositorio <code>%s</code> a <a href="%s">%s</a>
|
||||
create_issue=`incidencia aberta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`cerrou a incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reabriu a incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentou na incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`creado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`cerrou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reabriu o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentou na incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=transferiu o repositorio <code>%s</code> a <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=fixo push do tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Ver comparación destas %d achegas
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=hai
|
||||
|
||||
@@ -48,7 +48,7 @@ cancel=Annulla
|
||||
install=Installazione
|
||||
title=Passi d'installazione per il primo avvio
|
||||
docker_helper=Se stai utilizzando Gogs su Docker, per favore leggi le <a target="_blank" href="%s">Linee guida</a> con attenzione prima di cambiare qualcosa su questa pagina!
|
||||
requite_db_desc=Gogs requires MySQL, PostgreSQL, SQLite3, MSSQL or TiDB.
|
||||
requite_db_desc=Gogs richiede MySQL, PostgreSQL, SQLite3, MSSQL o TiDB.
|
||||
db_title=Impostazioni Database
|
||||
db_type=Tipo di database
|
||||
host=Host
|
||||
@@ -58,8 +58,8 @@ db_name=Nome del database
|
||||
db_helper=Utilizza il motore INNODB con codifica utf8_general_ci per MySQL.
|
||||
ssl_mode=Modalità SSL
|
||||
path=Percorso
|
||||
sqlite_helper=The file path of SQLite3 database. <br>Please use absolute path when you start as service.
|
||||
err_empty_db_path=SQLite3 database path cannot be empty.
|
||||
sqlite_helper=Il percorso del file di database di SQLite3. <br>Si prega di utilizzare il percorso assoluto quando si avvia come servizio.
|
||||
err_empty_db_path=Il percorso del database SQLite3 non può essere vuoto.
|
||||
no_admin_and_disable_registration=Non puoi disabilitare la registrazione senza aver creato un amministratore.
|
||||
err_empty_admin_password=La password dell'amministratore non puo' essere vuota.
|
||||
|
||||
@@ -74,7 +74,7 @@ domain=Dominio
|
||||
domain_helper=Questo influisce sugli URL per il clonaggio via SSH.
|
||||
ssh_port=Porta SSH
|
||||
ssh_port_helper=Numero di porta utilizzato dal server SSH, lasciare vuoto per disabilitare l'integrazione SSH.
|
||||
use_builtin_ssh_server=Use Builtin SSH Server
|
||||
use_builtin_ssh_server=Usa il server SSH integrato
|
||||
use_builtin_ssh_server_popup=Start builtin SSH server for Git operations to distinguish from system SSH daemon.
|
||||
http_port=Porta HTTP
|
||||
http_port_helper=Porta di ascolto dell'applicazione.
|
||||
@@ -201,6 +201,7 @@ Content=Contenuto
|
||||
require_error=` non può essere vuoto.`
|
||||
alpha_dash_error=` ammessi solo caratteri alfanumerici o trattini(-_).`
|
||||
alpha_dash_dot_error=` ammessi solo caratteri alfanumerici o trattini(-_) o punti.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error='deve essere %s.'
|
||||
min_size_error=` deve contenere almeno %s caratteri.`
|
||||
max_size_error=` deve contenere massimo %s caratteri.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull Requests
|
||||
labels=Etichette
|
||||
milestones=Traguardi
|
||||
commits=Commit
|
||||
git_branches=Branches
|
||||
releases=Rilasci
|
||||
file_raw=Originale
|
||||
file_history=Cronologia
|
||||
@@ -434,6 +436,13 @@ file_permalink=Permalink
|
||||
file_too_large=Questo file è troppo grande per essere mostrato
|
||||
video_not_supported_in_browser=Il tuo browser non supporta i tag "video" di HTML5.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Nuovo file
|
||||
editor.upload_file=Carica File
|
||||
editor.edit_file=Modifica file
|
||||
@@ -473,7 +482,7 @@ editor.add_subdir=Aggiungi sottocartella...
|
||||
editor.unable_to_upload_files=È fallito il caricamento dei file su '%s': %v
|
||||
editor.upload_files_to_dir=Carica file su '%s'
|
||||
|
||||
commits.commit_history=Commit History
|
||||
commits.commit_history=Cronologia Commit
|
||||
commits.commits=Commits
|
||||
commits.search=Ricerca una versione
|
||||
commits.find=Cerca
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Ho bisogno di <strong>tutto</strong>.
|
||||
settings.event_choose=Lasciami scegliere ciò di cui ho bisogno.
|
||||
settings.event_create=Crea
|
||||
settings.event_create_desc=Branch, o tag creato
|
||||
settings.event_pull_request=Pull request
|
||||
settings.event_pull_request_desc=Pull request aperta, chiusa, riaperta, modificata, assegnata, riassegnata, etichettata o sincronizzata.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push in un repository
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Attivo
|
||||
settings.active_helper=Anche i dettagli riguardanti l'evento che ha innescato l'hook saranno inviati.
|
||||
settings.add_hook_success=Il nuovo webhook è stato aggiunto.
|
||||
@@ -803,7 +822,6 @@ release.releases=Rilasci
|
||||
release.new_release=Nuovo Rilascio
|
||||
release.draft=Bozza
|
||||
release.prerelease=Pre-Rilascio
|
||||
release.stable=Stabile
|
||||
release.edit=modifica
|
||||
release.ahead=<strong>%d</strong> commits da %s da questo rilascio
|
||||
release.source_code=Codice Sorgente
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privati
|
||||
repos.watches=Segue
|
||||
repos.stars=Voti
|
||||
repos.issues=Problemi
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Pannello di configurazione dei meccanismi di autenticazione
|
||||
auths.new=Aggiungi Nuova Origine
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Timeout per il pull
|
||||
config.git_gc_timeout=Timeout per le operazioni di GC
|
||||
|
||||
config.log_config=Configurazione Log
|
||||
config.log_mode=Modalità Log
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Incarici di cron
|
||||
monitor.name=Nome
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Gli avvisi di sistema sono stati successivamente eliminat
|
||||
|
||||
[action]
|
||||
create_repo=ha creato il repository <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=repository rinominato da <code>%[1]s</code> a <a href="%[2]s">[3]s</a>
|
||||
commit_repo=ha pushato nel <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Visualizza comparazione tra questi %d commit
|
||||
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
|
||||
create_issue=`ha aperto il problema <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`creata pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`ha commentato il problema <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=ha trasferito il repository <code>%s</code> a <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=ha pushato il tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Visualizza comparazione tra questi %d commit
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=fa
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=コンテンツ
|
||||
require_error=空にできません
|
||||
alpha_dash_error=アルファベット、数字、ハイフン"-"、アンダースコア"_"のいずれかの必要があります
|
||||
alpha_dash_dot_error=' アルファベット、数値、ダッシュ(-)、アンダースコア(_) 、ドット(.)のいずれかを入力する必要があります。 '
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=`サイズは %s である必要があります`
|
||||
min_size_error=' 少なくとも %s 文字の必要があります '
|
||||
max_size_error=' %s 文字以下の必要があります '
|
||||
@@ -426,6 +427,7 @@ pulls=プルリクエスト
|
||||
labels=ラベル
|
||||
milestones=マイルストーン
|
||||
commits=コミット
|
||||
git_branches=Branches
|
||||
releases=リリース
|
||||
file_raw=Raw
|
||||
file_history=履歴
|
||||
@@ -434,6 +436,13 @@ file_permalink=パーマリンク
|
||||
file_too_large=このファイルは大きすぎるため、表示できません。
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=New file
|
||||
editor.upload_file=Upload file
|
||||
editor.edit_file=ファイルを編集
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=<strong>すべて</strong> が必要です。
|
||||
settings.event_choose=必要なものを選択しましょう。
|
||||
settings.event_create=Create
|
||||
settings.event_create_desc=ブランチ、またはタグを作成
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=プッシュ
|
||||
settings.event_push_desc=Git リポジトリにプッシュ
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=アクティブ
|
||||
settings.active_helper=このフックのトリガーが引かれた時に、イベントの詳細を配信します。
|
||||
settings.add_hook_success=新しい webhook が追加されました。
|
||||
@@ -803,7 +822,6 @@ release.releases=リリース
|
||||
release.new_release=新しいリリース
|
||||
release.draft=ドラフト
|
||||
release.prerelease=プレリリース
|
||||
release.stable=安定
|
||||
release.edit=編集
|
||||
release.ahead=このリリース以降 %s へ <strong>%d</strong> コミット
|
||||
release.source_code=ソース コード
|
||||
@@ -1019,6 +1037,7 @@ repos.private=プライベート
|
||||
repos.watches=Watches
|
||||
repos.stars=Stars
|
||||
repos.issues=課題
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=認証管理パネル
|
||||
auths.new=新しいソースを追加
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Pull Operation Timeout
|
||||
config.git_gc_timeout=GC Operation Timeout
|
||||
|
||||
config.log_config=ログの構成
|
||||
config.log_mode=ログ モード
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron タスク
|
||||
monitor.name=名前
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=システム通知が正常に削除されました。
|
||||
|
||||
[action]
|
||||
create_repo=がリポジトリ <a href="%s"> %s</a> を作成しました
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=<code>%[1]s</code> から <a href="%[2]s">[3]s</a> にリポジトリ名を変更しました
|
||||
commit_repo=<a href="%[1]s">%[4]s</a>を<a href="%[1]s/src/%[2]s">%[3]s</a>にプッシュしました
|
||||
compare_commits=これらの %d コミットの比較を表示
|
||||
transfer_repo=リポジトリ <code>%s</code> を <a href="%s">%s</a> へ転送しました
|
||||
create_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> を開きました`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> のコメント`
|
||||
create_pull_request=`プルリクエスト <a href="%s/pulls/%s"> %s[2]s</a>を作成`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`問題 <a href="%s/issues/%s">%s#%[2]s</a> のコメント`
|
||||
merge_pull_request=`プルリクエスト <a href="%s/pulls/%s"> %s[2]s</a>をマージしました`
|
||||
transfer_repo=リポジトリ <code>%s</code> を <a href="%s">%s</a> へ転送しました
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=<a href="%[1]s">%[3]s</a> に タグ <a href="%[1]s/src/%[2]s">%[2]s</a> をプッシュしました
|
||||
compare_commits=これらの %d コミットの比較を表示
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=前
|
||||
|
||||
@@ -48,7 +48,7 @@ cancel=취소
|
||||
install=설치
|
||||
title=첫 실행을 위한 설치단계
|
||||
docker_helper=Gogs를 Docker에서 운영하고 있다면 <a target="_blank" href="%s">안내</a>를 읽고 변경해 주세요!
|
||||
requite_db_desc=Gogs requires MySQL, PostgreSQL, SQLite3, MSSQL or TiDB.
|
||||
requite_db_desc=Gogs 는 MySQL, PostgreSQL, SQLite3, MSSQL 또는 TiDB 를 필요로 합니다.
|
||||
db_title=데이터베이스 설정
|
||||
db_type=데이터베이스 유형
|
||||
host=호스트
|
||||
@@ -58,8 +58,8 @@ db_name=데이터베이스 이름
|
||||
db_helper=MySQL에서는 utf8_general_ci 캐릭터셋으로 INNODB엔진을 이용해 주세요
|
||||
ssl_mode=SSL 모드
|
||||
path=경로
|
||||
sqlite_helper=The file path of SQLite3 database. <br>Please use absolute path when you start as service.
|
||||
err_empty_db_path=SQLite3 database path cannot be empty.
|
||||
sqlite_helper=SQLite3 데이터베이스의 경로입니다.<br>서비스를 시작할 때는 반드시 절대 경로를 사용해주세요.
|
||||
err_empty_db_path=SQLite3 데이터베이스의 경로는 비워둘 수 없습니다.
|
||||
no_admin_and_disable_registration=관리자 계정을 만들지 않고 등록을 비활성화할 수 없습니다.
|
||||
err_empty_admin_password=관리자 암호는 비워둘 수 없습니다.
|
||||
|
||||
@@ -74,7 +74,7 @@ domain=도메인
|
||||
domain_helper=Git SSH url에 영향을 미칩니다.
|
||||
ssh_port=SSH 포트
|
||||
ssh_port_helper=SSH서버가 실행되고 있는 포트를 입력하세요. 비워둘 경우 SSH를 사용하지 않습니다.
|
||||
use_builtin_ssh_server=Use Builtin SSH Server
|
||||
use_builtin_ssh_server=내장 SSH 서버 사용
|
||||
use_builtin_ssh_server_popup=Start builtin SSH server for Git operations to distinguish from system SSH daemon.
|
||||
http_port=HTTP 포트
|
||||
http_port_helper=포트 번호는 애플리케이션에서 열고 있습니다.
|
||||
@@ -201,6 +201,7 @@ Content=컨텐츠
|
||||
require_error=` 비어 있을 수 없습니다.`
|
||||
alpha_dash_error=`은(는) 숫자, 알파벳, 대시(-_) 문자로만 구성되어야 합니다.`
|
||||
alpha_dash_dot_error=` 숫자, 알파벳, 점(.), 대시(-_) 문자로만 구성되어야 합니다.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` %s 글자여야 합니다.`
|
||||
min_size_error=` 최소 %s 글자여야 합니다.`
|
||||
max_size_error=` %s 글자를 넘을 수 없습니다.`
|
||||
@@ -426,6 +427,7 @@ pulls=풀 리퀘스트
|
||||
labels=레이블
|
||||
milestones=마일스톤
|
||||
commits=커밋
|
||||
git_branches=Branches
|
||||
releases=릴리즈
|
||||
file_raw=Raw
|
||||
file_history=히스토리
|
||||
@@ -434,6 +436,13 @@ file_permalink=고유링크
|
||||
file_too_large=이 파일은 표시하기엔 너무 큽니다.
|
||||
video_not_supported_in_browser=이 브라우저는 HTML5 비디오 태그를 지원하지 않습니다.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=파일 생성
|
||||
editor.upload_file=파일 업로드
|
||||
editor.edit_file=파일 수정
|
||||
@@ -473,7 +482,7 @@ editor.add_subdir=하위 디렉토리 추가...
|
||||
editor.unable_to_upload_files=파일 '%s'를 업로드하는데 실패하였습니다. 에러: %v
|
||||
editor.upload_files_to_dir=파일 업로드 '%s'
|
||||
|
||||
commits.commit_history=Commit History
|
||||
commits.commit_history=커밋 기록
|
||||
commits.commits=커밋
|
||||
commits.search=커밋 검색
|
||||
commits.find=찾기
|
||||
@@ -641,24 +650,24 @@ settings.collaboration.admin=관리자
|
||||
settings.collaboration.write=쓰기
|
||||
settings.collaboration.read=읽기
|
||||
settings.collaboration.undefined=미정의
|
||||
settings.branches=Branches
|
||||
settings.default_branch=Default Branch
|
||||
settings.branches=브랜치
|
||||
settings.default_branch=기본 브랜치
|
||||
settings.default_branch_desc=The default branch is considered the "base" branch for code commits, pull requests and online editing.
|
||||
settings.update=Update
|
||||
settings.update_default_branch_success=Default branch of this repository has been updated successfully!
|
||||
settings.protected_branches=Protected Branches
|
||||
settings.protected_branches_desc=Protect branches from force pushing, accidental deletion and whitelist code committers.
|
||||
settings.choose_a_branch=Choose a branch...
|
||||
settings.branch_protection=Branch Protection
|
||||
settings.branch_protection_desc=Please choose protect options for branch <b>%s</b>.
|
||||
settings.protect_this_branch=Protect this branch
|
||||
settings.protect_this_branch_desc=Disable force pushes and prevent from deletion.
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.update=업데이트
|
||||
settings.update_default_branch_success=이 레포지토리의 기본 브랜치가 성공적으로 설정되었습니다!
|
||||
settings.protected_branches=보호된 브랜치
|
||||
settings.protected_branches_desc=보호된 브랜치는 force 푸시, 실수로 인한 코드 삭제를 방지하며 코드 커미터를 화이트리스트 합니다.
|
||||
settings.choose_a_branch=브랜치를 선택하세요...
|
||||
settings.branch_protection=브랜치 보호
|
||||
settings.branch_protection_desc=브랜치 <b>%s</b> 의 보호 설정을 선택하세요.
|
||||
settings.protect_this_branch=이 브랜치를 보호하기
|
||||
settings.protect_this_branch_desc=Force 푸시와 삭제를 비활성화합니다.
|
||||
settings.protect_require_pull_request=직접 push 를 하지 않고 Pull Request 를 필요로 하도록 합니다.
|
||||
settings.protect_require_pull_request_desc=이 브랜치에 직접 푸시를 하는 것을 막고 싶다면 이 옵션을 활성화하세요. 커밋은 다른 비보호 브랜치에 푸시되어야 하며 이 브랜치에는 Pull Request 를 통해 병합될 것입니다.
|
||||
settings.protect_whitelist_committers=이 브랜치에 푸시할 수 있는 유저
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=이 브랜치에 푸시를 할 수 있는 유저
|
||||
settings.protect_whitelist_search_users=유저 검색
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
settings.protect_whitelist_search_teams=Search teams
|
||||
settings.update_protect_branch_success=Protect options for this branch has been updated successfully!
|
||||
@@ -756,10 +765,20 @@ settings.event_send_everything=<strong>모든 것</strong>이 필요합니다.
|
||||
settings.event_choose=필요한 것을 선택해주세요.
|
||||
settings.event_create=생성
|
||||
settings.event_create_desc=브랜치 또는 태그를 생성합니다.
|
||||
settings.event_pull_request=끌어오기 요청
|
||||
settings.event_pull_request_desc=끌어오기 요청 열기, 닫기, 다시 열기, 편집, 할당, 할당 해제, 라벨 업데이트, 라벨 지우기 또는 동기화.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=푸시
|
||||
settings.event_push_desc=깃 저장소로 푸시
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=끌어오기 요청
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=활성
|
||||
settings.active_helper=후크를 트리거하면 이벤트에 대한 세부 정보도 전달됩니다.
|
||||
settings.add_hook_success=새로운 웹훅이 생성되었습니다.
|
||||
@@ -804,7 +823,6 @@ release.releases=릴리즈
|
||||
release.new_release=새로운 릴리즈
|
||||
release.draft=초안
|
||||
release.prerelease=사전 릴리즈
|
||||
release.stable=안정
|
||||
release.edit=편집
|
||||
release.ahead=이 릴리스 이후로 <strong>%d</strong> %s에 커밋합니다.
|
||||
release.source_code=소스 코드
|
||||
@@ -1020,6 +1038,7 @@ repos.private=비공개
|
||||
repos.watches=지켜보기
|
||||
repos.stars=Stars
|
||||
repos.issues=이슈
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=인증 관리 패널
|
||||
auths.new=새로운 소스를 추가
|
||||
@@ -1177,7 +1196,8 @@ config.git_pull_timeout=끌어오기 작업 시간 제한
|
||||
config.git_gc_timeout=가비지 콜렉션 작업 시간 제한
|
||||
|
||||
config.log_config=로그 설정
|
||||
config.log_mode=로그 모드
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron 작업
|
||||
monitor.name=이름
|
||||
@@ -1206,19 +1226,23 @@ notices.delete_success=시스템 알림들이 성공적으로 삭제되었습니
|
||||
|
||||
[action]
|
||||
create_repo=저장소를 만들었습니다. <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=<code>%[1]s에서</code>에서 <a href="%[2]s"> %[3]s</a>으로 저장소 이름을 바꾸었습니다.
|
||||
commit_repo=<a href="%[1]s">%[4]s</a>에서 <a href="%[1]s/src/%[2]s">%[3]s</a>으로 푸시함
|
||||
compare_commits=이 %d개의 커밋에 대한 비교 보기
|
||||
transfer_repo=<code>%s</code>에서 <a href="%s">%s</a>로 저장소가 전송되었습니다.
|
||||
create_issue=`열린 이슈 <a href="%s/issues/%s"> %s #%[2]s</a>`
|
||||
close_issue=`닫힌 이슈 <a href="%s/issues/%s"> %s #%[2]s</a>`
|
||||
reopen_issue=`다시 열린 이슈 <a href="%s/issues/%s"> %s #%[2]s</a>`
|
||||
comment_issue=`이슈에 댓글이 달렸습니다. <a href="%s/issues/%s"> %s #%[2]s</a>`
|
||||
create_pull_request=`만들어진 끌어오기 요청 <a href="%s/pulls/%s"> %s #%[2]s</a>`
|
||||
close_pull_request=`닫힌 끌어오기 요청 <a href="%s/pulls/%s"> %s #%[2]s</a>`
|
||||
reopen_pull_request=`다시 열린 끌어오기 요청 <a href="%s/pulls/%s"> %s #%[2]s</a>`
|
||||
comment_issue=`이슈에 댓글이 달렸습니다. <a href="%s/issues/%s"> %s #%[2]s</a>`
|
||||
merge_pull_request=`병합된 끌어오기 요청 <a href="%s/pulls/%s"> %s #%[2]s</a>`
|
||||
transfer_repo=<code>%s</code>에서 <a href="%s">%s</a>로 저장소가 전송되었습니다.
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=태그 <a href="%s/src/%s">%[2]s</a>를 <a href="%[1]s">%[3]s</a>로 푸시함
|
||||
compare_commits=이 %d개의 커밋에 대한 비교 보기
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=전
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Saturs
|
||||
require_error=` nedrīkst būt tukšs.`
|
||||
alpha_dash_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus vai domuzīmes (-_).`
|
||||
alpha_dash_dot_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus, domuzīmes (-_) vai punktu.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` jābūt %s simbolus garam.`
|
||||
min_size_error=` jabūt vismaz %s simbolu garumā.`
|
||||
max_size_error=` jabūt ne mazāk kā %s simbolu garumā.`
|
||||
@@ -426,6 +427,7 @@ pulls=Izmaiņu pieprasījumi
|
||||
labels=Etiķetes
|
||||
milestones=Atskaites punkti
|
||||
commits=Revīzijas
|
||||
git_branches=Branches
|
||||
releases=Laidieni
|
||||
file_raw=Neapstrādāts
|
||||
file_history=Vēsture
|
||||
@@ -434,6 +436,13 @@ file_permalink=Patstāvīgā saite
|
||||
file_too_large=Šis fails ir par lielu, lai to parādītu
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Jauns fails
|
||||
editor.upload_file=Augšupielādēt failu
|
||||
editor.edit_file=Labot failu
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Vēlos saņemt <strong>visu</strong>.
|
||||
settings.event_choose=Atzīmēt, ko vēlos saņemt.
|
||||
settings.event_create=Izveidot
|
||||
settings.event_create_desc=Atzara vai taga izveidošana
|
||||
settings.event_pull_request=Izmaiņu pieprasījums
|
||||
settings.event_pull_request_desc=Atvērts, aizvērts, atkāroti atvērts, labots, piešķirts vai noņemts izmaiņu pieprasījums, vai mainīta etiķete, vai veikta sinhronizācija.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Izmaiņu nosūtīšana
|
||||
settings.event_push_desc=Git izmaiņu nosūtīšana uz repozitoriju
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Izmaiņu pieprasījums
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktīvs
|
||||
settings.active_helper=Tiks nosūtīti notikuma dati, kad nostrādās šis āķis.
|
||||
settings.add_hook_success=Jauns tīmekļa āķis tika veiksmīgi pievienots.
|
||||
@@ -803,7 +822,6 @@ release.releases=Laidieni
|
||||
release.new_release=Jauns laidiens
|
||||
release.draft=Melnraksts
|
||||
release.prerelease=Pirmsizlaides versija
|
||||
release.stable=Stabila
|
||||
release.edit=labot
|
||||
release.ahead=<strong>%d</strong> revīzijas atzarā %s kopš šī laidiena
|
||||
release.source_code=Izejas kods
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privāts
|
||||
repos.watches=Vērošana
|
||||
repos.stars=Atzīmētās zvaigznītes
|
||||
repos.issues=Problēmas
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Autentifikācijas pārvaldības panelis
|
||||
auths.new=Pievienot jaunu avotu
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Izmaiņu saņemšanas darbības noilgums
|
||||
config.git_gc_timeout=GC darbības noilgums
|
||||
|
||||
config.log_config=Žurnalizēšanas konfigurācija
|
||||
config.log_mode=Žurnalizēšanas veids
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron uzdevumi
|
||||
monitor.name=Nosaukums
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Sistēmas paziņojumi tika veiksmīgi izdzēstas.
|
||||
|
||||
[action]
|
||||
create_repo=izveidoja repozitoriju <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=pārsauca repozitoriju no <code>%[1]s</code> uz <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=veica izmaiņu nosūtīšanu atzaram <a href="%[1]s/src/%[2]s">%[3]s</a> repozitorijā <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Salīdzināt šīs %d revīzijas
|
||||
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="%s">%s</a>
|
||||
create_issue=`reģistrēja problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`slēdza problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`atkārtoti atvēra problēmu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`izveidoja izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`aizvēra izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`atkārtoti atvēra izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`pievienoja komentāru problēmai <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`sapludināja izmaiņu pieprasījumu <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=mainīja repozitorija <code>%s</code> īpašnieku uz <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=pievienoja tagu <a href="%s/src/%s">%[2]s</a> repozitorijam <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Salīdzināt šīs %d revīzijas
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=atpakaļ
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Inhoud
|
||||
require_error=kan niet leeg zijn.
|
||||
alpha_dash_error=moet een valide alfanumeriek of dash(-_) karakter zijn.
|
||||
alpha_dash_dot_error=moet een valide alfanumeriek, dash(-_) of (.) punt karakter zijn.
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=moet groter zijn dan %s
|
||||
min_size_error=moet minimaal %s karakters bevatten.
|
||||
max_size_error=mag maximaal %s karakters bevatten.
|
||||
@@ -426,6 +427,7 @@ pulls=Pull-aanvragen
|
||||
labels=Labels
|
||||
milestones=Mijlpalen
|
||||
commits=Commits
|
||||
git_branches=Branches
|
||||
releases=Publicaties
|
||||
file_raw=Ruwe
|
||||
file_history=Geschiedenis
|
||||
@@ -434,6 +436,13 @@ file_permalink=Permalink
|
||||
file_too_large=Dit bestand is te groot om te worden getoond
|
||||
video_not_supported_in_browser=Uw browser ondersteunt geen HTML5 video label.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Nieuw bestand
|
||||
editor.upload_file=Bestand uploaden
|
||||
editor.edit_file=Bewerk bestand
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Ik moet <strong>alles</strong> hebben.
|
||||
settings.event_choose=Laat me kiezen wat ik nodig heb.
|
||||
settings.event_create=Creëer
|
||||
settings.event_create_desc=Branch, of tag aangemaakt
|
||||
settings.event_pull_request=Pull request
|
||||
settings.event_pull_request_desc=Pull request geopend, gesloten, opnieuw geopend, bewerkt, toegewezen, niet-toegewezen, label bijgewerkt, label gewist of gesynchroniseerd.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push naar een repository
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Actief
|
||||
settings.active_helper=We zullen details van de gebeurtenissen af leveren wanneer deze webhook wordt geactiveerd.
|
||||
settings.add_hook_success=Nieuwe webhook toegevoegd.
|
||||
@@ -803,7 +822,6 @@ release.releases=Releases
|
||||
release.new_release=Nieuwe release
|
||||
release.draft=Concept
|
||||
release.prerelease=Voorlopige versie
|
||||
release.stable=Stabiel
|
||||
release.edit=bewerken
|
||||
release.ahead=<strong>%d</strong> aanpassingen aan %s sinds deze versie
|
||||
release.source_code=Broncode
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Prive
|
||||
repos.watches=Volgers
|
||||
repos.stars=Sterren
|
||||
repos.issues=Kwesties
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Authenticatie-beheer paneel
|
||||
auths.new=Nieuwe bron toevoegen
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Pull Operation Timeout
|
||||
config.git_gc_timeout=GC Operation Timeout
|
||||
|
||||
config.log_config=Logconfiguratie
|
||||
config.log_mode=Log-modus
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron-taken
|
||||
monitor.name=Naam
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=System notices have been deleted successfully.
|
||||
|
||||
[action]
|
||||
create_repo=repositorie aangemaakt in <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=hernoemde repository van <code>%[1]s</code> naar <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=push update naar <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Toon vergelijking voor deze %d commits
|
||||
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="%s">%s</a>
|
||||
create_issue=`opende issue in <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`sloot kwestie <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`heropende kwestie <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`reactie op issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`maakte pull request <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`sloot pull request <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`heropende pull request <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`reactie op issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`voegde pull request samen <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
transfer_repo=repositorie verplaatst naar <code>%s</code> naar <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=geduwd label <a href="%s/src/%s"> %[2]s</a> naar <a href="%[1]s"> %[3]s</a>
|
||||
compare_commits=Toon vergelijking voor deze %d commits
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=geleden
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Treść
|
||||
require_error=` nie może być puste.`
|
||||
alpha_dash_error=` musi się składać z prawidłowych znaków alfanumerycznych, myślników oraz podkreśleń.`
|
||||
alpha_dash_dot_error=` musi się składać z prawidłowych znaków alfanumerycznych, myślników, podkreśleń oraz kropek.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` musi być wielkości %s.`
|
||||
min_size_error=` musi zawierać co najwyżej %s znaków.`
|
||||
max_size_error=` musi zawierać co najwyżej %s znaków.`
|
||||
@@ -426,6 +427,7 @@ pulls=Oczekujące zmiany
|
||||
labels=Etykiety
|
||||
milestones=Kamienie milowe
|
||||
commits=Commity
|
||||
git_branches=Branches
|
||||
releases=Wydania
|
||||
file_raw=Czysty
|
||||
file_history=Historia
|
||||
@@ -434,6 +436,13 @@ file_permalink=Bezpośredni odnośnik
|
||||
file_too_large=Ten plik jest zbyt duży, aby go wyświetlić
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Nowy plik
|
||||
editor.upload_file=Załaduj plik
|
||||
editor.edit_file=Edytuj plik
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Potrzebuję <strong>wszystkiego</strong>.
|
||||
settings.event_choose=Pozwól mi wybrać, czego potrzebuję.
|
||||
settings.event_create=Utwórz
|
||||
settings.event_create_desc=Utworzono gałąź lub tag
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Otworzono żądanie pull, zamknięto, otwarto ponownie, zaktualizowano, przypisano, nieprzypisano, zaktualizowano etykietę, wyczyszczono etykietę lub zsynchronizowano.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Wypchnięcie
|
||||
settings.event_push_desc=Wypchnięcie (push) do repozytorium Git
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktywny
|
||||
settings.active_helper=Dostarczymy szczegóły zdarzenia, gdy ten webhook zostanie wywołany.
|
||||
settings.add_hook_success=Nowy webhook został dodany.
|
||||
@@ -803,7 +822,6 @@ release.releases=Wydania
|
||||
release.new_release=Nowe wydanie
|
||||
release.draft=Szkic
|
||||
release.prerelease=Wersja wstępna
|
||||
release.stable=Stabilny
|
||||
release.edit=edytuj
|
||||
release.ahead=<strong>%d</strong> commitów w %s od tego wydania
|
||||
release.source_code=Kod źródłowy
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Prywatne
|
||||
repos.watches=Obserwujących
|
||||
repos.stars=Polubienia
|
||||
repos.issues=Problemy
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Panel zarządzania uwierzytelnianiem
|
||||
auths.new=Dodaj nowe źródło
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Limit czasu dla operacji pull
|
||||
config.git_gc_timeout=Limit czasu odśmiecania pamięci
|
||||
|
||||
config.log_config=Konfiguracja dziennika
|
||||
config.log_mode=Tryb dziennika
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Zadania cron
|
||||
monitor.name=Nazwa
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Powiadomienia systemowe zostały pomyślnie usunięte.
|
||||
|
||||
[action]
|
||||
create_repo=tworzy repozytorium <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=zmienia nazwę repozytorium <code>%[1]s</code> na <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=wypycha do <a href="%[1]s/src/%[2]s">%[3]s</a> w <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Zobacz porównanie tych %d commitów
|
||||
transfer_repo=przenosi repozytorium <code>%s</code> do <a href="%s">%s</a>
|
||||
create_issue=`zgłasza problem <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`zamknięcie problemu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`ponowne otwarcie problemu <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`komentuje problem <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`tworzy pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`zamknięcie pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`ponowne otwarcie pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`komentuje problem <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`scala pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=przenosi repozytorium <code>%s</code> do <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=taguje <a href="%s/src/%s">%[2]s</a> w <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Zobacz porównanie tych %d commitów
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=temu
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Conteúdo
|
||||
require_error=` não pode estar vazio.`
|
||||
alpha_dash_error=` devem ser caracteres alfanuméricos, hífen (-) ou sublinhado (_).`
|
||||
alpha_dash_dot_error=` devem ser caracteres alfanuméricos ou hífen (-) ou sublinhado (_).`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=`deve ser do tamanho %s.`
|
||||
min_size_error=` deve conter pelo menos %s caracteres.`
|
||||
max_size_error=` deve conter no máximo %s caracteres.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull Requests
|
||||
labels=Etiquetas
|
||||
milestones=Milestones
|
||||
commits=Commits
|
||||
git_branches=Branches
|
||||
releases=Versões
|
||||
file_raw=Raw
|
||||
file_history=Histórico
|
||||
@@ -434,6 +436,13 @@ file_permalink=Link permanente
|
||||
file_too_large=Este arquivo é muito grande para ser exibido
|
||||
video_not_supported_in_browser=Seu navegador não suporta a tag de vídeo do HTML5.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Novo arquivo
|
||||
editor.upload_file=Enviar arquivo
|
||||
editor.edit_file=Editar arquivo
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Preciso de <strong>tudo</strong>.
|
||||
settings.event_choose=Deixe-me escolher o que eu preciso.
|
||||
settings.event_create=Criar
|
||||
settings.event_create_desc=Branch ou Tag criado
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request aberto, fechado, reaberto, atribuído, desatribuído, teve etiqueta atualizada ou limpada ou foi sincronizado.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push para o repositório
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Ativo
|
||||
settings.active_helper=Enviaremos detalhes do evento quando este hook for acionado.
|
||||
settings.add_hook_success=Novos hooks de web foram adicionados.
|
||||
@@ -803,7 +822,6 @@ release.releases=Versões
|
||||
release.new_release=Nova versão
|
||||
release.draft=Rascunho
|
||||
release.prerelease=Versão prévia
|
||||
release.stable=Estável
|
||||
release.edit=editar
|
||||
release.ahead=<strong>%d</strong> commits para %s depois desta versão
|
||||
release.source_code=Código fonte
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privado
|
||||
repos.watches=Observadores
|
||||
repos.stars=Favoritos
|
||||
repos.issues=Issues
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Painel de gerenciamento da autenticação
|
||||
auths.new=Adicionar nova fonte
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Timeout para operação de pull
|
||||
config.git_gc_timeout=Timeout para execução do GC
|
||||
|
||||
config.log_config=Configuração de log
|
||||
config.log_mode=Modo do log
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Tarefas cron
|
||||
monitor.name=Nome
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Avisos do sistema foram excluídos com sucesso.
|
||||
|
||||
[action]
|
||||
create_repo=repositório criado <a href="%s"> %s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=renomeou o o repositório <code>%[1]s</code> para <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=pushed para <a href="%[1]s/src/%[2]s">%[3]s</a> em <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Ver comparação entre esses %d commits
|
||||
transfer_repo=repositório transferido de <code>%s</code> para <a href="%s">%s</a>
|
||||
create_issue=`questão aberta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`questão fechada <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`questão reaberta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentou sobre a questão <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`criou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`fechou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reabriu o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentou sobre a questão <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`mesclou o pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=repositório transferido de <code>%s</code> para <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=Foi feito push na tag <a href="%s/src/%s">%[2]s</a> para <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Ver comparação entre esses %d commits
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=atrás
|
||||
|
||||
@@ -48,7 +48,7 @@ cancel=Отмена
|
||||
install=Установка
|
||||
title=Установочные шаги для первого запуска
|
||||
docker_helper=Если вы запускаете Gogs внутри Docker, пожалуйста прочтите <a target="_blank" href="%s">эти советы</a> внимательно перед тем как что-либо изменить на этой странице!
|
||||
requite_db_desc=Gogs requires MySQL, PostgreSQL, SQLite3, MSSQL or TiDB.
|
||||
requite_db_desc=Gogs требует наличия MySQL, PostgreSQL, SQLite3, MSSQL или TiDB.
|
||||
db_title=Настройки базы данных
|
||||
db_type=Тип базы данных
|
||||
host=Хост
|
||||
@@ -58,8 +58,8 @@ db_name=Имя базы данных
|
||||
db_helper=Для MySQL используйте тип таблиц InnoDB с кодировкой utf8_general_ci.
|
||||
ssl_mode=Режим SSL
|
||||
path=Путь
|
||||
sqlite_helper=The file path of SQLite3 database. <br>Please use absolute path when you start as service.
|
||||
err_empty_db_path=SQLite3 database path cannot be empty.
|
||||
sqlite_helper=Путь к файлу базы данный SQLite3. <br>Пожалуйста, используйте абсолютный путь если Gogs запускается как сервис.
|
||||
err_empty_db_path=Путь к файлу базы данных SQLite3 не может быть пустым.
|
||||
no_admin_and_disable_registration=Вы не можете отключить регистрацию до создания учетной записи администратора.
|
||||
err_empty_admin_password=Пароль администратора не может быть пустым.
|
||||
|
||||
@@ -74,8 +74,8 @@ domain=Домен
|
||||
domain_helper=Влияет на URL-адреса для клонирования по SSH.
|
||||
ssh_port=SSH порт
|
||||
ssh_port_helper=Номер порта, который использует SSH сервер. Оставьте пустым, чтобы отключить SSH.
|
||||
use_builtin_ssh_server=Use Builtin SSH Server
|
||||
use_builtin_ssh_server_popup=Start builtin SSH server for Git operations to distinguish from system SSH daemon.
|
||||
use_builtin_ssh_server=Использовать встроенный SSH сервер
|
||||
use_builtin_ssh_server_popup=Запустить встроенный SSH сервер для различения операций Git и системного демона SSH.
|
||||
http_port=Порт HTTP
|
||||
http_port_helper=Номер порта, который приложение будет слушать.
|
||||
app_url=URL приложения
|
||||
@@ -117,7 +117,7 @@ sqlite3_not_available=Ваша версия не поддерживает SQLite
|
||||
invalid_db_setting=Настройки базы данных не правильные: %v
|
||||
invalid_repo_path=Недопустимый путь к корню репозитория: %v
|
||||
run_user_not_match=Текущий пользователь не является пользователем для запуска: %s -> %s
|
||||
invalid_smtp_from=SMTP From field is not valid: %v
|
||||
invalid_smtp_from=Поле SMTP From неправильное: %v
|
||||
save_config_failed=Не удалось сохранить конфигурацию: %v
|
||||
invalid_admin_setting=Указан недопустимый параметр учетной записи администратора: %v
|
||||
install_success=Добро пожаловать! Мы рады, что вы выбрали Gogs. Веселитесь и берегите себя.
|
||||
@@ -201,6 +201,7 @@ Content=Содержимое
|
||||
require_error=` не может быть пустым.`
|
||||
alpha_dash_error=«должен быть допустимым символьным, числовым или dash(-_) значением.»
|
||||
alpha_dash_dot_error=«должен быть допустимым символьным, числовым или dash(-_) символами, включая точку.»
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` должен быть размер %s.`
|
||||
min_size_error=«должен содержать по крайней мере %s символов.»
|
||||
max_size_error=` должен содержать максимум %s символов.`
|
||||
@@ -391,7 +392,7 @@ migrate_type_helper=Этот репозиторий будет <span class="text
|
||||
migrate_repo=Перенос репозитория
|
||||
migrate.clone_address=Скопировать адрес
|
||||
migrate.clone_address_desc=Это может быть HTTP/HTTPS/GIT URL-адрес.
|
||||
migrate.clone_address_desc_import_local=You're also allowed to migrate a repository by local server path.
|
||||
migrate.clone_address_desc_import_local=Вы также можете мигрировать репозиторий по локальному пути на сервере.
|
||||
migrate.permission_denied=У вас нет прав на импорт локальных репозиториев.
|
||||
migrate.invalid_local_path=Недопустимый локальный путь. Возможно он не существует или является не папкой.
|
||||
migrate.failed=Миграция не удалась: %v
|
||||
@@ -426,6 +427,7 @@ pulls=Запросы на слияние
|
||||
labels=Метки
|
||||
milestones=Этапы
|
||||
commits=Коммиты
|
||||
git_branches=Branches
|
||||
releases=Релизы
|
||||
file_raw=Исходник
|
||||
file_history=История
|
||||
@@ -434,6 +436,13 @@ file_permalink=Постоянная ссылка
|
||||
file_too_large=Этот файл слишком большой, поэтому он не может быть отображен
|
||||
video_not_supported_in_browser=Ваш браузер не поддерживает HTML5 видео тэг.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Новый файл
|
||||
editor.upload_file=Загрузить файл
|
||||
editor.edit_file=Редактировать файл
|
||||
@@ -473,7 +482,7 @@ editor.add_subdir=Добавьте подкаталог...
|
||||
editor.unable_to_upload_files=Не удалось загрузить файлы в «%s» из-за ошибки: %v
|
||||
editor.upload_files_to_dir=Загрузить файлы '%s'
|
||||
|
||||
commits.commit_history=Commit History
|
||||
commits.commit_history=История коммитов
|
||||
commits.commits=Коммиты
|
||||
commits.search=Поиск коммитов
|
||||
commits.find=Найти
|
||||
@@ -531,7 +540,7 @@ issues.next=Следующая страница
|
||||
issues.open_title=Открыто
|
||||
issues.closed_title=Закрыто
|
||||
issues.num_comments=комментариев: %d
|
||||
issues.commented_at=«прокомментировал <a href="#%s"> %s</a>»
|
||||
issues.commented_at=`прокомментировал <a href="#%s"> %s</a>`
|
||||
issues.delete_comment_confirm=Вы уверены, что хотите удалить этот комментарий?
|
||||
issues.no_content=Пока нет содержимого.
|
||||
issues.close_issue=Закрыть
|
||||
@@ -640,27 +649,27 @@ settings.collaboration.admin=Администратор
|
||||
settings.collaboration.write=Запись
|
||||
settings.collaboration.read=Просмотр
|
||||
settings.collaboration.undefined=Не определено
|
||||
settings.branches=Branches
|
||||
settings.default_branch=Default Branch
|
||||
settings.default_branch_desc=The default branch is considered the "base" branch for code commits, pull requests and online editing.
|
||||
settings.update=Update
|
||||
settings.update_default_branch_success=Default branch of this repository has been updated successfully!
|
||||
settings.protected_branches=Protected Branches
|
||||
settings.protected_branches_desc=Protect branches from force pushing, accidental deletion and whitelist code committers.
|
||||
settings.choose_a_branch=Choose a branch...
|
||||
settings.branch_protection=Branch Protection
|
||||
settings.branch_protection_desc=Please choose protect options for branch <b>%s</b>.
|
||||
settings.protect_this_branch=Protect this branch
|
||||
settings.protect_this_branch_desc=Disable force pushes and prevent from deletion.
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
settings.protect_whitelist_search_teams=Search teams
|
||||
settings.update_protect_branch_success=Protect options for this branch has been updated successfully!
|
||||
settings.branches=Ветки
|
||||
settings.default_branch=Ветка по умолчанию
|
||||
settings.default_branch_desc=Ветка по-умолчанию считается основной для коммитов, запросов на слияние и онлайн-редактирования.
|
||||
settings.update=Обновить
|
||||
settings.update_default_branch_success=Ветка по умолчанию для этого репозитория была успешно изменена!
|
||||
settings.protected_branches=Защищенные ветки
|
||||
settings.protected_branches_desc=Защитить ветки от принудительного push, случайного удаления и разрешить изменения только коммитерам из белого списка.
|
||||
settings.choose_a_branch=Выберите ветку...
|
||||
settings.branch_protection=Защита веток
|
||||
settings.branch_protection_desc=Пожалуйста, выберите параметры защиты для ветки <b>%s</b>.
|
||||
settings.protect_this_branch=Защитить эту ветку
|
||||
settings.protect_this_branch_desc=Выключить принудительный push и защитить от удаления.
|
||||
settings.protect_require_pull_request=Требовать запрос на слияние вместо прямого push
|
||||
settings.protect_require_pull_request_desc=Включите этот параметр для запрета прямого push в это ветку. Коммит должен быть запушен в незащищенную ветку и слит в эту ветку через запрос на слияние.
|
||||
settings.protect_whitelist_committers=Белый список тех, кто может делать push в эту ветку
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Пользователи которые могут делать push в эту ветку
|
||||
settings.protect_whitelist_search_users=Поиск пользователей
|
||||
settings.protect_whitelist_teams=Команды, члены которых могут делать push в эту ветку
|
||||
settings.protect_whitelist_search_teams=Поиск команд
|
||||
settings.update_protect_branch_success=Параметры защиты этой ветки были успешно обновлены!
|
||||
settings.hooks=Автоматическое обновление
|
||||
settings.githooks=Git хуки
|
||||
settings.basic_settings=Основные параметры
|
||||
@@ -679,8 +688,8 @@ settings.external_wiki_url_desc=Посетители будут перенапр
|
||||
settings.issues_desc=Включить систему отслеживания ошибок
|
||||
settings.use_internal_issue_tracker=Использовать встроенную легковесную систему отслеживания ошибок
|
||||
settings.use_external_issue_tracker=Использовать внешнюю систему отслеживания ошибок
|
||||
settings.external_tracker_url=External Issue Tracker URL
|
||||
settings.external_tracker_url_desc=Visitors will be redirected to URL when they click on the tab.
|
||||
settings.external_tracker_url=URL внешней системы отслеживания ошибок
|
||||
settings.external_tracker_url_desc=Посетители будут перенаправлены на URL когда они нажмут на вкладку.
|
||||
settings.tracker_url_format=Внешний формат ссылки системы отслеживания ошибок.
|
||||
settings.tracker_issue_style=Стиль Именования Внешней Системы Учета Задач:
|
||||
settings.tracker_issue_style.numeric=Цифровой
|
||||
@@ -688,7 +697,7 @@ settings.tracker_issue_style.alphanumeric=Буквенноцифровой
|
||||
settings.tracker_url_format_desc=Вы можете использовать шаблон <code>{user} {repo} {index}</code> для имени пользователя, репозитория и номера задачи.
|
||||
settings.pulls_desc=Включить публичные запросы на слияние
|
||||
settings.danger_zone=Опасная зона
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
settings.cannot_fork_to_same_owner=Вы не можете ответвить репозиторий его же владельцу.
|
||||
settings.new_owner_has_same_repo=У нового владельца уже есть хранилище с таким названием.
|
||||
settings.convert=Преобразовать в обычный репозиторий
|
||||
settings.convert_desc=Это зеркало можно преобразовать в обычный репозиторий. Это не может быть отменено.
|
||||
@@ -745,7 +754,7 @@ settings.add_webhook_desc=Мы отправим запрос <code>POST</code>
|
||||
settings.payload_url=URL обработчика
|
||||
settings.content_type=Тип содержимого
|
||||
settings.secret=Secret
|
||||
settings.secret_desc=Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.secret_desc=Секрет будет отправлен как SHA256 HMAC контента в шестнадцатеричном виде в заголовке <code>X-Gogs-Signature</code>.
|
||||
settings.slack_username=Имя пользователя
|
||||
settings.slack_icon_url=URL иконки
|
||||
settings.slack_color=Цвет
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Мне нужно <strong>все</strong>.
|
||||
settings.event_choose=Позвольте мне выбрать то, что нужно.
|
||||
settings.event_create=Создать
|
||||
settings.event_create_desc=Ветка или тэг созданы
|
||||
settings.event_pull_request=Запросы на слияние
|
||||
settings.event_pull_request_desc=Запрос слияния открыт, закрыт, переоткрыт, изменён, назначен, снят, метка обновлена, метка убрана, или синхронизирован.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Push в репозиторий
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Запросы на слияние
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Активен
|
||||
settings.active_helper=Подробности о событии, вызвавшем срабатывание хука, также будут предоставлены.
|
||||
settings.add_hook_success=Был добавлен новый webhook.
|
||||
@@ -768,12 +787,12 @@ settings.delete_webhook=Удалить автоматическое обновл
|
||||
settings.recent_deliveries=Недавние рассылки
|
||||
settings.hook_type=Тип перехватчика
|
||||
settings.add_slack_hook_desc=Добавить интеграцию с <a href="%s">Slack</a> в ваш репозиторий.
|
||||
settings.add_discord_hook_desc=Add <a href="%s">Discord</a> integration to your repository.
|
||||
settings.add_discord_hook_desc=Добавить интеграцию с <a href="%s">Discord</a> в ваш репозиторий.
|
||||
settings.slack_token=Token
|
||||
settings.slack_domain=Домен
|
||||
settings.slack_channel=Канал
|
||||
settings.deploy_keys=Ключи развертывания
|
||||
settings.deploy_keys_helper=<b>Common Gotcha!</b> If you're looking for adding personal public keys, please add them in your <a href="%s%s">account settings</a>.
|
||||
settings.deploy_keys_helper=<b>Common Gotcha!</b> Если вы ищите куда добавить персональные публичные ключи, добавьте их в <a href="%s%s">настройках вашего аккаунта</a>.
|
||||
settings.add_deploy_key=Добавить ключ развертывания
|
||||
settings.deploy_key_desc=Ключи развёртывания доступны только для чтения. Это не то же самое что и SSH-ключи аккаунта.
|
||||
settings.no_deploy_keys=Вы не добавляли ключи развертывания.
|
||||
@@ -803,7 +822,6 @@ release.releases=Релизы
|
||||
release.new_release=Новый релиз
|
||||
release.draft=Черновик
|
||||
release.prerelease=Пре-релиз
|
||||
release.stable=Стабильный
|
||||
release.edit=Редактировать
|
||||
release.ahead=<strong>%d</strong> коммитов %s начиная с этого релиза
|
||||
release.source_code=Исходный код
|
||||
@@ -852,7 +870,7 @@ team_permission_desc=Какой уровень разрешений должен
|
||||
|
||||
form.name_reserved=Наименование организации '%s' зарезервированно.
|
||||
form.name_pattern_not_allowed=Шаблон организации '%s' не допускается.
|
||||
form.team_name_reserved=Team name '%s' is reserved.
|
||||
form.team_name_reserved=Имя команды '%s' зарезервировано.
|
||||
|
||||
settings=Настройки
|
||||
settings.options=Опции
|
||||
@@ -943,8 +961,8 @@ dashboard.git_gc_repos=Выполнить сборку мусора на реп
|
||||
dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена.
|
||||
dashboard.resync_all_sshkeys=Переписать файл «.ssh/authorized_keys» (осторожно: не Gogs ключи будут утеряны)
|
||||
dashboard.resync_all_sshkeys_success=Были успешно переписаны все открытые ключи.
|
||||
dashboard.resync_all_hooks=Resync pre-receive, update and post-receive hooks of all repositories
|
||||
dashboard.resync_all_hooks_success=All repositories' pre-receive, update and post-receive hooks have been resynced successfully.
|
||||
dashboard.resync_all_hooks=Повторная синхронизация хуков pre-receive, update и post-receive во всех репозиториях
|
||||
dashboard.resync_all_hooks_success=Все хуки pre-receive, update и post-receive во всех репозиториях были успешно повторно синхронизированы.
|
||||
dashboard.reinit_missing_repos=Реинициализировать все репозитории с утерянными Git файлами
|
||||
dashboard.reinit_missing_repos_success=Все репозитории с утерянными Git файлами успешно реинициализированы.
|
||||
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Приватный
|
||||
repos.watches=Следят
|
||||
repos.stars=В избранном
|
||||
repos.issues=Задачи
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Панель управления аутнентификациями
|
||||
auths.new=Добавить новый источник
|
||||
@@ -1077,7 +1096,7 @@ config.offline_mode=Автономный режим
|
||||
config.disable_router_log=Отключение журнала маршрутизатора
|
||||
config.run_user=Запуск пользователем
|
||||
config.run_mode=Режим выполнения
|
||||
config.git_version=Git Version
|
||||
config.git_version=Версия Git
|
||||
config.static_file_root_path=Статичный путь до файла
|
||||
config.log_file_root_path=Путь до папки с логами
|
||||
config.reverse_auth_user=Заголовок с именем пользователя для авторизации на reverse proxy
|
||||
@@ -1094,15 +1113,15 @@ config.ssh_keygen_path=Путь к генератору ключей ('ssh-keyge
|
||||
config.ssh_minimum_key_size_check=Минимальный размер ключа проверки
|
||||
config.ssh_minimum_key_sizes=Минимальные размеры ключа
|
||||
|
||||
config.repo_config=Repository Configuration
|
||||
config.repo_config=Настройка репозитория
|
||||
config.repo_root_path=Путь до корня репозитория
|
||||
config.script_type=Тип сценария
|
||||
config.repo_force_private=Force Private
|
||||
config.max_creation_limit=Max Creation Limit
|
||||
config.preferred_licenses=Preferred Licenses
|
||||
config.disable_http_git=Disable HTTP Git
|
||||
config.enable_local_path_migration=Enable Local Path Migration
|
||||
config.commits_fetch_concurrency=Commits Fetch Concurrency
|
||||
config.repo_force_private=Сделать личным принудительно
|
||||
config.max_creation_limit=Лимит созданий
|
||||
config.preferred_licenses=Предпочитаемые лицензии
|
||||
config.disable_http_git=Выключить HTTP Git
|
||||
config.enable_local_path_migration=Включить миграцию с локального пути
|
||||
config.commits_fetch_concurrency=Параллельность получения коммитов
|
||||
|
||||
config.db_config=Конфигурация базы данных
|
||||
config.db_type=Тип
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Время Ожидания Операции Извле
|
||||
config.git_gc_timeout=Время Ожидания Операции Сборки Мусора
|
||||
|
||||
config.log_config=Конфигурация журнала
|
||||
config.log_mode=Режим журналирования
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Задачи cron
|
||||
monitor.name=Имя
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Системное уведомление успешно
|
||||
|
||||
[action]
|
||||
create_repo=создал(а) репозиторий <a href="%s"> %s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=переименовал(а) репозиторий из <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=запушил(а) <a href="%[1]s/src/%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Просмотр сравнение для этих %d коммитов
|
||||
transfer_repo=перенес репозиторий <code>%s</code> в <a href="%s">%s</a>
|
||||
create_issue=`открыл(а) задачу <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`закрыл(а) задачу <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`возобновил(а) задачу <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`прокомментировал(а) вопрос <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`создал запрос на слияние <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`закрыл запрос на слияние <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`открыл снова запрос на слияние <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`прокомментировал(а) вопрос <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`слил пул реквест <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=перенес репозиторий <code>%s</code> в <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=запушил(а) метку <a href="%s/src/%s">%[2]s</a> в <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Просмотр сравнение для этих %d коммитов
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=назад
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Садржај
|
||||
require_error=` не може бити празно.`
|
||||
alpha_dash_error=` мора се састојати словима, бројевима или dash(-_) карактера.`
|
||||
alpha_dash_dot_error=` мора се састојати словима, бројевима, dash(-_) карактера, или тачком.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` мора бити величине %s.`
|
||||
min_size_error=` мора да садржи најмање %s карактера.`
|
||||
max_size_error=` мора да садржи највише %s карактера.`
|
||||
@@ -426,6 +427,7 @@ pulls=Захтеви за спајање
|
||||
labels=Лабеле
|
||||
milestones=Фазе
|
||||
commits=Комити
|
||||
git_branches=Branches
|
||||
releases=Издања
|
||||
file_raw=Датотека
|
||||
file_history=Историја
|
||||
@@ -434,6 +436,13 @@ file_permalink=Пермалинк
|
||||
file_too_large=Ова датотека је превише веика да би се приказала
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Нова датотека
|
||||
editor.upload_file=Отпреми датотеку
|
||||
editor.edit_file=Ажурирај датотеку
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=У <strong>свим</strong> догађајима
|
||||
settings.event_choose=Изабраћу шта ми је потребно.
|
||||
settings.event_create=Креирај
|
||||
settings.event_create_desc=Створена грана или ознака
|
||||
settings.event_pull_request=Захтев за спајање
|
||||
settings.event_pull_request_desc=Захтев за спајање отворенo, затворено, додељено, недодељенo, лабела ажурирана, лабела избрисана, или синхронизовано.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push у спремиште
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Захтев за спајање
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Активно
|
||||
settings.active_helper=Детаљи о догађају што је проузроковало hook ће исто бити испоручено.
|
||||
settings.add_hook_success=Додат је нови webhook.
|
||||
@@ -803,7 +822,6 @@ release.releases=Издања
|
||||
release.new_release=Ново издање
|
||||
release.draft=Нацрт
|
||||
release.prerelease=Пред-верзија
|
||||
release.stable=Стабилно
|
||||
release.edit=уреди
|
||||
release.ahead=<strong>%d</strong> комита на %s почев од овог издања
|
||||
release.source_code=Изворни код
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Приватно
|
||||
repos.watches=Watches
|
||||
repos.stars=Фаворити
|
||||
repos.issues=Задаци
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Контролна панела аутентикације
|
||||
auths.new=Додај нови извор
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Време до отказивања pull операци
|
||||
config.git_gc_timeout=Време до отказивања cакупљање смећа
|
||||
|
||||
config.log_config=Kонфигурација журнала
|
||||
config.log_mode=Режим журналовања
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron задаци
|
||||
monitor.name=Име
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Системска обавештавања су успе
|
||||
|
||||
[action]
|
||||
create_repo=креира спремиште <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=преимензје спремиште од <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=извршује push на <a href="%[1]s/src/%[2]s">%[3]s</a> у <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Поређење ових %d комита
|
||||
transfer_repo=преноси спремиште <code>%s</code> на <a href="%s">%s</a>
|
||||
create_issue=`отвара задатак <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`затвара задатак <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`поново отвара задатак <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`коментарише на задатаку <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`шаље захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`затвара захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`поново отвара захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`коментарише на задатаку <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`прихваћује захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=преноси спремиште <code>%s</code> на <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=извршује push са ознаком <a href="%s/src/%s">%[2]s</a> на <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Поређење ових %d комита
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=пре
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Innehåll
|
||||
require_error=får inte vara tomt
|
||||
alpha_dash_error=` får bara innehålla bokstäver, nummer och bindestreck (-_).`
|
||||
alpha_dash_dot_error=` får bara innehålla bokstäver, nummer, bindestreck (-_) och punkt`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` måste vara av storleken %s`
|
||||
min_size_error=` måste innehålla minst %s tecken.`
|
||||
max_size_error=` får inte innehålla mer än %s tecken.`
|
||||
@@ -426,6 +427,7 @@ pulls=Pull-förfrågningar
|
||||
labels=Etiketter
|
||||
milestones=Milstenar
|
||||
commits=Incheckningar
|
||||
git_branches=Branches
|
||||
releases=Släpp
|
||||
file_raw=Rå
|
||||
file_history=Historik
|
||||
@@ -434,6 +436,13 @@ file_permalink=Permalänk
|
||||
file_too_large=Denna fil är för stor för att visas
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=Ny fil
|
||||
editor.upload_file=Ladda upp fil
|
||||
editor.edit_file=Redigera fil
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Jag behöver <strong>allt</strong>.
|
||||
settings.event_choose=Låt mig välja.
|
||||
settings.event_create=Skapa
|
||||
settings.event_create_desc=Branch eller tagg skapad
|
||||
settings.event_pull_request=Hämtningsbegäran
|
||||
settings.event_pull_request_desc=Hämtningsbegäran öppnad, stängd, återöppnad, redigerad, tilldelad, otilldelad, etikett uppdaterad, etikett rensad eller synkroniserad.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Pusha
|
||||
settings.event_push_desc=Uppladdning till ett förråd
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Hämtningsbegäran
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktiv
|
||||
settings.active_helper=Detaljer kring händelsen som triggade kroken kommer också levereras.
|
||||
settings.add_hook_success=Ny webbkrok har lagts till.
|
||||
@@ -803,7 +822,6 @@ release.releases=Släpp
|
||||
release.new_release=Nytt Släpp
|
||||
release.draft=Utkast
|
||||
release.prerelease=Försläpp
|
||||
release.stable=Stabil
|
||||
release.edit=redigera
|
||||
release.ahead=<strong>%d</strong> ändringar mot %s sedan detta släpp
|
||||
release.source_code=Källkod
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Privat
|
||||
repos.watches=Vakter
|
||||
repos.stars=Stjärnor
|
||||
repos.issues=Ärenden
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Panel för hantering av autentisering
|
||||
auths.new=Lägg till ny källa
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Pull Operation Timeout
|
||||
config.git_gc_timeout=GC Operation Timeout
|
||||
|
||||
config.log_config=Logg-konfiguration
|
||||
config.log_mode=Loggningsläge
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron-jobb
|
||||
monitor.name=Namn
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=System notices have been deleted successfully.
|
||||
|
||||
[action]
|
||||
create_repo=skapade utvecklingskatalog <a href="%s"> %s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=pushed to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=View comparison for these %d commits
|
||||
transfer_repo=transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
create_issue=`opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=View comparison for these %d commits
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=sedan
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Content
|
||||
require_error=` boş olamaz.`
|
||||
alpha_dash_error=` sadece karakter, rakam veya çizgi(-_) içermelidir.`
|
||||
alpha_dash_dot_error=` sadece karakter, rakam, çizgi(-_) veya nokta içermelidir.`
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=` uzunluk en fazla %s olmalıdır.`
|
||||
min_size_error=` en az %s karakter içermelidir.`
|
||||
max_size_error=` en fazla %s karakter içermelidir.`
|
||||
@@ -426,6 +427,7 @@ pulls=Değişiklik İstekleri
|
||||
labels=Etiketler
|
||||
milestones=Kilometre Taşları
|
||||
commits=İşlemeler
|
||||
git_branches=Branches
|
||||
releases=Sürümler
|
||||
file_raw=Ham
|
||||
file_history=Geçmiş
|
||||
@@ -434,6 +436,13 @@ file_permalink=Kalıcı Bağlantı
|
||||
file_too_large=Bu dosya sergilenmek için çok büyük
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=New file
|
||||
editor.upload_file=Upload file
|
||||
editor.edit_file=Dosya düzenle
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=<strong>Her şeye</strong> ihtiyacım var.
|
||||
settings.event_choose=Neye ihtiyacım olduğunu seçtir.
|
||||
settings.event_create=Oluştur
|
||||
settings.event_create_desc=Dal veya biçim imi oluşturuldu
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Bir depoya git push
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=Aktif
|
||||
settings.active_helper=Bu isteği tetikleyen olaya ilişkin detaylar da gönderilecektir.
|
||||
settings.add_hook_success=Yeni web isteği eklendi.
|
||||
@@ -803,7 +822,6 @@ release.releases=Sürümler
|
||||
release.new_release=Yeni Sürüm
|
||||
release.draft=Taslak
|
||||
release.prerelease=Ön Sürüm
|
||||
release.stable=Kararlı
|
||||
release.edit=düzenle
|
||||
release.ahead=%s son sürümden beri <strong>%d</strong> işleme
|
||||
release.source_code=Kaynak Kodu
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Özel
|
||||
repos.watches=İzlemeler
|
||||
repos.stars=Yıldızlar
|
||||
repos.issues=Sorunlar
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=Yetkilendirme Yönetim Paneli
|
||||
auths.new=Yeni Kaynak Ekle
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Pull Operation Timeout
|
||||
config.git_gc_timeout=GC Operation Timeout
|
||||
|
||||
config.log_config=Log Yapılandırması
|
||||
config.log_mode=Log Modu
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron Görevleri
|
||||
monitor.name=İsim
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Sistem bildirimleri başarıyla silindi.
|
||||
|
||||
[action]
|
||||
create_repo=depo <a href="%s">%s</a> oluşturuldu
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=<code>%[1]s</code> olan depo adını <a href="%[2]s">%[3]s</a> buna çevirdi
|
||||
commit_repo=<a href="%[1]s">%[4]s</a> zamanında <a href="%[1]s/src/%[2]s">%[3]s</a> buraya push yaptı
|
||||
compare_commits=Bu %d işlemeler için karşılaştırmaları görüntüle
|
||||
transfer_repo=depo <code>%s</code> <a href="%s">%s</a>'a aktarıldı
|
||||
create_issue=`<a href="%s/issues/%s">%s#%[2]s</a> sorununu açtı`
|
||||
close_issue=`<a href="%s/issues/%s">%s#%[2]s</a> sorununu kapattı`
|
||||
reopen_issue=`<a href="%s/issues/%s">%s#%[2]s</a> sorununu tekrar açtı`
|
||||
comment_issue=`<a href="%s/issues/%s">%s#%[2]s</a> sorununa yorum yazdı`
|
||||
create_pull_request=`<a href="%s/pulls/%s">%s#%[2]s</a> değişiklik isteğini oluşturdu`
|
||||
close_pull_request=`<a href="%s/pulls/%s">%s#%[2]s</a> değişiklik isteğini kapattı`
|
||||
reopen_pull_request=`<a href="%s/pulls/%s">%s#%[2]s</a> değişiklik isteğini tekrar açtı`
|
||||
comment_issue=`<a href="%s/issues/%s">%s#%[2]s</a> sorununa yorum yazdı`
|
||||
merge_pull_request=`<a href="%s/pulls/%s">%s#%[2]s</a> değişim isteğini birleştirdi`
|
||||
transfer_repo=depo <code>%s</code> <a href="%s">%s</a>'a aktarıldı
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=etiket <a href="%s/src/%s">%[2]s</a> <a href="%[1]s">%[3]s</a>'a itelendi
|
||||
compare_commits=Bu %d işlemeler için karşılaştırmaları görüntüle
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=önce
|
||||
|
||||
@@ -40,7 +40,7 @@ your_settings=Ваші налаштування
|
||||
|
||||
activities=Дії
|
||||
pull_requests=Запити на злиття
|
||||
issues=Обговорення
|
||||
issues=Проблеми
|
||||
|
||||
cancel=Скасувати
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Вміст
|
||||
require_error=' не може бути пустим.'
|
||||
alpha_dash_error=` має складатись з буков, цифр, або рисок(-_).`
|
||||
alpha_dash_dot_error=` має складатись з буков, цифр, рисок(-_), або крапок.`
|
||||
alpha_dash_dot_slash_error=` мусить бути валідною буквою, або цифрою, або рискою(-_), або крапкою, або слешем.`
|
||||
size_error=` має мати розмір %s.`
|
||||
min_size_error=' має містити принаймні %s символів.'
|
||||
max_size_error=' має містити принаймні %s символів.'
|
||||
@@ -426,6 +427,7 @@ pulls=Запити на злиття
|
||||
labels=Мітка
|
||||
milestones=Проміжні етапи
|
||||
commits=Коміти
|
||||
git_branches=Гілки
|
||||
releases=Релізи
|
||||
file_raw=Запис
|
||||
file_history=Історія
|
||||
@@ -434,6 +436,13 @@ file_permalink=Постійне посилання
|
||||
file_too_large=Цей файл завеликий для показу
|
||||
video_not_supported_in_browser=Ваш браузер не підтримує єлемент HTML5 video.
|
||||
|
||||
branches.overview=Огляд
|
||||
branches.active_branches=Активні гілки
|
||||
branches.stale_branches=Застарілі гілки
|
||||
branches.all=Усі гілки
|
||||
branches.updated_by=Оновлено %[1]s з %[2]s
|
||||
branches.change_default_branch=Гілку за замовчуванням змінено
|
||||
|
||||
editor.new_file=Новий файл
|
||||
editor.upload_file=Завантажити файл
|
||||
editor.edit_file=Редагування файла
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Вимкнути примусовий push т
|
||||
settings.protect_require_pull_request=Вимагати запрос на злиття замість прямого push
|
||||
settings.protect_require_pull_request_desc=Увімкніть цю опцію для заборони прямого push у цю гілку. Коміт має бути запушений у іншу, незахищену гілку та влитий у цю через запрос на злиття.
|
||||
settings.protect_whitelist_committers=Білий список тих, хто може робити push у цю гілку
|
||||
settings.protect_whitelist_committers_desc=Додати людей або команди у білий список для виконання push до цієї гілки.
|
||||
settings.protect_whitelist_committers_desc=Додати людей або команди до білого списку тих, хто може робити push у цю гілку. Користувачі з білого списку оминатимуть контроль запитів на злиття.
|
||||
settings.protect_whitelist_users=Користувачі що можуть виконувати push до цієї гілки
|
||||
settings.protect_whitelist_search_users=Пошук користувачів
|
||||
settings.protect_whitelist_teams=Команди, члени яких можуть виконувати push до цієї гілки
|
||||
@@ -688,7 +697,7 @@ settings.tracker_issue_style.alphanumeric=Буквено-цифровий
|
||||
settings.tracker_url_format_desc=Ви можете використовувати заповнювач <code>{user} {repo} {index}</code> для ім'я користувача, назви репозиторію на номеру проблеми.
|
||||
settings.pulls_desc=Увімкнути публічні запроси на злиття
|
||||
settings.danger_zone=Небезпечна зона
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
settings.cannot_fork_to_same_owner=Ви не можете клонувати репозиторій його ж власнику.
|
||||
settings.new_owner_has_same_repo=Новий власник вже має репозиторій з такою назвою.
|
||||
settings.convert=Перетворити на звичайний репозиторій
|
||||
settings.convert_desc=Ви можете сконвертувати це дзеркало у звичайний репозиторій. Це не може бути повернуто.
|
||||
@@ -745,7 +754,7 @@ settings.add_webhook_desc=Gogs відправляє <code>POST</code> запит
|
||||
settings.payload_url=URL розробника
|
||||
settings.content_type=Тип змісту
|
||||
settings.secret=Таємний код
|
||||
settings.secret_desc=Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.secret_desc=Секрет буде вислано SHA256 HMAC hex-сумою вміста у хідері <code>X-Gogs-Signature</code>.
|
||||
settings.slack_username=Ім'я користувача
|
||||
settings.slack_icon_url=URL іконки
|
||||
settings.slack_color=Колір
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=Мені потрібно <strong>усе</strong>
|
||||
settings.event_choose=Дозвольте мені вибрати те, що потрібно.
|
||||
settings.event_create=Створити
|
||||
settings.event_create_desc=Гілку або тег створено
|
||||
settings.event_pull_request=Запити до злиття
|
||||
settings.event_pull_request_desc=Запрос злиття відкрито, закрито, перевідкрито, змінено, призначено, знято, мітку оновлено, мітку прибрано або синхронізовано.
|
||||
settings.event_delete=Видалити
|
||||
settings.event_delete_desc=Гілку або мітку було видалено
|
||||
settings.event_fork=Відгалуження
|
||||
settings.event_fork_desc=Репозиторій було відгалуджено
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push до репозиторію
|
||||
settings.event_issues=Проблеми
|
||||
settings.event_issues_desc=Проблему відкрито, закрито, перевідкрито, відредаговано, призначено, відкріплено, змінено мітку, очищено мітку, створено етап, очищено етап.
|
||||
settings.event_issue_comment=Коментар проблеми
|
||||
settings.event_issue_comment_desc=Коментар проблеми створено, видалено чи відредаговано.
|
||||
settings.event_pull_request=Запити до злиття
|
||||
settings.event_pull_request_desc=Запрос на злиття відкрито, закрито, перевідкрито, прикріплено, відкріплено, оновлено мітку, очищено мітку, створено етап, очищено етап або синхронізовано.
|
||||
settings.event_release=Реліз
|
||||
settings.event_release_desc=Реліз опубліковано у репозиторії.
|
||||
settings.active=Активний
|
||||
settings.active_helper=Подробиці події, що викликала спрацювання хука, будуть надані також.
|
||||
settings.add_hook_success=Новий web-хук було додано.
|
||||
@@ -803,7 +822,6 @@ release.releases=Релізи
|
||||
release.new_release=Новий реліз
|
||||
release.draft=Чернетка
|
||||
release.prerelease=Пре-реліз
|
||||
release.stable=Стабільний
|
||||
release.edit=редагувати
|
||||
release.ahead=<strong>%d</strong> коммітів %s після цього релізу
|
||||
release.source_code=Вихідний код
|
||||
@@ -1019,6 +1037,7 @@ repos.private=Приватний
|
||||
repos.watches=Стежать
|
||||
repos.stars=У обраному
|
||||
repos.issues=Питання
|
||||
repos.size=Розмір
|
||||
|
||||
auths.auth_manage_panel=Керування автентифікацій
|
||||
auths.new=Додати нове джерело
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Тайм-аут операції витягання
|
||||
config.git_gc_timeout=Тайм-аут операції GC
|
||||
|
||||
config.log_config=Конфігурація журналу
|
||||
config.log_mode=Режим журналювання
|
||||
config.log_mode=Режим
|
||||
config.log_options=Опції
|
||||
|
||||
monitor.cron=Завдання cron
|
||||
monitor.name=Назва
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=Системні повідомлення було усп
|
||||
|
||||
[action]
|
||||
create_repo=створено репозиторій <a href="%s">%s</a>
|
||||
fork_repo=відгалуджено репозиторій у <a href="%s">%s</a>
|
||||
rename_repo=репозиторій перейменовано з <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=запушено до <a href="%[1]s/src/%[2]s">%[3]s</a> у <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=Перегляд порівняння для цих %d комітів
|
||||
transfer_repo=перенесено репозиторій <code>%s</code> у <a href="%s">%s</a>
|
||||
create_issue=`відкрито проблему <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`закрито проблему <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`перевідкрито проблему <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`відкоментовано проблему <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`створено запит на втягування <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`закрито запит на втягування <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`перевідкрито запит на втягування <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`відкоментовано проблему <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`запит на злиття влито <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=перенесено репозиторій <code>%s</code> у <a href="%s">%s</a>
|
||||
create_branch=створено нову гілку <a href="%[1]s/src/%[2]s">%[3]s</a> у <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=видалено гілку <code>%[2]s</code> у <a href="%[1]s">%[3]s</a>
|
||||
push_tag=заштовхнуто тег <a href="%s/src/%s">%[2]s</a> до <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=Перегляд порівняння для цих %d комітів
|
||||
delete_tag=видалено мітку <code>%[2]s</code> у <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=тому
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=内容
|
||||
require_error=不能为空。
|
||||
alpha_dash_error=必须为英文字母、阿拉伯数字或横线(-_)。
|
||||
alpha_dash_dot_error=必须为英文字母、阿拉伯数字、横线(-_)或点。
|
||||
alpha_dash_dot_slash_error=必须为英文字母、阿拉伯数字、横线(-_)、点或斜线。
|
||||
size_error=长度必须为 %s。
|
||||
min_size_error=长度最小为 %s 个字符。
|
||||
max_size_error=长度最大为 %s 个字符。
|
||||
@@ -426,6 +427,7 @@ pulls=合并请求
|
||||
labels=标签管理
|
||||
milestones=里程碑
|
||||
commits=提交历史
|
||||
git_branches=代码分支
|
||||
releases=版本发布
|
||||
file_raw=原始文件
|
||||
file_history=文件历史
|
||||
@@ -434,6 +436,13 @@ file_permalink=永久链接
|
||||
file_too_large=文件过大导致无法显示
|
||||
video_not_supported_in_browser=您的浏览器不支持使用 HTML5 播放视频。
|
||||
|
||||
branches.overview=概况
|
||||
branches.active_branches=活跃分支
|
||||
branches.stale_branches=陈旧分支
|
||||
branches.all=所有分支
|
||||
branches.updated_by=由 %[2]s 更新于 %[1]s
|
||||
branches.change_default_branch=更改默认分支
|
||||
|
||||
editor.new_file=新的文件
|
||||
editor.upload_file=上传文件
|
||||
editor.edit_file=编辑文件
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=禁止强制推送和删除分支。
|
||||
settings.protect_require_pull_request=要求通过合并请求提交代码
|
||||
settings.protect_require_pull_request_desc=启用该选项后代码将不能直接被推送到此分支,所有的代码提交都必须通过另一个非保护分支发起合并请求进行合并。
|
||||
settings.protect_whitelist_committers=限制可以推送代码的成员
|
||||
settings.protect_whitelist_committers_desc=添加用户或团队到可直接推送代码的白名单。
|
||||
settings.protect_whitelist_committers_desc=添加用户或团队到可直接推送代码的白名单,列入白名单中的用户将跳过合并请求检查。
|
||||
settings.protect_whitelist_users=允许推送到此分支的用户
|
||||
settings.protect_whitelist_search_users=搜索用户
|
||||
settings.protect_whitelist_teams=允许其成员推送到此分支的团队
|
||||
@@ -751,14 +760,24 @@ settings.slack_icon_url=图标 URL
|
||||
settings.slack_color=颜色代码
|
||||
settings.event_desc=请设置您希望触发 Web 钩子的事件:
|
||||
settings.event_push_only=只推送 <code>push</code> 事件。
|
||||
settings.event_send_everything=请把 <strong>一切</strong> 都给我
|
||||
settings.event_choose=我的命运自己主宰
|
||||
settings.event_send_everything=推送 <strong>所有</strong> 事件
|
||||
settings.event_choose=选择指定的事件
|
||||
settings.event_create=创建
|
||||
settings.event_create_desc=创建分支或标签
|
||||
settings.event_pull_request=合并请求
|
||||
settings.event_pull_request_desc=开启、关闭、重新开启、编辑、指派、取消指派、更新标签、清除标签或同步合并请求
|
||||
settings.event_delete=删除
|
||||
settings.event_delete_desc=删除分支或标签
|
||||
settings.event_fork=派生
|
||||
settings.event_fork_desc=仓库被派生
|
||||
settings.event_push=推送
|
||||
settings.event_push_desc=Git 仓库推送
|
||||
settings.event_issues=工单
|
||||
settings.event_issues_desc=工单被开启、关闭、重新开启、编辑、指派、取消指派、更新标签、清除标签、设置里程碑或取消设置里程碑
|
||||
settings.event_issue_comment=工单评论
|
||||
settings.event_issue_comment_desc=工单评论被创建、编辑和删除
|
||||
settings.event_pull_request=合并请求
|
||||
settings.event_pull_request_desc=合并请求被开启、关闭、重新开启、编辑、指派、取消指派、更新标签、清除标签、设置里程碑、取消设置里程碑或代码同步
|
||||
settings.event_release=版本发布
|
||||
settings.event_release_desc=仓库发布新的版本
|
||||
settings.active=是否激活
|
||||
settings.active_helper=当指定事件发生时我们将会触发此 Web 钩子。
|
||||
settings.add_hook_success=Web 钩子添加成功!
|
||||
@@ -803,7 +822,6 @@ release.releases=版本发布
|
||||
release.new_release=发布新版
|
||||
release.draft=草稿
|
||||
release.prerelease=预发行
|
||||
release.stable=稳定
|
||||
release.edit=编辑
|
||||
release.ahead=在该版本发布之后已有 <strong>%d</strong> 次代码提交到 %s 分支
|
||||
release.source_code=源代码
|
||||
@@ -1019,6 +1037,7 @@ repos.private=私有库
|
||||
repos.watches=关注数
|
||||
repos.stars=点赞数
|
||||
repos.issues=工单数
|
||||
repos.size=用量
|
||||
|
||||
auths.auth_manage_panel=认证管理面板
|
||||
auths.new=添加新的源
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=拉取操作超时
|
||||
config.git_gc_timeout=GC 操作超时
|
||||
|
||||
config.log_config=日志配置
|
||||
config.log_mode=日志模式
|
||||
config.log_mode=模式
|
||||
config.log_options=选项
|
||||
|
||||
monitor.cron=Cron 任务
|
||||
monitor.name=任务名称
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=系统提示删除成功!
|
||||
|
||||
[action]
|
||||
create_repo=创建了仓库 <a href="%s">%s</a>
|
||||
fork_repo=派生了仓库 <a href="%s">%s</a>
|
||||
rename_repo=重命名仓库 <code>%[1]s</code> 为 <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=推送了 <a href="%[1]s/src/%[2]s">%[3]s</a> 分支的代码到 <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=对比 %d 次代码提交
|
||||
transfer_repo=将仓库 <code>%s</code> 转移至 <a href="%s">%s</a>
|
||||
create_issue=`创建了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`关闭了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`重新开启了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`评论了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`创建了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`关闭了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`重新开启了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`评论了工单 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`合并了合并请求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=将仓库 <code>%s</code> 转移至 <a href="%s">%s</a>
|
||||
create_branch=创建了新的分支 <a href="%[1]s/src/%[2]s">%[3]s</a> 到 <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=删除了 <a href="%[1]s">%[3]s</a> 的分支 <code>%[2]s</code>
|
||||
push_tag=推送了标签 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=对比 %d 次代码提交
|
||||
delete_tag=删除了 <a href="%[1]s">%[3]s</a> 的标签 <code>%[2]s</code>
|
||||
|
||||
[tool]
|
||||
ago=之前
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=Content
|
||||
require_error=不能為空。
|
||||
alpha_dash_error=必須為英文字母、阿拉伯數字或橫線(-_)。
|
||||
alpha_dash_dot_error=必須為英文字母、阿拉伯數字、橫線(-_)或點。
|
||||
alpha_dash_dot_slash_error=` must be valid alpha or numeric or dash(-_) or dot characters or slashes.`
|
||||
size_error=長度必須為 %s。
|
||||
min_size_error=長度最小為 %s 個字符。
|
||||
max_size_error=長度最大為 %s 個字符。
|
||||
@@ -426,6 +427,7 @@ pulls=合併請求
|
||||
labels=標籤
|
||||
milestones=里程碑
|
||||
commits=提交歷史
|
||||
git_branches=Branches
|
||||
releases=版本發佈
|
||||
file_raw=原始文件
|
||||
file_history=文件歷史
|
||||
@@ -434,6 +436,13 @@ file_permalink=永久連結
|
||||
file_too_large=This file is too large to be shown
|
||||
video_not_supported_in_browser=Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview=Overview
|
||||
branches.active_branches=Active Branches
|
||||
branches.stale_branches=Stale Branches
|
||||
branches.all=All Branches
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.change_default_branch=Change Default Branch
|
||||
|
||||
editor.new_file=New file
|
||||
editor.upload_file=Upload file
|
||||
editor.edit_file=Edit file
|
||||
@@ -655,7 +664,7 @@ settings.protect_this_branch_desc=Disable force pushes and prevent from deletion
|
||||
settings.protect_require_pull_request=Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc=Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers=Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch.
|
||||
settings.protect_whitelist_committers_desc=Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=推送 <strong>所有</strong> 事件
|
||||
settings.event_choose=讓我選擇我的需要
|
||||
settings.event_create=創建
|
||||
settings.event_create_desc=創建分支或標籤
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
|
||||
settings.event_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_push=推送
|
||||
settings.event_push_desc=Git 倉庫推送
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.active=是否激活
|
||||
settings.active_helper=當指定事件發生時我們將會觸發此 Web 鉤子。
|
||||
settings.add_hook_success=Web 鉤子添加成功!
|
||||
@@ -803,7 +822,6 @@ release.releases=版本發佈
|
||||
release.new_release=發佈新版本
|
||||
release.draft=草稿
|
||||
release.prerelease=預發佈版本
|
||||
release.stable=穩定
|
||||
release.edit=編輯
|
||||
release.ahead=在該版本發佈之後已有 <strong>%d</strong> 次代碼提交到 %s 分支
|
||||
release.source_code=源代碼
|
||||
@@ -1019,6 +1037,7 @@ repos.private=私有庫
|
||||
repos.watches=關註數
|
||||
repos.stars=讚好數
|
||||
repos.issues=問題數
|
||||
repos.size=Size
|
||||
|
||||
auths.auth_manage_panel=認證管理面板
|
||||
auths.new=添加新認證源
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=Pull Operation Timeout
|
||||
config.git_gc_timeout=GC Operation Timeout
|
||||
|
||||
config.log_config=日誌配置
|
||||
config.log_mode=日誌模式
|
||||
config.log_mode=Mode
|
||||
config.log_options=Options
|
||||
|
||||
monitor.cron=Cron 任務
|
||||
monitor.name=任務名稱
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=系統提示刪除成功!
|
||||
|
||||
[action]
|
||||
create_repo=創建了儲存庫 <a href="%s">%s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
rename_repo=重新命名倉庫 <code>%[1]s</code> 為 <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=推送了 <a href="%[1]s/src/%[2]s">%[3]s</a> 分支的代碼到 <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=查看 %d 次提交的內容比對
|
||||
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
|
||||
create_issue=`創建了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`創建了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`合併了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
|
||||
create_branch=created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag=推送了標籤 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=查看 %d 次提交的內容比對
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
|
||||
[tool]
|
||||
ago=之前
|
||||
|
||||
@@ -201,6 +201,7 @@ Content=內容
|
||||
require_error=不能為空。
|
||||
alpha_dash_error=必須為英文字母、阿拉伯數字或橫線(-_)。
|
||||
alpha_dash_dot_error=必須為英文字母、阿拉伯數字、橫線(-_)或點。
|
||||
alpha_dash_dot_slash_error=` 必須是合法的英文字母、數字、分隔符號(-_)、半形句點或斜線。`
|
||||
size_error=長度必須為 %s。
|
||||
min_size_error=長度最小為 %s 個字符。
|
||||
max_size_error=長度最大為 %s 個字符。
|
||||
@@ -426,6 +427,7 @@ pulls=合併請求
|
||||
labels=標籤
|
||||
milestones=里程碑
|
||||
commits=提交歷史
|
||||
git_branches=分支列表
|
||||
releases=版本發佈
|
||||
file_raw=原始文件
|
||||
file_history=文件歷史
|
||||
@@ -434,6 +436,13 @@ file_permalink=永久連結
|
||||
file_too_large=檔案太大,無法顯示
|
||||
video_not_supported_in_browser=您的瀏覽器不支援 HTML5 影片播放標籤。
|
||||
|
||||
branches.overview=概覽
|
||||
branches.active_branches=活躍分支
|
||||
branches.stale_branches=陳舊分支
|
||||
branches.all=所有分支
|
||||
branches.updated_by=%[2]s 更新了 %[1]s
|
||||
branches.change_default_branch=變更預設分支
|
||||
|
||||
editor.new_file=開新檔案
|
||||
editor.upload_file=上傳檔案
|
||||
editor.edit_file=編輯文件
|
||||
@@ -655,11 +664,11 @@ settings.protect_this_branch_desc=停用強制Push及分支刪除。
|
||||
settings.protect_require_pull_request=請使用 pull request 來更新(合併)程式碼。
|
||||
settings.protect_require_pull_request_desc=啟用這個選項之後,程式碼將無法直接 Push 到這個分支,所有 Commit 必須先 Push 到另一個非保護的分支,再透過 Pull Request 來要求合併。
|
||||
settings.protect_whitelist_committers=限制誰可以 Push 到這個分支
|
||||
settings.protect_whitelist_committers_desc=新增用戶或團隊到可以直接push到這個分支的白名單。
|
||||
settings.protect_whitelist_users=Users who can push to this branch
|
||||
settings.protect_whitelist_search_users=Search users
|
||||
settings.protect_whitelist_teams=Teams for which members of them can push to this branch
|
||||
settings.protect_whitelist_search_teams=Search teams
|
||||
settings.protect_whitelist_committers_desc=新增成員或團隊到允許直接 push 到這個分支的白名單。白名單中的使用者將會略過 pull request 的檢查。
|
||||
settings.protect_whitelist_users=限制那些使用者可以 push 到這個分支
|
||||
settings.protect_whitelist_search_users=搜尋用戶
|
||||
settings.protect_whitelist_teams=團隊的成員可以 push 到這個分支
|
||||
settings.protect_whitelist_search_teams=搜尋團隊
|
||||
settings.update_protect_branch_success=此分支設置保護已更新成功!
|
||||
settings.hooks=管理 Web 鉤子
|
||||
settings.githooks=管理 Git 鉤子
|
||||
@@ -688,7 +697,7 @@ settings.tracker_issue_style.alphanumeric=字母及數字
|
||||
settings.tracker_url_format_desc=您可以使用 <code>{user} {repo} {index}</code> 分別作為用戶名、倉庫名和問題索引的占位符。
|
||||
settings.pulls_desc=啟用合併請求以接受社區貢獻
|
||||
settings.danger_zone=危險操作區
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
settings.cannot_fork_to_same_owner=你不可以 fork 一個 repository 到它的擁有者。
|
||||
settings.new_owner_has_same_repo=新的倉庫擁有者已經存在同名倉庫!
|
||||
settings.convert=轉換為正規倉庫
|
||||
settings.convert_desc=您可以將此鏡像轉成正規倉庫。此動做不可逆。
|
||||
@@ -745,7 +754,7 @@ settings.add_webhook_desc=我們會通過 <code>POST</code> 請求將訂閱事
|
||||
settings.payload_url=推送地址
|
||||
settings.content_type=數據格式
|
||||
settings.secret=密鑰文本
|
||||
settings.secret_desc=Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.secret_desc=密鑰將會以 SHA256 HMAC 的十六進位數字放進<code>X-Gogs-Signature</code> 標頭中送出。
|
||||
settings.slack_username=服務名稱
|
||||
settings.slack_icon_url=圖標 URL
|
||||
settings.slack_color=顏色代碼
|
||||
@@ -755,10 +764,20 @@ settings.event_send_everything=推送 <strong>所有</strong> 事件
|
||||
settings.event_choose=讓我選擇我的需要
|
||||
settings.event_create=創建
|
||||
settings.event_create_desc=創建分支或標籤
|
||||
settings.event_pull_request=合併請求
|
||||
settings.event_pull_request_desc=請求打開,關閉,重新打開,編輯,分配,未分配,標籤更新,標籤清除,或同步。
|
||||
settings.event_delete=刪除
|
||||
settings.event_delete_desc=分支或標籤已經被刪除
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository 已經 fork
|
||||
settings.event_push=推送
|
||||
settings.event_push_desc=Git 倉庫推送
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=已經開啟、關閉、重啟、修改、指派、取消指派、更新標籤、清除標籤、新增里程碑或刪除里程碑的 issue。
|
||||
settings.event_issue_comment=Issue 評論
|
||||
settings.event_issue_comment_desc=已經建立、編輯或刪除的 Issue 評論。
|
||||
settings.event_pull_request=合併請求
|
||||
settings.event_pull_request_desc=已經開啟、關閉、重啟、編輯、指派、解除指派、更新標籤、清除標籤、新增里程碑、刪除里程碑或同步的 pull request。
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release 將發佈在一個 repository 中。
|
||||
settings.active=是否激活
|
||||
settings.active_helper=當指定事件發生時我們將會觸發此 Web 鉤子。
|
||||
settings.add_hook_success=Web 鉤子添加成功!
|
||||
@@ -803,7 +822,6 @@ release.releases=版本發佈
|
||||
release.new_release=發佈新版本
|
||||
release.draft=草稿
|
||||
release.prerelease=預發佈版本
|
||||
release.stable=穩定
|
||||
release.edit=編輯
|
||||
release.ahead=在該版本發佈之後已有 <strong>%d</strong> 次代碼提交到 %s 分支
|
||||
release.source_code=源代碼
|
||||
@@ -1019,6 +1037,7 @@ repos.private=私有庫
|
||||
repos.watches=關註數
|
||||
repos.stars=讚好數
|
||||
repos.issues=問題數
|
||||
repos.size=大小
|
||||
|
||||
auths.auth_manage_panel=認證管理面板
|
||||
auths.new=添加新認證源
|
||||
@@ -1176,7 +1195,8 @@ config.git_pull_timeout=操作超時
|
||||
config.git_gc_timeout=GC 操作超時
|
||||
|
||||
config.log_config=日誌配置
|
||||
config.log_mode=日誌模式
|
||||
config.log_mode=模式
|
||||
config.log_options=選項
|
||||
|
||||
monitor.cron=Cron 任務
|
||||
monitor.name=任務名稱
|
||||
@@ -1205,19 +1225,23 @@ notices.delete_success=系統提示刪除成功!
|
||||
|
||||
[action]
|
||||
create_repo=創建了儲存庫 <a href="%s">%s</a>
|
||||
fork_repo=已經 fork 一個 repository 到 <a href="%s">%s</a>
|
||||
rename_repo=重新命名倉庫 <code>%[1]s</code> 為 <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=推送了 <a href="%[1]s/src/%[2]s">%[3]s</a> 分支的代碼到 <a href="%[1]s">%[4]s</a>
|
||||
compare_commits=查看 %d 次提交的內容比對
|
||||
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
|
||||
create_issue=`創建了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue=`已關閉問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue=`已重新開啟問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`創建了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`已關閉合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`已重新開啟合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`合併了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
|
||||
create_branch=在 <a href="%[1]s">%[4]s</a> 建立新的分支 <a href="%[1]s/src/%[2]s">%[3]s</a>
|
||||
delete_branch=已經刪除在 <a href="%[1]s">%[3]s</a> 上的分支 <code>%[2]s</code>
|
||||
push_tag=推送了標籤 <a href="%s/src/%s">%[2]s</a> 到 <a href="%[1]s">%[3]s</a>
|
||||
compare_commits=查看 %d 次提交的內容比對
|
||||
delete_tag=已經刪除在 <a href="%[1]s">%[3]s</a> 上的標籤 <code>%[2]s</code>
|
||||
|
||||
[tool]
|
||||
ago=之前
|
||||
|
||||
@@ -65,7 +65,7 @@ $ docker run --name=gogs -p 10022:22 -p 10080:3000 -v gogs-data:/data gogs/gogs
|
||||
Most of settings are obvious and easy to understand, but there are some settings can be confusing by running Gogs inside Docker:
|
||||
|
||||
- **Repository Root Path**: keep it as default value `/home/git/gogs-repositories` because `start.sh` already made a symbolic link for you.
|
||||
- **Run User**: keep it as default value `git` because `start.sh` already setup a user with name `git`.
|
||||
- **Run User**: keep it as default value `git` because `build.sh` already setup a user with name `git`.
|
||||
- **Domain**: fill in with Docker container IP (e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
|
||||
- **SSH Port**: Use the exposed port from Docker container. For example, your SSH server listens on `22` inside Docker, **but** you expose it by `10022:22`, then use `10022` for this value. **Builtin SSH server is not recommended inside Docker Container**
|
||||
- **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, **and** you expose it by `10080:3000`, but you still use `3000` for this value.
|
||||
@@ -112,4 +112,4 @@ Steps to upgrade Gogs with Docker:
|
||||
|
||||
## Useful Links
|
||||
|
||||
- [Share port 22 between Gogs inside Docker & the local system](http://www.ateijelo.com/blog/2016/07/09/share-port-22-between-docker-gogs-ssh-and-local-system)
|
||||
- [Share port 22 between Gogs inside Docker & the local system](http://www.ateijelo.com/blog/2016/07/09/share-port-22-between-docker-gogs-ssh-and-local-system)
|
||||
|
||||
15
gogs.go
15
gogs.go
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.10.0.0227"
|
||||
const APP_VER = "0.10.18.0313"
|
||||
|
||||
func init() {
|
||||
setting.AppVer = APP_VER
|
||||
@@ -28,13 +28,14 @@ func main() {
|
||||
app.Usage = "A painless self-hosted Git service"
|
||||
app.Version = APP_VER
|
||||
app.Commands = []cli.Command{
|
||||
cmd.CmdWeb,
|
||||
cmd.Web,
|
||||
cmd.Serv,
|
||||
cmd.CmdHook,
|
||||
cmd.CmdDump,
|
||||
cmd.CmdCert,
|
||||
cmd.CmdAdmin,
|
||||
cmd.CmdImport,
|
||||
cmd.Hook,
|
||||
cmd.Cert,
|
||||
cmd.Admin,
|
||||
cmd.Import,
|
||||
cmd.Backup,
|
||||
cmd.Restore,
|
||||
}
|
||||
app.Flags = append(app.Flags, []cli.Flag{}...)
|
||||
app.Run(os.Args)
|
||||
|
||||
141
models/action.go
141
models/action.go
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
type ActionType int
|
||||
|
||||
// To maintain backward compatibility only append to the end of list
|
||||
const (
|
||||
ACTION_CREATE_REPO ActionType = iota + 1 // 1
|
||||
ACTION_RENAME_REPO // 2
|
||||
@@ -42,6 +43,10 @@ const (
|
||||
ACTION_REOPEN_ISSUE // 13
|
||||
ACTION_CLOSE_PULL_REQUEST // 14
|
||||
ACTION_REOPEN_PULL_REQUEST // 15
|
||||
ACTION_CREATE_BRANCH // 16
|
||||
ACTION_DELETE_BRANCH // 17
|
||||
ACTION_DELETE_TAG // 18
|
||||
ACTION_FORK_REPO // 19
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -66,7 +71,7 @@ func init() {
|
||||
// Action represents user operation type and other information to repository,
|
||||
// it implemented interface base.Actioner so that can be used in template render.
|
||||
type Action struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
ID int64
|
||||
UserID int64 // Receiver user id.
|
||||
OpType ActionType
|
||||
ActUserID int64 // Action user id.
|
||||
@@ -172,26 +177,26 @@ func (a *Action) GetIssueContent() string {
|
||||
return issue.Content
|
||||
}
|
||||
|
||||
func newRepoAction(e Engine, u *User, repo *Repository) (err error) {
|
||||
if err = notifyWatchers(e, &Action{
|
||||
ActUserID: u.ID,
|
||||
ActUserName: u.Name,
|
||||
OpType: ACTION_CREATE_REPO,
|
||||
func newRepoAction(e Engine, doer, owner *User, repo *Repository) (err error) {
|
||||
opType := ACTION_CREATE_REPO
|
||||
if repo.IsFork {
|
||||
opType = ACTION_FORK_REPO
|
||||
}
|
||||
|
||||
return notifyWatchers(e, &Action{
|
||||
ActUserID: doer.ID,
|
||||
ActUserName: doer.Name,
|
||||
OpType: opType,
|
||||
RepoID: repo.ID,
|
||||
RepoUserName: repo.Owner.Name,
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("notify watchers '%d/%d': %v", u.ID, repo.ID, err)
|
||||
}
|
||||
|
||||
log.Trace("action.newRepoAction: %s/%s", u.Name, repo.Name)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// NewRepoAction adds new action for creating repository.
|
||||
func NewRepoAction(u *User, repo *Repository) (err error) {
|
||||
return newRepoAction(x, u, repo)
|
||||
func NewRepoAction(doer, owner *User, repo *Repository) (err error) {
|
||||
return newRepoAction(x, doer, owner, repo)
|
||||
}
|
||||
|
||||
func renameRepoAction(e Engine, actUser *User, oldRepoName string, repo *Repository) (err error) {
|
||||
@@ -458,18 +463,16 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||
return fmt.Errorf("UpdateRepository: %v", err)
|
||||
}
|
||||
|
||||
isNewBranch := false
|
||||
isNewRef := opts.OldCommitID == git.EMPTY_SHA
|
||||
isDelRef := opts.NewCommitID == git.EMPTY_SHA
|
||||
|
||||
opType := ACTION_COMMIT_REPO
|
||||
// Check it's tag push or branch.
|
||||
// Check if it's tag push or branch.
|
||||
if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) {
|
||||
opType = ACTION_PUSH_TAG
|
||||
opts.Commits = &PushCommits{}
|
||||
} else {
|
||||
// TODO: detect branch deletion
|
||||
// if not the first commit, set the compare URL.
|
||||
if opts.OldCommitID == git.EMPTY_SHA {
|
||||
isNewBranch = true
|
||||
} else {
|
||||
if !isNewRef && !isDelRef {
|
||||
opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
|
||||
}
|
||||
|
||||
@@ -488,38 +491,57 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||
}
|
||||
|
||||
refName := git.RefEndName(opts.RefFullName)
|
||||
if err = NotifyWatchers(&Action{
|
||||
action := &Action{
|
||||
ActUserID: pusher.ID,
|
||||
ActUserName: pusher.Name,
|
||||
OpType: opType,
|
||||
Content: string(data),
|
||||
RepoID: repo.ID,
|
||||
RepoUserName: repo.MustOwner().Name,
|
||||
RepoName: repo.Name,
|
||||
RefName: refName,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("NotifyWatchers: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
go HookQueue.Add(repo.ID)
|
||||
}()
|
||||
|
||||
apiPusher := pusher.APIFormat()
|
||||
apiRepo := repo.APIFormat(nil)
|
||||
apiPusher := pusher.APIFormat()
|
||||
switch opType {
|
||||
case ACTION_COMMIT_REPO: // Push
|
||||
if isDelRef {
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_DELETE, &api.DeletePayload{
|
||||
Ref: refName,
|
||||
RefType: "branch",
|
||||
PusherType: api.PUSHER_TYPE_USER,
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
|
||||
}
|
||||
|
||||
action.OpType = ACTION_DELETE_BRANCH
|
||||
if err = NotifyWatchers(action); err != nil {
|
||||
return fmt.Errorf("NotifyWatchers.(delete branch): %v", err)
|
||||
}
|
||||
|
||||
// Delete branch doesn't have anything to push or compare
|
||||
return nil
|
||||
}
|
||||
|
||||
compareURL := setting.AppUrl + opts.Commits.CompareURL
|
||||
if isNewBranch {
|
||||
if isNewRef {
|
||||
compareURL = ""
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_CREATE, &api.CreatePayload{
|
||||
Ref: refName,
|
||||
RefType: "branch",
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
Ref: refName,
|
||||
RefType: "branch",
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks (new branch): %v", err)
|
||||
return fmt.Errorf("PrepareWebhooks.(new branch): %v", err)
|
||||
}
|
||||
|
||||
action.OpType = ACTION_CREATE_BRANCH
|
||||
if err = NotifyWatchers(action); err != nil {
|
||||
return fmt.Errorf("NotifyWatchers.(new branch): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,16 +555,47 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||
Pusher: apiPusher,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks (new commit): %v", err)
|
||||
return fmt.Errorf("PrepareWebhooks.(new commit): %v", err)
|
||||
}
|
||||
|
||||
case ACTION_PUSH_TAG: // Create
|
||||
return PrepareWebhooks(repo, HOOK_EVENT_CREATE, &api.CreatePayload{
|
||||
Ref: refName,
|
||||
RefType: "tag",
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
})
|
||||
action.OpType = ACTION_COMMIT_REPO
|
||||
if err = NotifyWatchers(action); err != nil {
|
||||
return fmt.Errorf("NotifyWatchers.(new commit): %v", err)
|
||||
}
|
||||
|
||||
case ACTION_PUSH_TAG: // Tag
|
||||
if isDelRef {
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_DELETE, &api.DeletePayload{
|
||||
Ref: refName,
|
||||
RefType: "tag",
|
||||
PusherType: api.PUSHER_TYPE_USER,
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
|
||||
}
|
||||
|
||||
action.OpType = ACTION_DELETE_TAG
|
||||
if err = NotifyWatchers(action); err != nil {
|
||||
return fmt.Errorf("NotifyWatchers.(delete tag): %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_CREATE, &api.CreatePayload{
|
||||
Ref: refName,
|
||||
RefType: "tag",
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks.(new tag): %v", err)
|
||||
}
|
||||
|
||||
action.OpType = ACTION_PUSH_TAG
|
||||
if err = NotifyWatchers(action); err != nil {
|
||||
return fmt.Errorf("NotifyWatchers.(new tag): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -110,7 +110,7 @@ func GetAttachmentByUUID(uuid string) (*Attachment, error) {
|
||||
}
|
||||
|
||||
func getAttachmentsByIssueID(e Engine, issueID int64) ([]*Attachment, error) {
|
||||
attachments := make([]*Attachment, 0, 10)
|
||||
attachments := make([]*Attachment, 0, 5)
|
||||
return attachments, e.Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments)
|
||||
}
|
||||
|
||||
@@ -120,15 +120,25 @@ func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) {
|
||||
}
|
||||
|
||||
func getAttachmentsByCommentID(e Engine, commentID int64) ([]*Attachment, error) {
|
||||
attachments := make([]*Attachment, 0, 10)
|
||||
attachments := make([]*Attachment, 0, 5)
|
||||
return attachments, e.Where("comment_id=?", commentID).Find(&attachments)
|
||||
}
|
||||
|
||||
// GetAttachmentsByCommentID returns all attachments if comment by given ID.
|
||||
// GetAttachmentsByCommentID returns all attachments of a comment.
|
||||
func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) {
|
||||
return getAttachmentsByCommentID(x, commentID)
|
||||
}
|
||||
|
||||
func getAttachmentsByReleaseID(e Engine, releaseID int64) ([]*Attachment, error) {
|
||||
attachments := make([]*Attachment, 0, 10)
|
||||
return attachments, e.Where("release_id = ?", releaseID).Find(&attachments)
|
||||
}
|
||||
|
||||
// GetAttachmentsByReleaseID returns all attachments of a release.
|
||||
func GetAttachmentsByReleaseID(releaseID int64) ([]*Attachment, error) {
|
||||
return getAttachmentsByReleaseID(x, releaseID)
|
||||
}
|
||||
|
||||
// DeleteAttachment deletes the given attachment and optionally the associated file.
|
||||
func DeleteAttachment(a *Attachment, remove bool) error {
|
||||
_, err := DeleteAttachments([]*Attachment{a}, remove)
|
||||
|
||||
@@ -150,9 +150,13 @@ func (c *Comment) APIFormat() *api.Comment {
|
||||
}
|
||||
}
|
||||
|
||||
func CommentHashTag(id int64) string {
|
||||
return "issuecomment-" + com.ToStr(id)
|
||||
}
|
||||
|
||||
// HashTag returns unique hash tag for comment.
|
||||
func (c *Comment) HashTag() string {
|
||||
return "issuecomment-" + com.ToStr(c.ID)
|
||||
return CommentHashTag(c.ID)
|
||||
}
|
||||
|
||||
// EventTag returns unique event hash tag for comment.
|
||||
@@ -330,7 +334,7 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
|
||||
|
||||
// CreateIssueComment creates a plain issue comment.
|
||||
func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content string, attachments []string) (*Comment, error) {
|
||||
return CreateComment(&CreateCommentOptions{
|
||||
comment, err := CreateComment(&CreateCommentOptions{
|
||||
Type: COMMENT_TYPE_COMMENT,
|
||||
Doer: doer,
|
||||
Repo: repo,
|
||||
@@ -338,6 +342,22 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
|
||||
Content: content,
|
||||
Attachments: attachments,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CreateComment: %v", err)
|
||||
}
|
||||
|
||||
comment.Issue = issue
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_ISSUE_COMMENT, &api.IssueCommentPayload{
|
||||
Action: api.HOOK_ISSUE_COMMENT_CREATED,
|
||||
Issue: issue.APIFormat(),
|
||||
Comment: comment.APIFormat(),
|
||||
Repository: repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
|
||||
}
|
||||
|
||||
return comment, nil
|
||||
}
|
||||
|
||||
// CreateRefComment creates a commit reference comment to issue.
|
||||
@@ -437,13 +457,33 @@ func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
|
||||
}
|
||||
|
||||
// UpdateComment updates information of comment.
|
||||
func UpdateComment(c *Comment) error {
|
||||
_, err := x.Id(c.ID).AllCols().Update(c)
|
||||
return err
|
||||
func UpdateComment(doer *User, c *Comment, oldContent string) (err error) {
|
||||
if _, err = x.Id(c.ID).AllCols().Update(c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.Issue.LoadAttributes(); err != nil {
|
||||
log.Error(2, "Issue.LoadAttributes [issue_id: %d]: %v", c.IssueID, err)
|
||||
} else if err = PrepareWebhooks(c.Issue.Repo, HOOK_EVENT_ISSUE_COMMENT, &api.IssueCommentPayload{
|
||||
Action: api.HOOK_ISSUE_COMMENT_EDITED,
|
||||
Issue: c.Issue.APIFormat(),
|
||||
Comment: c.APIFormat(),
|
||||
Changes: &api.ChangesPayload{
|
||||
Body: &api.ChangesFromPayload{
|
||||
From: oldContent,
|
||||
},
|
||||
},
|
||||
Repository: c.Issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", c.ID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCommentByID deletes the comment by given ID.
|
||||
func DeleteCommentByID(id int64) error {
|
||||
func DeleteCommentByID(doer *User, id int64) error {
|
||||
comment, err := GetCommentByID(id)
|
||||
if err != nil {
|
||||
if IsErrCommentNotExist(err) {
|
||||
@@ -468,5 +508,20 @@ func DeleteCommentByID(id int64) error {
|
||||
}
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
if err = sess.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
}
|
||||
|
||||
if err = comment.Issue.LoadAttributes(); err != nil {
|
||||
log.Error(2, "Issue.LoadAttributes [issue_id: %d]: %v", comment.IssueID, err)
|
||||
} else if err = PrepareWebhooks(comment.Issue.Repo, HOOK_EVENT_ISSUE_COMMENT, &api.IssueCommentPayload{
|
||||
Action: api.HOOK_ISSUE_COMMENT_DELETED,
|
||||
Issue: comment.Issue.APIFormat(),
|
||||
Comment: comment.APIFormat(),
|
||||
Repository: comment.Issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error(2, "PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
12
models/errors/errors.go
Normal file
12
models/errors/errors.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2017 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 errors
|
||||
|
||||
import "errors"
|
||||
|
||||
// New is a wrapper of real errors.New function.
|
||||
func New(text string) error {
|
||||
return errors.New(text)
|
||||
}
|
||||
20
models/errors/issue.go
Normal file
20
models/errors/issue.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2017 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type InvalidIssueReference struct {
|
||||
Ref string
|
||||
}
|
||||
|
||||
func IsInvalidIssueReference(err error) bool {
|
||||
_, ok := err.(InvalidIssueReference)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err InvalidIssueReference) Error() string {
|
||||
return fmt.Sprintf("invalid issue reference [ref: %s]", err.Ref)
|
||||
}
|
||||
33
models/errors/login_source.go
Normal file
33
models/errors/login_source.go
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type LoginSourceNotActivated struct {
|
||||
SourceID int64
|
||||
}
|
||||
|
||||
func IsLoginSourceNotActivated(err error) bool {
|
||||
_, ok := err.(LoginSourceNotActivated)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err LoginSourceNotActivated) Error() string {
|
||||
return fmt.Sprintf("login source is not activated [source_id: %d]", err.SourceID)
|
||||
}
|
||||
|
||||
type InvalidLoginSourceType struct {
|
||||
Type interface{}
|
||||
}
|
||||
|
||||
func IsInvalidLoginSourceType(err error) bool {
|
||||
_, ok := err.(InvalidLoginSourceType)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err InvalidLoginSourceType) Error() string {
|
||||
return fmt.Sprintf("invalid login source type [type: %v]", err.Type)
|
||||
}
|
||||
33
models/errors/repo.go
Normal file
33
models/errors/repo.go
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type InvalidRepoReference struct {
|
||||
Ref string
|
||||
}
|
||||
|
||||
func IsInvalidRepoReference(err error) bool {
|
||||
_, ok := err.(InvalidRepoReference)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err InvalidRepoReference) Error() string {
|
||||
return fmt.Sprintf("invalid repository reference [ref: %s]", err.Ref)
|
||||
}
|
||||
|
||||
type MirrorNotExist struct {
|
||||
RepoID int64
|
||||
}
|
||||
|
||||
func IsMirrorNotExist(err error) bool {
|
||||
_, ok := err.(MirrorNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err MirrorNotExist) Error() string {
|
||||
return fmt.Sprintf("mirror does not exist [repo_id: %d]", err.RepoID)
|
||||
}
|
||||
31
models/errors/user.go
Normal file
31
models/errors/user.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2017 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type EmptyName struct{}
|
||||
|
||||
func IsEmptyName(err error) bool {
|
||||
_, ok := err.(EmptyName)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err EmptyName) Error() string {
|
||||
return "empty name"
|
||||
}
|
||||
|
||||
type UserNotKeyOwner struct {
|
||||
KeyID int64
|
||||
}
|
||||
|
||||
func IsUserNotKeyOwner(err error) bool {
|
||||
_, ok := err.(UserNotKeyOwner)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err UserNotKeyOwner) Error() string {
|
||||
return fmt.Sprintf("user is not the owner of public key [key_id: %d]", err.KeyID)
|
||||
}
|
||||
33
models/errors/user_mail.go
Normal file
33
models/errors/user_mail.go
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type EmailNotFound struct {
|
||||
Email string
|
||||
}
|
||||
|
||||
func IsEmailNotFound(err error) bool {
|
||||
_, ok := err.(EmailNotFound)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err EmailNotFound) Error() string {
|
||||
return fmt.Sprintf("email is not found [email: %s]", err.Email)
|
||||
}
|
||||
|
||||
type EmailNotVerified struct {
|
||||
Email string
|
||||
}
|
||||
|
||||
func IsEmailNotVerified(err error) bool {
|
||||
_, ok := err.(EmailNotVerified)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err EmailNotVerified) Error() string {
|
||||
return fmt.Sprintf("email has not been verified [email: %s]", err.Email)
|
||||
}
|
||||
154
models/issue.go
154
models/issue.go
@@ -5,16 +5,17 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/xorm"
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models/errors"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
@@ -230,7 +231,7 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
|
||||
if issue.IsPull {
|
||||
err = issue.PullRequest.LoadIssue()
|
||||
if err != nil {
|
||||
log.Error(4, "LoadIssue: %v", err)
|
||||
log.Error(2, "LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_PULL_REQUEST, &api.PullRequestPayload{
|
||||
@@ -240,11 +241,17 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
} else {
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_ISSUES, &api.IssuesPayload{
|
||||
Action: api.HOOK_ISSUE_LABEL_UPDATED,
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
} else {
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +341,7 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
|
||||
if issue.IsPull {
|
||||
err = issue.PullRequest.LoadIssue()
|
||||
if err != nil {
|
||||
log.Error(4, "LoadIssue: %v", err)
|
||||
log.Error(2, "LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_PULL_REQUEST, &api.PullRequestPayload{
|
||||
@@ -344,11 +351,17 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
} else {
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_ISSUES, &api.IssuesPayload{
|
||||
Action: api.HOOK_ISSUE_LABEL_CLEARED,
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
} else {
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -470,11 +483,22 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
|
||||
apiPullRequest.Action = api.HOOK_ISSUE_REOPENED
|
||||
}
|
||||
err = PrepareWebhooks(repo, HOOK_EVENT_PULL_REQUEST, apiPullRequest)
|
||||
} else {
|
||||
apiIssues := &api.IssuesPayload{
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Repository: repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
}
|
||||
if isClosed {
|
||||
apiIssues.Action = api.HOOK_ISSUE_CLOSED
|
||||
} else {
|
||||
apiIssues.Action = api.HOOK_ISSUE_REOPENED
|
||||
}
|
||||
err = PrepareWebhooks(repo, HOOK_EVENT_ISSUES, apiIssues)
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(4, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
|
||||
} else {
|
||||
go HookQueue.Add(repo.ID)
|
||||
log.Error(2, "PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -490,22 +514,33 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
|
||||
if issue.IsPull {
|
||||
issue.PullRequest.Issue = issue
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_PULL_REQUEST, &api.PullRequestPayload{
|
||||
Action: api.HOOK_ISSUE_EDITED,
|
||||
Index: issue.Index,
|
||||
Action: api.HOOK_ISSUE_EDITED,
|
||||
Index: issue.Index,
|
||||
PullRequest: issue.PullRequest.APIFormat(),
|
||||
Changes: &api.ChangesPayload{
|
||||
Title: &api.ChangesFromPayload{
|
||||
From: oldTitle,
|
||||
},
|
||||
},
|
||||
PullRequest: issue.PullRequest.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
} else {
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_ISSUES, &api.IssuesPayload{
|
||||
Action: api.HOOK_ISSUE_EDITED,
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Changes: &api.ChangesPayload{
|
||||
Title: &api.ChangesFromPayload{
|
||||
From: oldTitle,
|
||||
},
|
||||
},
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
} else {
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -521,22 +556,33 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
|
||||
if issue.IsPull {
|
||||
issue.PullRequest.Issue = issue
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_PULL_REQUEST, &api.PullRequestPayload{
|
||||
Action: api.HOOK_ISSUE_EDITED,
|
||||
Index: issue.Index,
|
||||
Action: api.HOOK_ISSUE_EDITED,
|
||||
Index: issue.Index,
|
||||
PullRequest: issue.PullRequest.APIFormat(),
|
||||
Changes: &api.ChangesPayload{
|
||||
Body: &api.ChangesFromPayload{
|
||||
From: oldContent,
|
||||
},
|
||||
},
|
||||
PullRequest: issue.PullRequest.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
} else {
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_ISSUES, &api.IssuesPayload{
|
||||
Action: api.HOOK_ISSUE_EDITED,
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Changes: &api.ChangesPayload{
|
||||
Body: &api.ChangesFromPayload{
|
||||
From: oldContent,
|
||||
},
|
||||
},
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(4, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
} else {
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -570,11 +616,22 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
|
||||
apiPullRequest.Action = api.HOOK_ISSUE_ASSIGNED
|
||||
}
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_PULL_REQUEST, apiPullRequest)
|
||||
} else {
|
||||
apiIssues := &api.IssuesPayload{
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
}
|
||||
if isRemoveAssignee {
|
||||
apiIssues.Action = api.HOOK_ISSUE_UNASSIGNED
|
||||
} else {
|
||||
apiIssues.Action = api.HOOK_ISSUE_ASSIGNED
|
||||
}
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_ISSUES, apiIssues)
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, isRemoveAssignee, err)
|
||||
} else {
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -684,7 +741,7 @@ func newIssue(e *xorm.Session, opts NewIssueOptions) (err error) {
|
||||
return opts.Issue.loadAttributes(e)
|
||||
}
|
||||
|
||||
// NewIssue creates new issue with labels for repository.
|
||||
// NewIssue creates new issue with labels and attachments for repository.
|
||||
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
@@ -715,10 +772,20 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
log.Error(4, "NotifyWatchers: %v", err)
|
||||
log.Error(2, "NotifyWatchers: %v", err)
|
||||
}
|
||||
if err = issue.MailParticipants(); err != nil {
|
||||
log.Error(4, "MailParticipants: %v", err)
|
||||
log.Error(2, "MailParticipants: %v", err)
|
||||
}
|
||||
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_ISSUES, &api.IssuesPayload{
|
||||
Action: api.HOOK_ISSUE_OPENED,
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Repository: repo.APIFormat(nil),
|
||||
Sender: issue.Poster.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error(2, "PrepareWebhooks: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -729,7 +796,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
|
||||
func GetIssueByRef(ref string) (*Issue, error) {
|
||||
n := strings.IndexByte(ref, byte('#'))
|
||||
if n == -1 {
|
||||
return nil, ErrMissingIssueNumber
|
||||
return nil, errors.InvalidIssueReference{ref}
|
||||
}
|
||||
|
||||
index, err := com.StrTo(ref[n+1:]).Int64()
|
||||
@@ -914,6 +981,23 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
|
||||
return issues, nil
|
||||
}
|
||||
|
||||
// GetParticipantsByIssueID returns all users who are participated in comments of an issue.
|
||||
func GetParticipantsByIssueID(issueID int64) ([]*User, error) {
|
||||
userIDs := make([]int64, 0, 5)
|
||||
if err := x.Table("comment").Cols("poster_id").
|
||||
Where("issue_id = ?", issueID).
|
||||
Distinct("poster_id").
|
||||
Find(&userIDs); err != nil {
|
||||
return nil, fmt.Errorf("get poster IDs: %v", err)
|
||||
}
|
||||
if len(userIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
users := make([]*User, 0, len(userIDs))
|
||||
return users, x.In("id", userIDs).Find(&users)
|
||||
}
|
||||
|
||||
// .___ ____ ___
|
||||
// | | ______ ________ __ ____ | | \______ ___________
|
||||
// | |/ ___// ___/ | \_/ __ \| | / ___// __ \_ __ \
|
||||
|
||||
@@ -240,7 +240,13 @@ func newIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues++
|
||||
}
|
||||
return updateLabel(e, label)
|
||||
|
||||
if err = updateLabel(e, label); err != nil {
|
||||
return fmt.Errorf("updateLabel: %v", err)
|
||||
}
|
||||
|
||||
issue.Labels = append(issue.Labels, label)
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewIssueLabel creates a new issue-label relation.
|
||||
@@ -313,7 +319,17 @@ func deleteIssueLabel(e *xorm.Session, issue *Issue, label *Label) (err error) {
|
||||
if issue.IsClosed {
|
||||
label.NumClosedIssues--
|
||||
}
|
||||
return updateLabel(e, label)
|
||||
if err = updateLabel(e, label); err != nil {
|
||||
return fmt.Errorf("updateLabel: %v", err)
|
||||
}
|
||||
|
||||
for i := range issue.Labels {
|
||||
if issue.Labels[i].ID == label.ID {
|
||||
issue.Labels = append(issue.Labels[:i], issue.Labels[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteIssueLabel deletes issue-label relation.
|
||||
|
||||
@@ -91,18 +91,30 @@ func NewMailerIssue(issue *Issue) mailer.Issue {
|
||||
}
|
||||
|
||||
// mailIssueCommentToParticipants can be used for both new issue creation and comment.
|
||||
// This functions sends two list of emails:
|
||||
// 1. Repository watchers and users who are participated in comments.
|
||||
// 2. Users who are not in 1. but get mentioned in current issue/comment.
|
||||
func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string) error {
|
||||
if !setting.Service.EnableNotifyMail {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mail wahtcers.
|
||||
watchers, err := GetWatchers(issue.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetWatchers [%d]: %v", issue.RepoID, err)
|
||||
return fmt.Errorf("GetWatchers [repo_id: %d]: %v", issue.RepoID, err)
|
||||
}
|
||||
participants, err := GetParticipantsByIssueID(issue.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetParticipantsByIssueID [issue_id: %d]: %v", issue.ID, err)
|
||||
}
|
||||
|
||||
tos := make([]string, 0, len(watchers)) // List of email addresses.
|
||||
// In case the issue poster is not watching the repository,
|
||||
// even if we have duplicated in watchers, can be safely filtered out.
|
||||
if issue.PosterID != doer.ID {
|
||||
participants = append(participants, issue.Poster)
|
||||
}
|
||||
|
||||
tos := make([]string, 0, len(watchers)) // List of email addresses
|
||||
names := make([]string, 0, len(watchers))
|
||||
for i := range watchers {
|
||||
if watchers[i].UserID == doer.ID {
|
||||
@@ -120,6 +132,16 @@ func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string)
|
||||
tos = append(tos, to.Email)
|
||||
names = append(names, to.Name)
|
||||
}
|
||||
for i := range participants {
|
||||
if participants[i].ID == doer.ID {
|
||||
continue
|
||||
} else if com.IsSliceContainsStr(names, participants[i].Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
tos = append(tos, participants[i].Email)
|
||||
names = append(names, participants[i].Name)
|
||||
}
|
||||
mailer.SendIssueCommentMail(NewMailerIssue(issue), NewMailerRepo(issue.Repo), NewMailerUser(doer), tos)
|
||||
|
||||
// Mail mentioned people and exclude watchers.
|
||||
|
||||
@@ -7,7 +7,6 @@ package models
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/smtp"
|
||||
"net/textproto"
|
||||
@@ -20,6 +19,7 @@ import (
|
||||
"github.com/go-xorm/xorm"
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
"github.com/gogits/gogs/models/errors"
|
||||
"github.com/gogits/gogs/modules/auth/ldap"
|
||||
"github.com/gogits/gogs/modules/auth/pam"
|
||||
)
|
||||
@@ -394,7 +394,7 @@ func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return ErrUnsupportedLoginType
|
||||
return errors.New("Unsupported SMTP authentication method")
|
||||
}
|
||||
|
||||
// LoginViaSMTP queries if login/password is valid against the SMTP,
|
||||
@@ -416,7 +416,7 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC
|
||||
} else if cfg.Auth == SMTP_LOGIN {
|
||||
auth = &smtpLoginAuth{login, password}
|
||||
} else {
|
||||
return nil, errors.New("Unsupported SMTP auth type")
|
||||
return nil, errors.New("Unsupported SMTP authentication type")
|
||||
}
|
||||
|
||||
if err := SMTPAuth(auth, cfg); err != nil {
|
||||
@@ -489,7 +489,7 @@ func LoginViaPAM(user *User, login, password string, sourceID int64, cfg *PAMCon
|
||||
|
||||
func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) {
|
||||
if !source.IsActived {
|
||||
return nil, ErrLoginSourceNotActived
|
||||
return nil, errors.LoginSourceNotActivated{source.ID}
|
||||
}
|
||||
|
||||
switch source.Type {
|
||||
@@ -501,7 +501,7 @@ func ExternalUserLogin(user *User, login, password string, source *LoginSource,
|
||||
return LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister)
|
||||
}
|
||||
|
||||
return nil, ErrUnsupportedLoginType
|
||||
return nil, errors.InvalidLoginSourceType{source.Type}
|
||||
}
|
||||
|
||||
// UserSignIn validates user name and password.
|
||||
|
||||
@@ -42,7 +42,7 @@ func (m *migration) Migrate(x *xorm.Engine) error {
|
||||
|
||||
// The version table. Should have only one row with id==1
|
||||
type Version struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
ID int64
|
||||
Version int64
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ var migrations = []Migration{
|
||||
NewMigration("set comment updated with created", setCommentUpdatedWithCreated),
|
||||
// v14 -> v15:v0.9.147
|
||||
NewMigration("generate and migrate Git hooks", generateAndMigrateGitHooks),
|
||||
// v15 -> v16:v0.10.16
|
||||
NewMigration("update repository sizes", updateRepositorySizes),
|
||||
}
|
||||
|
||||
// Migrate database to current version
|
||||
|
||||
77
models/migrations/v16.go
Normal file
77
models/migrations/v16.go
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2017 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 migrations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
"github.com/gogits/git-module"
|
||||
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
func updateRepositorySizes(x *xorm.Engine) (err error) {
|
||||
log.Info("This migration could take up to minutes, please be patient.")
|
||||
type Repository struct {
|
||||
ID int64
|
||||
OwnerID int64
|
||||
Name string
|
||||
Size int64
|
||||
}
|
||||
type User struct {
|
||||
ID int64
|
||||
Name string
|
||||
}
|
||||
if err = x.Sync2(new(Repository)); err != nil {
|
||||
return fmt.Errorf("Sync2: %v", err)
|
||||
}
|
||||
|
||||
// For the sake of SQLite3, we can't use x.Iterate here.
|
||||
offset := 0
|
||||
for {
|
||||
repos := make([]*Repository, 0, 10)
|
||||
if err = x.Sql(fmt.Sprintf("SELECT * FROM `repository` ORDER BY id ASC LIMIT 10 OFFSET %d", offset)).
|
||||
Find(&repos); err != nil {
|
||||
return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
|
||||
}
|
||||
log.Trace("Select [offset: %d, repos: %d]", offset, len(repos))
|
||||
if len(repos) == 0 {
|
||||
break
|
||||
}
|
||||
offset += 10
|
||||
|
||||
for _, repo := range repos {
|
||||
if repo.Name == "." || repo.Name == ".." {
|
||||
continue
|
||||
}
|
||||
|
||||
user := new(User)
|
||||
has, err := x.Where("id = ?", repo.OwnerID).Get(user)
|
||||
if err != nil {
|
||||
return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
|
||||
} else if !has {
|
||||
continue
|
||||
}
|
||||
|
||||
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
|
||||
countObject, err := git.GetRepoSize(repoPath)
|
||||
if err != nil {
|
||||
log.Warn("GetRepoSize: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
repo.Size = countObject.Size + countObject.SizePack
|
||||
if _, err = x.Id(repo.ID).Cols("size").Update(repo); err != nil {
|
||||
return fmt.Errorf("update size: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -5,9 +5,11 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
@@ -272,6 +274,8 @@ func changeMilestoneAssign(e *xorm.Session, issue *Issue, oldMilestoneID int64)
|
||||
} else if _, err = e.Exec("UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?", issue.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issue.Milestone = nil
|
||||
}
|
||||
|
||||
if issue.MilestoneID > 0 {
|
||||
@@ -290,13 +294,15 @@ func changeMilestoneAssign(e *xorm.Session, issue *Issue, oldMilestoneID int64)
|
||||
} else if _, err = e.Exec("UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?", m.ID, issue.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issue.Milestone = m
|
||||
}
|
||||
|
||||
return updateIssue(e, issue)
|
||||
}
|
||||
|
||||
// ChangeMilestoneAssign changes assignment of milestone for issue.
|
||||
func ChangeMilestoneAssign(issue *Issue, oldMilestoneID int64) (err error) {
|
||||
func ChangeMilestoneAssign(doer *User, issue *Issue, oldMilestoneID int64) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
@@ -306,7 +312,45 @@ func ChangeMilestoneAssign(issue *Issue, oldMilestoneID int64) (err error) {
|
||||
if err = changeMilestoneAssign(sess, issue, oldMilestoneID); err != nil {
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
|
||||
if err = sess.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
}
|
||||
|
||||
var hookAction api.HookIssueAction
|
||||
if issue.MilestoneID > 0 {
|
||||
hookAction = api.HOOK_ISSUE_MILESTONED
|
||||
} else {
|
||||
hookAction = api.HOOK_ISSUE_DEMILESTONED
|
||||
}
|
||||
|
||||
if issue.IsPull {
|
||||
err = issue.PullRequest.LoadIssue()
|
||||
if err != nil {
|
||||
log.Error(2, "LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_PULL_REQUEST, &api.PullRequestPayload{
|
||||
Action: hookAction,
|
||||
Index: issue.Index,
|
||||
PullRequest: issue.PullRequest.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
} else {
|
||||
err = PrepareWebhooks(issue.Repo, HOOK_EVENT_ISSUES, &api.IssuesPayload{
|
||||
Action: hookAction,
|
||||
Index: issue.Index,
|
||||
Issue: issue.APIFormat(),
|
||||
Repository: issue.Repo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
log.Error(2, "PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteMilestoneOfRepoByID deletes a milestone from a repository.
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"github.com/gogits/git-module"
|
||||
|
||||
"github.com/gogits/gogs/models/errors"
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/gogits/gogs/modules/sync"
|
||||
@@ -55,7 +56,7 @@ func (m *Mirror) AfterSet(colName string, _ xorm.Cell) {
|
||||
case "repo_id":
|
||||
m.Repo, err = GetRepositoryByID(m.RepoID)
|
||||
if err != nil {
|
||||
log.Error(3, "GetRepositoryByID[%d]: %v", m.ID, err)
|
||||
log.Error(3, "GetRepositoryByID [%d]: %v", m.ID, err)
|
||||
}
|
||||
case "updated_unix":
|
||||
m.Updated = time.Unix(m.UpdatedUnix, 0).Local()
|
||||
@@ -76,7 +77,7 @@ func (m *Mirror) readAddress() {
|
||||
|
||||
cfg, err := ini.Load(m.Repo.GitConfigPath())
|
||||
if err != nil {
|
||||
log.Error(4, "Load: %v", err)
|
||||
log.Error(2, "Load: %v", err)
|
||||
return
|
||||
}
|
||||
m.address = cfg.Section("remote \"origin\"").Key("url").Value()
|
||||
@@ -142,9 +143,9 @@ func (m *Mirror) runSync() bool {
|
||||
URL: m.FullAddress(),
|
||||
Timeout: 10 * time.Second,
|
||||
}) {
|
||||
desc := fmt.Sprintf("Mirror repository URL is not accessible: %s", m.MosaicsAddress())
|
||||
desc := fmt.Sprintf("Source URL of mirror repository '%s' is not accessible: %s", m.Repo.FullName(), m.MosaicsAddress())
|
||||
if err := CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err)
|
||||
log.Error(2, "CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -157,9 +158,9 @@ func (m *Mirror) runSync() bool {
|
||||
timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath),
|
||||
"git", gitArgs...); err != nil {
|
||||
desc := fmt.Sprintf("Fail to update mirror repository '%s': %s", repoPath, stderr)
|
||||
log.Error(4, desc)
|
||||
log.Error(2, desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err)
|
||||
log.Error(2, "CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -168,9 +169,9 @@ func (m *Mirror) runSync() bool {
|
||||
timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath),
|
||||
"git", "remote", "update", "--prune"); err != nil {
|
||||
desc := fmt.Sprintf("Fail to update mirror wiki repository '%s': %s", wikiPath, stderr)
|
||||
log.Error(4, desc)
|
||||
log.Error(2, desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err)
|
||||
log.Error(2, "CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -185,7 +186,7 @@ func getMirrorByRepoID(e Engine, repoID int64) (*Mirror, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrMirrorNotExist
|
||||
return nil, errors.MirrorNotExist{repoID}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
@@ -222,14 +223,14 @@ func MirrorUpdate() {
|
||||
if err := x.Where("next_update_unix<=?", time.Now().Unix()).Iterate(new(Mirror), func(idx int, bean interface{}) error {
|
||||
m := bean.(*Mirror)
|
||||
if m.Repo == nil {
|
||||
log.Error(4, "Disconnected mirror repository found: %d", m.ID)
|
||||
log.Error(2, "Disconnected mirror repository found: %d", m.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
MirrorQueue.Add(m.RepoID)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Error(4, "MirrorUpdate: %v", err)
|
||||
log.Error(2, "MirrorUpdate: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ func SyncMirrors() {
|
||||
|
||||
m, err := GetMirrorByRepoID(com.StrTo(repoID).MustInt64())
|
||||
if err != nil {
|
||||
log.Error(4, "GetMirrorByRepoID [%s]: %v", repoID, err)
|
||||
log.Error(2, "GetMirrorByRepoID [%s]: %v", m.RepoID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -253,9 +254,14 @@ func SyncMirrors() {
|
||||
|
||||
m.ScheduleNextUpdate()
|
||||
if err = UpdateMirror(m); err != nil {
|
||||
log.Error(4, "UpdateMirror [%s]: %v", repoID, err)
|
||||
log.Error(2, "UpdateMirror [%s]: %v", m.RepoID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Update repository last updated time
|
||||
if _, err = x.Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", time.Now().Unix(), m.RepoID); err != nil {
|
||||
log.Error(2, "Update repository 'updated_unix' [%s]: %v", m.RepoID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
@@ -13,6 +15,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-xorm/core"
|
||||
@@ -262,7 +265,89 @@ func Ping() error {
|
||||
return x.Ping()
|
||||
}
|
||||
|
||||
// DumpDatabase dumps all data from database to file system.
|
||||
func DumpDatabase(filePath string) error {
|
||||
return x.DumpAllToFile(filePath)
|
||||
// The version table. Should have only one row with id==1
|
||||
type Version struct {
|
||||
ID int64
|
||||
Version int64
|
||||
}
|
||||
|
||||
// DumpDatabase dumps all data from database to file system in JSON format.
|
||||
func DumpDatabase(dirPath string) (err error) {
|
||||
os.MkdirAll(dirPath, os.ModePerm)
|
||||
// Purposely create a local variable to not modify global variable
|
||||
tables := append(tables, new(Version))
|
||||
for _, table := range tables {
|
||||
tableName := strings.TrimPrefix(fmt.Sprintf("%T", table), "*models.")
|
||||
tableFile := path.Join(dirPath, tableName+".json")
|
||||
f, err := os.Create(tableFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to create JSON file: %v", err)
|
||||
}
|
||||
|
||||
if err = x.Asc("id").Iterate(table, func(idx int, bean interface{}) (err error) {
|
||||
enc := json.NewEncoder(f)
|
||||
return enc.Encode(bean)
|
||||
}); err != nil {
|
||||
f.Close()
|
||||
return fmt.Errorf("fail to dump table '%s': %v", tableName, err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ImportDatabase imports data from backup archive.
|
||||
func ImportDatabase(dirPath string) (err error) {
|
||||
// Purposely create a local variable to not modify global variable
|
||||
tables := append(tables, new(Version))
|
||||
for _, table := range tables {
|
||||
tableName := strings.TrimPrefix(fmt.Sprintf("%T", table), "*models.")
|
||||
tableFile := path.Join(dirPath, tableName+".json")
|
||||
if !com.IsExist(tableFile) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = x.DropTables(table); err != nil {
|
||||
return fmt.Errorf("fail to drop table '%s': %v", tableName, err)
|
||||
} else if err = x.Sync2(table); err != nil {
|
||||
return fmt.Errorf("fail to sync table '%s': %v", tableName, err)
|
||||
}
|
||||
|
||||
f, err := os.Open(tableFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to open JSON file: %v", err)
|
||||
}
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
switch bean := table.(type) {
|
||||
case *LoginSource:
|
||||
meta := make(map[string]interface{})
|
||||
if err = json.Unmarshal(scanner.Bytes(), &meta); err != nil {
|
||||
return fmt.Errorf("fail to unmarshal to map: %v", err)
|
||||
}
|
||||
|
||||
tp := LoginType(com.StrTo(com.ToStr(meta["Type"])).MustInt64())
|
||||
switch tp {
|
||||
case LOGIN_LDAP, LOGIN_DLDAP:
|
||||
bean.Cfg = new(LDAPConfig)
|
||||
case LOGIN_SMTP:
|
||||
bean.Cfg = new(SMTPConfig)
|
||||
case LOGIN_PAM:
|
||||
bean.Cfg = new(PAMConfig)
|
||||
default:
|
||||
return fmt.Errorf("unrecognized login source type:: %v", tp)
|
||||
}
|
||||
table = bean
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(scanner.Bytes(), table); err != nil {
|
||||
return fmt.Errorf("fail to unmarshal to struct: %v", err)
|
||||
}
|
||||
|
||||
if _, err = x.Insert(table); err != nil {
|
||||
return fmt.Errorf("fail to insert strcut: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ var (
|
||||
)
|
||||
|
||||
// IsOwnedBy returns true if given user is in the owner team.
|
||||
func (org *User) IsOwnedBy(uid int64) bool {
|
||||
return IsOrganizationOwner(org.ID, uid)
|
||||
func (org *User) IsOwnedBy(userID int64) bool {
|
||||
return IsOrganizationOwner(org.ID, userID)
|
||||
}
|
||||
|
||||
// IsOrgMember returns true if given user is member of organization.
|
||||
@@ -246,8 +246,8 @@ type OrgUser struct {
|
||||
}
|
||||
|
||||
// IsOrganizationOwner returns true if given user is in the owner team.
|
||||
func IsOrganizationOwner(orgId, uid int64) bool {
|
||||
has, _ := x.Where("is_owner=?", true).And("uid=?", uid).And("org_id=?", orgId).Get(new(OrgUser))
|
||||
func IsOrganizationOwner(orgID, userID int64) bool {
|
||||
has, _ := x.Where("is_owner = ?", true).And("uid = ?", userID).And("org_id = ?", orgID).Get(new(OrgUser))
|
||||
return has
|
||||
}
|
||||
|
||||
@@ -303,16 +303,15 @@ func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
|
||||
return getOwnedOrgsByUserID(sess.Desc(desc), userID)
|
||||
}
|
||||
|
||||
// GetOrgUsersByUserID returns all organization-user relations by user ID.
|
||||
func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) {
|
||||
ous := make([]*OrgUser, 0, 10)
|
||||
sess := x.Where("uid=?", uid)
|
||||
if !all {
|
||||
// Only show public organizations
|
||||
sess.And("is_public=?", true)
|
||||
// GetOrgIDsByUserID returns a list of organization IDs that user belongs to.
|
||||
// The showPrivate indicates whether to include private memberships.
|
||||
func GetOrgIDsByUserID(userID int64, showPrivate bool) ([]int64, error) {
|
||||
orgIDs := make([]int64, 0, 5)
|
||||
sess := x.Table("org_user").Where("uid = ?", userID)
|
||||
if !showPrivate {
|
||||
sess.And("is_public = ?", true)
|
||||
}
|
||||
err := sess.Find(&ous)
|
||||
return ous, err
|
||||
return orgIDs, sess.Distinct("org_id").Find(&orgIDs)
|
||||
}
|
||||
|
||||
func getOrgUsersByOrgID(e Engine, orgID int64) ([]*OrgUser, error) {
|
||||
|
||||
@@ -329,14 +329,6 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
|
||||
return nil
|
||||
}
|
||||
|
||||
// patchConflicts is a list of conflit description from Git.
|
||||
var patchConflicts = []string{
|
||||
"patch does not apply",
|
||||
"already exists in working directory",
|
||||
"unrecognized input",
|
||||
"error:",
|
||||
}
|
||||
|
||||
// testPatch checks if patch can be merged to base repository without conflit.
|
||||
// FIXME: make a mechanism to clean up stable local copies.
|
||||
func (pr *PullRequest) testPatch() (err error) {
|
||||
@@ -372,16 +364,9 @@ func (pr *PullRequest) testPatch() (err error) {
|
||||
fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
|
||||
"git", "apply", "--check", patchPath)
|
||||
if err != nil {
|
||||
for i := range patchConflicts {
|
||||
if strings.Contains(stderr, patchConflicts[i]) {
|
||||
log.Trace("PullRequest[%d].testPatch (apply): has conflit", pr.ID)
|
||||
fmt.Println(stderr)
|
||||
pr.Status = PULL_REQUEST_STATUS_CONFLICT
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("git apply --check: %v - %s", err, stderr)
|
||||
log.Trace("PullRequest[%d].testPatch (apply): has conflit\n%s", pr.ID, stderr)
|
||||
pr.Status = PULL_REQUEST_STATUS_CONFLICT
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -437,9 +422,10 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
|
||||
RepoName: repo.Name,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
log.Error(4, "NotifyWatchers: %v", err)
|
||||
} else if err = pull.MailParticipants(); err != nil {
|
||||
log.Error(4, "MailParticipants: %v", err)
|
||||
log.Error(2, "NotifyWatchers: %v", err)
|
||||
}
|
||||
if err = pull.MailParticipants(); err != nil {
|
||||
log.Error(2, "MailParticipants: %v", err)
|
||||
}
|
||||
|
||||
pr.Issue = pull
|
||||
@@ -451,9 +437,8 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
|
||||
Repository: repo.APIFormat(nil),
|
||||
Sender: pull.Poster.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error(4, "PrepareWebhooks: %v", err)
|
||||
log.Error(2, "PrepareWebhooks: %v", err)
|
||||
}
|
||||
go HookQueue.Add(repo.ID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
"github.com/gogits/git-module"
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
)
|
||||
@@ -21,6 +23,7 @@ import (
|
||||
type Release struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64
|
||||
Repo *Repository `xorm:"-"`
|
||||
PublisherID int64
|
||||
Publisher *User `xorm:"-"`
|
||||
TagName string
|
||||
@@ -36,6 +39,8 @@ type Release struct {
|
||||
|
||||
Created time.Time `xorm:"-"`
|
||||
CreatedUnix int64
|
||||
|
||||
Attachments []*Attachment `xorm:"-"`
|
||||
}
|
||||
|
||||
func (r *Release) BeforeInsert() {
|
||||
@@ -51,6 +56,56 @@ func (r *Release) AfterSet(colName string, _ xorm.Cell) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Release) loadAttributes(e Engine) (err error) {
|
||||
if r.Repo == nil {
|
||||
r.Repo, err = getRepositoryByID(e, r.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getRepositoryByID [repo_id: %d]: %v", r.RepoID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if r.Publisher == nil {
|
||||
r.Publisher, err = getUserByID(e, r.PublisherID)
|
||||
if err != nil {
|
||||
if IsErrUserNotExist(err) {
|
||||
r.PublisherID = -1
|
||||
r.Publisher = NewGhostUser()
|
||||
} else {
|
||||
return fmt.Errorf("getUserByID.(Publisher) [publisher_id: %d]: %v", r.PublisherID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if r.Attachments == nil {
|
||||
r.Attachments, err = getAttachmentsByReleaseID(e, r.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByReleaseID [%d]: %v", r.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Release) LoadAttributes() error {
|
||||
return r.loadAttributes(x)
|
||||
}
|
||||
|
||||
// This method assumes some fields assigned with values:
|
||||
// Required - Publisher
|
||||
func (r *Release) APIFormat() *api.Release {
|
||||
return &api.Release{
|
||||
ID: r.ID,
|
||||
TagName: r.TagName,
|
||||
TargetCommitish: r.Target,
|
||||
Name: r.Title,
|
||||
Body: r.Note,
|
||||
Draft: r.IsDraft,
|
||||
Prerelease: r.IsPrerelease,
|
||||
Author: r.Publisher.APIFormat(),
|
||||
Created: r.Created,
|
||||
}
|
||||
}
|
||||
|
||||
// IsReleaseExist returns true if release with given tag name already exists.
|
||||
func IsReleaseExist(repoID int64, tagName string) (bool, error) {
|
||||
if len(tagName) == 0 {
|
||||
@@ -60,31 +115,31 @@ func IsReleaseExist(repoID int64, tagName string) (bool, error) {
|
||||
return x.Get(&Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)})
|
||||
}
|
||||
|
||||
func createTag(gitRepo *git.Repository, rel *Release) error {
|
||||
func createTag(gitRepo *git.Repository, r *Release) error {
|
||||
// Only actual create when publish.
|
||||
if !rel.IsDraft {
|
||||
if !gitRepo.IsTagExist(rel.TagName) {
|
||||
commit, err := gitRepo.GetBranchCommit(rel.Target)
|
||||
if !r.IsDraft {
|
||||
if !gitRepo.IsTagExist(r.TagName) {
|
||||
commit, err := gitRepo.GetBranchCommit(r.Target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetBranchCommit: %v", err)
|
||||
}
|
||||
|
||||
// Trim '--' prefix to prevent command line argument vulnerability.
|
||||
rel.TagName = strings.TrimPrefix(rel.TagName, "--")
|
||||
if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil {
|
||||
r.TagName = strings.TrimPrefix(r.TagName, "--")
|
||||
if err = gitRepo.CreateTag(r.TagName, commit.ID.String()); err != nil {
|
||||
if strings.Contains(err.Error(), "is not a valid tag name") {
|
||||
return ErrInvalidTagName{rel.TagName}
|
||||
return ErrInvalidTagName{r.TagName}
|
||||
}
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
commit, err := gitRepo.GetTagCommit(rel.TagName)
|
||||
commit, err := gitRepo.GetTagCommit(r.TagName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetTagCommit: %v", err)
|
||||
}
|
||||
|
||||
rel.Sha1 = commit.ID.String()
|
||||
rel.NumCommits, err = commit.CommitsCount()
|
||||
r.Sha1 = commit.ID.String()
|
||||
r.NumCommits, err = commit.CommitsCount()
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsCount: %v", err)
|
||||
}
|
||||
@@ -93,21 +148,61 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateRelease creates a new release of repository.
|
||||
func CreateRelease(gitRepo *git.Repository, rel *Release) error {
|
||||
isExist, err := IsReleaseExist(rel.RepoID, rel.TagName)
|
||||
func (r *Release) preparePublishWebhooks() {
|
||||
if err := PrepareWebhooks(r.Repo, HOOK_EVENT_RELEASE, &api.ReleasePayload{
|
||||
Action: api.HOOK_RELEASE_PUBLISHED,
|
||||
Release: r.APIFormat(),
|
||||
Repository: r.Repo.APIFormat(nil),
|
||||
Sender: r.Publisher.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error(2, "PrepareWebhooks: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// NewRelease creates a new release with attachments for repository.
|
||||
func NewRelease(gitRepo *git.Repository, r *Release, uuids []string) error {
|
||||
isExist, err := IsReleaseExist(r.RepoID, r.TagName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return ErrReleaseAlreadyExist{rel.TagName}
|
||||
return ErrReleaseAlreadyExist{r.TagName}
|
||||
}
|
||||
|
||||
if err = createTag(gitRepo, rel); err != nil {
|
||||
if err = createTag(gitRepo, r); err != nil {
|
||||
return err
|
||||
}
|
||||
rel.LowerTagName = strings.ToLower(rel.TagName)
|
||||
_, err = x.InsertOne(rel)
|
||||
return err
|
||||
r.LowerTagName = strings.ToLower(r.TagName)
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(r); err != nil {
|
||||
return fmt.Errorf("Insert: %v", err)
|
||||
}
|
||||
|
||||
if len(uuids) > 0 {
|
||||
if _, err = sess.In("uuid", uuids).Cols("release_id").Update(&Attachment{ReleaseID: r.ID}); err != nil {
|
||||
return fmt.Errorf("link attachments: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = sess.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
}
|
||||
|
||||
// Only send webhook when actually published, skip drafts
|
||||
if r.IsDraft {
|
||||
return nil
|
||||
}
|
||||
r, err = GetReleaseByID(r.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetReleaseByID: %v", err)
|
||||
}
|
||||
r.preparePublishWebhooks()
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRelease returns release by given ID.
|
||||
@@ -119,63 +214,109 @@ func GetRelease(repoID int64, tagName string) (*Release, error) {
|
||||
return nil, ErrReleaseNotExist{0, tagName}
|
||||
}
|
||||
|
||||
rel := &Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)}
|
||||
_, err = x.Get(rel)
|
||||
return rel, err
|
||||
r := &Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)}
|
||||
if _, err = x.Get(r); err != nil {
|
||||
return nil, fmt.Errorf("Get: %v", err)
|
||||
}
|
||||
|
||||
return r, r.LoadAttributes()
|
||||
}
|
||||
|
||||
// GetReleaseByID returns release with given ID.
|
||||
func GetReleaseByID(id int64) (*Release, error) {
|
||||
rel := new(Release)
|
||||
has, err := x.Id(id).Get(rel)
|
||||
r := new(Release)
|
||||
has, err := x.Id(id).Get(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrReleaseNotExist{id, ""}
|
||||
}
|
||||
|
||||
return rel, nil
|
||||
return r, r.LoadAttributes()
|
||||
}
|
||||
|
||||
// GetReleasesByRepoID returns a list of releases of repository.
|
||||
func GetReleasesByRepoID(repoID int64) (rels []*Release, err error) {
|
||||
err = x.Desc("created_unix").Find(&rels, Release{RepoID: repoID})
|
||||
return rels, err
|
||||
// GetPublishedReleasesByRepoID returns a list of published releases of repository.
|
||||
// If matches is not empty, only published releases in matches will be returned.
|
||||
// In any case, drafts won't be returned by this function.
|
||||
func GetPublishedReleasesByRepoID(repoID int64, matches ...string) ([]*Release, error) {
|
||||
sess := x.Where("repo_id = ?", repoID).And("is_draft = ?", false).Desc("created_unix")
|
||||
if len(matches) > 0 {
|
||||
sess.In("tag_name", matches)
|
||||
}
|
||||
releases := make([]*Release, 0, 5)
|
||||
return releases, sess.Find(&releases, new(Release))
|
||||
}
|
||||
|
||||
// GetDraftReleasesByRepoID returns all draft releases of repository.
|
||||
func GetDraftReleasesByRepoID(repoID int64) ([]*Release, error) {
|
||||
releases := make([]*Release, 0)
|
||||
return releases, x.Where("repo_id = ?", repoID).And("is_draft = ?", true).Find(&releases)
|
||||
}
|
||||
|
||||
type ReleaseSorter struct {
|
||||
rels []*Release
|
||||
releases []*Release
|
||||
}
|
||||
|
||||
func (rs *ReleaseSorter) Len() int {
|
||||
return len(rs.rels)
|
||||
return len(rs.releases)
|
||||
}
|
||||
|
||||
func (rs *ReleaseSorter) Less(i, j int) bool {
|
||||
diffNum := rs.rels[i].NumCommits - rs.rels[j].NumCommits
|
||||
diffNum := rs.releases[i].NumCommits - rs.releases[j].NumCommits
|
||||
if diffNum != 0 {
|
||||
return diffNum > 0
|
||||
}
|
||||
return rs.rels[i].Created.After(rs.rels[j].Created)
|
||||
return rs.releases[i].Created.After(rs.releases[j].Created)
|
||||
}
|
||||
|
||||
func (rs *ReleaseSorter) Swap(i, j int) {
|
||||
rs.rels[i], rs.rels[j] = rs.rels[j], rs.rels[i]
|
||||
rs.releases[i], rs.releases[j] = rs.releases[j], rs.releases[i]
|
||||
}
|
||||
|
||||
// SortReleases sorts releases by number of commits and created time.
|
||||
func SortReleases(rels []*Release) {
|
||||
sorter := &ReleaseSorter{rels: rels}
|
||||
sorter := &ReleaseSorter{releases: rels}
|
||||
sort.Sort(sorter)
|
||||
}
|
||||
|
||||
// UpdateRelease updates information of a release.
|
||||
func UpdateRelease(gitRepo *git.Repository, rel *Release) (err error) {
|
||||
if err = createTag(gitRepo, rel); err != nil {
|
||||
func UpdateRelease(doer *User, gitRepo *git.Repository, r *Release, isPublish bool, uuids []string) (err error) {
|
||||
if err = createTag(gitRepo, r); err != nil {
|
||||
return fmt.Errorf("createTag: %v", err)
|
||||
}
|
||||
|
||||
r.PublisherID = doer.ID
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = x.Id(rel.ID).AllCols().Update(rel)
|
||||
return err
|
||||
if _, err = sess.Id(r.ID).AllCols().Update(r); err != nil {
|
||||
return fmt.Errorf("Update: %v", err)
|
||||
}
|
||||
|
||||
// Unlink all current attachments and link back later if still valid
|
||||
if _, err = sess.Exec("UPDATE attachment SET release_id = 0 WHERE release_id = ?", r.ID); err != nil {
|
||||
return fmt.Errorf("unlink current attachments: %v", err)
|
||||
}
|
||||
|
||||
if len(uuids) > 0 {
|
||||
if _, err = sess.In("uuid", uuids).Cols("release_id").Update(&Attachment{ReleaseID: r.ID}); err != nil {
|
||||
return fmt.Errorf("link attachments: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = sess.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
}
|
||||
|
||||
if !isPublish {
|
||||
return nil
|
||||
}
|
||||
r.Publisher = doer
|
||||
r.preparePublishWebhooks()
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteReleaseOfRepoByID deletes a release and corresponding Git tag by given ID.
|
||||
|
||||
166
models/repo.go
166
models/repo.go
@@ -6,7 +6,6 @@ package models
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
@@ -29,6 +28,7 @@ import (
|
||||
git "github.com/gogits/git-module"
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models/errors"
|
||||
"github.com/gogits/gogs/modules/bindata"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
@@ -38,14 +38,6 @@ import (
|
||||
|
||||
var repoWorkingPool = sync.NewExclusivePool()
|
||||
|
||||
var (
|
||||
ErrRepoFileNotExist = errors.New("Repository file does not exist")
|
||||
ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
|
||||
ErrMirrorNotExist = errors.New("Mirror does not exist")
|
||||
ErrInvalidReference = errors.New("Invalid reference specified")
|
||||
ErrNameEmpty = errors.New("Name is empty")
|
||||
)
|
||||
|
||||
var (
|
||||
Gitignores, Licenses, Readmes, LabelTemplates []string
|
||||
|
||||
@@ -148,7 +140,7 @@ func NewRepoContext() {
|
||||
RemoveAllWithNotice("Clean up repository temporary data", filepath.Join(setting.AppDataPath, "tmp"))
|
||||
}
|
||||
|
||||
// Repository represents a git repository.
|
||||
// Repository contains information of a repository.
|
||||
type Repository struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
OwnerID int64 `xorm:"UNIQUE(s)"`
|
||||
@@ -158,6 +150,7 @@ type Repository struct {
|
||||
Description string
|
||||
Website string
|
||||
DefaultBranch string
|
||||
Size int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
|
||||
NumWatches int
|
||||
NumStars int
|
||||
@@ -300,6 +293,19 @@ func (repo *Repository) mustOwner(e Engine) *User {
|
||||
return repo.Owner
|
||||
}
|
||||
|
||||
func (repo *Repository) UpdateSize() error {
|
||||
countObject, err := git.GetRepoSize(repo.RepoPath())
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetRepoSize: %v", err)
|
||||
}
|
||||
|
||||
repo.Size = countObject.Size + countObject.SizePack
|
||||
if _, err = x.Id(repo.ID).Cols("size").Update(repo); err != nil {
|
||||
return fmt.Errorf("update size: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ComposeMetas composes a map of metas for rendering external issue tracker URL.
|
||||
func (repo *Repository) ComposeMetas() map[string]string {
|
||||
if !repo.EnableExternalTracker {
|
||||
@@ -628,8 +634,8 @@ func wikiRemoteURL(remote string) string {
|
||||
}
|
||||
|
||||
// MigrateRepository migrates a existing repository from other project hosting.
|
||||
func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||
repo, err := CreateRepository(u, CreateRepoOptions{
|
||||
func MigrateRepository(doer, owner *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||
repo, err := CreateRepository(doer, owner, CreateRepoOptions{
|
||||
Name: opts.Name,
|
||||
Description: opts.Description,
|
||||
IsPrivate: opts.IsPrivate,
|
||||
@@ -639,11 +645,11 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repoPath := RepoPath(u.Name, opts.Name)
|
||||
wikiPath := WikiPath(u.Name, opts.Name)
|
||||
repoPath := RepoPath(owner.Name, opts.Name)
|
||||
wikiPath := WikiPath(owner.Name, opts.Name)
|
||||
|
||||
if u.IsOrganization() {
|
||||
t, err := u.GetOwnerTeam()
|
||||
if owner.IsOrganization() {
|
||||
t, err := owner.GetOwnerTeam()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -882,8 +888,8 @@ func prepareRepoCommit(repo *Repository, tmpDir, repoPath string, opts CreateRep
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitRepository initializes README and .gitignore if needed.
|
||||
func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts CreateRepoOptions) (err error) {
|
||||
// initRepository performs initial commit with chosen setup files on behave of doer.
|
||||
func initRepository(e Engine, repoPath string, doer *User, repo *Repository, opts CreateRepoOptions) (err error) {
|
||||
// Somehow the directory could exist.
|
||||
if com.IsExist(repoPath) {
|
||||
return fmt.Errorf("initRepository: path already exists: %s", repoPath)
|
||||
@@ -908,7 +914,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C
|
||||
}
|
||||
|
||||
// Apply changes and commit.
|
||||
if err = initRepoCommit(tmpDir, u.NewGitSig()); err != nil {
|
||||
if err = initRepoCommit(tmpDir, doer.NewGitSig()); err != nil {
|
||||
return fmt.Errorf("initRepoCommit: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -941,32 +947,32 @@ func IsUsableRepoName(name string) error {
|
||||
return isUsableName(reservedRepoNames, reservedRepoPatterns, name)
|
||||
}
|
||||
|
||||
func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
|
||||
func createRepository(e *xorm.Session, doer, owner *User, repo *Repository) (err error) {
|
||||
if err = IsUsableRepoName(repo.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
has, err := isRepositoryExist(e, u, repo.Name)
|
||||
has, err := isRepositoryExist(e, owner, repo.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||||
} else if has {
|
||||
return ErrRepoAlreadyExist{u.Name, repo.Name}
|
||||
return ErrRepoAlreadyExist{owner.Name, repo.Name}
|
||||
}
|
||||
|
||||
if _, err = e.Insert(repo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.NumRepos++
|
||||
owner.NumRepos++
|
||||
// Remember visibility preference.
|
||||
u.LastRepoVisibility = repo.IsPrivate
|
||||
if err = updateUser(e, u); err != nil {
|
||||
owner.LastRepoVisibility = repo.IsPrivate
|
||||
if err = updateUser(e, owner); err != nil {
|
||||
return fmt.Errorf("updateUser: %v", err)
|
||||
}
|
||||
|
||||
// Give access to all members in owner team.
|
||||
if u.IsOrganization() {
|
||||
t, err := u.getOwnerTeam(e)
|
||||
if owner.IsOrganization() {
|
||||
t, err := owner.getOwnerTeam(e)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getOwnerTeam: %v", err)
|
||||
} else if err = t.addRepository(e, repo); err != nil {
|
||||
@@ -979,9 +985,9 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if err = watchRepo(e, u.ID, repo.ID, true); err != nil {
|
||||
if err = watchRepo(e, owner.ID, repo.ID, true); err != nil {
|
||||
return fmt.Errorf("watchRepo: %v", err)
|
||||
} else if err = newRepoAction(e, u, repo); err != nil {
|
||||
} else if err = newRepoAction(e, doer, owner, repo); err != nil {
|
||||
return fmt.Errorf("newRepoAction: %v", err)
|
||||
}
|
||||
|
||||
@@ -989,14 +995,14 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
|
||||
}
|
||||
|
||||
// CreateRepository creates a repository for given user or organization.
|
||||
func CreateRepository(u *User, opts CreateRepoOptions) (_ *Repository, err error) {
|
||||
if !u.CanCreateRepo() {
|
||||
return nil, ErrReachLimitOfRepo{u.MaxRepoCreation}
|
||||
func CreateRepository(doer, owner *User, opts CreateRepoOptions) (_ *Repository, err error) {
|
||||
if !owner.CanCreateRepo() {
|
||||
return nil, ErrReachLimitOfRepo{owner.MaxRepoCreation}
|
||||
}
|
||||
|
||||
repo := &Repository{
|
||||
OwnerID: u.ID,
|
||||
Owner: u,
|
||||
OwnerID: owner.ID,
|
||||
Owner: owner,
|
||||
Name: opts.Name,
|
||||
LowerName: strings.ToLower(opts.Name),
|
||||
Description: opts.Description,
|
||||
@@ -1012,14 +1018,14 @@ func CreateRepository(u *User, opts CreateRepoOptions) (_ *Repository, err error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = createRepository(sess, u, repo); err != nil {
|
||||
if err = createRepository(sess, doer, owner, repo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// No need for init mirror.
|
||||
if !opts.IsMirror {
|
||||
repoPath := RepoPath(u.Name, repo.Name)
|
||||
if err = initRepository(sess, repoPath, u, repo, opts); err != nil {
|
||||
repoPath := RepoPath(owner.Name, repo.Name)
|
||||
if err = initRepository(sess, repoPath, doer, repo, opts); err != nil {
|
||||
RemoveAllWithNotice("Delete repository for initialization failure", repoPath)
|
||||
return nil, fmt.Errorf("initRepository: %v", err)
|
||||
}
|
||||
@@ -1028,7 +1034,7 @@ func CreateRepository(u *User, opts CreateRepoOptions) (_ *Repository, err error
|
||||
repoPath, fmt.Sprintf("CreateRepository 'git update-server-info': %s", repoPath),
|
||||
"git", "update-server-info")
|
||||
if err != nil {
|
||||
return nil, errors.New("CreateRepository 'git update-server-info': " + stderr)
|
||||
return nil, fmt.Errorf("CreateRepository 'git update-server-info': %s", stderr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1474,7 +1480,7 @@ func DeleteRepository(uid, repoID int64) error {
|
||||
func GetRepositoryByRef(ref string) (*Repository, error) {
|
||||
n := strings.IndexByte(ref, byte('/'))
|
||||
if n < 2 {
|
||||
return nil, ErrInvalidReference
|
||||
return nil, errors.InvalidRepoReference{ref}
|
||||
}
|
||||
|
||||
userName, repoName := ref[:n], ref[n+1:]
|
||||
@@ -1564,6 +1570,7 @@ func GetRepositoryCount(u *User) (int64, error) {
|
||||
type SearchRepoOptions struct {
|
||||
Keyword string
|
||||
OwnerID int64
|
||||
UserID int64 // When set results will contain all public/private repositories user has access to
|
||||
OrderBy string
|
||||
Private bool // Include private repositories in results
|
||||
Page int
|
||||
@@ -1583,14 +1590,22 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int
|
||||
}
|
||||
|
||||
repos = make([]*Repository, 0, opts.PageSize)
|
||||
|
||||
// Append conditions
|
||||
sess := x.Where("LOWER(lower_name) LIKE ?", "%"+opts.Keyword+"%")
|
||||
if opts.OwnerID > 0 {
|
||||
sess.And("owner_id = ?", opts.OwnerID)
|
||||
sess := x.Alias("repo")
|
||||
// Attempt to find repositories that opts.UserID has access to,
|
||||
// this does not include other people's private repositories even if opts.UserID is an admin.
|
||||
if !opts.Private && opts.UserID > 0 {
|
||||
sess.Join("LEFT", "access", "access.repo_id = repo.id").
|
||||
Where("repo.lower_name LIKE ? AND (repo.owner_id = ? OR access.user_id = ? OR repo.is_private = ?)",
|
||||
"%"+opts.Keyword+"%", opts.UserID, opts.UserID, false)
|
||||
} else {
|
||||
sess.Where("repo.lower_name LIKE ?", "%"+opts.Keyword+"%")
|
||||
// Only return public repositories if opts.Private is not set
|
||||
if !opts.Private {
|
||||
sess.And("repo.is_private = ?", false)
|
||||
}
|
||||
}
|
||||
if !opts.Private {
|
||||
sess.And("is_private=?", false)
|
||||
if opts.OwnerID > 0 {
|
||||
sess.And("repo.owner_id = ?", opts.OwnerID)
|
||||
}
|
||||
|
||||
var countSess xorm.Session
|
||||
@@ -1601,7 +1616,7 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int
|
||||
}
|
||||
|
||||
if len(opts.OrderBy) > 0 {
|
||||
sess.OrderBy(opts.OrderBy)
|
||||
sess.OrderBy("repo." + opts.OrderBy)
|
||||
}
|
||||
return repos, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&repos)
|
||||
}
|
||||
@@ -2068,25 +2083,28 @@ func (repo *Repository) GetWatchers(page int) ([]*User, error) {
|
||||
|
||||
func notifyWatchers(e Engine, act *Action) error {
|
||||
// Add feeds for user self and all watchers.
|
||||
watches, err := getWatchers(e, act.RepoID)
|
||||
watchers, err := getWatchers(e, act.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get watchers: %v", err)
|
||||
return fmt.Errorf("getWatchers: %v", err)
|
||||
}
|
||||
|
||||
// Reset ID to reuse Action object
|
||||
act.ID = 0
|
||||
|
||||
// Add feed for actioner.
|
||||
act.UserID = act.ActUserID
|
||||
if _, err = e.InsertOne(act); err != nil {
|
||||
return fmt.Errorf("insert new actioner: %v", err)
|
||||
if _, err = e.Insert(act); err != nil {
|
||||
return fmt.Errorf("insert new action: %v", err)
|
||||
}
|
||||
|
||||
for i := range watches {
|
||||
if act.ActUserID == watches[i].UserID {
|
||||
for i := range watchers {
|
||||
if act.ActUserID == watchers[i].UserID {
|
||||
continue
|
||||
}
|
||||
|
||||
act.ID = 0
|
||||
act.UserID = watches[i].UserID
|
||||
if _, err = e.InsertOne(act); err != nil {
|
||||
act.UserID = watchers[i].UserID
|
||||
if _, err = e.Insert(act); err != nil {
|
||||
return fmt.Errorf("insert new action: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -2161,24 +2179,26 @@ func (repo *Repository) GetStargazers(page int) ([]*User, error) {
|
||||
// \___ / \____/|__| |__|_ \
|
||||
// \/ \/
|
||||
|
||||
// HasForkedRepo checks if given user has already forked a repository with given ID.
|
||||
// HasForkedRepo checks if given user has already forked a repository.
|
||||
// When user has already forked, it returns true along with the repository.
|
||||
func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
|
||||
repo := new(Repository)
|
||||
has, _ := x.Where("owner_id=? AND fork_id=?", ownerID, repoID).Get(repo)
|
||||
has, _ := x.Where("owner_id = ? AND fork_id = ?", ownerID, repoID).Get(repo)
|
||||
return repo, has
|
||||
}
|
||||
|
||||
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
|
||||
// ForkRepository creates a fork of target repository under another user domain.
|
||||
func ForkRepository(doer, owner *User, baseRepo *Repository, name, desc string) (_ *Repository, err error) {
|
||||
repo := &Repository{
|
||||
OwnerID: u.ID,
|
||||
Owner: u,
|
||||
OwnerID: owner.ID,
|
||||
Owner: owner,
|
||||
Name: name,
|
||||
LowerName: strings.ToLower(name),
|
||||
Description: desc,
|
||||
DefaultBranch: oldRepo.DefaultBranch,
|
||||
IsPrivate: oldRepo.IsPrivate,
|
||||
DefaultBranch: baseRepo.DefaultBranch,
|
||||
IsPrivate: baseRepo.IsPrivate,
|
||||
IsFork: true,
|
||||
ForkID: oldRepo.ID,
|
||||
ForkID: baseRepo.ID,
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
@@ -2187,18 +2207,16 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = createRepository(sess, u, repo); err != nil {
|
||||
if err = createRepository(sess, doer, owner, repo); err != nil {
|
||||
return nil, err
|
||||
} else if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", baseRepo.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repoPath := RepoPath(u.Name, repo.Name)
|
||||
repoPath := repo.repoPath(sess)
|
||||
_, stderr, err := process.ExecTimeout(10*time.Minute,
|
||||
fmt.Sprintf("ForkRepository 'git clone': %s/%s", u.Name, repo.Name),
|
||||
"git", "clone", "--bare", oldRepo.RepoPath(), repoPath)
|
||||
fmt.Sprintf("ForkRepository 'git clone': %s/%s", owner.Name, repo.Name),
|
||||
"git", "clone", "--bare", baseRepo.RepoPath(), repoPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("git clone: %v", stderr)
|
||||
}
|
||||
@@ -2212,6 +2230,12 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
|
||||
|
||||
if err = createDelegateHooks(repoPath); err != nil {
|
||||
return nil, fmt.Errorf("createDelegateHooks: %v", err)
|
||||
} else if err = prepareWebhooks(sess, baseRepo, HOOK_EVENT_FORK, &api.ForkPayload{
|
||||
Forkee: repo.APIFormat(nil),
|
||||
Repo: baseRepo.APIFormat(nil),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("prepareWebhooks: %v", err)
|
||||
}
|
||||
|
||||
return repo, sess.Commit()
|
||||
|
||||
@@ -15,8 +15,11 @@ import (
|
||||
)
|
||||
|
||||
type Branch struct {
|
||||
Path string
|
||||
Name string
|
||||
RepoPath string
|
||||
Name string
|
||||
|
||||
IsProtected bool
|
||||
Commit *git.Commit
|
||||
}
|
||||
|
||||
func GetBranchesByPath(path string) ([]*Branch, error) {
|
||||
@@ -33,8 +36,8 @@ func GetBranchesByPath(path string) ([]*Branch, error) {
|
||||
branches := make([]*Branch, len(brs))
|
||||
for i := range brs {
|
||||
branches[i] = &Branch{
|
||||
Path: path,
|
||||
Name: brs[i],
|
||||
RepoPath: path,
|
||||
Name: brs[i],
|
||||
}
|
||||
}
|
||||
return branches, nil
|
||||
@@ -45,8 +48,8 @@ func (repo *Repository) GetBranch(br string) (*Branch, error) {
|
||||
return nil, ErrBranchNotExist{br}
|
||||
}
|
||||
return &Branch{
|
||||
Path: repo.RepoPath(),
|
||||
Name: br,
|
||||
RepoPath: repo.RepoPath(),
|
||||
Name: br,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -55,7 +58,7 @@ func (repo *Repository) GetBranches() ([]*Branch, error) {
|
||||
}
|
||||
|
||||
func (br *Branch) GetCommit() (*git.Commit, error) {
|
||||
gitRepo, err := git.OpenRepository(br.Path)
|
||||
gitRepo, err := git.OpenRepository(br.RepoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -125,7 +128,6 @@ func UpdateProtectBranch(protectBranch *ProtectBranch) (err error) {
|
||||
if _, err = sess.Insert(protectBranch); err != nil {
|
||||
return fmt.Errorf("Insert: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = sess.Id(protectBranch.ID).AllCols().Update(protectBranch); err != nil {
|
||||
|
||||
@@ -527,6 +527,7 @@ func RewriteAllPublicKeys() error {
|
||||
sshOpLocker.Lock()
|
||||
defer sshOpLocker.Unlock()
|
||||
|
||||
os.MkdirAll(setting.SSH.RootPath, os.ModePerm)
|
||||
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||
tmpPath := fpath + ".tmp"
|
||||
f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
git "github.com/gogits/git-module"
|
||||
)
|
||||
|
||||
@@ -29,6 +27,10 @@ func CommitToPushCommit(commit *git.Commit) *PushCommit {
|
||||
}
|
||||
|
||||
func ListToPushCommits(l *list.List) *PushCommits {
|
||||
if l == nil {
|
||||
return &PushCommits{}
|
||||
}
|
||||
|
||||
commits := make([]*PushCommit, 0)
|
||||
var actEmail string
|
||||
for e := l.Front(); e != nil; e = e.Next() {
|
||||
@@ -68,12 +70,6 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
|
||||
return fmt.Errorf("Fail to call 'git update-server-info': %v", err)
|
||||
}
|
||||
|
||||
if isDelRef {
|
||||
log.Trace("Reference '%s' has been deleted from '%s/%s' by %s",
|
||||
opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName)
|
||||
return nil
|
||||
}
|
||||
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("OpenRepository: %v", err)
|
||||
@@ -89,7 +85,11 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
|
||||
return fmt.Errorf("GetRepositoryByName: %v", err)
|
||||
}
|
||||
|
||||
// Push tags.
|
||||
if err = repo.UpdateSize(); err != nil {
|
||||
return fmt.Errorf("UpdateSize: %v", err)
|
||||
}
|
||||
|
||||
// Push tags
|
||||
if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) {
|
||||
if err := CommitRepoAction(CommitRepoActionOptions{
|
||||
PusherName: opts.PusherName,
|
||||
@@ -100,27 +100,30 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
|
||||
NewCommitID: opts.NewCommitID,
|
||||
Commits: &PushCommits{},
|
||||
}); err != nil {
|
||||
return fmt.Errorf("CommitRepoAction (tag): %v", err)
|
||||
return fmt.Errorf("CommitRepoAction.(tag): %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("gitRepo.GetCommit: %v", err)
|
||||
}
|
||||
|
||||
// Push new branch.
|
||||
var l *list.List
|
||||
if isNewRef {
|
||||
l, err = newCommit.CommitsBeforeLimit(10)
|
||||
// Skip read parent commits when delete branch
|
||||
if !isDelRef {
|
||||
// Push new branch
|
||||
newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err)
|
||||
return fmt.Errorf("GetCommit [commit_id: %s]: %v", opts.NewCommitID, err)
|
||||
}
|
||||
} else {
|
||||
l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err)
|
||||
|
||||
if isNewRef {
|
||||
l, err = newCommit.CommitsBeforeLimit(10)
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsBeforeLimit [commit_id: %s]: %v", newCommit.ID, err)
|
||||
}
|
||||
} else {
|
||||
l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsBeforeUntil [commit_id: %s]: %v", opts.OldCommitID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +136,7 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
|
||||
NewCommitID: opts.NewCommitID,
|
||||
Commits: ListToPushCommits(l),
|
||||
}); err != nil {
|
||||
return fmt.Errorf("CommitRepoAction (branch): %v", err)
|
||||
return fmt.Errorf("CommitRepoAction.(branch): %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/jpeg"
|
||||
@@ -30,6 +29,7 @@ import (
|
||||
"github.com/gogits/git-module"
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models/errors"
|
||||
"github.com/gogits/gogs/modules/avatar"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/markdown"
|
||||
@@ -43,15 +43,6 @@ const (
|
||||
USER_TYPE_ORGANIZATION
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUserNotKeyOwner = errors.New("User does not the owner of public key")
|
||||
ErrEmailNotExist = errors.New("E-mail does not exist")
|
||||
ErrEmailNotActivated = errors.New("E-mail address has not been activated")
|
||||
ErrUserNameIllegal = errors.New("User name contains illegal characters")
|
||||
ErrLoginSourceNotActived = errors.New("Login source is not actived")
|
||||
ErrUnsupportedLoginType = errors.New("Login source is unknown")
|
||||
)
|
||||
|
||||
// User represents the object of individual and member of organization.
|
||||
type User struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
@@ -448,18 +439,18 @@ func (u *User) GetOwnedOrganizations() (err error) {
|
||||
}
|
||||
|
||||
// GetOrganizations returns all organizations that user belongs to.
|
||||
func (u *User) GetOrganizations(all bool) error {
|
||||
ous, err := GetOrgUsersByUserID(u.ID, all)
|
||||
func (u *User) GetOrganizations(showPrivate bool) error {
|
||||
orgIDs, err := GetOrgIDsByUserID(u.ID, showPrivate)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("GetOrgIDsByUserID: %v", err)
|
||||
}
|
||||
if len(orgIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
u.Orgs = make([]*User, len(ous))
|
||||
for i, ou := range ous {
|
||||
u.Orgs[i], err = GetUserByID(ou.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Orgs = make([]*User, 0, len(orgIDs))
|
||||
if err = x.Where("type = ?", USER_TYPE_ORGANIZATION).In("id", orgIDs).Find(&u.Orgs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -519,7 +510,7 @@ var (
|
||||
func isUsableName(names, patterns []string, name string) error {
|
||||
name = strings.TrimSpace(strings.ToLower(name))
|
||||
if utf8.RuneCountInString(name) == 0 {
|
||||
return ErrNameEmpty
|
||||
return errors.EmptyName{}
|
||||
}
|
||||
|
||||
for i := range names {
|
||||
@@ -685,7 +676,13 @@ func ChangeUserName(u *User, newUserName string) (err error) {
|
||||
return fmt.Errorf("Delete repository wiki local copy: %v", err)
|
||||
}
|
||||
|
||||
return os.Rename(UserPath(u.Name), UserPath(newUserName))
|
||||
// Rename or create user base directory
|
||||
baseDir := UserPath(u.Name)
|
||||
newBaseDir := UserPath(newUserName)
|
||||
if com.IsExist(baseDir) {
|
||||
return os.Rename(baseDir, newBaseDir)
|
||||
}
|
||||
return os.MkdirAll(newBaseDir, os.ModePerm)
|
||||
}
|
||||
|
||||
func updateUser(e Engine, u *User) error {
|
||||
@@ -884,11 +881,11 @@ func UserPath(userName string) string {
|
||||
|
||||
func GetUserByKeyID(keyID int64) (*User, error) {
|
||||
user := new(User)
|
||||
has, err := x.Sql("SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?", keyID).Get(user)
|
||||
has, err := x.SQL("SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?", keyID).Get(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrUserNotKeyOwner
|
||||
return nil, errors.UserNotKeyOwner{keyID}
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ package models
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gogits/gogs/models/errors"
|
||||
)
|
||||
|
||||
// EmailAdresses is the list of all email addresses of a user. Can contain the
|
||||
@@ -163,11 +165,11 @@ func MakeEmailPrimary(email *EmailAddress) error {
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrEmailNotExist
|
||||
return errors.EmailNotFound{email.Email}
|
||||
}
|
||||
|
||||
if !email.IsActivated {
|
||||
return ErrEmailNotActivated
|
||||
return errors.EmailNotVerified{email.Email}
|
||||
}
|
||||
|
||||
user := &User{ID: email.UID}
|
||||
|
||||
@@ -62,9 +62,14 @@ func IsValidHookContentType(name string) bool {
|
||||
}
|
||||
|
||||
type HookEvents struct {
|
||||
Create bool `json:"create"`
|
||||
Push bool `json:"push"`
|
||||
PullRequest bool `json:"pull_request"`
|
||||
Create bool `json:"create"`
|
||||
Delete bool `json:"delete"`
|
||||
Fork bool `json:"fork"`
|
||||
Push bool `json:"push"`
|
||||
Issues bool `json:"issues"`
|
||||
IssueComment bool `json:"issue_comment"`
|
||||
PullRequest bool `json:"pull_request"`
|
||||
Release bool `json:"release"`
|
||||
}
|
||||
|
||||
// HookEvent represents events that will delivery hook.
|
||||
@@ -156,28 +161,69 @@ func (w *Webhook) HasCreateEvent() bool {
|
||||
(w.ChooseEvents && w.HookEvents.Create)
|
||||
}
|
||||
|
||||
// HasDeleteEvent returns true if hook enabled delete event.
|
||||
func (w *Webhook) HasDeleteEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.Delete)
|
||||
}
|
||||
|
||||
// HasForkEvent returns true if hook enabled fork event.
|
||||
func (w *Webhook) HasForkEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.Fork)
|
||||
}
|
||||
|
||||
// HasPushEvent returns true if hook enabled push event.
|
||||
func (w *Webhook) HasPushEvent() bool {
|
||||
return w.PushOnly || w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.Push)
|
||||
}
|
||||
|
||||
// HasIssuesEvent returns true if hook enabled issues event.
|
||||
func (w *Webhook) HasIssuesEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.Issues)
|
||||
}
|
||||
|
||||
// HasIssueCommentEvent returns true if hook enabled issue comment event.
|
||||
func (w *Webhook) HasIssueCommentEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.IssueComment)
|
||||
}
|
||||
|
||||
// HasPullRequestEvent returns true if hook enabled pull request event.
|
||||
func (w *Webhook) HasPullRequestEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequest)
|
||||
}
|
||||
|
||||
// HasReleaseEvent returns true if hook enabled release event.
|
||||
func (w *Webhook) HasReleaseEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.Release)
|
||||
}
|
||||
|
||||
type eventChecker struct {
|
||||
checker func() bool
|
||||
typ HookEventType
|
||||
}
|
||||
|
||||
func (w *Webhook) EventsArray() []string {
|
||||
events := make([]string, 0, 3)
|
||||
if w.HasCreateEvent() {
|
||||
events = append(events, "create")
|
||||
events := make([]string, 0, 7)
|
||||
eventCheckers := []eventChecker{
|
||||
{w.HasCreateEvent, HOOK_EVENT_CREATE},
|
||||
{w.HasDeleteEvent, HOOK_EVENT_DELETE},
|
||||
{w.HasForkEvent, HOOK_EVENT_FORK},
|
||||
{w.HasPushEvent, HOOK_EVENT_PUSH},
|
||||
{w.HasIssuesEvent, HOOK_EVENT_ISSUES},
|
||||
{w.HasIssueCommentEvent, HOOK_EVENT_ISSUE_COMMENT},
|
||||
{w.HasPullRequestEvent, HOOK_EVENT_PULL_REQUEST},
|
||||
{w.HasReleaseEvent, HOOK_EVENT_RELEASE},
|
||||
}
|
||||
if w.HasPushEvent() {
|
||||
events = append(events, "push")
|
||||
}
|
||||
if w.HasPullRequestEvent() {
|
||||
events = append(events, "pull_request")
|
||||
for _, c := range eventCheckers {
|
||||
if c.checker() {
|
||||
events = append(events, string(c.typ))
|
||||
}
|
||||
}
|
||||
return events
|
||||
}
|
||||
@@ -225,10 +271,10 @@ func GetWebhookByOrgID(orgID, id int64) (*Webhook, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetActiveWebhooksByRepoID returns all active webhooks of repository.
|
||||
func GetActiveWebhooksByRepoID(repoID int64) ([]*Webhook, error) {
|
||||
// getActiveWebhooksByRepoID returns all active webhooks of repository.
|
||||
func getActiveWebhooksByRepoID(e Engine, repoID int64) ([]*Webhook, error) {
|
||||
webhooks := make([]*Webhook, 0, 5)
|
||||
return webhooks, x.Where("repo_id = ?", repoID).And("is_active = ?", true).Find(&webhooks)
|
||||
return webhooks, e.Where("repo_id = ?", repoID).And("is_active = ?", true).Find(&webhooks)
|
||||
}
|
||||
|
||||
// GetWebhooksByRepoID returns all webhooks of a repository.
|
||||
@@ -283,10 +329,10 @@ func GetWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) {
|
||||
return ws, err
|
||||
}
|
||||
|
||||
// GetActiveWebhooksByOrgID returns all active webhooks for an organization.
|
||||
func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) {
|
||||
err = x.Where("org_id=?", orgID).And("is_active=?", true).Find(&ws)
|
||||
return ws, err
|
||||
// getActiveWebhooksByOrgID returns all active webhooks for an organization.
|
||||
func getActiveWebhooksByOrgID(e Engine, orgID int64) ([]*Webhook, error) {
|
||||
ws := make([]*Webhook, 0, 3)
|
||||
return ws, e.Where("org_id=?", orgID).And("is_active=?", true).Find(&ws)
|
||||
}
|
||||
|
||||
// ___ ___ __ ___________ __
|
||||
@@ -336,9 +382,14 @@ func IsValidHookTaskType(name string) bool {
|
||||
type HookEventType string
|
||||
|
||||
const (
|
||||
HOOK_EVENT_CREATE HookEventType = "create"
|
||||
HOOK_EVENT_PUSH HookEventType = "push"
|
||||
HOOK_EVENT_PULL_REQUEST HookEventType = "pull_request"
|
||||
HOOK_EVENT_CREATE HookEventType = "create"
|
||||
HOOK_EVENT_DELETE HookEventType = "delete"
|
||||
HOOK_EVENT_FORK HookEventType = "fork"
|
||||
HOOK_EVENT_PUSH HookEventType = "push"
|
||||
HOOK_EVENT_ISSUES HookEventType = "issues"
|
||||
HOOK_EVENT_ISSUE_COMMENT HookEventType = "issue_comment"
|
||||
HOOK_EVENT_PULL_REQUEST HookEventType = "pull_request"
|
||||
HOOK_EVENT_RELEASE HookEventType = "release"
|
||||
)
|
||||
|
||||
// HookRequest represents hook task request information.
|
||||
@@ -430,16 +481,16 @@ func HookTasks(hookID int64, page int) ([]*HookTask, error) {
|
||||
return tasks, x.Limit(setting.Webhook.PagingNum, (page-1)*setting.Webhook.PagingNum).Where("hook_id=?", hookID).Desc("id").Find(&tasks)
|
||||
}
|
||||
|
||||
// CreateHookTask creates a new hook task,
|
||||
// createHookTask creates a new hook task,
|
||||
// it handles conversion from Payload to PayloadContent.
|
||||
func CreateHookTask(t *HookTask) error {
|
||||
func createHookTask(e Engine, t *HookTask) error {
|
||||
data, err := t.Payloader.JSONPayload()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.UUID = gouuid.NewV4().String()
|
||||
t.PayloadContent = string(data)
|
||||
_, err = x.Insert(t)
|
||||
_, err = e.Insert(t)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -449,8 +500,8 @@ func UpdateHookTask(t *HookTask) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// prepareWebhooks adds list of webhooks to task queue.
|
||||
func prepareWebhooks(repo *Repository, event HookEventType, p api.Payloader, webhooks []*Webhook) (err error) {
|
||||
// prepareHookTasks adds list of webhooks to task queue.
|
||||
func prepareHookTasks(e Engine, repo *Repository, event HookEventType, p api.Payloader, webhooks []*Webhook) (err error) {
|
||||
if len(webhooks) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -462,14 +513,34 @@ func prepareWebhooks(repo *Repository, event HookEventType, p api.Payloader, web
|
||||
if !w.HasCreateEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_DELETE:
|
||||
if !w.HasDeleteEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_FORK:
|
||||
if !w.HasForkEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_PUSH:
|
||||
if !w.HasPushEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_ISSUES:
|
||||
if !w.HasIssuesEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_ISSUE_COMMENT:
|
||||
if !w.HasIssueCommentEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_PULL_REQUEST:
|
||||
if !w.HasPullRequestEvent() {
|
||||
continue
|
||||
}
|
||||
case HOOK_EVENT_RELEASE:
|
||||
if !w.HasReleaseEvent() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Use separate objects so modifcations won't be made on payload on non-Gogs type hooks.
|
||||
@@ -499,7 +570,7 @@ func prepareWebhooks(repo *Repository, event HookEventType, p api.Payloader, web
|
||||
signature = hex.EncodeToString(sig.Sum(nil))
|
||||
}
|
||||
|
||||
if err = CreateHookTask(&HookTask{
|
||||
if err = createHookTask(e, &HookTask{
|
||||
RepoID: repo.ID,
|
||||
HookID: w.ID,
|
||||
Type: w.HookTaskType,
|
||||
@@ -510,29 +581,38 @@ func prepareWebhooks(repo *Repository, event HookEventType, p api.Payloader, web
|
||||
EventType: event,
|
||||
IsSSL: w.IsSSL,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("CreateHookTask: %v", err)
|
||||
return fmt.Errorf("createHookTask: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// It's safe to fail when the whole function is called during hook execution
|
||||
// because resource released after exit.
|
||||
// FIXME: need a more safe way to not call this function if it's during hook execution.
|
||||
go HookQueue.Add(repo.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareWebhooks(e Engine, repo *Repository, event HookEventType, p api.Payloader) error {
|
||||
webhooks, err := getActiveWebhooksByRepoID(e, repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getActiveWebhooksByRepoID [%d]: %v", repo.ID, err)
|
||||
}
|
||||
|
||||
// check if repo belongs to org and append additional webhooks
|
||||
if repo.mustOwner(e).IsOrganization() {
|
||||
// get hooks for org
|
||||
orgws, err := getActiveWebhooksByOrgID(e, repo.OwnerID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getActiveWebhooksByOrgID [%d]: %v", repo.OwnerID, err)
|
||||
}
|
||||
webhooks = append(webhooks, orgws...)
|
||||
}
|
||||
return prepareHookTasks(e, repo, event, p, webhooks)
|
||||
}
|
||||
|
||||
// PrepareWebhooks adds all active webhooks to task queue.
|
||||
func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) error {
|
||||
webhooks, err := GetActiveWebhooksByRepoID(repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetActiveWebhooksByRepoID [%d]: %v", repo.ID, err)
|
||||
}
|
||||
|
||||
// check if repo belongs to org and append additional webhooks
|
||||
if repo.MustOwner().IsOrganization() {
|
||||
// get hooks for org
|
||||
orgws, err := GetActiveWebhooksByOrgID(repo.OwnerID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetActiveWebhooksByOrgID [%d]: %v", repo.OwnerID, err)
|
||||
}
|
||||
webhooks = append(webhooks, orgws...)
|
||||
}
|
||||
return prepareWebhooks(repo, event, p, webhooks)
|
||||
return prepareWebhooks(x, repo, event, p)
|
||||
}
|
||||
|
||||
// TestWebhook adds the test webhook matches the ID to task queue.
|
||||
@@ -541,7 +621,7 @@ func TestWebhook(repo *Repository, event HookEventType, p api.Payloader, webhook
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetWebhookOfRepoByID [repo_id: %d, id: %d]: %v", repo.ID, webhookID, err)
|
||||
}
|
||||
return prepareWebhooks(repo, event, p, []*Webhook{webhook})
|
||||
return prepareHookTasks(x, repo, event, p, []*Webhook{webhook})
|
||||
}
|
||||
|
||||
func (t *HookTask) deliver() {
|
||||
|
||||
@@ -68,22 +68,50 @@ func DiscordSHALinkFormatter(url string, text string) string {
|
||||
return fmt.Sprintf("[`%s`](%s)", text, url)
|
||||
}
|
||||
|
||||
func getDiscordCreatePayload(p *api.CreatePayload, slack *SlackMeta) (*DiscordPayload, error) {
|
||||
// Created tag/branch
|
||||
// getDiscordCreatePayload composes Discord payload for create new branch or tag.
|
||||
func getDiscordCreatePayload(p *api.CreatePayload) (*DiscordPayload, error) {
|
||||
refName := git.RefEndName(p.Ref)
|
||||
|
||||
repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
|
||||
refLink := DiscordLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName)
|
||||
content := fmt.Sprintf("Created new %s: %s/%s", p.RefType, repoLink, refLink)
|
||||
|
||||
color, _ := strconv.ParseInt(strings.TrimLeft(slack.Color, "#"), 16, 32)
|
||||
return &DiscordPayload{
|
||||
Username: slack.Username,
|
||||
AvatarURL: slack.IconURL,
|
||||
Embeds: []*DiscordEmbedObject{{
|
||||
Description: content,
|
||||
URL: setting.AppUrl + p.Sender.UserName,
|
||||
Color: int(color),
|
||||
Author: &DiscordEmbedAuthorObject{
|
||||
Name: p.Sender.UserName,
|
||||
IconURL: p.Sender.AvatarUrl,
|
||||
},
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getDiscordDeletePayload composes Discord payload for delete a branch or tag.
|
||||
func getDiscordDeletePayload(p *api.DeletePayload) (*DiscordPayload, error) {
|
||||
refName := git.RefEndName(p.Ref)
|
||||
repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
|
||||
content := fmt.Sprintf("Deleted %s: %s/%s", p.RefType, repoLink, refName)
|
||||
return &DiscordPayload{
|
||||
Embeds: []*DiscordEmbedObject{{
|
||||
Description: content,
|
||||
URL: setting.AppUrl + p.Sender.UserName,
|
||||
Author: &DiscordEmbedAuthorObject{
|
||||
Name: p.Sender.UserName,
|
||||
IconURL: p.Sender.AvatarUrl,
|
||||
},
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getDiscordForkPayload composes Discord payload for forked by a repository.
|
||||
func getDiscordForkPayload(p *api.ForkPayload) (*DiscordPayload, error) {
|
||||
baseLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
|
||||
forkLink := DiscordLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
|
||||
content := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
|
||||
return &DiscordPayload{
|
||||
Embeds: []*DiscordEmbedObject{{
|
||||
Description: content,
|
||||
URL: setting.AppUrl + p.Sender.UserName,
|
||||
Author: &DiscordEmbedAuthorObject{
|
||||
Name: p.Sender.UserName,
|
||||
IconURL: p.Sender.AvatarUrl,
|
||||
@@ -141,6 +169,117 @@ func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) (*DiscordPayloa
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getDiscordIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) (*DiscordPayload, error) {
|
||||
title := fmt.Sprintf("#%d %s", p.Index, p.Issue.Title)
|
||||
url := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index)
|
||||
content := ""
|
||||
fields := make([]*DiscordEmbedFieldObject, 0, 1)
|
||||
switch p.Action {
|
||||
case api.HOOK_ISSUE_OPENED:
|
||||
title = "New issue: " + title
|
||||
content = p.Issue.Body
|
||||
case api.HOOK_ISSUE_CLOSED:
|
||||
title = "Issue closed: " + title
|
||||
case api.HOOK_ISSUE_REOPENED:
|
||||
title = "Issue re-opened: " + title
|
||||
case api.HOOK_ISSUE_EDITED:
|
||||
title = "Issue edited: " + title
|
||||
content = p.Issue.Body
|
||||
case api.HOOK_ISSUE_ASSIGNED:
|
||||
title = "Issue assigned: " + title
|
||||
fields = []*DiscordEmbedFieldObject{{
|
||||
Name: "New Assignee",
|
||||
Value: p.Issue.Assignee.UserName,
|
||||
}}
|
||||
case api.HOOK_ISSUE_UNASSIGNED:
|
||||
title = "Issue unassigned: " + title
|
||||
case api.HOOK_ISSUE_LABEL_UPDATED:
|
||||
title = "Issue labels updated: " + title
|
||||
labels := make([]string, len(p.Issue.Labels))
|
||||
for i := range p.Issue.Labels {
|
||||
labels[i] = p.Issue.Labels[i].Name
|
||||
}
|
||||
if len(labels) == 0 {
|
||||
labels = []string{"<empty>"}
|
||||
}
|
||||
fields = []*DiscordEmbedFieldObject{{
|
||||
Name: "Labels",
|
||||
Value: strings.Join(labels, ", "),
|
||||
}}
|
||||
case api.HOOK_ISSUE_LABEL_CLEARED:
|
||||
title = "Issue labels cleared: " + title
|
||||
case api.HOOK_ISSUE_SYNCHRONIZED:
|
||||
title = "Issue synchronized: " + title
|
||||
case api.HOOK_ISSUE_MILESTONED:
|
||||
title = "Issue milestoned: " + title
|
||||
fields = []*DiscordEmbedFieldObject{{
|
||||
Name: "New Milestone",
|
||||
Value: p.Issue.Milestone.Title,
|
||||
}}
|
||||
case api.HOOK_ISSUE_DEMILESTONED:
|
||||
title = "Issue demilestoned: " + title
|
||||
}
|
||||
|
||||
color, _ := strconv.ParseInt(strings.TrimLeft(slack.Color, "#"), 16, 32)
|
||||
return &DiscordPayload{
|
||||
Username: slack.Username,
|
||||
AvatarURL: slack.IconURL,
|
||||
Embeds: []*DiscordEmbedObject{{
|
||||
Title: title,
|
||||
Description: content,
|
||||
URL: url,
|
||||
Color: int(color),
|
||||
Footer: &DiscordEmbedFooterObject{
|
||||
Text: p.Repository.FullName,
|
||||
},
|
||||
Author: &DiscordEmbedAuthorObject{
|
||||
Name: p.Sender.UserName,
|
||||
IconURL: p.Sender.AvatarUrl,
|
||||
},
|
||||
Fields: fields,
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*DiscordPayload, error) {
|
||||
title := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
|
||||
content := ""
|
||||
fields := make([]*DiscordEmbedFieldObject, 0, 1)
|
||||
switch p.Action {
|
||||
case api.HOOK_ISSUE_COMMENT_CREATED:
|
||||
title = "New comment: " + title
|
||||
content = p.Comment.Body
|
||||
case api.HOOK_ISSUE_COMMENT_EDITED:
|
||||
title = "Comment edited: " + title
|
||||
content = p.Comment.Body
|
||||
case api.HOOK_ISSUE_COMMENT_DELETED:
|
||||
title = "Comment deleted: " + title
|
||||
url = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
|
||||
content = p.Comment.Body
|
||||
}
|
||||
|
||||
color, _ := strconv.ParseInt(strings.TrimLeft(slack.Color, "#"), 16, 32)
|
||||
return &DiscordPayload{
|
||||
Username: slack.Username,
|
||||
AvatarURL: slack.IconURL,
|
||||
Embeds: []*DiscordEmbedObject{{
|
||||
Title: title,
|
||||
Description: content,
|
||||
URL: url,
|
||||
Color: int(color),
|
||||
Footer: &DiscordEmbedFooterObject{
|
||||
Text: p.Repository.FullName,
|
||||
},
|
||||
Author: &DiscordEmbedAuthorObject{
|
||||
Name: p.Sender.UserName,
|
||||
IconURL: p.Sender.AvatarUrl,
|
||||
},
|
||||
Fields: fields,
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*DiscordPayload, error) {
|
||||
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
|
||||
url := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
|
||||
@@ -183,6 +322,14 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (
|
||||
title = "Pull request labels cleared: " + title
|
||||
case api.HOOK_ISSUE_SYNCHRONIZED:
|
||||
title = "Pull request synchronized: " + title
|
||||
case api.HOOK_ISSUE_MILESTONED:
|
||||
title = "Pull request milestoned: " + title
|
||||
fields = []*DiscordEmbedFieldObject{{
|
||||
Name: "New Milestone",
|
||||
Value: p.PullRequest.Milestone.Title,
|
||||
}}
|
||||
case api.HOOK_ISSUE_DEMILESTONED:
|
||||
title = "Pull request demilestoned: " + title
|
||||
}
|
||||
|
||||
color, _ := strconv.ParseInt(strings.TrimLeft(slack.Color, "#"), 16, 32)
|
||||
@@ -206,22 +353,56 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*DiscordPayload, error) {
|
||||
d := new(DiscordPayload)
|
||||
func getDiscordReleasePayload(p *api.ReleasePayload) (*DiscordPayload, error) {
|
||||
repoLink := DiscordLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
|
||||
refLink := DiscordLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
|
||||
content := fmt.Sprintf("Published new release %s of %s", refLink, repoLink)
|
||||
return &DiscordPayload{
|
||||
Embeds: []*DiscordEmbedObject{{
|
||||
Description: content,
|
||||
URL: setting.AppUrl + p.Sender.UserName,
|
||||
Author: &DiscordEmbedAuthorObject{
|
||||
Name: p.Sender.UserName,
|
||||
IconURL: p.Sender.AvatarUrl,
|
||||
},
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (payload *DiscordPayload, err error) {
|
||||
slack := &SlackMeta{}
|
||||
if err := json.Unmarshal([]byte(meta), &slack); err != nil {
|
||||
return d, fmt.Errorf("GetDiscordPayload meta json: %v", err)
|
||||
return nil, fmt.Errorf("json.Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
switch event {
|
||||
case HOOK_EVENT_CREATE:
|
||||
return getDiscordCreatePayload(p.(*api.CreatePayload), slack)
|
||||
payload, err = getDiscordCreatePayload(p.(*api.CreatePayload))
|
||||
case HOOK_EVENT_DELETE:
|
||||
payload, err = getDiscordDeletePayload(p.(*api.DeletePayload))
|
||||
case HOOK_EVENT_FORK:
|
||||
payload, err = getDiscordForkPayload(p.(*api.ForkPayload))
|
||||
case HOOK_EVENT_PUSH:
|
||||
return getDiscordPushPayload(p.(*api.PushPayload), slack)
|
||||
payload, err = getDiscordPushPayload(p.(*api.PushPayload), slack)
|
||||
case HOOK_EVENT_ISSUES:
|
||||
payload, err = getDiscordIssuesPayload(p.(*api.IssuesPayload), slack)
|
||||
case HOOK_EVENT_ISSUE_COMMENT:
|
||||
payload, err = getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
|
||||
case HOOK_EVENT_PULL_REQUEST:
|
||||
return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), slack)
|
||||
payload, err = getDiscordPullRequestPayload(p.(*api.PullRequestPayload), slack)
|
||||
case HOOK_EVENT_RELEASE:
|
||||
payload, err = getDiscordReleasePayload(p.(*api.ReleasePayload))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("event '%s': %v", event, err)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
payload.Username = slack.Username
|
||||
payload.AvatarURL = slack.IconURL
|
||||
if len(payload.Embeds) > 0 {
|
||||
color, _ := strconv.ParseInt(strings.TrimLeft(slack.Color, "#"), 16, 32)
|
||||
payload.Embeds[0].Color = int(color)
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
@@ -69,19 +69,34 @@ func SlackLinkFormatter(url string, text string) string {
|
||||
return fmt.Sprintf("<%s|%s>", url, SlackTextFormatter(text))
|
||||
}
|
||||
|
||||
func getSlackCreatePayload(p *api.CreatePayload, slack *SlackMeta) (*SlackPayload, error) {
|
||||
// Created tag/branch
|
||||
// getSlackCreatePayload composes Slack payload for create new branch or tag.
|
||||
func getSlackCreatePayload(p *api.CreatePayload) (*SlackPayload, error) {
|
||||
refName := git.RefEndName(p.Ref)
|
||||
|
||||
repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
|
||||
refLink := SlackLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName)
|
||||
text := fmt.Sprintf("[%s:%s] %s created by %s", repoLink, refLink, p.RefType, p.Sender.UserName)
|
||||
|
||||
return &SlackPayload{
|
||||
Channel: slack.Channel,
|
||||
Text: text,
|
||||
Username: slack.Username,
|
||||
IconURL: slack.IconURL,
|
||||
Text: text,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getSlackDeletePayload composes Slack payload for delete a branch or tag.
|
||||
func getSlackDeletePayload(p *api.DeletePayload) (*SlackPayload, error) {
|
||||
refName := git.RefEndName(p.Ref)
|
||||
repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
|
||||
text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName)
|
||||
return &SlackPayload{
|
||||
Text: text,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getSlackForkPayload composes Slack payload for forked by a repository.
|
||||
func getSlackForkPayload(p *api.ForkPayload) (*SlackPayload, error) {
|
||||
baseLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
|
||||
forkLink := SlackLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
|
||||
text := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
|
||||
return &SlackPayload{
|
||||
Text: text,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -130,6 +145,86 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, e
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getSlackIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) (*SlackPayload, error) {
|
||||
senderLink := SlackLinkFormatter(setting.AppUrl+p.Sender.UserName, p.Sender.UserName)
|
||||
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index),
|
||||
fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
|
||||
var text, title, attachmentText string
|
||||
switch p.Action {
|
||||
case api.HOOK_ISSUE_OPENED:
|
||||
text = fmt.Sprintf("[%s] New issue created by %s", p.Repository.FullName, senderLink)
|
||||
title = titleLink
|
||||
attachmentText = SlackTextFormatter(p.Issue.Body)
|
||||
case api.HOOK_ISSUE_CLOSED:
|
||||
text = fmt.Sprintf("[%s] Issue closed: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_REOPENED:
|
||||
text = fmt.Sprintf("[%s] Issue re-opened: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_EDITED:
|
||||
text = fmt.Sprintf("[%s] Issue edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
attachmentText = SlackTextFormatter(p.Issue.Body)
|
||||
case api.HOOK_ISSUE_ASSIGNED:
|
||||
text = fmt.Sprintf("[%s] Issue assigned to %s: %s by %s", p.Repository.FullName,
|
||||
SlackLinkFormatter(setting.AppUrl+p.Issue.Assignee.UserName, p.Issue.Assignee.UserName),
|
||||
titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_UNASSIGNED:
|
||||
text = fmt.Sprintf("[%s] Issue unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_LABEL_UPDATED:
|
||||
text = fmt.Sprintf("[%s] Issue labels updated: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_LABEL_CLEARED:
|
||||
text = fmt.Sprintf("[%s] Issue labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_MILESTONED:
|
||||
text = fmt.Sprintf("[%s] Issue milestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_DEMILESTONED:
|
||||
text = fmt.Sprintf("[%s] Issue demilestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
}
|
||||
|
||||
return &SlackPayload{
|
||||
Channel: slack.Channel,
|
||||
Text: text,
|
||||
Username: slack.Username,
|
||||
IconURL: slack.IconURL,
|
||||
Attachments: []*SlackAttachment{{
|
||||
Color: slack.Color,
|
||||
Title: title,
|
||||
Text: attachmentText,
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) {
|
||||
senderLink := SlackLinkFormatter(setting.AppUrl+p.Sender.UserName, p.Sender.UserName)
|
||||
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)),
|
||||
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
|
||||
var text, title, attachmentText string
|
||||
switch p.Action {
|
||||
case api.HOOK_ISSUE_COMMENT_CREATED:
|
||||
text = fmt.Sprintf("[%s] New comment created by %s", p.Repository.FullName, senderLink)
|
||||
title = titleLink
|
||||
attachmentText = SlackTextFormatter(p.Comment.Body)
|
||||
case api.HOOK_ISSUE_COMMENT_EDITED:
|
||||
text = fmt.Sprintf("[%s] Comment edited by %s", p.Repository.FullName, senderLink)
|
||||
title = titleLink
|
||||
attachmentText = SlackTextFormatter(p.Comment.Body)
|
||||
case api.HOOK_ISSUE_COMMENT_DELETED:
|
||||
text = fmt.Sprintf("[%s] Comment deleted by %s", p.Repository.FullName, senderLink)
|
||||
title = SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index),
|
||||
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
|
||||
attachmentText = SlackTextFormatter(p.Comment.Body)
|
||||
}
|
||||
|
||||
return &SlackPayload{
|
||||
Channel: slack.Channel,
|
||||
Text: text,
|
||||
Username: slack.Username,
|
||||
IconURL: slack.IconURL,
|
||||
Attachments: []*SlackAttachment{{
|
||||
Color: slack.Color,
|
||||
Title: title,
|
||||
Text: attachmentText,
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*SlackPayload, error) {
|
||||
senderLink := SlackLinkFormatter(setting.AppUrl+p.Sender.UserName, p.Sender.UserName)
|
||||
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
|
||||
@@ -163,6 +258,10 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S
|
||||
text = fmt.Sprintf("[%s] Pull request labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_SYNCHRONIZED:
|
||||
text = fmt.Sprintf("[%s] Pull request synchronized: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_MILESTONED:
|
||||
text = fmt.Sprintf("[%s] Pull request milestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
case api.HOOK_ISSUE_DEMILESTONED:
|
||||
text = fmt.Sprintf("[%s] Pull request demilestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||
}
|
||||
|
||||
return &SlackPayload{
|
||||
@@ -178,22 +277,49 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackPayload, error) {
|
||||
s := new(SlackPayload)
|
||||
func getSlackReleasePayload(p *api.ReleasePayload) (*SlackPayload, error) {
|
||||
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
|
||||
refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
|
||||
text := fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
|
||||
return &SlackPayload{
|
||||
Text: text,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (payload *SlackPayload, err error) {
|
||||
slack := &SlackMeta{}
|
||||
if err := json.Unmarshal([]byte(meta), &slack); err != nil {
|
||||
return s, fmt.Errorf("GetSlackPayload meta json: %v", err)
|
||||
return nil, fmt.Errorf("json.Unmarshal: %v", err)
|
||||
}
|
||||
|
||||
switch event {
|
||||
case HOOK_EVENT_CREATE:
|
||||
return getSlackCreatePayload(p.(*api.CreatePayload), slack)
|
||||
payload, err = getSlackCreatePayload(p.(*api.CreatePayload))
|
||||
case HOOK_EVENT_DELETE:
|
||||
payload, err = getSlackDeletePayload(p.(*api.DeletePayload))
|
||||
case HOOK_EVENT_FORK:
|
||||
payload, err = getSlackForkPayload(p.(*api.ForkPayload))
|
||||
case HOOK_EVENT_PUSH:
|
||||
return getSlackPushPayload(p.(*api.PushPayload), slack)
|
||||
payload, err = getSlackPushPayload(p.(*api.PushPayload), slack)
|
||||
case HOOK_EVENT_ISSUES:
|
||||
payload, err = getSlackIssuesPayload(p.(*api.IssuesPayload), slack)
|
||||
case HOOK_EVENT_ISSUE_COMMENT:
|
||||
payload, err = getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
|
||||
case HOOK_EVENT_PULL_REQUEST:
|
||||
return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
|
||||
payload, err = getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
|
||||
case HOOK_EVENT_RELEASE:
|
||||
payload, err = getSlackReleasePayload(p.(*api.ReleasePayload))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("event '%s': %v", event, err)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
payload.Channel = slack.Channel
|
||||
payload.Username = slack.Username
|
||||
payload.IconURL = slack.IconURL
|
||||
if len(payload.Attachments) > 0 {
|
||||
payload.Attachments[0].Color = slack.Color
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-macaron/binding"
|
||||
"github.com/go-macaron/session"
|
||||
gouuid "github.com/satori/go.uuid"
|
||||
log "gopkg.in/clog.v1"
|
||||
@@ -147,130 +144,3 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
|
||||
}
|
||||
return u, false
|
||||
}
|
||||
|
||||
type Form interface {
|
||||
binding.Validator
|
||||
}
|
||||
|
||||
func init() {
|
||||
binding.SetNameMapper(com.ToSnakeCase)
|
||||
}
|
||||
|
||||
// AssignForm assign form values back to the template data.
|
||||
func AssignForm(form interface{}, data map[string]interface{}) {
|
||||
typ := reflect.TypeOf(form)
|
||||
val := reflect.ValueOf(form)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
|
||||
fieldName := field.Tag.Get("form")
|
||||
// Allow ignored fields in the struct
|
||||
if fieldName == "-" {
|
||||
continue
|
||||
} else if len(fieldName) == 0 {
|
||||
fieldName = com.ToSnakeCase(field.Name)
|
||||
}
|
||||
|
||||
data[fieldName] = val.Field(i).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
func getRuleBody(field reflect.StructField, prefix string) string {
|
||||
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
|
||||
if strings.HasPrefix(rule, prefix) {
|
||||
return rule[len(prefix) : len(rule)-1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetSize(field reflect.StructField) string {
|
||||
return getRuleBody(field, "Size(")
|
||||
}
|
||||
|
||||
func GetMinSize(field reflect.StructField) string {
|
||||
return getRuleBody(field, "MinSize(")
|
||||
}
|
||||
|
||||
func GetMaxSize(field reflect.StructField) string {
|
||||
return getRuleBody(field, "MaxSize(")
|
||||
}
|
||||
|
||||
func GetInclude(field reflect.StructField) string {
|
||||
return getRuleBody(field, "Include(")
|
||||
}
|
||||
|
||||
// FIXME: struct contains a struct
|
||||
func validateStruct(obj interface{}) binding.Errors {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors {
|
||||
if errs.Len() == 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
data["HasError"] = true
|
||||
AssignForm(f, data)
|
||||
|
||||
typ := reflect.TypeOf(f)
|
||||
val := reflect.ValueOf(f)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
|
||||
fieldName := field.Tag.Get("form")
|
||||
// Allow ignored fields in the struct
|
||||
if fieldName == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
if errs[0].FieldNames[0] == field.Name {
|
||||
data["Err_"+field.Name] = true
|
||||
|
||||
trName := field.Tag.Get("locale")
|
||||
if len(trName) == 0 {
|
||||
trName = l.Tr("form." + field.Name)
|
||||
} else {
|
||||
trName = l.Tr(trName)
|
||||
}
|
||||
|
||||
switch errs[0].Classification {
|
||||
case binding.ERR_REQUIRED:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.require_error")
|
||||
case binding.ERR_ALPHA_DASH:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
|
||||
case binding.ERR_ALPHA_DASH_DOT:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
|
||||
case binding.ERR_SIZE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.size_error", GetSize(field))
|
||||
case binding.ERR_MIN_SIZE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))
|
||||
case binding.ERR_MAX_SIZE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.max_size_error", GetMaxSize(field))
|
||||
case binding.ERR_EMAIL:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.email_error")
|
||||
case binding.ERR_URL:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.url_error")
|
||||
case binding.ERR_INCLUDE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.include_error", GetInclude(field))
|
||||
default:
|
||||
data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification
|
||||
}
|
||||
return errs
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
"github.com/go-macaron/binding"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
// ________ .__ __ .__
|
||||
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
|
||||
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
|
||||
// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
|
||||
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
|
||||
// \/ /_____/ \/ \/ \/ \/ \/
|
||||
|
||||
type CreateOrgForm struct {
|
||||
OrgName string `binding:"Required;AlphaDashDot;MaxSize(35)" locale:"org.org_name_holder"`
|
||||
}
|
||||
|
||||
func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type UpdateOrgSettingForm struct {
|
||||
Name string `binding:"Required;AlphaDashDot;MaxSize(35)" locale:"org.org_name_holder"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
MaxRepoCreation int
|
||||
}
|
||||
|
||||
func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ___________
|
||||
// \__ ___/___ _____ _____
|
||||
// | |_/ __ \\__ \ / \
|
||||
// | |\ ___/ / __ \| Y Y \
|
||||
// |____| \___ >____ /__|_| /
|
||||
// \/ \/ \/
|
||||
|
||||
type CreateTeamForm struct {
|
||||
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Permission string
|
||||
}
|
||||
|
||||
func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -372,7 +372,7 @@ func logn(n, b float64) float64 {
|
||||
|
||||
func humanateBytes(s uint64, base float64, sizes []string) string {
|
||||
if s < 10 {
|
||||
return fmt.Sprintf("%dB", s)
|
||||
return fmt.Sprintf("%d B", s)
|
||||
}
|
||||
e := math.Floor(logn(float64(s), base))
|
||||
suffix := sizes[int(e)]
|
||||
@@ -382,7 +382,7 @@ func humanateBytes(s uint64, base float64, sizes []string) string {
|
||||
f = "%.1f"
|
||||
}
|
||||
|
||||
return fmt.Sprintf(f+"%s", val, suffix)
|
||||
return fmt.Sprintf(f+" %s", val, suffix)
|
||||
}
|
||||
|
||||
// FileSize calculates the file size and generate user-friendly string.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -32,7 +32,7 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) {
|
||||
}
|
||||
|
||||
if status == 500 {
|
||||
log.Error(4, "%s: %s", title, message)
|
||||
log.Error(3, "%s: %s", title, message)
|
||||
}
|
||||
|
||||
ctx.JSON(status, map[string]string{
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/form"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
@@ -78,9 +79,9 @@ func (ctx *Context) HTML(status int, name base.TplName) {
|
||||
}
|
||||
|
||||
// RenderWithErr used for page has form validation but need to prompt error to users.
|
||||
func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form interface{}) {
|
||||
if form != nil {
|
||||
auth.AssignForm(form, ctx.Data)
|
||||
func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, f interface{}) {
|
||||
if f != nil {
|
||||
form.Assign(f, ctx.Data)
|
||||
}
|
||||
ctx.Flash.ErrorMsg = msg
|
||||
ctx.Data["Flash"] = ctx.Flash
|
||||
@@ -158,6 +159,9 @@ func Contexter() macaron.Handler {
|
||||
|
||||
if len(setting.HTTP.AccessControlAllowOrigin) > 0 {
|
||||
ctx.Header().Set("Access-Control-Allow-Origin", setting.HTTP.AccessControlAllowOrigin)
|
||||
ctx.Header().Set("'Access-Control-Allow-Credentials' ", "true")
|
||||
ctx.Header().Set("Access-Control-Max-Age", "3600")
|
||||
ctx.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
|
||||
}
|
||||
|
||||
// Compute current URL for real-time change language.
|
||||
|
||||
@@ -456,13 +456,6 @@ func RepoRef() macaron.Handler {
|
||||
}
|
||||
}
|
||||
ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest
|
||||
|
||||
ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "CommitsCount", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package auth
|
||||
package form
|
||||
|
||||
import (
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/go-macaron/binding"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
type AdminCrateUserForm struct {
|
||||
type AdminCrateUser struct {
|
||||
LoginType string `binding:"Required"`
|
||||
LoginName string
|
||||
UserName string `binding:"Required;AlphaDashDot;MaxSize(35)"`
|
||||
@@ -19,11 +18,11 @@ type AdminCrateUserForm struct {
|
||||
SendNotify bool
|
||||
}
|
||||
|
||||
func (f *AdminCrateUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *AdminCrateUser) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type AdminEditUserForm struct {
|
||||
type AdminEditUser struct {
|
||||
LoginType string `binding:"Required"`
|
||||
LoginName string
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
@@ -39,6 +38,6 @@ type AdminEditUserForm struct {
|
||||
ProhibitLogin bool
|
||||
}
|
||||
|
||||
func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *AdminEditUser) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -2,14 +2,14 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package auth
|
||||
package form
|
||||
|
||||
import (
|
||||
"github.com/go-macaron/binding"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
type AuthenticationForm struct {
|
||||
type Authentication struct {
|
||||
ID int64
|
||||
Type int `binding:"Range(2,5)"`
|
||||
Name string `binding:"Required;MaxSize(30)"`
|
||||
@@ -37,6 +37,6 @@ type AuthenticationForm struct {
|
||||
PAMServiceName string
|
||||
}
|
||||
|
||||
func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *Authentication) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
155
modules/form/form.go
Normal file
155
modules/form/form.go
Normal file
@@ -0,0 +1,155 @@
|
||||
// Copyright 2017 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 form
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-macaron/binding"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
const ERR_ALPHA_DASH_DOT_SLASH = "AlphaDashDotSlashError"
|
||||
|
||||
var AlphaDashDotSlashPattern = regexp.MustCompile("[^\\d\\w-_\\./]")
|
||||
|
||||
func init() {
|
||||
binding.SetNameMapper(com.ToSnakeCase)
|
||||
binding.AddRule(&binding.Rule{
|
||||
IsMatch: func(rule string) bool {
|
||||
return rule == "AlphaDashDotSlash"
|
||||
},
|
||||
IsValid: func(errs binding.Errors, name string, v interface{}) (bool, binding.Errors) {
|
||||
if AlphaDashDotSlashPattern.MatchString(fmt.Sprintf("%v", v)) {
|
||||
errs.Add([]string{name}, ERR_ALPHA_DASH_DOT_SLASH, "AlphaDashDotSlash")
|
||||
return false, errs
|
||||
}
|
||||
return true, errs
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type Form interface {
|
||||
binding.Validator
|
||||
}
|
||||
|
||||
// Assign assign form values back to the template data.
|
||||
func Assign(form interface{}, data map[string]interface{}) {
|
||||
typ := reflect.TypeOf(form)
|
||||
val := reflect.ValueOf(form)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
|
||||
fieldName := field.Tag.Get("form")
|
||||
// Allow ignored fields in the struct
|
||||
if fieldName == "-" {
|
||||
continue
|
||||
} else if len(fieldName) == 0 {
|
||||
fieldName = com.ToSnakeCase(field.Name)
|
||||
}
|
||||
|
||||
data[fieldName] = val.Field(i).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
func getRuleBody(field reflect.StructField, prefix string) string {
|
||||
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
|
||||
if strings.HasPrefix(rule, prefix) {
|
||||
return rule[len(prefix) : len(rule)-1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getSize(field reflect.StructField) string {
|
||||
return getRuleBody(field, "Size(")
|
||||
}
|
||||
|
||||
func getMinSize(field reflect.StructField) string {
|
||||
return getRuleBody(field, "MinSize(")
|
||||
}
|
||||
|
||||
func getMaxSize(field reflect.StructField) string {
|
||||
return getRuleBody(field, "MaxSize(")
|
||||
}
|
||||
|
||||
func getInclude(field reflect.StructField) string {
|
||||
return getRuleBody(field, "Include(")
|
||||
}
|
||||
|
||||
func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors {
|
||||
if errs.Len() == 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
data["HasError"] = true
|
||||
Assign(f, data)
|
||||
|
||||
typ := reflect.TypeOf(f)
|
||||
val := reflect.ValueOf(f)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
|
||||
fieldName := field.Tag.Get("form")
|
||||
// Allow ignored fields in the struct
|
||||
if fieldName == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
if errs[0].FieldNames[0] == field.Name {
|
||||
data["Err_"+field.Name] = true
|
||||
|
||||
trName := field.Tag.Get("locale")
|
||||
if len(trName) == 0 {
|
||||
trName = l.Tr("form." + field.Name)
|
||||
} else {
|
||||
trName = l.Tr(trName)
|
||||
}
|
||||
|
||||
switch errs[0].Classification {
|
||||
case binding.ERR_REQUIRED:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.require_error")
|
||||
case binding.ERR_ALPHA_DASH:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
|
||||
case binding.ERR_ALPHA_DASH_DOT:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
|
||||
case ERR_ALPHA_DASH_DOT_SLASH:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_slash_error")
|
||||
case binding.ERR_SIZE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.size_error", getSize(field))
|
||||
case binding.ERR_MIN_SIZE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", getMinSize(field))
|
||||
case binding.ERR_MAX_SIZE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.max_size_error", getMaxSize(field))
|
||||
case binding.ERR_EMAIL:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.email_error")
|
||||
case binding.ERR_URL:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.url_error")
|
||||
case binding.ERR_INCLUDE:
|
||||
data["ErrorMsg"] = trName + l.Tr("form.include_error", getInclude(field))
|
||||
default:
|
||||
data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification
|
||||
}
|
||||
return errs
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
41
modules/form/org.go
Normal file
41
modules/form/org.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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 form
|
||||
|
||||
import (
|
||||
"github.com/go-macaron/binding"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
type CreateOrg struct {
|
||||
OrgName string `binding:"Required;AlphaDashDot;MaxSize(35)" locale:"org.org_name_holder"`
|
||||
}
|
||||
|
||||
func (f *CreateOrg) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type UpdateOrgSetting struct {
|
||||
Name string `binding:"Required;AlphaDashDot;MaxSize(35)" locale:"org.org_name_holder"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
MaxRepoCreation int
|
||||
}
|
||||
|
||||
func (f *UpdateOrgSetting) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type CreateTeam struct {
|
||||
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Permission string
|
||||
}
|
||||
|
||||
func (f *CreateTeam) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package auth
|
||||
package form
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
@@ -22,8 +22,8 @@ import (
|
||||
// |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______|
|
||||
// \/ \/ \/ \/ \/ \/ \/
|
||||
|
||||
type CreateRepoForm struct {
|
||||
Uid int64 `binding:"Required"`
|
||||
type CreateRepo struct {
|
||||
UserID int64 `binding:"Required"`
|
||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
Private bool
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
@@ -33,11 +33,11 @@ type CreateRepoForm struct {
|
||||
Readme string
|
||||
}
|
||||
|
||||
func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *CreateRepo) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type MigrateRepoForm struct {
|
||||
type MigrateRepo struct {
|
||||
CloneAddr string `json:"clone_addr" binding:"Required"`
|
||||
AuthUsername string `json:"auth_username"`
|
||||
AuthPassword string `json:"auth_password"`
|
||||
@@ -48,7 +48,7 @@ type MigrateRepoForm struct {
|
||||
Description string `json:"description" binding:"MaxSize(255)"`
|
||||
}
|
||||
|
||||
func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *MigrateRepo) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
|
||||
// and returns composed URL with needed username and password.
|
||||
// It also checks if given user has permission when remote address
|
||||
// is actually a local path.
|
||||
func (f MigrateRepoForm) ParseRemoteAddr(user *models.User) (string, error) {
|
||||
func (f MigrateRepo) ParseRemoteAddr(user *models.User) (string, error) {
|
||||
remoteAddr := strings.TrimSpace(f.CloneAddr)
|
||||
|
||||
// Remote address can be HTTP/HTTPS/Git URL or local path.
|
||||
@@ -80,7 +80,7 @@ func (f MigrateRepoForm) ParseRemoteAddr(user *models.User) (string, error) {
|
||||
return remoteAddr, nil
|
||||
}
|
||||
|
||||
type RepoSettingForm struct {
|
||||
type RepoSetting struct {
|
||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
@@ -102,7 +102,7 @@ type RepoSettingForm struct {
|
||||
EnablePulls bool
|
||||
}
|
||||
|
||||
func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *RepoSetting) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
|
||||
// |______ / |__| (____ /___| /\___ >___| /
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
type ProtectBranchForm struct {
|
||||
type ProtectBranch struct {
|
||||
Protected bool
|
||||
RequirePullRequest bool
|
||||
EnableWhitelist bool
|
||||
@@ -121,7 +121,7 @@ type ProtectBranchForm struct {
|
||||
WhitelistTeams string
|
||||
}
|
||||
|
||||
func (f *ProtectBranchForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *ProtectBranch) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -132,59 +132,64 @@ func (f *ProtectBranchForm) Validate(ctx *macaron.Context, errs binding.Errors)
|
||||
// \__/\ / \___ >___ /___| /___| /\____/|__|_ \
|
||||
// \/ \/ \/ \/ \/ \/
|
||||
|
||||
type WebhookForm struct {
|
||||
Events string
|
||||
Create bool
|
||||
Push bool
|
||||
PullRequest bool
|
||||
Active bool
|
||||
type Webhook struct {
|
||||
Events string
|
||||
Create bool
|
||||
Delete bool
|
||||
Fork bool
|
||||
Push bool
|
||||
Issues bool
|
||||
IssueComment bool
|
||||
PullRequest bool
|
||||
Release bool
|
||||
Active bool
|
||||
}
|
||||
|
||||
func (f WebhookForm) PushOnly() bool {
|
||||
func (f Webhook) PushOnly() bool {
|
||||
return f.Events == "push_only"
|
||||
}
|
||||
|
||||
func (f WebhookForm) SendEverything() bool {
|
||||
func (f Webhook) SendEverything() bool {
|
||||
return f.Events == "send_everything"
|
||||
}
|
||||
|
||||
func (f WebhookForm) ChooseEvents() bool {
|
||||
func (f Webhook) ChooseEvents() bool {
|
||||
return f.Events == "choose_events"
|
||||
}
|
||||
|
||||
type NewWebhookForm struct {
|
||||
type NewWebhook struct {
|
||||
PayloadURL string `binding:"Required;Url"`
|
||||
ContentType int `binding:"Required"`
|
||||
Secret string
|
||||
WebhookForm
|
||||
Webhook
|
||||
}
|
||||
|
||||
func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewWebhook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type NewSlackHookForm struct {
|
||||
type NewSlackHook struct {
|
||||
PayloadURL string `binding:"Required;Url"`
|
||||
Channel string `binding:"Required"`
|
||||
Username string
|
||||
IconURL string
|
||||
Color string
|
||||
WebhookForm
|
||||
Webhook
|
||||
}
|
||||
|
||||
func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewSlackHook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type NewDiscordHookForm struct {
|
||||
type NewDiscordHook struct {
|
||||
PayloadURL string `binding:"Required;Url"`
|
||||
Username string
|
||||
IconURL string
|
||||
Color string
|
||||
WebhookForm
|
||||
Webhook
|
||||
}
|
||||
|
||||
func (f *NewDiscordHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewDiscordHook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -195,7 +200,7 @@ func (f *NewDiscordHookForm) Validate(ctx *macaron.Context, errs binding.Errors)
|
||||
// |___/____ >____ >____/ \___ >
|
||||
// \/ \/ \/
|
||||
|
||||
type CreateIssueForm struct {
|
||||
type NewIssue struct {
|
||||
Title string `binding:"Required;MaxSize(255)"`
|
||||
LabelIDs string `form:"label_ids"`
|
||||
MilestoneID int64
|
||||
@@ -204,17 +209,17 @@ type CreateIssueForm struct {
|
||||
Files []string
|
||||
}
|
||||
|
||||
func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewIssue) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type CreateCommentForm struct {
|
||||
type CreateComment struct {
|
||||
Content string
|
||||
Status string `binding:"OmitEmpty;In(reopen,close)"`
|
||||
Files []string
|
||||
}
|
||||
|
||||
func (f *CreateCommentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *CreateComment) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -225,13 +230,13 @@ func (f *CreateCommentForm) Validate(ctx *macaron.Context, errs binding.Errors)
|
||||
// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
type CreateMilestoneForm struct {
|
||||
type CreateMilestone struct {
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string
|
||||
Deadline string
|
||||
}
|
||||
|
||||
func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *CreateMilestone) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -242,21 +247,21 @@ func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors
|
||||
// |_______ (____ /___ /\___ >____/
|
||||
// \/ \/ \/ \/
|
||||
|
||||
type CreateLabelForm struct {
|
||||
type CreateLabel struct {
|
||||
ID int64
|
||||
Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_name"`
|
||||
Color string `binding:"Required;Size(7)" locale:"repo.issues.label_color"`
|
||||
}
|
||||
|
||||
func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *CreateLabel) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type InitializeLabelsForm struct {
|
||||
type InitializeLabels struct {
|
||||
TemplateName string `binding:"Required"`
|
||||
}
|
||||
|
||||
func (f *InitializeLabelsForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *InitializeLabels) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -267,27 +272,29 @@ func (f *InitializeLabelsForm) Validate(ctx *macaron.Context, errs binding.Error
|
||||
// |____|_ /\___ >____/\___ >____ /____ >\___ >
|
||||
// \/ \/ \/ \/ \/ \/
|
||||
|
||||
type NewReleaseForm struct {
|
||||
type NewRelease struct {
|
||||
TagName string `binding:"Required"`
|
||||
Target string `form:"tag_target" binding:"Required"`
|
||||
Title string `binding:"Required"`
|
||||
Content string
|
||||
Draft string
|
||||
Prerelease bool
|
||||
Files []string
|
||||
}
|
||||
|
||||
func (f *NewReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewRelease) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type EditReleaseForm struct {
|
||||
Title string `form:"title" binding:"Required"`
|
||||
Content string `form:"content"`
|
||||
Draft string `form:"draft"`
|
||||
Prerelease bool `form:"prerelease"`
|
||||
type EditRelease struct {
|
||||
Title string `binding:"Required"`
|
||||
Content string
|
||||
Draft string
|
||||
Prerelease bool
|
||||
Files []string
|
||||
}
|
||||
|
||||
func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *EditRelease) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -298,7 +305,7 @@ func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
|
||||
// \__/\ / |__|__|_ \__|
|
||||
// \/ \/
|
||||
|
||||
type NewWikiForm struct {
|
||||
type NewWiki struct {
|
||||
OldTitle string
|
||||
Title string `binding:"Required"`
|
||||
Content string `binding:"Required"`
|
||||
@@ -306,7 +313,7 @@ type NewWikiForm struct {
|
||||
}
|
||||
|
||||
// FIXME: use code generation to generate this method.
|
||||
func (f *NewWikiForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewWiki) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -317,29 +324,29 @@ func (f *NewWikiForm) Validate(ctx *macaron.Context, errs binding.Errors) bindin
|
||||
// /_______ /\____ | |__||__|
|
||||
// \/ \/
|
||||
|
||||
type EditRepoFileForm struct {
|
||||
type EditRepoFile struct {
|
||||
TreePath string `binding:"Required;MaxSize(500)"`
|
||||
Content string `binding:"Required"`
|
||||
CommitSummary string `binding:"MaxSize(100)`
|
||||
CommitMessage string
|
||||
CommitChoice string `binding:"Required;MaxSize(50)"`
|
||||
NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`
|
||||
NewBranchName string `binding:"AlphaDashDotSlash;MaxSize(100)"`
|
||||
LastCommit string
|
||||
}
|
||||
|
||||
func (f *EditRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *EditRepoFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
func (f *EditRepoFileForm) IsNewBrnach() bool {
|
||||
func (f *EditRepoFile) IsNewBrnach() bool {
|
||||
return f.CommitChoice == "commit-to-new-branch"
|
||||
}
|
||||
|
||||
type EditPreviewDiffForm struct {
|
||||
type EditPreviewDiff struct {
|
||||
Content string
|
||||
}
|
||||
|
||||
func (f *EditPreviewDiffForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *EditPreviewDiff) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -351,7 +358,7 @@ func (f *EditPreviewDiffForm) Validate(ctx *macaron.Context, errs binding.Errors
|
||||
// |__| \/ \/
|
||||
//
|
||||
|
||||
type UploadRepoFileForm struct {
|
||||
type UploadRepoFile struct {
|
||||
TreePath string `binding:MaxSize(500)"`
|
||||
CommitSummary string `binding:"MaxSize(100)`
|
||||
CommitMessage string
|
||||
@@ -360,19 +367,19 @@ type UploadRepoFileForm struct {
|
||||
Files []string
|
||||
}
|
||||
|
||||
func (f *UploadRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *UploadRepoFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
func (f *UploadRepoFileForm) IsNewBrnach() bool {
|
||||
func (f *UploadRepoFile) IsNewBrnach() bool {
|
||||
return f.CommitChoice == "commit-to-new-branch"
|
||||
}
|
||||
|
||||
type RemoveUploadFileForm struct {
|
||||
type RemoveUploadFile struct {
|
||||
File string `binding:"Required;MaxSize(50)"`
|
||||
}
|
||||
|
||||
func (f *RemoveUploadFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *RemoveUploadFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -383,17 +390,17 @@ func (f *RemoveUploadFileForm) Validate(ctx *macaron.Context, errs binding.Error
|
||||
// /_______ /\___ >____/\___ >__| \___ >
|
||||
// \/ \/ \/ \/
|
||||
|
||||
type DeleteRepoFileForm struct {
|
||||
type DeleteRepoFile struct {
|
||||
CommitSummary string `binding:"MaxSize(100)`
|
||||
CommitMessage string
|
||||
CommitChoice string `binding:"Required;MaxSize(50)"`
|
||||
NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`
|
||||
}
|
||||
|
||||
func (f *DeleteRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *DeleteRepoFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
func (f *DeleteRepoFileForm) IsNewBrnach() bool {
|
||||
func (f *DeleteRepoFile) IsNewBrnach() bool {
|
||||
return f.CommitChoice == "commit-to-new-branch"
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package auth
|
||||
package form
|
||||
|
||||
import (
|
||||
"mime/multipart"
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
type InstallForm struct {
|
||||
type Install struct {
|
||||
DbType string `binding:"Required"`
|
||||
DbHost string
|
||||
DbUser string
|
||||
@@ -50,7 +50,7 @@ type InstallForm struct {
|
||||
AdminEmail string `binding:"OmitEmpty;MinSize(3);MaxSize(254);Include(@)" locale:"install.admin_email"`
|
||||
}
|
||||
|
||||
func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *Install) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -61,24 +61,24 @@ func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) bindin
|
||||
// \____|__ /______/ |____| \___|_ /
|
||||
// \/ \/
|
||||
|
||||
type RegisterForm struct {
|
||||
type Register struct {
|
||||
UserName string `binding:"Required;AlphaDashDot;MaxSize(35)"`
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
Password string `binding:"Required;MaxSize(255)"`
|
||||
Retype string
|
||||
}
|
||||
|
||||
func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *Register) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type SignInForm struct {
|
||||
type SignIn struct {
|
||||
UserName string `binding:"Required;MaxSize(254)"`
|
||||
Password string `binding:"Required;MaxSize(255)"`
|
||||
Remember bool
|
||||
}
|
||||
|
||||
func (f *SignInForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *SignIn) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -89,15 +89,15 @@ func (f *SignInForm) Validate(ctx *macaron.Context, errs binding.Errors) binding
|
||||
// /_______ //_______ / |____| |____| |___\____|__ /\______ /_______ /
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
type UpdateProfileForm struct {
|
||||
Name string `binding:"OmitEmpty;MaxSize(35)"`
|
||||
type UpdateProfile struct {
|
||||
Name string `binding:"Required;AlphaDashDot;MaxSize(35)"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
}
|
||||
|
||||
func (f *UpdateProfileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *UpdateProfile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
@@ -106,48 +106,48 @@ const (
|
||||
AVATAR_BYMAIL string = "bymail"
|
||||
)
|
||||
|
||||
type AvatarForm struct {
|
||||
type Avatar struct {
|
||||
Source string
|
||||
Avatar *multipart.FileHeader
|
||||
Gravatar string `binding:"OmitEmpty;Email;MaxSize(254)"`
|
||||
Federavatar bool
|
||||
}
|
||||
|
||||
func (f *AvatarForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *Avatar) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type AddEmailForm struct {
|
||||
type AddEmail struct {
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
}
|
||||
|
||||
func (f *AddEmailForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *AddEmail) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type ChangePasswordForm struct {
|
||||
OldPassword string `form:"old_password" binding:"Required;MinSize(1);MaxSize(255)"`
|
||||
Password string `form:"password" binding:"Required;MaxSize(255)"`
|
||||
Retype string `form:"retype"`
|
||||
type ChangePassword struct {
|
||||
OldPassword string `binding:"Required;MinSize(1);MaxSize(255)"`
|
||||
Password string `binding:"Required;MaxSize(255)"`
|
||||
Retype string
|
||||
}
|
||||
|
||||
func (f *ChangePasswordForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *ChangePassword) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type AddSSHKeyForm struct {
|
||||
type AddSSHKey struct {
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string `binding:"Required"`
|
||||
}
|
||||
|
||||
func (f *AddSSHKeyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *AddSSHKey) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type NewAccessTokenForm struct {
|
||||
type NewAccessToken struct {
|
||||
Name string `binding:"Required"`
|
||||
}
|
||||
|
||||
func (f *NewAccessTokenForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
func (f *NewAccessToken) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
return validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func (r *Request) Debug(isdebug bool) *Request {
|
||||
return r
|
||||
}
|
||||
|
||||
// SetTimeout sets connect time out and read-write time out for BeegoRequest.
|
||||
// SetTimeout sets connect time out and read-write time out for Request.
|
||||
func (r *Request) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *Request {
|
||||
r.setting.ConnectTimeout = connectTimeout
|
||||
r.setting.ReadWriteTimeout = readWriteTimeout
|
||||
|
||||
@@ -36,16 +36,18 @@ func NewMessageFrom(to []string, from, subject, htmlBody string) *Message {
|
||||
msg.SetHeader("Subject", subject)
|
||||
msg.SetDateHeader("Date", time.Now())
|
||||
|
||||
body, err := html2text.FromString(htmlBody)
|
||||
if err != nil {
|
||||
log.Error(4, "html2text.FromString: %v", err)
|
||||
msg.SetBody("text/html", htmlBody)
|
||||
} else {
|
||||
msg.SetBody("text/plain", body)
|
||||
if setting.MailService.EnableHTMLAlternative {
|
||||
msg.AddAlternative("text/html", htmlBody)
|
||||
contentType := "text/html"
|
||||
body := htmlBody
|
||||
if setting.MailService.UsePlainText {
|
||||
plainBody, err := html2text.FromString(htmlBody)
|
||||
if err != nil {
|
||||
log.Error(2, "html2text.FromString: %v", err)
|
||||
} else {
|
||||
contentType = "text/plain"
|
||||
body = plainBody
|
||||
}
|
||||
}
|
||||
msg.SetBody(contentType, body)
|
||||
|
||||
return &Message{
|
||||
Message: msg,
|
||||
|
||||
@@ -192,42 +192,11 @@ func (options *Renderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
|
||||
// Note: this section is for purpose of increase performance and
|
||||
// reduce memory allocation at runtime since they are constant literals.
|
||||
var (
|
||||
svgSuffix = []byte(".svg")
|
||||
svgSuffixWithMark = []byte(".svg?")
|
||||
spaceBytes = []byte(" ")
|
||||
spaceEncodedBytes = []byte("%20")
|
||||
pound = []byte("#")
|
||||
space = " "
|
||||
spaceEncoded = "%20"
|
||||
pound = []byte("#")
|
||||
space = " "
|
||||
spaceEncoded = "%20"
|
||||
)
|
||||
|
||||
// Image defines how images should be processed to produce corresponding HTML elements.
|
||||
func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
||||
prefix := strings.Replace(r.urlPrefix, "/src/", "/raw/", 1)
|
||||
if len(link) > 0 {
|
||||
if isLink(link) {
|
||||
// External link with .svg suffix usually means CI status.
|
||||
// TODO: define a keyword to allow non-svg images render as external link.
|
||||
if bytes.HasSuffix(link, svgSuffix) || bytes.Contains(link, svgSuffixWithMark) {
|
||||
r.Renderer.Image(out, link, title, alt)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if link[0] != '/' {
|
||||
prefix += "/"
|
||||
}
|
||||
link = bytes.Replace([]byte((prefix + string(link))), spaceBytes, spaceEncodedBytes, -1)
|
||||
fmt.Println(333, string(link))
|
||||
}
|
||||
}
|
||||
|
||||
out.WriteString(`<a href="`)
|
||||
out.Write(link)
|
||||
out.WriteString(`">`)
|
||||
r.Renderer.Image(out, link, title, alt)
|
||||
out.WriteString("</a>")
|
||||
}
|
||||
|
||||
// cutoutVerbosePrefix cutouts URL prefix including sub-path to
|
||||
// return a clean unified string of request URL path.
|
||||
func cutoutVerbosePrefix(prefix string) string {
|
||||
@@ -325,6 +294,23 @@ func RenderRaw(body []byte, urlPrefix string) []byte {
|
||||
htmlFlags := 0
|
||||
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||
|
||||
if setting.Smartypants.Enabled {
|
||||
htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
|
||||
if setting.Smartypants.Fractions {
|
||||
htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
|
||||
}
|
||||
if setting.Smartypants.Dashes {
|
||||
htmlFlags |= blackfriday.HTML_SMARTYPANTS_DASHES
|
||||
}
|
||||
if setting.Smartypants.LatexDashes {
|
||||
htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
|
||||
}
|
||||
if setting.Smartypants.AngledQuotes {
|
||||
htmlFlags |= blackfriday.HTML_SMARTYPANTS_ANGLED_QUOTES
|
||||
}
|
||||
}
|
||||
|
||||
renderer := &Renderer{
|
||||
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
|
||||
urlPrefix: urlPrefix,
|
||||
@@ -353,14 +339,72 @@ var (
|
||||
rightAngleBracket = []byte(">")
|
||||
)
|
||||
|
||||
var noEndTags = []string{"img", "input", "br", "hr"}
|
||||
var noEndTags = []string{"input", "br", "hr", "img"}
|
||||
|
||||
// wrapImgWithLink warps link to standalone <img> tags.
|
||||
func wrapImgWithLink(urlPrefix string, buf *bytes.Buffer, token html.Token) {
|
||||
var src, alt string
|
||||
// Extract "src" and "alt" attributes
|
||||
for i := range token.Attr {
|
||||
switch token.Attr[i].Key {
|
||||
case "src":
|
||||
src = token.Attr[i].Val
|
||||
case "alt":
|
||||
alt = token.Attr[i].Val
|
||||
}
|
||||
}
|
||||
|
||||
// Skip in case the "src" is empty
|
||||
if len(src) == 0 {
|
||||
buf.WriteString(token.String())
|
||||
return
|
||||
}
|
||||
|
||||
// Prepend repository base URL for internal links
|
||||
needPrepend := !isLink([]byte(src))
|
||||
if needPrepend {
|
||||
urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1)
|
||||
if src[0] != '/' {
|
||||
urlPrefix += "/"
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString(`<a href="`)
|
||||
if needPrepend {
|
||||
buf.WriteString(urlPrefix)
|
||||
buf.WriteString(src)
|
||||
} else {
|
||||
buf.WriteString(src)
|
||||
}
|
||||
buf.WriteString(`">`)
|
||||
|
||||
if needPrepend {
|
||||
src = strings.Replace(urlPrefix+string(src), " ", "%20", -1)
|
||||
buf.WriteString(`<img src="`)
|
||||
buf.WriteString(src)
|
||||
buf.WriteString(`"`)
|
||||
|
||||
if len(alt) > 0 {
|
||||
buf.WriteString(` alt="`)
|
||||
buf.WriteString(alt)
|
||||
buf.WriteString(`"`)
|
||||
}
|
||||
|
||||
buf.WriteString(`>`)
|
||||
|
||||
} else {
|
||||
buf.WriteString(token.String())
|
||||
}
|
||||
|
||||
buf.WriteString(`</a>`)
|
||||
}
|
||||
|
||||
// PostProcess treats different types of HTML differently,
|
||||
// and only renders special links for plain text blocks.
|
||||
func PostProcess(rawHtml []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
func PostProcess(rawHTML []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
startTags := make([]string, 0, 5)
|
||||
var buf bytes.Buffer
|
||||
tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
|
||||
buf := bytes.NewBuffer(nil)
|
||||
tokenizer := html.NewTokenizer(bytes.NewReader(rawHTML))
|
||||
|
||||
OUTER_LOOP:
|
||||
for html.ErrorToken != tokenizer.Next() {
|
||||
@@ -370,8 +414,14 @@ OUTER_LOOP:
|
||||
buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix, metas))
|
||||
|
||||
case html.StartTagToken:
|
||||
buf.WriteString(token.String())
|
||||
tagName := token.Data
|
||||
|
||||
if tagName == "img" {
|
||||
wrapImgWithLink(urlPrefix, buf, token)
|
||||
continue OUTER_LOOP
|
||||
}
|
||||
|
||||
buf.WriteString(token.String())
|
||||
// If this is an excluded tag, we skip processing all output until a close tag is encountered.
|
||||
if strings.EqualFold("a", tagName) || strings.EqualFold("code", tagName) || strings.EqualFold("pre", tagName) {
|
||||
stackNum := 1
|
||||
@@ -381,14 +431,14 @@ OUTER_LOOP:
|
||||
// Copy the token to the output verbatim
|
||||
buf.WriteString(token.String())
|
||||
|
||||
if token.Type == html.StartTagToken {
|
||||
// Stack number doesn't increate for tags without end tags.
|
||||
if token.Type == html.StartTagToken && !com.IsSliceContainsStr(noEndTags, token.Data) {
|
||||
stackNum++
|
||||
}
|
||||
|
||||
// If this is the close tag to the outer-most, we are done
|
||||
if token.Type == html.EndTagToken {
|
||||
stackNum--
|
||||
|
||||
if stackNum <= 0 && strings.EqualFold(tagName, token.Data) {
|
||||
break
|
||||
}
|
||||
@@ -397,8 +447,8 @@ OUTER_LOOP:
|
||||
continue OUTER_LOOP
|
||||
}
|
||||
|
||||
if !com.IsSliceContainsStr(noEndTags, token.Data) {
|
||||
startTags = append(startTags, token.Data)
|
||||
if !com.IsSliceContainsStr(noEndTags, tagName) {
|
||||
startTags = append(startTags, tagName)
|
||||
}
|
||||
|
||||
case html.EndTagToken:
|
||||
@@ -422,7 +472,7 @@ OUTER_LOOP:
|
||||
|
||||
// If we are not at the end of the input, then some other parsing error has occurred,
|
||||
// so return the input verbatim.
|
||||
return rawHtml
|
||||
return rawHTML
|
||||
}
|
||||
|
||||
// Render renders Markdown to HTML with special links.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
_ "github.com/kardianos/minwinsvc"
|
||||
_ "github.com/gogits/minwinsvc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -142,10 +142,21 @@ var (
|
||||
Types []string
|
||||
QueueLength int
|
||||
DeliverTimeout int
|
||||
SkipTLSVerify bool
|
||||
SkipTLSVerify bool `ini:"SKIP_TLS_VERIFY"`
|
||||
PagingNum int
|
||||
}
|
||||
|
||||
// Release settigns
|
||||
Release struct {
|
||||
Attachment struct {
|
||||
Enabled bool
|
||||
TempPath string
|
||||
AllowedTypes []string `delim:"|"`
|
||||
MaxSize int64
|
||||
MaxFiles int
|
||||
} `ini:"-"`
|
||||
}
|
||||
|
||||
// Markdown sttings
|
||||
Markdown struct {
|
||||
EnableHardLineBreak bool
|
||||
@@ -153,6 +164,15 @@ var (
|
||||
FileExtensions []string
|
||||
}
|
||||
|
||||
// Smartypants settings
|
||||
Smartypants struct {
|
||||
Enabled bool
|
||||
Fractions bool
|
||||
Dashes bool
|
||||
LatexDashes bool
|
||||
AngledQuotes bool
|
||||
}
|
||||
|
||||
// Admin settings
|
||||
Admin struct {
|
||||
DisableRegularOrgCreation bool
|
||||
@@ -581,8 +601,12 @@ func NewContext() {
|
||||
log.Fatal(2, "Fail to map HTTP settings: %v", err)
|
||||
} else if err = Cfg.Section("webhook").MapTo(&Webhook); err != nil {
|
||||
log.Fatal(2, "Fail to map Webhook settings: %v", err)
|
||||
} else if err = Cfg.Section("release.attachment").MapTo(&Release.Attachment); err != nil {
|
||||
log.Fatal(2, "Fail to map Release.Attachment settings: %v", err)
|
||||
} else if err = Cfg.Section("markdown").MapTo(&Markdown); err != nil {
|
||||
log.Fatal(2, "Fail to map Markdown settings: %v", err)
|
||||
} else if err = Cfg.Section("smartypants").MapTo(&Smartypants); err != nil {
|
||||
log.Fatal(2, "Fail to map Smartypants settings: %v", err)
|
||||
} else if err = Cfg.Section("admin").MapTo(&Admin); err != nil {
|
||||
log.Fatal(2, "Fail to map Admin settings: %v", err)
|
||||
} else if err = Cfg.Section("cron").MapTo(&Cron); err != nil {
|
||||
@@ -751,18 +775,18 @@ func newSessionService() {
|
||||
|
||||
// Mailer represents mail service.
|
||||
type Mailer struct {
|
||||
QueueLength int
|
||||
Name string
|
||||
Host string
|
||||
From string
|
||||
FromEmail string
|
||||
User, Passwd string
|
||||
DisableHelo bool
|
||||
HeloHostname string
|
||||
SkipVerify bool
|
||||
UseCertificate bool
|
||||
CertFile, KeyFile string
|
||||
EnableHTMLAlternative bool
|
||||
QueueLength int
|
||||
Subject string
|
||||
Host string
|
||||
From string
|
||||
FromEmail string
|
||||
User, Passwd string
|
||||
DisableHelo bool
|
||||
HeloHostname string
|
||||
SkipVerify bool
|
||||
UseCertificate bool
|
||||
CertFile, KeyFile string
|
||||
UsePlainText bool
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -777,18 +801,18 @@ func newMailService() {
|
||||
}
|
||||
|
||||
MailService = &Mailer{
|
||||
QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100),
|
||||
Name: sec.Key("NAME").MustString(AppName),
|
||||
Host: sec.Key("HOST").String(),
|
||||
User: sec.Key("USER").String(),
|
||||
Passwd: sec.Key("PASSWD").String(),
|
||||
DisableHelo: sec.Key("DISABLE_HELO").MustBool(),
|
||||
HeloHostname: sec.Key("HELO_HOSTNAME").String(),
|
||||
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
|
||||
UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(),
|
||||
CertFile: sec.Key("CERT_FILE").String(),
|
||||
KeyFile: sec.Key("KEY_FILE").String(),
|
||||
EnableHTMLAlternative: sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(),
|
||||
QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100),
|
||||
Subject: sec.Key("SUBJECT").MustString(AppName),
|
||||
Host: sec.Key("HOST").String(),
|
||||
User: sec.Key("USER").String(),
|
||||
Passwd: sec.Key("PASSWD").String(),
|
||||
DisableHelo: sec.Key("DISABLE_HELO").MustBool(),
|
||||
HeloHostname: sec.Key("HELO_HOSTNAME").String(),
|
||||
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
|
||||
UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(),
|
||||
CertFile: sec.Key("CERT_FILE").String(),
|
||||
KeyFile: sec.Key("KEY_FILE").String(),
|
||||
UsePlainText: sec.Key("USE_PLAIN_TEXT").MustBool(),
|
||||
}
|
||||
MailService.From = sec.Key("FROM").MustString(MailService.User)
|
||||
|
||||
|
||||
@@ -242,12 +242,14 @@ func ActionIcon(opType int) string {
|
||||
switch opType {
|
||||
case 1, 8: // Create and transfer repository
|
||||
return "repo"
|
||||
case 5, 9: // Commit repository
|
||||
case 5: // Commit repository
|
||||
return "git-commit"
|
||||
case 6: // Create issue
|
||||
return "issue-opened"
|
||||
case 7: // New pull request
|
||||
return "git-pull-request"
|
||||
case 9: // Push tag
|
||||
return "tag"
|
||||
case 10: // Comment issue
|
||||
return "comment-discussion"
|
||||
case 11: // Merge pull request
|
||||
@@ -256,6 +258,12 @@ func ActionIcon(opType int) string {
|
||||
return "issue-closed"
|
||||
case 13, 15: // Reopen issue or pull request
|
||||
return "issue-reopened"
|
||||
case 16: // Create branch
|
||||
return "git-branch"
|
||||
case 17, 18: // Delete branch or tag
|
||||
return "alert"
|
||||
case 19: // Fork a repository
|
||||
return "repo-forked"
|
||||
default:
|
||||
return "invalid type"
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
},
|
||||
"\/css\/semantic-2.2.9.min.css": {
|
||||
"\/css\/semantic-2.2.7.min.css": {
|
||||
"fileType": 16,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 1,
|
||||
"inputAbbreviatedPath": "\/css\/semantic-2.2.9.min.css",
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/css\/semantic-2.2.7.min.css",
|
||||
"outputAbbreviatedPath": "No Output Path",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
@@ -161,12 +161,12 @@
|
||||
"outputStyle": 1,
|
||||
"syntaxCheckerStyle": 1
|
||||
},
|
||||
"\/js\/semantic-2.2.9.min.js": {
|
||||
"\/js\/semantic-2.2.7.min.js": {
|
||||
"fileType": 64,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 1,
|
||||
"inputAbbreviatedPath": "\/js\/semantic-2.2.9.min.js",
|
||||
"outputAbbreviatedPath": "\/js\/min\/semantic-2.2.9.min-min.js",
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/js\/semantic-2.2.7.min.js",
|
||||
"outputAbbreviatedPath": "\/js\/min\/semantic-2.2.7.min-min.js",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"outputStyle": 1,
|
||||
|
||||
@@ -125,6 +125,11 @@ code.wrap {
|
||||
.ui.form .ui.button {
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui.menu,
|
||||
.ui.vertical.menu,
|
||||
.ui.segment {
|
||||
box-shadow: none;
|
||||
}
|
||||
.ui .text.red {
|
||||
color: #d95c5c !important;
|
||||
}
|
||||
@@ -1222,6 +1227,33 @@ footer .ui.language .menu {
|
||||
right: 0!important;
|
||||
left: auto!important;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list {
|
||||
padding: 0;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item {
|
||||
margin: 0;
|
||||
line-height: 31px;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item:not(:last-child) {
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item .column {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item .column .octicon {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item .column code {
|
||||
padding: 4px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item .column .ui.text:not(i) {
|
||||
font-size: 12px;
|
||||
}
|
||||
.repository.branches:not(.settings) .ui.list > .item .column .ui.button {
|
||||
font-size: 12px;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.repository.file.list #repo-desc {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
@@ -1235,6 +1267,20 @@ footer .ui.language .menu {
|
||||
padding: 8px 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.repository.file.list #git-stats {
|
||||
padding: 10px;
|
||||
line-height: 0;
|
||||
}
|
||||
.repository.file.list #git-stats .list {
|
||||
width: 100%;
|
||||
}
|
||||
.repository.file.list #git-stats .list .item {
|
||||
margin-left: 0;
|
||||
width: 33.33%;
|
||||
}
|
||||
.repository.file.list #git-stats .list .item .text b {
|
||||
font-size: 15px;
|
||||
}
|
||||
.repository.file.list #repo-files-table thead th {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 5px;
|
||||
@@ -1858,24 +1904,24 @@ footer .ui.language .menu {
|
||||
list-style: none;
|
||||
padding-top: 15px;
|
||||
}
|
||||
.repository .label.list .item {
|
||||
.repository .label.list > .item {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed #AAA;
|
||||
}
|
||||
.repository .label.list .item a {
|
||||
.repository .label.list > .item a {
|
||||
font-size: 15px;
|
||||
padding-top: 5px;
|
||||
padding-right: 10px;
|
||||
color: #666;
|
||||
}
|
||||
.repository .label.list .item a:hover {
|
||||
.repository .label.list > .item a:hover {
|
||||
color: #000;
|
||||
}
|
||||
.repository .label.list .item a.open-issues {
|
||||
.repository .label.list > .item a.open-issues {
|
||||
margin-right: 30px;
|
||||
}
|
||||
.repository .label.list .item .ui.label {
|
||||
.repository .label.list > .item .ui.label {
|
||||
font-size: 1em;
|
||||
}
|
||||
.repository .milestone.list {
|
||||
@@ -2164,11 +2210,11 @@ footer .ui.language .menu {
|
||||
}
|
||||
.repository.release #release-list > li .meta .tag:not(.icon) {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.repository.release #release-list > li .meta .commit {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.repository.release #release-list > li .detail {
|
||||
border-left: 1px solid #DDD;
|
||||
@@ -2292,28 +2338,28 @@ footer .ui.language .menu {
|
||||
margin-left: 5px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
.repository.settings.branches .protected-branches .selection.dropdown {
|
||||
.repository.settings.settings.branches .protected-branches .selection.dropdown {
|
||||
width: 300px;
|
||||
}
|
||||
.repository.settings.branches .protected-branches .item {
|
||||
.repository.settings.settings.branches .protected-branches .item {
|
||||
border: 1px solid #eaeaea;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
.repository.settings.branches .protected-branches .item:not(:last-child) {
|
||||
.repository.settings.settings.branches .protected-branches .item:not(:last-child) {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.repository.settings.branches .branch-protection .help {
|
||||
.repository.settings.settings.branches .branch-protection .help {
|
||||
margin-left: 26px;
|
||||
padding-top: 0;
|
||||
}
|
||||
.repository.settings.branches .branch-protection .fields {
|
||||
.repository.settings.settings.branches .branch-protection .fields {
|
||||
margin-left: 20px;
|
||||
display: block;
|
||||
}
|
||||
.repository.settings.branches .branch-protection .whitelist {
|
||||
.repository.settings.settings.branches .branch-protection .whitelist {
|
||||
margin-left: 26px;
|
||||
}
|
||||
.repository.settings.branches .branch-protection .whitelist .dropdown img {
|
||||
.repository.settings.settings.branches .branch-protection .whitelist .dropdown img {
|
||||
display: inline-block;
|
||||
}
|
||||
.repository.settings.webhooks .types .menu .item {
|
||||
@@ -2427,10 +2473,6 @@ footer .ui.language .menu {
|
||||
.settings .content {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.settings .content > .header,
|
||||
.settings .content .segment {
|
||||
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15);
|
||||
}
|
||||
.settings .key.list .item:not(:first-child) {
|
||||
border-top: 1px solid #eaeaea;
|
||||
}
|
||||
@@ -2921,7 +2963,7 @@ footer .ui.language .menu {
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
.feeds .news code {
|
||||
padding: 1px;
|
||||
padding: 3px;
|
||||
font-size: 85%;
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 3px;
|
||||
@@ -2993,10 +3035,6 @@ footer .ui.language .menu {
|
||||
.admin .table.segment:not(.select) td:first-of-type {
|
||||
padding-left: 15px !important;
|
||||
}
|
||||
.admin .ui.header,
|
||||
.admin .ui.segment {
|
||||
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15);
|
||||
}
|
||||
.admin.user .email {
|
||||
max-width: 200px;
|
||||
}
|
||||
@@ -3019,6 +3057,19 @@ footer .ui.language .menu {
|
||||
.admin.config #test-mail-btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.admin.config table tbody tr td:first-child {
|
||||
font-weight: bold;
|
||||
}
|
||||
.admin.config pre {
|
||||
background-color: #f7f7f7;
|
||||
padding: 5px;
|
||||
}
|
||||
.admin.config .log-config table tbody tr td:first-child {
|
||||
width: 100px;
|
||||
}
|
||||
.admin.config .log-config table tbody tr td:not(first-child) {
|
||||
max-width: 0;
|
||||
}
|
||||
.explore {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 80px;
|
||||
|
||||
@@ -29,10 +29,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.ui.header,
|
||||
.ui.segment {
|
||||
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
|
||||
}
|
||||
|
||||
&.user {
|
||||
.email {
|
||||
@@ -62,5 +58,22 @@
|
||||
#test-mail-btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
table tbody tr td:first-child {
|
||||
font-weight: bold;
|
||||
}
|
||||
pre {
|
||||
background-color: #f7f7f7;
|
||||
padding: 5px;
|
||||
}
|
||||
.log-config {
|
||||
table tbody tr td {
|
||||
&:first-child {
|
||||
width: 100px;
|
||||
}
|
||||
&:not(first-child) {
|
||||
max-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,12 @@ pre, code {
|
||||
}
|
||||
}
|
||||
|
||||
&.menu,
|
||||
&.vertical.menu,
|
||||
&.segment {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.text {
|
||||
&.red {
|
||||
color: #d95c5c !important;
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
code {
|
||||
padding: 1px;
|
||||
padding: 3px;
|
||||
font-size: 85%;
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 3px;
|
||||
|
||||
@@ -150,6 +150,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.branches:not(.settings) {
|
||||
.ui.list {
|
||||
padding: 0;
|
||||
>.item {
|
||||
margin: 0;
|
||||
line-height: 31px;
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
.column {
|
||||
padding: 5px 15px;
|
||||
.octicon {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
code {
|
||||
padding: 4px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.ui.text:not(i) {
|
||||
font-size: 12px;
|
||||
}
|
||||
.ui.button {
|
||||
font-size: 12px;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.file.list {
|
||||
#repo-desc {
|
||||
font-size: 1.2em;
|
||||
@@ -167,6 +197,20 @@
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
#git-stats {
|
||||
padding: 10px;
|
||||
line-height: 0;
|
||||
.list {
|
||||
width: 100%;
|
||||
.item {
|
||||
margin-left: 0;
|
||||
width: 33.33%;
|
||||
.text b {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#repo-files-table {
|
||||
thead {
|
||||
@@ -784,7 +828,7 @@
|
||||
.label.list {
|
||||
list-style: none;
|
||||
padding-top: 15px;
|
||||
.item {
|
||||
>.item {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed #AAA;
|
||||
@@ -1132,11 +1176,11 @@
|
||||
|
||||
.tag:not(.icon) {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.commit {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
.detail {
|
||||
@@ -1307,7 +1351,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.branches {
|
||||
&.settings.branches {
|
||||
.protected-branches {
|
||||
.selection.dropdown {
|
||||
width: 300px;
|
||||
@@ -1476,10 +1520,6 @@
|
||||
.settings {
|
||||
.content {
|
||||
margin-top: 2px;
|
||||
>.header,
|
||||
.segment {
|
||||
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
|
||||
}
|
||||
}
|
||||
.key.list {
|
||||
.item:not(:first-child) {
|
||||
|
||||
@@ -240,7 +240,7 @@ func Config(ctx *context.Context) {
|
||||
Mode: strings.Title(setting.LogModes[i]),
|
||||
}
|
||||
|
||||
result, _ := json.Marshal(setting.LogConfigs[i])
|
||||
result, _ := json.MarshalIndent(setting.LogConfigs[i], "", " ")
|
||||
loggers[i].Config = string(result)
|
||||
}
|
||||
ctx.Data["Loggers"] = loggers
|
||||
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/auth/ldap"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/context"
|
||||
"github.com/gogits/gogs/modules/form"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
@@ -76,64 +76,64 @@ func NewAuthSource(ctx *context.Context) {
|
||||
ctx.HTML(200, AUTH_NEW)
|
||||
}
|
||||
|
||||
func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig {
|
||||
func parseLDAPConfig(f form.Authentication) *models.LDAPConfig {
|
||||
return &models.LDAPConfig{
|
||||
Source: &ldap.Source{
|
||||
Name: form.Name,
|
||||
Host: form.Host,
|
||||
Port: form.Port,
|
||||
SecurityProtocol: ldap.SecurityProtocol(form.SecurityProtocol),
|
||||
SkipVerify: form.SkipVerify,
|
||||
BindDN: form.BindDN,
|
||||
UserDN: form.UserDN,
|
||||
BindPassword: form.BindPassword,
|
||||
UserBase: form.UserBase,
|
||||
AttributeUsername: form.AttributeUsername,
|
||||
AttributeName: form.AttributeName,
|
||||
AttributeSurname: form.AttributeSurname,
|
||||
AttributeMail: form.AttributeMail,
|
||||
AttributesInBind: form.AttributesInBind,
|
||||
Filter: form.Filter,
|
||||
AdminFilter: form.AdminFilter,
|
||||
Name: f.Name,
|
||||
Host: f.Host,
|
||||
Port: f.Port,
|
||||
SecurityProtocol: ldap.SecurityProtocol(f.SecurityProtocol),
|
||||
SkipVerify: f.SkipVerify,
|
||||
BindDN: f.BindDN,
|
||||
UserDN: f.UserDN,
|
||||
BindPassword: f.BindPassword,
|
||||
UserBase: f.UserBase,
|
||||
AttributeUsername: f.AttributeUsername,
|
||||
AttributeName: f.AttributeName,
|
||||
AttributeSurname: f.AttributeSurname,
|
||||
AttributeMail: f.AttributeMail,
|
||||
AttributesInBind: f.AttributesInBind,
|
||||
Filter: f.Filter,
|
||||
AdminFilter: f.AdminFilter,
|
||||
Enabled: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func parseSMTPConfig(form auth.AuthenticationForm) *models.SMTPConfig {
|
||||
func parseSMTPConfig(f form.Authentication) *models.SMTPConfig {
|
||||
return &models.SMTPConfig{
|
||||
Auth: form.SMTPAuth,
|
||||
Host: form.SMTPHost,
|
||||
Port: form.SMTPPort,
|
||||
AllowedDomains: form.AllowedDomains,
|
||||
TLS: form.TLS,
|
||||
SkipVerify: form.SkipVerify,
|
||||
Auth: f.SMTPAuth,
|
||||
Host: f.SMTPHost,
|
||||
Port: f.SMTPPort,
|
||||
AllowedDomains: f.AllowedDomains,
|
||||
TLS: f.TLS,
|
||||
SkipVerify: f.SkipVerify,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
|
||||
func NewAuthSourcePost(ctx *context.Context, f form.Authentication) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.auths.new")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminAuthentications"] = true
|
||||
|
||||
ctx.Data["CurrentTypeName"] = models.LoginNames[models.LoginType(form.Type)]
|
||||
ctx.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SecurityProtocol(form.SecurityProtocol)]
|
||||
ctx.Data["CurrentTypeName"] = models.LoginNames[models.LoginType(f.Type)]
|
||||
ctx.Data["CurrentSecurityProtocol"] = models.SecurityProtocolNames[ldap.SecurityProtocol(f.SecurityProtocol)]
|
||||
ctx.Data["AuthSources"] = authSources
|
||||
ctx.Data["SecurityProtocols"] = securityProtocols
|
||||
ctx.Data["SMTPAuths"] = models.SMTPAuths
|
||||
|
||||
hasTLS := false
|
||||
var config core.Conversion
|
||||
switch models.LoginType(form.Type) {
|
||||
switch models.LoginType(f.Type) {
|
||||
case models.LOGIN_LDAP, models.LOGIN_DLDAP:
|
||||
config = parseLDAPConfig(form)
|
||||
hasTLS = ldap.SecurityProtocol(form.SecurityProtocol) > ldap.SECURITY_PROTOCOL_UNENCRYPTED
|
||||
config = parseLDAPConfig(f)
|
||||
hasTLS = ldap.SecurityProtocol(f.SecurityProtocol) > ldap.SECURITY_PROTOCOL_UNENCRYPTED
|
||||
case models.LOGIN_SMTP:
|
||||
config = parseSMTPConfig(form)
|
||||
config = parseSMTPConfig(f)
|
||||
hasTLS = true
|
||||
case models.LOGIN_PAM:
|
||||
config = &models.PAMConfig{
|
||||
ServiceName: form.PAMServiceName,
|
||||
ServiceName: f.PAMServiceName,
|
||||
}
|
||||
default:
|
||||
ctx.Error(400)
|
||||
@@ -147,23 +147,23 @@ func NewAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
|
||||
}
|
||||
|
||||
if err := models.CreateLoginSource(&models.LoginSource{
|
||||
Type: models.LoginType(form.Type),
|
||||
Name: form.Name,
|
||||
IsActived: form.IsActive,
|
||||
Type: models.LoginType(f.Type),
|
||||
Name: f.Name,
|
||||
IsActived: f.IsActive,
|
||||
Cfg: config,
|
||||
}); err != nil {
|
||||
if models.IsErrLoginSourceAlreadyExist(err) {
|
||||
ctx.Data["Err_Name"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("admin.auths.login_source_exist", err.(models.ErrLoginSourceAlreadyExist).Name), AUTH_NEW, form)
|
||||
ctx.RenderWithErr(ctx.Tr("admin.auths.login_source_exist", err.(models.ErrLoginSourceAlreadyExist).Name), AUTH_NEW, f)
|
||||
} else {
|
||||
ctx.Handle(500, "CreateSource", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Authentication created by admin(%s): %s", ctx.User.Name, form.Name)
|
||||
log.Trace("Authentication created by admin(%s): %s", ctx.User.Name, f.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.new_success", form.Name))
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.new_success", f.Name))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths")
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ func EditAuthSource(ctx *context.Context) {
|
||||
ctx.HTML(200, AUTH_EDIT)
|
||||
}
|
||||
|
||||
func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
|
||||
func EditAuthSourcePost(ctx *context.Context, f form.Authentication) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.auths.edit")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminAuthentications"] = true
|
||||
@@ -207,22 +207,22 @@ func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
|
||||
}
|
||||
|
||||
var config core.Conversion
|
||||
switch models.LoginType(form.Type) {
|
||||
switch models.LoginType(f.Type) {
|
||||
case models.LOGIN_LDAP, models.LOGIN_DLDAP:
|
||||
config = parseLDAPConfig(form)
|
||||
config = parseLDAPConfig(f)
|
||||
case models.LOGIN_SMTP:
|
||||
config = parseSMTPConfig(form)
|
||||
config = parseSMTPConfig(f)
|
||||
case models.LOGIN_PAM:
|
||||
config = &models.PAMConfig{
|
||||
ServiceName: form.PAMServiceName,
|
||||
ServiceName: f.PAMServiceName,
|
||||
}
|
||||
default:
|
||||
ctx.Error(400)
|
||||
return
|
||||
}
|
||||
|
||||
source.Name = form.Name
|
||||
source.IsActived = form.IsActive
|
||||
source.Name = f.Name
|
||||
source.IsActived = f.IsActive
|
||||
source.Cfg = config
|
||||
if err := models.UpdateSource(source); err != nil {
|
||||
ctx.Handle(500, "UpdateSource", err)
|
||||
@@ -231,7 +231,7 @@ func EditAuthSourcePost(ctx *context.Context, form auth.AuthenticationForm) {
|
||||
log.Trace("Authentication changed by admin(%s): %d", ctx.User.Name, source.ID)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.auths.update_success"))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + com.ToStr(form.ID))
|
||||
ctx.Redirect(setting.AppSubUrl + "/admin/auths/" + com.ToStr(f.ID))
|
||||
}
|
||||
|
||||
func DeleteAuthSource(ctx *context.Context) {
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/context"
|
||||
"github.com/gogits/gogs/modules/form"
|
||||
"github.com/gogits/gogs/modules/mailer"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/gogits/gogs/routers"
|
||||
@@ -58,7 +58,7 @@ func NewUser(ctx *context.Context) {
|
||||
ctx.HTML(200, USER_NEW)
|
||||
}
|
||||
|
||||
func NewUserPost(ctx *context.Context, form auth.AdminCrateUserForm) {
|
||||
func NewUserPost(ctx *context.Context, f form.AdminCrateUser) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminUsers"] = true
|
||||
@@ -78,19 +78,19 @@ func NewUserPost(ctx *context.Context, form auth.AdminCrateUserForm) {
|
||||
}
|
||||
|
||||
u := &models.User{
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
Name: f.UserName,
|
||||
Email: f.Email,
|
||||
Passwd: f.Password,
|
||||
IsActive: true,
|
||||
LoginType: models.LOGIN_PLAIN,
|
||||
}
|
||||
|
||||
if len(form.LoginType) > 0 {
|
||||
fields := strings.Split(form.LoginType, "-")
|
||||
if len(f.LoginType) > 0 {
|
||||
fields := strings.Split(f.LoginType, "-")
|
||||
if len(fields) == 2 {
|
||||
u.LoginType = models.LoginType(com.StrTo(fields[0]).MustInt())
|
||||
u.LoginSource = com.StrTo(fields[1]).MustInt64()
|
||||
u.LoginName = form.LoginName
|
||||
u.LoginName = f.LoginName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,16 +98,16 @@ func NewUserPost(ctx *context.Context, form auth.AdminCrateUserForm) {
|
||||
switch {
|
||||
case models.IsErrUserAlreadyExist(err):
|
||||
ctx.Data["Err_UserName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), USER_NEW, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), USER_NEW, &f)
|
||||
case models.IsErrEmailAlreadyUsed(err):
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), USER_NEW, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), USER_NEW, &f)
|
||||
case models.IsErrNameReserved(err):
|
||||
ctx.Data["Err_UserName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("user.form.name_reserved", err.(models.ErrNameReserved).Name), USER_NEW, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("user.form.name_reserved", err.(models.ErrNameReserved).Name), USER_NEW, &f)
|
||||
case models.IsErrNamePatternNotAllowed(err):
|
||||
ctx.Data["Err_UserName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("user.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), USER_NEW, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("user.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), USER_NEW, &f)
|
||||
default:
|
||||
ctx.Handle(500, "CreateUser", err)
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func NewUserPost(ctx *context.Context, form auth.AdminCrateUserForm) {
|
||||
log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
|
||||
|
||||
// Send email notification.
|
||||
if form.SendNotify && setting.MailService != nil {
|
||||
if f.SendNotify && setting.MailService != nil {
|
||||
mailer.SendRegisterNotifyMail(ctx.Context, models.NewMailerUser(u))
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func EditUser(ctx *context.Context) {
|
||||
ctx.HTML(200, USER_EDIT)
|
||||
}
|
||||
|
||||
func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
|
||||
func EditUserPost(ctx *context.Context, f form.AdminEditUser) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.users.edit_account")
|
||||
ctx.Data["PageIsAdmin"] = true
|
||||
ctx.Data["PageIsAdminUsers"] = true
|
||||
@@ -182,7 +182,7 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
|
||||
return
|
||||
}
|
||||
|
||||
fields := strings.Split(form.LoginType, "-")
|
||||
fields := strings.Split(f.LoginType, "-")
|
||||
if len(fields) == 2 {
|
||||
loginType := models.LoginType(com.StrTo(fields[0]).MustInt())
|
||||
loginSource := com.StrTo(fields[1]).MustInt64()
|
||||
@@ -193,8 +193,8 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(form.Password) > 0 {
|
||||
u.Passwd = form.Password
|
||||
if len(f.Password) > 0 {
|
||||
u.Passwd = f.Password
|
||||
var err error
|
||||
if u.Salt, err = models.GetUserSalt(); err != nil {
|
||||
ctx.Handle(500, "UpdateUser", err)
|
||||
@@ -203,22 +203,22 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
|
||||
u.EncodePasswd()
|
||||
}
|
||||
|
||||
u.LoginName = form.LoginName
|
||||
u.FullName = form.FullName
|
||||
u.Email = form.Email
|
||||
u.Website = form.Website
|
||||
u.Location = form.Location
|
||||
u.MaxRepoCreation = form.MaxRepoCreation
|
||||
u.IsActive = form.Active
|
||||
u.IsAdmin = form.Admin
|
||||
u.AllowGitHook = form.AllowGitHook
|
||||
u.AllowImportLocal = form.AllowImportLocal
|
||||
u.ProhibitLogin = form.ProhibitLogin
|
||||
u.LoginName = f.LoginName
|
||||
u.FullName = f.FullName
|
||||
u.Email = f.Email
|
||||
u.Website = f.Website
|
||||
u.Location = f.Location
|
||||
u.MaxRepoCreation = f.MaxRepoCreation
|
||||
u.IsActive = f.Active
|
||||
u.IsAdmin = f.Admin
|
||||
u.AllowGitHook = f.AllowGitHook
|
||||
u.AllowImportLocal = f.AllowImportLocal
|
||||
u.ProhibitLogin = f.ProhibitLogin
|
||||
|
||||
if err := models.UpdateUser(u); err != nil {
|
||||
if models.IsErrEmailAlreadyUsed(err) {
|
||||
ctx.Data["Err_Email"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), USER_EDIT, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), USER_EDIT, &f)
|
||||
} else {
|
||||
ctx.Handle(500, "UpdateUser", err)
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/context"
|
||||
"github.com/gogits/gogs/modules/form"
|
||||
"github.com/gogits/gogs/routers/api/v1/admin"
|
||||
"github.com/gogits/gogs/routers/api/v1/misc"
|
||||
"github.com/gogits/gogs/routers/api/v1/org"
|
||||
@@ -173,6 +173,9 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
bind := binding.Bind
|
||||
|
||||
m.Group("/v1", func() {
|
||||
// Handle preflight OPTIONS request
|
||||
m.Options("/*", func() {})
|
||||
|
||||
// Miscellaneous
|
||||
m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
|
||||
m.Post("/markdown/raw", misc.MarkdownRaw)
|
||||
@@ -237,7 +240,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
})
|
||||
|
||||
m.Group("/repos", func() {
|
||||
m.Post("/migrate", bind(auth.MigrateRepoForm{}), repo.Migrate)
|
||||
m.Post("/migrate", bind(form.MigrateRepo{}), repo.Migrate)
|
||||
m.Combo("/:username/:reponame").Get(repo.Get).
|
||||
Delete(repo.Delete)
|
||||
|
||||
@@ -258,7 +261,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Get("/forks", repo.ListForks)
|
||||
m.Group("/branches", func() {
|
||||
m.Get("", repo.ListBranches)
|
||||
m.Get("/:branchname", repo.GetBranch)
|
||||
m.Get("/*", repo.GetBranch)
|
||||
})
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo.ListDeployKeys).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user