mirror of
https://github.com/gogs/gogs.git
synced 2026-03-01 01:30:57 +01:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c154721f4a | ||
|
|
48cdae2829 | ||
|
|
9571a9b53d | ||
|
|
f1e0ebfe93 | ||
|
|
c7ba519af2 | ||
|
|
04de977855 | ||
|
|
591a05caa3 | ||
|
|
82700ea95a | ||
|
|
a36b29c25c | ||
|
|
c3af3ff1d0 | ||
|
|
1592e578ed | ||
|
|
e640683c97 | ||
|
|
e6bddd3ed2 | ||
|
|
bd0549caea | ||
|
|
08a53e5eca | ||
|
|
025972ef64 | ||
|
|
00a3e368b4 | ||
|
|
6b2465746a | ||
|
|
35e2cee5c5 | ||
|
|
d775fe7936 | ||
|
|
dc13eb6df0 | ||
|
|
798636c95b | ||
|
|
25fdf6cb16 | ||
|
|
044a45db2e | ||
|
|
0aec2df74f | ||
|
|
4f9c5b60c5 | ||
|
|
bd13df972e | ||
|
|
a971910723 | ||
|
|
b8a6fee6d6 | ||
|
|
0bfa981e70 | ||
|
|
070bdda011 | ||
|
|
e19c026083 | ||
|
|
8b383f86de | ||
|
|
9ebd62f676 | ||
|
|
2c3e2b701e | ||
|
|
16f95123cd | ||
|
|
0a176df6fb | ||
|
|
d862c43be0 | ||
|
|
a452767e34 | ||
|
|
f0aeef82a1 |
13
.pkgr.yml
13
.pkgr.yml
@@ -1,15 +1,13 @@
|
||||
targets:
|
||||
debian-7: &debian
|
||||
debian-8: &debian
|
||||
build_dependencies:
|
||||
- libpam0g-dev
|
||||
dependencies:
|
||||
- libpam0g
|
||||
- git
|
||||
debian-8:
|
||||
<<: *debian
|
||||
debian-9:
|
||||
<<: *debian
|
||||
ubuntu-12.04:
|
||||
debian-10:
|
||||
<<: *debian
|
||||
ubuntu-14.04:
|
||||
<<: *debian
|
||||
@@ -18,6 +16,8 @@ targets:
|
||||
build_dependencies:
|
||||
- bzr
|
||||
- mercurial
|
||||
ubuntu-18.04:
|
||||
<<: *debian
|
||||
centos-6: &el
|
||||
build_dependencies:
|
||||
- pam-devel
|
||||
@@ -33,4 +33,7 @@ before:
|
||||
after:
|
||||
- mv bin/gogs gogs
|
||||
after_install: ./packager/hooks/postinst
|
||||
buildpack: https://github.com/heroku/heroku-buildpack-go.git#v62
|
||||
# Can be updated after CentOS 6 support is dropped, otherwise fails with
|
||||
# `fatal: bad config file line 2 in /home/pkgr/.gitconfig` because of
|
||||
# https://github.com/heroku/heroku-buildpack-go/blob/f96ebebfa7605fd3916521e42ab050c81c9b947a/lib/common.sh#L238
|
||||
buildpack: https://github.com/heroku/heroku-buildpack-go.git#v76
|
||||
|
||||
@@ -4,6 +4,7 @@ go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
|
||||
@@ -20,7 +20,8 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
s6 \
|
||||
shadow \
|
||||
socat \
|
||||
tzdata
|
||||
tzdata \
|
||||
rsync
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM aarch64/alpine:3.5
|
||||
FROM arm64v8/alpine:latest
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-arm64 /usr/sbin/gosu
|
||||
@@ -14,7 +14,8 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
s6 \
|
||||
shadow \
|
||||
socat \
|
||||
tzdata
|
||||
tzdata \
|
||||
rsync
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM arm64v8/alpine:3.8
|
||||
FROM arm64v8/alpine:latest
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
ENV QEMU_EXECVE 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM armhf/alpine:3.5
|
||||
FROM arm32v7/alpine:latest
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-armhf /usr/sbin/gosu
|
||||
@@ -14,7 +14,8 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
s6 \
|
||||
shadow \
|
||||
socat \
|
||||
tzdata
|
||||
tzdata \
|
||||
rsync
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM armhf/alpine:3.5
|
||||
FROM arm32v7/alpine:latest
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
ENV QEMU_EXECVE 1
|
||||
@@ -30,7 +30,8 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
s6 \
|
||||
shadow \
|
||||
socat \
|
||||
tzdata
|
||||
tzdata \
|
||||
rsync
|
||||
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
|
||||
@@ -69,13 +69,14 @@ This project aims to build a simple, stable and extensible self-hosted Git servi
|
||||
|
||||
Make sure you install the [prerequisites](https://gogs.io/docs/installation) first.
|
||||
|
||||
There are 5 ways to install Gogs:
|
||||
There are 6 ways to install Gogs:
|
||||
|
||||
- [Install from binary](https://gogs.io/docs/installation/install_from_binary.html)
|
||||
- [Install from source](https://gogs.io/docs/installation/install_from_source.html)
|
||||
- [Install from packages](https://gogs.io/docs/installation/install_from_packages.html)
|
||||
- [Ship with Docker](https://github.com/gogs/gogs/tree/master/docker)
|
||||
- [Install with Vagrant](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
|
||||
- [Install with Kubernetes Using Helm Charts](https://github.com/helm/charts/tree/master/incubator/gogs)
|
||||
|
||||
### Tutorials
|
||||
|
||||
@@ -83,7 +84,7 @@ There are 5 ways to install Gogs:
|
||||
- [Run your own GitHub-like service with the help of Docker](http://blog.hypriot.com/post/run-your-own-github-like-service-with-docker/)
|
||||
- [Dockerized Gogs git server and alpine postgres in 20 minutes or less](http://garthwaite.org/docker-gogs.html)
|
||||
- [Host Your Own Private GitHub with Gogs](https://eladnava.com/host-your-own-private-github-with-gogs-io/)
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://mynook.info/blog/post/host-your-own-git-server-using-gogs) (Chinese)
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://blog.mynook.info/post/host-your-own-git-server-using-gogs/) (Chinese)
|
||||
- [阿里云上 Ubuntu 14.04 64 位安装 Gogs](http://my.oschina.net/luyao/blog/375654) (Chinese)
|
||||
- [Installing Gogs on FreeBSD](https://www.codejam.info/2015/03/installing-gogs-on-freebsd.html)
|
||||
- [Gogs on Raspberry Pi](http://blog.meinside.pe.kr/Gogs-on-Raspberry-Pi/)
|
||||
@@ -103,6 +104,7 @@ There are 5 ways to install Gogs:
|
||||
- [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
|
||||
- [YunoHost](https://github.com/YunoHost-Apps/gogs_ynh)
|
||||
- [DPlatform](https://github.com/j8r/DPlatform)
|
||||
- [LunaNode](https://github.com/LunaNode/launchgogs)
|
||||
|
||||
## Software and Service Support
|
||||
|
||||
@@ -125,8 +127,9 @@ There are 5 ways to install Gogs:
|
||||
|
||||
- Thanks [Egon Elbre](https://twitter.com/egonelbre) for designing logo.
|
||||
- Thanks [Crowdin](https://crowdin.com/project/gogs) for sponsoring open source translation plan.
|
||||
- Thanks [DigitalOcean](https://www.digitalocean.com) and [VPSServer](https://www.vpsserver.com/) for sponsoring VPS service.
|
||||
- Thanks [DigitalOcean](https://www.digitalocean.com), [VPSServer](https://www.vpsserver.com/), [Hosted.nl](https://www.hosted.nl/) and [MonoVM](https://monovm.com) for sponsoring VPS services.
|
||||
- Thanks [KeyCDN](https://www.keycdn.com/) for sponsoring CDN service.
|
||||
- Thanks [Buildkite](https://buildkite.com) for sponsoring open source CI/CD plan.
|
||||
|
||||
## Contributors
|
||||
|
||||
|
||||
@@ -50,17 +50,18 @@ Gogs 是一款极易搭建的自助 Git 服务。
|
||||
|
||||
在安装 Gogs 之前,您需要先安装 [基本环境](https://gogs.io/docs/installation)。
|
||||
|
||||
然后,您可以通过以下 5 种方式来安装 Gogs:
|
||||
然后,您可以通过以下 6 种方式来安装 Gogs:
|
||||
|
||||
- [二进制安装](https://gogs.io/docs/installation/install_from_binary.html)
|
||||
- [源码安装](https://gogs.io/docs/installation/install_from_source.html)
|
||||
- [包管理安装](https://gogs.io/docs/installation/install_from_packages.html)
|
||||
- [采用 Docker 部署](https://github.com/gogs/gogs/tree/master/docker)
|
||||
- [通过 Vagrant 安装](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
|
||||
- [通过基于 Kubernetes 的 Helm Charts](https://github.com/helm/charts/tree/master/incubator/gogs)
|
||||
|
||||
### 使用教程
|
||||
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://mynook.info/blog/post/host-your-own-git-server-using-gogs)
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://blog.mynook.info/post/host-your-own-git-server-using-gogs/)
|
||||
- [阿里云上 Ubuntu 14.04 64 位安装 Gogs](http://my.oschina.net/luyao/blog/375654)
|
||||
|
||||
### 云端部署
|
||||
@@ -72,6 +73,7 @@ Gogs 是一款极易搭建的自助 Git 服务。
|
||||
- [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
|
||||
- [YunoHost](https://github.com/mbugeia/gogs_ynh)
|
||||
- [DPlatform](https://github.com/j8r/DPlatform)
|
||||
- [LunaNode](https://github.com/LunaNode/launchgogs)
|
||||
|
||||
## 软件及服务支持
|
||||
|
||||
@@ -94,8 +96,9 @@ Gogs 是一款极易搭建的自助 Git 服务。
|
||||
|
||||
- 感谢 [Egon Elbre](https://twitter.com/egonelbre) 设计的 Logo。
|
||||
- 感谢 [Crowdin](https://crowdin.com/project/gogs) 提供免费的开源项目本地化支持。
|
||||
- 感谢 [DigitalOcean](https://www.digitalocean.com) 和 [VPSServer](https://www.vpsserver.com/) 提供服务器赞助。
|
||||
- 感谢 [DigitalOcean](https://www.digitalocean.com)、[VPSServer](https://www.vpsserver.com/)、[Hosted.nl](https://www.hosted.nl/) 和 [MonoVM](https://monovm.com) 提供服务器赞助。
|
||||
- 感谢 [KeyCDN](https://www.keycdn.com/) 提供 CDN 服务赞助。
|
||||
- 感谢 [Buildkite](https://buildkite.com) 提供免费的开源项目 CI/CD 支持。
|
||||
|
||||
## 贡献成员
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ func runServ(c *cli.Context) error {
|
||||
fail("Internal error", "Fail to get user by key ID '%d': %v", key.ID, err)
|
||||
}
|
||||
|
||||
mode, err := models.AccessLevel(user.ID, repo)
|
||||
mode, err := models.UserAccessMode(user.ID, repo)
|
||||
if err != nil {
|
||||
fail("Internal error", "Fail to check access: %v", err)
|
||||
}
|
||||
|
||||
76
conf/gitignore/UnrealEngine
vendored
Normal file
76
conf/gitignore/UnrealEngine
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Visual Studio 2015 user specific files
|
||||
.vs/
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.ipa
|
||||
|
||||
# These project files can be generated by the engine
|
||||
*.xcodeproj
|
||||
*.xcworkspace
|
||||
*.sln
|
||||
*.suo
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
|
||||
# Precompiled Assets
|
||||
SourceArt/**/*.png
|
||||
SourceArt/**/*.tga
|
||||
|
||||
# Binary Files
|
||||
Binaries/*
|
||||
Plugins/*/Binaries/*
|
||||
|
||||
# Builds
|
||||
Build/*
|
||||
|
||||
# Whitelist PakBlacklist-<BuildConfiguration>.txt files
|
||||
!Build/*/
|
||||
Build/*/**
|
||||
!Build/*/PakBlacklist*.txt
|
||||
|
||||
# Don't ignore icon files in Build
|
||||
!Build/**/*.ico
|
||||
|
||||
# Built data for maps
|
||||
*_BuiltData.uasset
|
||||
|
||||
# Configuration files generated by the Editor
|
||||
Saved/*
|
||||
|
||||
# Compiled source files for the engine to use
|
||||
Intermediate/*
|
||||
Plugins/*/Intermediate/*
|
||||
|
||||
# Cache files for the editor to use
|
||||
DerivedDataCache/*
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ Luc Stepniewski <luc AT stepniewski DOT fr>
|
||||
Łukasz Jan Niemier <lukasz AT niemier DOT pl>
|
||||
Marc Schiller <marc AT schiller DOT im>
|
||||
Marvin Menzerath <github AT marvin-menzerath DOT de>
|
||||
Mathias Rangel Wulff <m AT rawu DOT dk>
|
||||
Michael Härtl <haertl DOT mike AT gmail DOT com>
|
||||
Miguel de la Cruz <miguel AT mcrx DOT me>
|
||||
Mikhail Burdin <xdshot9000 AT gmail DOT com>
|
||||
|
||||
@@ -322,7 +322,7 @@ add_key=Schlüssel hinzufügen
|
||||
ssh_desc=Dies ist eine Liste aller SSH-Schlüssel, die Ihrem Konto zugeordnet sind. Bitte entfernen Sie alle Schlüssel, die Ihnen nicht bekannt sind.
|
||||
ssh_helper=<strong>Brauchen Sie Hilfe?</strong> Hier ist eine Anleitung zum <a href="%s">Erzeugen von SSH-Schlüsseln</a> oder <a href="%s">Lösen einfacher SSH-Probleme</a>.
|
||||
add_new_key=SSH-Schlüssel hinzufügen
|
||||
ssh_key_been_used=Inhalt des öffentlichen Schlüssels wurde verwendet.
|
||||
ssh_key_been_used=Inhalt des öffentlichen Schlüssels wurde bereits verwendet.
|
||||
ssh_key_name_used=Ein öffentlicher Schlüssel mit diesem Namen existiert bereits.
|
||||
key_name=Schlüsselname
|
||||
key_content=Inhalt
|
||||
|
||||
@@ -48,7 +48,7 @@ cancel=Cancelar
|
||||
install=Instalación
|
||||
title=Pasos da instalación por primeira vez
|
||||
docker_helper=Se está executando Gogs usando Docker, por favor lea <a target="_blank" href="%s"> estas pautas</a> antes de cambiar nada nesta páxina!
|
||||
requite_db_desc=Gogs requires MySQL, PostgreSQL, SQLite3, MSSQL or TiDB.
|
||||
requite_db_desc=Gogs require MySQL, PostgreSQL, SQLite3, MSSQL ouTiDB.
|
||||
db_title=Configuración de base de datos
|
||||
db_type=Tipo de base de datos
|
||||
host=Host
|
||||
@@ -58,8 +58,8 @@ db_name=Nome da base de datos
|
||||
db_helper=Por favor, empregue o motor INNODB coa configuración de caracteres utf8_general_ci para MySQL.
|
||||
ssl_mode=Modo SSL
|
||||
path=Ruta
|
||||
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=A ruta do ficheiro da base de datos SQLite3. <br> Utilice a ruta absoluta cando arrique o servicio.
|
||||
err_empty_db_path=A ruta da base de datos SQLite3 non pode estar baleira.
|
||||
no_admin_and_disable_registration=Non pode deshabilitar o rexistro sen crear unha conta de administrador.
|
||||
err_empty_admin_password=O contrasinal de administrador non pode estar baleiro.
|
||||
|
||||
@@ -74,16 +74,16 @@ domain=Dominio
|
||||
domain_helper=Isto afecta ás URLs para clonar por SSH.
|
||||
ssh_port=Porto SSH
|
||||
ssh_port_helper=Número de porto do seu servidor SSH, déixeo en branco para desactivar 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=Utilizar Builin en Sevidor SSH
|
||||
use_builtin_ssh_server_popup=Inicia o servidor SSH integrado para que as operacións de Git sexan distintas do demonio SSH do sistema.
|
||||
http_port=Porto HTTP
|
||||
http_port_helper=Porto no que escoitará a aplicación.
|
||||
app_url=URL da aplicación
|
||||
app_url_helper=Isto afecta ás URLs para clonar por HTTP/HTTPS e a algúns correos electrónicos.
|
||||
log_root_path=Ruta do rexistro
|
||||
log_root_path_helper=Directorio onde almacenar os rexistros.
|
||||
enable_console_mode=Enable Console Mode
|
||||
enable_console_mode_popup=In addition to file mode, also print logs to console.
|
||||
enable_console_mode=Habilitar Modo Consola
|
||||
enable_console_mode_popup=Ademáis do modo de ficheiro, tamén imprime os rexistros para a consola.
|
||||
|
||||
optional_title=Configuración opcional
|
||||
email_title=Configuración do servizo de correo
|
||||
@@ -119,7 +119,8 @@ sqlite3_not_available=A túa versión non soporta SQLite3, por favor, descarga o
|
||||
invalid_db_setting=A configuración da base de datos non é correcta: %v
|
||||
invalid_repo_path=A ruta da raíz do repositorio é inválida: %v
|
||||
run_user_not_match=A persoa usuaria que está executando a aplicación non é a persoa usuaria actual: %s -> %s
|
||||
smtp_host_missing_port=SMTP Host is missing port in address.
|
||||
smtp_host_missing_port=Falta o porto do Host SMTP
|
||||
|
||||
invalid_smtp_from=O campo From do SMTP non é valido: %v
|
||||
save_config_failed=Erro ao gardar a configuración: %v
|
||||
invalid_admin_setting=A configuración da conta de administración é inválida: %v
|
||||
@@ -151,8 +152,8 @@ register_hepler_msg=Xa tes unha conta? Inicia sesión!
|
||||
social_register_hepler_msg=Xa tes unha conta? Enlázaa!
|
||||
disable_register_prompt=Sentímolo, o rexistro está deshabilitado. Por favor, contacta co administrador do sitio.
|
||||
disable_register_mail=Sentímolo. Os correos de confirmación de rexistro están deshabilitados.
|
||||
auth_source=Authentication Source
|
||||
local=Local
|
||||
auth_source=Fonte de Autenticación
|
||||
local=Configuración rexional
|
||||
remember_me=Recórdame
|
||||
forgot_password=Esquecín o meu contrasinal
|
||||
forget_password=Esqueciches o teu contrasinal?
|
||||
@@ -171,13 +172,13 @@ reset_password_helper=Prema aquí para restablecer o seu contrasinal
|
||||
password_too_short=A lonxitude do contrasinal non pode ser menor de 6.
|
||||
non_local_account=Contas que non son locais non poden cambiar os contrasinais a través de Gogs.
|
||||
|
||||
login_two_factor=Two-factor Authentication
|
||||
login_two_factor_passcode=Authentication Passcode
|
||||
login_two_factor_enter_recovery_code=Enter a two-factor recovery code
|
||||
login_two_factor_recovery=Two-factor Recovery
|
||||
login_two_factor_recovery_code=Recovery Code
|
||||
login_two_factor_enter_passcode=Enter a two-factor passcode
|
||||
login_two_factor_invalid_recovery_code=Recovery code has been used or does not valid.
|
||||
login_two_factor=Autenticación en dous pasos
|
||||
login_two_factor_passcode=Código de Autenticación
|
||||
login_two_factor_enter_recovery_code=Introduza o código de recuperación da verificación en dous pasos
|
||||
login_two_factor_recovery=Recuperación en dous pasos
|
||||
login_two_factor_recovery_code=Codigo de Recuperación
|
||||
login_two_factor_enter_passcode=Introduza o código de acceso en dous pasos
|
||||
login_two_factor_invalid_recovery_code=O código de recuperación foi usado ou non é válido.
|
||||
|
||||
[mail]
|
||||
activate_account=Por favor, activa a túa conta
|
||||
@@ -214,7 +215,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.`
|
||||
alpha_dash_dot_slash_error=` debe ser un carácter válido : numérico, alfabético, guión(-_) puntos ou barras.`
|
||||
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.`
|
||||
@@ -231,7 +232,7 @@ org_name_been_taken=Xa existe unha organización con este nome.
|
||||
team_name_been_taken=Xa existe un equipo con este nome.
|
||||
email_been_used=Este enderezo de correo electrónico xa está en uso.
|
||||
username_password_incorrect=Nome de usuario ou contrasinal incorrectos.
|
||||
auth_source_mismatch=The authentication source selected is not associated with the user.
|
||||
auth_source_mismatch=A fonte de autenticación seleccionada non está asociada co usuario.
|
||||
enterred_invalid_repo_name=Por favor, asegúrate de que introduciches correctamente o nome do repositorio.
|
||||
enterred_invalid_owner_name=Por favor, asegúrate de que introduciches correctamente o nome do propietario.
|
||||
enterred_invalid_password=Por favor, asegúrate de que introduciches correctamente o teu contrasinal.
|
||||
@@ -267,8 +268,8 @@ profile=Perfil
|
||||
password=Contrasinal
|
||||
avatar=Avatar
|
||||
ssh_keys=Claves SSH
|
||||
security=Security
|
||||
repos=Repositories
|
||||
security=Seguridade
|
||||
repos=Repositorios
|
||||
orgs=Organizacións
|
||||
applications=Aplicacións
|
||||
delete=Eliminar conta
|
||||
@@ -337,29 +338,29 @@ no_activity=Non hai actividade recente
|
||||
key_state_desc=Esta clave foi usada nos últimos 7 días
|
||||
token_state_desc=Token usado nos últimos 7 días
|
||||
|
||||
two_factor=Two-factor Authentication
|
||||
two_factor_status=Status:
|
||||
two_factor_on=On
|
||||
two_factor_off=Off
|
||||
two_factor_enable=Enable
|
||||
two_factor_disable=Disable
|
||||
two_factor=Autenticación en Dous Pasos
|
||||
two_factor_status=Estado:
|
||||
two_factor_on=Si
|
||||
two_factor_off=Non
|
||||
two_factor_enable=Activar
|
||||
two_factor_disable=Desactivar
|
||||
two_factor_view_recovery_codes=View and save <a href="%s%s">your recovery codes</a> in a safe place. You can use them as passcode if you lose access to your authentication application.
|
||||
two_factor_http=For HTTP/HTTPS operations, you are no longer able to use plain username and password. Please create and use <a href="%[1]s%[2]s">Personal Access Token</a> as your credential, e.g. <code>%[3]s</code>.
|
||||
two_factor_enable_title=Enable Two-factor Authentication
|
||||
two_factor_scan_qr=Please use your authentication application to scan the image:
|
||||
two_factor_or_enter_secret=Or enter the secret:
|
||||
two_factor_then_enter_passcode=Then enter passcode:
|
||||
two_factor_verify=Verify
|
||||
two_factor_then_enter_passcode=A continuación, introduza o código:
|
||||
two_factor_verify=Verificar
|
||||
two_factor_invalid_passcode=The passcode you entered is not valid, please try again!
|
||||
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
|
||||
two_factor_enable_error=Enable Two-factor authentication failed: %v
|
||||
two_factor_enable_success=Two-factor authentication has enabled for your account successfully!
|
||||
two_factor_recovery_codes_title=Two-factor Authentication Recovery Codes
|
||||
two_factor_recovery_codes_desc=Recovery codes are used when you temporarily lose access to your authentication application. Each recovery code can only be used once, <b>please keep these codes in a safe place</b>.
|
||||
two_factor_regenerate_recovery_codes=Regenerate Recovery Codes
|
||||
two_factor_regenerate_recovery_codes=Rexenerar Códigos de Recuperación
|
||||
two_factor_regenerate_recovery_codes_error=Regenerate recovery codes failed: %v
|
||||
two_factor_regenerate_recovery_codes_success=New recovery codes has been generated successfully!
|
||||
two_factor_disable_title=Disable Two-factor Authentication
|
||||
two_factor_disable_title=Desactivar a verificación en dous pasos
|
||||
two_factor_disable_desc=Your account security level will decrease after disabled two-factor authentication. Do you want to continue?
|
||||
two_factor_disable_success=Two-factor authentication has disabled successfully!
|
||||
|
||||
@@ -379,8 +380,8 @@ orgs.none=Non es membro de nengunha organización.
|
||||
orgs.leave_title=Deixar unha organización
|
||||
orgs.leave_desc=Deixarás de ter aceso ao tódolos repositorios e equipos despois de deixar a organización. Desexas abandonala?
|
||||
|
||||
repos.leave=Leave
|
||||
repos.leave_title=Leave repository
|
||||
repos.leave=Abandoar
|
||||
repos.leave_title=Deixar repositorio
|
||||
repos.leave_desc=You will lose access to the repository after you left. Do you want to continue?
|
||||
repos.leave_success=You have left repository '%s' successfully!
|
||||
|
||||
|
||||
@@ -1141,7 +1141,7 @@ auths.pam_service_name=PAM szolgáltatás neve
|
||||
auths.enable_auto_register=Automatikus regisztráció engedélyezése
|
||||
auths.edit=Hitelesítési beállítások szerkesztése
|
||||
auths.activated=Ez a hitelesítés mód aktiválva van
|
||||
auths.default_auth=This authentication is default login source
|
||||
auths.default_auth=Ez az alapértelmezett hitelesítési mód a bejelentkezéshez
|
||||
auths.new_success=Az új hitelesítési mód '%s' sikeresen hozzáadva.
|
||||
auths.update_success=A hitelesítési beállítások sikeresen firssítve lettek.
|
||||
auths.update=Hitelesítési forrás frissítése
|
||||
|
||||
@@ -151,8 +151,8 @@ register_hepler_msg=Sudah memiliki account? Sign in sekarang!
|
||||
social_register_hepler_msg=Sudah memiliki account? Ikat sekarang!
|
||||
disable_register_prompt=Maaf, pendaftaran telah dinonaktifkan. Hubungi administrator situs.
|
||||
disable_register_mail=Maaf, konfirmasi pendaftaran melalui email telah dinonaktifkan.
|
||||
auth_source=Authentication Source
|
||||
local=Local
|
||||
auth_source=Sumber Autentikasi
|
||||
local=Lokal
|
||||
remember_me=Ingat saya
|
||||
forgot_password=Lupa Sandi
|
||||
forget_password=Lupa sandi?
|
||||
@@ -160,7 +160,7 @@ sign_up_now=Membutuhkan akun? Daftar sekarang.
|
||||
confirmation_mail_sent_prompt=Email konfirmasi baru telah terkirim ke <b>%s</b>, silakan cek inbox Anda dalam waktu %d jam untuk menyelesaikan proses pendaftaran.
|
||||
active_your_account=Aktifkan Akun Anda
|
||||
prohibit_login=Login tidak diperbolehkan
|
||||
prohibit_login_desc=Account Anda tidak diperbolehkan untuk login, silahkan hubungi admin situs.
|
||||
prohibit_login_desc=Akun Anda tidak diperbolehkan untuk masuk, silakan hubungi admin situs.
|
||||
resent_limit_prompt=Maaf, Anda telah meminta email aktivasi beberapa saat lalu. Silakan tunggu 3 menit kemudian untuk dapat mencoba lagi.
|
||||
has_unconfirmed_mail=Hi %s, Anda memiliki alamat email yang belum terkonfirmasi (<b>%s</b>). Jika Anda belum menerima email konfirmasi atau perlu untuk mengirim ulang yang baru, silakan klik pada tombol di bawah ini.
|
||||
resend_mail=Klik di sini untuk mengirim kembali email aktivasi
|
||||
@@ -171,10 +171,10 @@ reset_password_helper=Klik di sini untuk menyetel ulang sandi
|
||||
password_too_short=Panjang sandi tidak bisa kurang dari 6 huruf.
|
||||
non_local_account=Akun non-lokal tidak dapat mengganti password lewat Gogs.
|
||||
|
||||
login_two_factor=Dua faktor otentikasi
|
||||
login_two_factor_passcode=Kode otentikasi
|
||||
login_two_factor=Autentikasi Dua Faktor
|
||||
login_two_factor_passcode=Kode Akses Autentikasi
|
||||
login_two_factor_enter_recovery_code=Masukkan kode pemulihan dua faktor
|
||||
login_two_factor_recovery=Dua faktor pemulihan
|
||||
login_two_factor_recovery=Pemulihan Dua Faktor
|
||||
login_two_factor_recovery_code=Kode pemulihan
|
||||
login_two_factor_enter_passcode=Masukkan kode akses dua faktor
|
||||
login_two_factor_invalid_recovery_code=Kode pemulihan telah digunakan atau tidak sesuai.
|
||||
@@ -231,7 +231,7 @@ org_name_been_taken=Nama organisasi telah diambil.
|
||||
team_name_been_taken=Nama tim telah diambil.
|
||||
email_been_used=Alamat email telah digunakan.
|
||||
username_password_incorrect=Nama pengguna atau sandi tidak benar.
|
||||
auth_source_mismatch=The authentication source selected is not associated with the user.
|
||||
auth_source_mismatch=Sumber autentikasi yang dipilih tidak terkait dengan pengguna.
|
||||
enterred_invalid_repo_name=Pastikan bahwa nama repositori yang Anda masukkan benar.
|
||||
enterred_invalid_owner_name=Pastikan bahwa nama pemilik yang Anda masukkan benar.
|
||||
enterred_invalid_password=Harap pastikan bahwa sandi yang Anda masukkan benar.
|
||||
@@ -240,7 +240,7 @@ last_org_owner=Menghapus pengguna terakhir dari tim pemilik tidak diperbolehkan,
|
||||
|
||||
invalid_ssh_key=Maaf, kami tidak dapat memverifikasi kunci SSH Anda: %s
|
||||
unable_verify_ssh_key=Gogs tidak dapat memverifikasi kunci SSH Anda, tetapi kita menganggap bahwa itu sah, silakan periksa kembali.
|
||||
auth_failed=Otentikasi gagal: %v
|
||||
auth_failed=Autentikasi gagal: %v
|
||||
|
||||
still_own_repo=Akun Anda masih memiliki kepemilikan atas setidaknya satu repositori, Anda harus menghapus atau mentransfernya terlebih dahulu.
|
||||
still_has_org=Akun Anda masih memiliki keanggotaan dalam setidaknya satu organisasi, Anda harus meninggalkan atau menghapus keanggotaan Anda terlebih dahulu.
|
||||
@@ -274,7 +274,7 @@ applications=Aplikasi
|
||||
delete=Menghapus akun
|
||||
|
||||
public_profile=Profil publik
|
||||
profile_desc=Alamat email Anda bersifat publik dan akan digunakan untuk setiap akun pemberitahuan terkait, dan setiap operasi berbasis web yang dilakukan melalui situs.
|
||||
profile_desc=Alamat email Anda bersifat publik dan akan digunakan untuk setiap akun yang terkait pemberitahuan dan setiap operasi berbasis web yang dilakukan melalui situs.
|
||||
password_username_disabled=Pengguna jenis bebas-lokal tidak diperbolehkan untuk mengubah nama pengguna mereka.
|
||||
full_name=Nama lengkap
|
||||
website=Situs web
|
||||
@@ -288,7 +288,7 @@ cancel=Batal
|
||||
|
||||
lookup_avatar_by_mail=Cari avatar dari email
|
||||
federated_avatar_lookup=Aktifkan Pencarian Avatar Representasi
|
||||
enable_custom_avatar=Mengaktifkan avatar kustom
|
||||
enable_custom_avatar=Gunakan Avatar Kostum
|
||||
choose_new_avatar=Pilih avatar baru
|
||||
update_avatar=Ubah pengaturan avatar
|
||||
delete_current_avatar=Hapus avatar terkini
|
||||
@@ -320,7 +320,7 @@ add_email_success=Alamat email barumu telah berhasil ditambahkan.
|
||||
manage_ssh_keys=Kelola Kunci SSH
|
||||
add_key=Tambah kunci
|
||||
ssh_desc=Ini adalah daftar kunci SSH yang terkait dengan akun Anda. Karena kunci ini memungkinkan seseorang menggunakannya untuk mendapatkan akses ke repositori Anda, sangat penting bagi Anda untuk memastikan Anda mengenalinya.
|
||||
ssh_helper=<strong>Nggak tau gimana?</strong> Cek arahannya GitHub buat<a href="%s">bikin kunci SSH-mu sendiri</a> atau benerin <a href="%s">masalah yang umum</a> yang mungkin sedang kamu alami dengan SSH-mu.
|
||||
ssh_helper=<strong>Tidak tahu caranya?</strong> Kunjungi petunjuk GitHub untuk <a href="%s">membuat kunci SSH Anda sendiri</a> atau perbaiki <a href="%s">masalah umum</a> yang mungkin sedang Anda alami dengan SSH.
|
||||
add_new_key=Tambah kunci SSH
|
||||
ssh_key_been_used=Public key telah digunakan.
|
||||
ssh_key_name_used=Public key dengan nama itu udah pernah ada.
|
||||
@@ -337,7 +337,7 @@ no_activity=Tidak ada aktifitas terakhir
|
||||
key_state_desc=Kunci ini digunakan dalam 7 hari terakhir
|
||||
token_state_desc=Token ini digunakan dalam 7 hari terakhir
|
||||
|
||||
two_factor=Otentikasi dua faktor
|
||||
two_factor=Autentikasi dua faktor
|
||||
two_factor_status=Status:
|
||||
two_factor_on=Nyala
|
||||
two_factor_off=Mati
|
||||
@@ -345,21 +345,21 @@ two_factor_enable=Aktifkan
|
||||
two_factor_disable=Nonaktifkan
|
||||
two_factor_view_recovery_codes=Lihat dan simpan <a href="%s%s"> kode pemulihan anda</a> di tempat yang aman. Anda dapat menggunakannya sebagai kode akses jika Anda kehilangan akses otentikasi aplikasi.
|
||||
two_factor_http=Untuk operasi HTTP/HTTPS, Anda tidak lagi mampu menggunakan nama pengguna dan kata sandi. Silakan membuat dan menggunakan <a href="%[1]s%[2]s"> Token akses pribadi</a> sebagai kredensial Anda, misalnya <code>%[3]s</code>.
|
||||
two_factor_enable_title=Aktifkan Otentikasi Dua-faktor
|
||||
two_factor_enable_title=Aktifkan Autentikasi Dua Faktor
|
||||
two_factor_scan_qr=Silakan gunakan aplikasi autentikasi Anda untuk memindai gambar:
|
||||
two_factor_or_enter_secret=Atau masukkan rahasianya:
|
||||
two_factor_then_enter_passcode=Masukan kode akses:
|
||||
two_factor_then_enter_passcode=Kemudian, masukkan kode akses:
|
||||
two_factor_verify=Verifikasi
|
||||
two_factor_invalid_passcode=Kode akses yang Anda masukan tidak sah, silahkan coba lagi!
|
||||
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
|
||||
two_factor_enable_error=Aktifkan Autentikasi dua faktor gagal: %v
|
||||
two_factor_enable_success=Autentikasi dua faktor telah memungkinkan akun Anda berhasil!
|
||||
two_factor_recovery_codes_title=Kode Pemulihan Otentikasi dua faktor
|
||||
two_factor_invalid_passcode=Kode akses yang Anda masukkan tidak sah, silakan coba lagi!
|
||||
two_factor_reused_passcode=Kode akses yang Anda masukkan sudah digunakan, coba yang lain!
|
||||
two_factor_enable_error=Gagal mengaktifkan autentikasi Dua Faktor: %v
|
||||
two_factor_enable_success=Autentikasi Dua faktor untuk akun Anda berhasil diaktifkan!
|
||||
two_factor_recovery_codes_title=Kode Pemulihan Autentikasi Dua Faktor
|
||||
two_factor_recovery_codes_desc=Kode pemulihan digunakan saat Anda sementara kehilangan akses ke aplikasi autentikasi Anda. Setiap kode pemulihan hanya dapat digunakan satu kali, <b> simpan kode ini di tempat yang aman </ b>.
|
||||
two_factor_regenerate_recovery_codes=Regenerate Recovery Codes
|
||||
two_factor_regenerate_recovery_codes_error=Regenerasi kode pemulihan gagal: %v
|
||||
two_factor_regenerate_recovery_codes_success=Kode pemulihan baru telah berhasil dibuat!
|
||||
two_factor_disable_title=Nonaktifkan Otentikasi Dua Faktor
|
||||
two_factor_disable_title=Nonaktifkan Autentikasi Dua Faktor
|
||||
two_factor_disable_desc=Tingkat keamanan akun Anda akan menurun setelah autentikasi dua faktor dinonaktifkan. Apakah Anda ingin melanjutkan?
|
||||
two_factor_disable_success=Autentikasi dua faktor telah berhasil dilakukan!
|
||||
|
||||
@@ -422,7 +422,7 @@ watchers=Watchers
|
||||
stargazers=Stargazers
|
||||
forks=Forks
|
||||
repo_description_helper=Description of repository. Maximum 512 characters length.
|
||||
repo_description_length=Available characters
|
||||
repo_description_length=Karakter tersedia
|
||||
|
||||
form.reach_limit_of_creation=Pemiliknya telah mencapai batas pembuatan maksimum %d repositori.
|
||||
form.name_reserved=Nama repositori '%s' dicadangkan.
|
||||
@@ -520,7 +520,7 @@ editor.file_changed_while_editing=Konten file telah berubah sejak Anda mulai men
|
||||
editor.file_already_exists=File dengan nama '%s' sudah ada di repositori ini.
|
||||
editor.no_changes_to_show=Tidak ada perubahan untuk ditunjukkan.
|
||||
editor.fail_to_update_file=Gagal memperbarui / membuat file '%s' dengan error: %v
|
||||
editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
|
||||
editor.fail_to_delete_file=Gagal menghapus file '%s' dengan error: %v
|
||||
editor.add_subdir=Tambahkan subdirektori...
|
||||
editor.unable_to_upload_files=Gagal mengunggah file ke '%s' dengan kesalahan: %v
|
||||
editor.upload_files_to_dir=Upload file ke '%s'
|
||||
@@ -641,7 +641,7 @@ pulls.cannot_auto_merge_desc=Permintaan tarik ini tidak bisa digabungkan secara
|
||||
pulls.cannot_auto_merge_helper=Silahkan bergabung secara manual untuk menyelesaikan konflik.
|
||||
pulls.create_merge_commit=Membuat komit penggabungan
|
||||
pulls.rebase_before_merging=Rebase sebelum penggabungan
|
||||
pulls.commit_description=Commit Description
|
||||
pulls.commit_description=Deskripsi Commit
|
||||
pulls.merge_pull_request=Permintaan tarik gabungan
|
||||
pulls.open_unmerged_pull_exists='Anda tidak dapat melakukan operasi membuka kembali karena sudah ada permintaan tarik terbuka (#%d) dari repositori yang sama dengan penggabungan informasi yang sama dan menunggu penggabungan. '
|
||||
pulls.delete_branch=Menghapus cabang
|
||||
@@ -992,7 +992,7 @@ dashboard=Dasbor
|
||||
users=Pengguna
|
||||
organizations=Organisasi
|
||||
repositories=Repositori
|
||||
authentication=Otentikasi
|
||||
authentication=Autentikasi
|
||||
config=Konfigurasi
|
||||
notices=Pemberitahuan sistem
|
||||
monitor=Pemantauan
|
||||
@@ -1064,16 +1064,16 @@ users.created=Dibuat
|
||||
users.send_register_notify=Kirim Pemberitahuan Pendaftaran ke Pengguna
|
||||
users.new_success=Akun baru '%s' telah berhasil dibuat.
|
||||
users.edit=Edit
|
||||
users.auth_source=Sumber Otentikasi
|
||||
users.auth_source=Sumber Autentikasi
|
||||
users.local=Lokal
|
||||
users.auth_login_name=Nama login otentikasi
|
||||
users.auth_login_name=Nama Masuk Autentikasi
|
||||
users.password_helper=Biarkan kosong agar tetap tidak berubah.
|
||||
users.update_profile_success=Profil akun telah berhasil diupdate.
|
||||
users.edit_account=Mengedit akun
|
||||
users.max_repo_creation=Maximum Repository Creation Limit
|
||||
users.max_repo_creation_desc=(Set -1 untuk menggunakan batas default global)
|
||||
users.is_activated=Akun ini diaktifkan
|
||||
users.prohibit_login=Akun ini dilarang masuk
|
||||
users.prohibit_login=Akun ini tidak diperbolekan masuk
|
||||
users.is_admin=Akun ini memiliki izin administrator
|
||||
users.allow_git_hook=Akun ini memiliki izin untuk membuat kait Git
|
||||
users.allow_import_local=Akun ini memiliki izin untuk mengimpor repositori lokal
|
||||
@@ -1097,7 +1097,7 @@ repos.stars=Bintang
|
||||
repos.issues=Masalah
|
||||
repos.size=Ukuran
|
||||
|
||||
auths.auth_sources=Authentication Sources
|
||||
auths.auth_sources=Sumber Autentikasi
|
||||
auths.new=Tambahkan Sumber Baru
|
||||
auths.name=Nama
|
||||
auths.type=Mengetik
|
||||
@@ -1105,7 +1105,7 @@ auths.enabled=Diaktifkan
|
||||
auths.default=Default
|
||||
auths.updated=Diperbarui
|
||||
auths.auth_type=Jenis Autentikasi
|
||||
auths.auth_name=Nama Otentikasi
|
||||
auths.auth_name=Nama Autentikasi
|
||||
auths.security_protocol=Protokol Keamanan
|
||||
auths.domain=Domain
|
||||
auths.host=Tuan rumah
|
||||
@@ -1130,7 +1130,7 @@ auths.attributes_in_bind=Ambil atribut dalam konteks Bind DN
|
||||
auths.filter=Pengguna saringan
|
||||
auths.admin_filter=Admin Filter
|
||||
auths.ms_ad_sa=Ms Ad SA
|
||||
auths.smtp_auth=SMTP Authentication Type
|
||||
auths.smtp_auth=Autentikasi tipe SMTP
|
||||
auths.smtphost=Host SMTP
|
||||
auths.smtpport=Port SMTP
|
||||
auths.allowed_domains=Domains di izinkan
|
||||
@@ -1139,18 +1139,18 @@ auths.enable_tls=Enable TLS Encryption
|
||||
auths.skip_tls_verify=Skip TLS Verify
|
||||
auths.pam_service_name=Nama layanan PAM
|
||||
auths.enable_auto_register=Mengaktifkan pendaftaran otomatis
|
||||
auths.edit=Mengubah pengaturan pembuktian
|
||||
auths.activated=This authentication is activated
|
||||
auths.default_auth=This authentication is default login source
|
||||
auths.new_success=New authentication '%s' has been added successfully.
|
||||
auths.update_success=Authentication setting has been updated successfully.
|
||||
auths.update=Memperbarui pengetahuan otentikasi
|
||||
auths.delete=Hapus otentikasi ini
|
||||
auths.delete_auth_title=Authentication Deletion
|
||||
auths.delete_auth_desc=Otentikasi ini akan dihapus, apakah anda ingin melanjutkan?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Authentication has been deleted successfully!
|
||||
auths.login_source_exist=Login source '%s' already exists.
|
||||
auths.edit=Ubah Pengaturan Autentikasi
|
||||
auths.activated=Autentikasi ini diaktifkan
|
||||
auths.default_auth=Autentikasi ini adalah sumber masuk bawaan
|
||||
auths.new_success=Autentikasi baru %s berhasil ditambahkan.
|
||||
auths.update_success=Pengaturan autentikasi berhasil diperbarui.
|
||||
auths.update=Perbarui Pengaturan Autentikasi
|
||||
auths.delete=Hapus Autentikasi Ini
|
||||
auths.delete_auth_title=Penghapusan Autentikasi
|
||||
auths.delete_auth_desc=Autentikasi ini akan dihapus, apakah Anda ingin melanjutkan?
|
||||
auths.still_in_used=Autentikasi ini masih digunakan oleh pengguna lain, silakan hapus atau ubah pengguna tersebut ke tipe masuk lainnya.
|
||||
auths.deletion_success=Autentikasi berhasil dihapus!
|
||||
auths.login_source_exist=Sumber masuk %s sudah tersedia.
|
||||
|
||||
config.not_set=(tidak diterapkan)
|
||||
config.server_config=Server Configuration
|
||||
@@ -1165,7 +1165,7 @@ config.run_mode=Run Mode
|
||||
config.git_version=Git Version
|
||||
config.static_file_root_path=Static File Root Path
|
||||
config.log_file_root_path=Log File Root Path
|
||||
config.reverse_auth_user=Reverse Authentication User
|
||||
config.reverse_auth_user=Mengembalikan Pengguna Autentikasi
|
||||
|
||||
config.ssh_config=SSH Configuration
|
||||
config.ssh_enabled=Diaktifkan
|
||||
|
||||
@@ -174,10 +174,10 @@ non_local_account=Gli account non locali non possono modificare le password tram
|
||||
login_two_factor=Autenticazione in Due Passaggi
|
||||
login_two_factor_passcode=Codice di autenticazione
|
||||
login_two_factor_enter_recovery_code=Inserisci il codice di recupero dell'Autenticazione a due Fattori
|
||||
login_two_factor_recovery=Two-factor Recovery
|
||||
login_two_factor_recovery=Recupero a due fattori
|
||||
login_two_factor_recovery_code=Recupera il codice
|
||||
login_two_factor_enter_passcode=Enter a two-factor passcode
|
||||
login_two_factor_invalid_recovery_code=Recovery code has been used or does not valid.
|
||||
login_two_factor_enter_passcode=Inserisci un codice di accesso a due fattori
|
||||
login_two_factor_invalid_recovery_code=Il codice di recupero è stato utilizzato o non è valido.
|
||||
|
||||
[mail]
|
||||
activate_account=Per favore attiva il tuo account
|
||||
@@ -214,7 +214,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.`
|
||||
alpha_dash_dot_slash_error=` ammessi solo caratteri alfanumerici o trattini(-_) o punti o slash.`
|
||||
size_error='deve essere %s.'
|
||||
min_size_error=` deve contenere almeno %s caratteri.`
|
||||
max_size_error=` deve contenere massimo %s caratteri.`
|
||||
@@ -231,7 +231,7 @@ org_name_been_taken=Il nome dell'Organizzazione è già utlizzato.
|
||||
team_name_been_taken=Il nome del Team è già utilizzato.
|
||||
email_been_used=L'indirizzo E-mail è già utilizzato.
|
||||
username_password_incorrect=Nome utente o password incorretti.
|
||||
auth_source_mismatch=The authentication source selected is not associated with the user.
|
||||
auth_source_mismatch=La sorgente di autenticazione selezionata non è associata all'utente.
|
||||
enterred_invalid_repo_name=Si prega di assicurarsi che il nome del repository inserito sia corretto.
|
||||
enterred_invalid_owner_name=Si prega di assicurarsi che il nome del proprietario inserito sia corretto.
|
||||
enterred_invalid_password=Verificare che la password inserita sia corretta.
|
||||
@@ -344,7 +344,7 @@ two_factor_off=Non attivo
|
||||
two_factor_enable=Abilita
|
||||
two_factor_disable=Disattivata
|
||||
two_factor_view_recovery_codes=Visualizza e memorizza i tuoi <a href="%s%s">codici di recupero</a> in un posto sicuro. Puoi utilizzarli come codice di sicurezza se perdi gli accessi all'applicazione di autenticazione.
|
||||
two_factor_http=For HTTP/HTTPS operations, you are no longer able to use plain username and password. Please create and use <a href="%[1]s%[2]s">Personal Access Token</a> as your credential, e.g. <code>%[3]s</code>.
|
||||
two_factor_http=Per le operazioni HTTP/HTTPS, non sei più in grado di utilizzare nome utente e password. Si prega di creare e utilizzare <a href="%[1]s%[2]s">Token di accesso personale</a> come credenziali, ad esempio. <code>%[3]s</code>.
|
||||
two_factor_enable_title=Abilita l'autenticazione in due passaggi
|
||||
two_factor_scan_qr=Per favore, utilizza la tua applicazione di autenticazione per scansionare l'immagine:
|
||||
two_factor_or_enter_secret=O inserisci la chiave segreta:
|
||||
@@ -353,9 +353,9 @@ two_factor_verify=Verifica
|
||||
two_factor_invalid_passcode=La chiave di sicurezza che hai inserito non è valida, riprova!
|
||||
two_factor_reused_passcode=La chiave di sicurezza che hai inserito è già stata utilizzata, provane un'altra!
|
||||
two_factor_enable_error=Impossibile abilitare l'autenticazione a due fattori: %v
|
||||
two_factor_enable_success=Two-factor authentication has enabled for your account successfully!
|
||||
two_factor_recovery_codes_title=Two-factor Authentication Recovery Codes
|
||||
two_factor_recovery_codes_desc=Recovery codes are used when you temporarily lose access to your authentication application. Each recovery code can only be used once, <b>please keep these codes in a safe place</b>.
|
||||
two_factor_enable_success=Autenticazione a due fattori abilitata per il tuo account con successo!
|
||||
two_factor_recovery_codes_title=Codici di recupero autenticazione a due fattori
|
||||
two_factor_recovery_codes_desc=I codici di recupero vengono utilizzati quando si perde temporaneamente l'accesso all'applicazione di autenticazione. Ogni codice di recupero può essere utilizzato solo una volta, <b>si prega di mantenere questi codici in un posto sicuro</b>.
|
||||
two_factor_regenerate_recovery_codes=Rigenera codici di recupero
|
||||
two_factor_regenerate_recovery_codes_error=Impossibile rigenerare codici di recupero: %v
|
||||
two_factor_regenerate_recovery_codes_success=I nuovi codici di recupero sono stati generati correttamente!
|
||||
@@ -381,8 +381,8 @@ orgs.leave_desc=Abbandonando l'organizzazione perderai l'accesso a tutti i repos
|
||||
|
||||
repos.leave=Abbandona
|
||||
repos.leave_title=Lascia il repository
|
||||
repos.leave_desc=You will lose access to the repository after you left. Do you want to continue?
|
||||
repos.leave_success=You have left repository '%s' successfully!
|
||||
repos.leave_desc=Perderai l'accesso al repository dopo che hai lasciato. Vuoi continuare?
|
||||
repos.leave_success=Hai lasciato il repository '%s' con successo!
|
||||
|
||||
delete_account=Elimina Account
|
||||
delete_prompt=L'operazione eliminerà permanentemente l'account e <strong>NON POTRÀ</strong> essere annullata!
|
||||
|
||||
@@ -14,10 +14,10 @@ page=ページ
|
||||
template=テンプレート
|
||||
language=言語
|
||||
create_new=作成...
|
||||
user_profile_and_more=ユーザープロファイルなど
|
||||
user_profile_and_more=ユーザープロフィールなど
|
||||
signed_in_as=サインイン済み
|
||||
|
||||
username=ユーザ名
|
||||
username=ユーザー名
|
||||
email=メールアドレス
|
||||
password=パスワード
|
||||
re_type=再入力
|
||||
@@ -52,13 +52,13 @@ requite_db_desc=Gogs は、MySQL、PostgreSQL、SQLite3 または TiDB が必要
|
||||
db_title=データベース設定
|
||||
db_type=データベースの種類
|
||||
host=ホスト
|
||||
user=ユーザ
|
||||
user=ユーザー
|
||||
password=パスワード
|
||||
db_name=データベース名
|
||||
db_helper=MySQLではエンジンがINNODB、文字セットがutf8_general_ciである必要があります。
|
||||
ssl_mode=SSL モード
|
||||
path=パス
|
||||
sqlite_helper=SQLite3データベースのファイルパスです。<br>serviceとして起動する場合は、絶対パスを使用してください。
|
||||
sqlite_helper=SQLite3かTiDBのデータベースのファイルパス。<br>サービスとして開始する際には絶対パスを利用してください。
|
||||
err_empty_db_path=SQLite3 データベースのPATHを空にすることはできません。
|
||||
no_admin_and_disable_registration=管理者アカウントを作成せずに登録を無効にすることはできません。
|
||||
err_empty_admin_password=管理者パスワードは空白にできません。
|
||||
@@ -68,7 +68,7 @@ app_name=アプリケーション名
|
||||
app_name_helper=素晴らしい組織名を入れてください!
|
||||
repo_path=リポジトリのルートパス
|
||||
repo_path_helper=すべての Git リモート リポジトリはこのディレクトリに保存されます。
|
||||
run_user=実行ユーザ
|
||||
run_user=実行ユーザー
|
||||
run_user_helper=ユーザーはリポジトリのルートパスへのアクセス権限、及び Gogs の実行権限を持っている必要があります。
|
||||
domain=ドメイン
|
||||
domain_helper=これはSSH用クローンURLに影響します。
|
||||
@@ -109,7 +109,7 @@ require_sign_in_view=サインインしたユーザのみページ閲覧を許
|
||||
require_sign_in_view_popup=サインインしたユーザのみがページを閲覧できます。ビジターはサインインもしくはサインアップページのみ見られます。
|
||||
admin_setting_desc=今管理者アカウントを作成する必要はありません。ID = 1のユーザ は自動的に管理者の権限を獲得します。
|
||||
admin_title=管理者アカウントの設定
|
||||
admin_name=ユーザ名
|
||||
admin_name=ユーザー名
|
||||
admin_password=パスワード
|
||||
confirm_password=パスワード確認
|
||||
admin_email=管理者の電子メール
|
||||
@@ -118,7 +118,7 @@ test_git_failed='Git' コマンドテストに失敗: %v
|
||||
sqlite3_not_available=このリリース バージョンは SQLite3 をサポートしていません。gobuild バージョンではない、公式のバイナリ バージョンを %s からダウンロードしてください。
|
||||
invalid_db_setting=データベースの設定が正しくありません: %v
|
||||
invalid_repo_path=リポジトリのルートパスが無効です: %v
|
||||
run_user_not_match=実行ユーザーは、現在のユーザーではない: %s-> %s
|
||||
run_user_not_match=実行ユーザーは現在のユーザーではありません: %s -> %s
|
||||
smtp_host_missing_port=SMTPホストのポートが見つかりません。
|
||||
invalid_smtp_from=SMTP From フィールドの値が有効ではありません: %v
|
||||
save_config_failed=構成の保存に失敗した: %v
|
||||
@@ -129,7 +129,7 @@ invalid_log_root_path=ログのルートパスがむこうです: %v
|
||||
[home]
|
||||
uname_holder=ユーザー名またはEメール
|
||||
password_holder=パスワード
|
||||
switch_dashboard_context=ダッシュ ボードのコンテキストを切替
|
||||
switch_dashboard_context=ダッシュボードコンテキストの切替
|
||||
my_repos=自分のリポジトリ
|
||||
show_more_repos=リポジトリをさらに表示…
|
||||
collaborative_repos=共同リポジトリ
|
||||
@@ -141,7 +141,7 @@ issues.in_your_repos=あなたのリポジトリ
|
||||
|
||||
[explore]
|
||||
repos=リポジトリ
|
||||
users=ユーザ
|
||||
users=ユーザー
|
||||
organizations=組織
|
||||
search=検索
|
||||
|
||||
@@ -260,7 +260,7 @@ follow=フォロー
|
||||
unfollow=フォロー解除
|
||||
|
||||
form.name_reserved=ユーザー名 '%s' は使用されています。
|
||||
form.name_pattern_not_allowed=ユーザ名のパターン '%s' は許可されていません。
|
||||
form.name_pattern_not_allowed=ユーザー名のパターン '%s' は許可されていません。
|
||||
|
||||
[settings]
|
||||
profile=プロフィール
|
||||
@@ -275,7 +275,7 @@ delete=アカウントを削除
|
||||
|
||||
public_profile=パブリック プロフィール
|
||||
profile_desc=あなたのメールアドレスは公開され、任意のアカウント関連の通知に使用されます。また、Webベースの操作はサイトを介して行います。
|
||||
password_username_disabled=ローカルユーザ以外はユーザ名を変更できません。
|
||||
password_username_disabled=ローカルユーザー以外はユーザー名を変更できません。
|
||||
full_name=フルネーム
|
||||
website=WEBサイト
|
||||
location=ロケーション
|
||||
@@ -301,7 +301,7 @@ new_password=新しいパスワード
|
||||
retype_new_password=新しいパスワードを再入力します。
|
||||
password_incorrect=現在のパスワードが正しくありません。
|
||||
change_password_success=パスワードが正常に変更されました。今すぐ新しいパスワードを使用してサインインすることができます。
|
||||
password_change_disabled=ローカルユーザ以外はパスワードを変更できません。
|
||||
password_change_disabled=ローカルユーザー以外はパスワードを変更できません。
|
||||
|
||||
emails=メールアドレス
|
||||
manage_emails=メールアドレスを管理
|
||||
@@ -351,7 +351,7 @@ two_factor_or_enter_secret=またはシークレットを入力:
|
||||
two_factor_then_enter_passcode=パスコードを入力してください:
|
||||
two_factor_verify=確認
|
||||
two_factor_invalid_passcode=入力されたパスコードは使用できません。もう一度お試しください。
|
||||
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
|
||||
two_factor_reused_passcode=入力したパスコードは既に使用されています。別のパスコードを試してください。
|
||||
two_factor_enable_error=2段階認証の有効化に失敗しました: %v
|
||||
two_factor_enable_success=2段階認証があなたのアカウントで有効化されました!
|
||||
two_factor_recovery_codes_title=2段階認証のリカバリーコード
|
||||
@@ -416,13 +416,13 @@ mirror_prune=Prune
|
||||
mirror_prune_desc=リモートに存在しないリモート追跡参照を削除する
|
||||
mirror_interval=ミラー 間隔(時)
|
||||
mirror_address=ミラー アドレス
|
||||
mirror_address_desc=アドレスに必要なユーザーの資格情報を入力してください。
|
||||
mirror_address_desc=必要なユーザー資格情報をアドレスに含めてください。
|
||||
mirror_last_synced=最終同期
|
||||
watchers=ウォッチャー
|
||||
stargazers=スターゲイザー
|
||||
forks=フォーク
|
||||
repo_description_helper=Description of repository. Maximum 512 characters length.
|
||||
repo_description_length=Available characters
|
||||
repo_description_helper=リポジトリの説明 (512文字以内)
|
||||
repo_description_length=利用可能な文字
|
||||
|
||||
form.reach_limit_of_creation=リポジトリの最大作成数 %d にすでに達しています。
|
||||
form.name_reserved=リポジトリ名 '%s' は使用されています。
|
||||
@@ -445,11 +445,11 @@ copy_link=コピー
|
||||
copy_link_success=コピーされました!
|
||||
copy_link_error=⌘ C または Ctrl-C キーを押してコピー
|
||||
copied=コピー成功
|
||||
unwatch=Unwatch
|
||||
watch=Watch
|
||||
unstar=Unstar
|
||||
star=Star
|
||||
fork=Fork
|
||||
unwatch=ウォッチ解除
|
||||
watch=ウォッチ
|
||||
unstar=スターを外す
|
||||
star=スター
|
||||
fork=フォーク
|
||||
|
||||
no_desc=説明なし
|
||||
quick_guide=クイック ガイド
|
||||
@@ -520,7 +520,7 @@ editor.file_changed_while_editing=あなたが編集を開始してから、フ
|
||||
editor.file_already_exists=ファイル名 '%s' は、このリポジトリに既に存在します。
|
||||
editor.no_changes_to_show=表示する変更箇所はありません。
|
||||
editor.fail_to_update_file=ファイル '%s' の作成/更新に失敗しました: %v
|
||||
editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
|
||||
editor.fail_to_delete_file=ファイル '%s' エラーを削除できませんでした: %v
|
||||
editor.add_subdir=サブディレクトリを追加...
|
||||
editor.unable_to_upload_files='%s' へのファイルアップロード中にエラーが発生し、失敗しました: %v
|
||||
editor.upload_files_to_dir='%s' にファイルをアップロード
|
||||
@@ -633,7 +633,7 @@ pulls.tab_commits=コミット
|
||||
pulls.tab_files=変更されたファイル
|
||||
pulls.reopen_to_merge=マージ操作を実行するには、このプルリクエストを再び開いてください。
|
||||
pulls.merged=マージされた
|
||||
pulls.has_merged=このプルプルリクエストは正常にマージされました!
|
||||
pulls.has_merged=このプルリクエストは正常にマージされました!
|
||||
pulls.data_broken=フォーク情報の削除によってこのプルリクエストのデータは壊れています。
|
||||
pulls.is_checking=コンフリクトが発生していないかチェック中です、しばらく待ったのちページを更新してください。
|
||||
pulls.can_auto_merge_desc=このプルリクエストは自動的にマージできます。
|
||||
@@ -641,7 +641,7 @@ pulls.cannot_auto_merge_desc=コンフリクトが発生しているため、こ
|
||||
pulls.cannot_auto_merge_helper=競合を解決するためには、手動でマージする必要があります。
|
||||
pulls.create_merge_commit=マージコミットを作成する
|
||||
pulls.rebase_before_merging=マージする前に再配置します。
|
||||
pulls.commit_description=Commit Description
|
||||
pulls.commit_description=コミットの説明
|
||||
pulls.merge_pull_request=プルリクエストをマージします。
|
||||
pulls.open_unmerged_pull_exists=`同じリポジトリに同じマージ情報持つ未解決のプルリクエスト (#%d) が存在するため再び開くことができません。`
|
||||
pulls.delete_branch=ブランチの削除
|
||||
@@ -746,7 +746,7 @@ settings.tracker_issue_style=外部課題トラッキングシステムの命名
|
||||
settings.tracker_issue_style.numeric=数値
|
||||
settings.tracker_issue_style.alphanumeric=英数字
|
||||
settings.tracker_url_format_desc=ユーザー名、リポジトリ名、課題番号を埋め込むために <code>{user} {repo} {index}</code> が使用できます。
|
||||
settings.pulls_desc=Enable pull requests to accept contributions between repositories and branches
|
||||
settings.pulls_desc=プルリクエストを有効にし、リポジトリとブランチ間のコントリビューションを受け入れる
|
||||
settings.pulls.ignore_whitespace=空白の変更を無視する
|
||||
settings.pulls.allow_rebase_merge=コミットをマージするためのリベースの使用を許可する
|
||||
settings.danger_zone=危険地帯
|
||||
@@ -758,7 +758,7 @@ settings.convert_notices_1=- この操作によりリポジトリはミラーリ
|
||||
settings.convert_confirm=変更を確認
|
||||
settings.convert_succeed=リポジトリは正常に通常リポジトリへ変更されました。
|
||||
settings.transfer=オーナー移転
|
||||
settings.transfer_desc=リポジトリをあなたが管理者権限を持っている別のユーザーまた組織に移譲します。
|
||||
settings.transfer_desc=このリポジトリを、別のユーザーまたはあなたが管理者権限を所持している組織に委譲します。
|
||||
settings.transfer_notices_1=-新しい所有者が個人ユーザーの場合、あなたがアクセスできなくなります。
|
||||
settings.transfer_notices_2=- 新しい所有者が組織で、あなたがその組織の所有者である場合はアクセス権が残ります。
|
||||
settings.transfer_form_title=操作を確認するために、以下の情報を入力してください。
|
||||
@@ -810,7 +810,7 @@ settings.payload_url=ペイロードの URL
|
||||
settings.content_type=コンテンツ タイプ
|
||||
settings.secret=秘密
|
||||
settings.secret_desc=秘密キーは、 <code>X-Gogs-Signature</code> ヘッダーを介してペイロードの HMAC SHA256 六角ダイジェストとして送信されます。
|
||||
settings.slack_username=ユーザ名
|
||||
settings.slack_username=ユーザー名
|
||||
settings.slack_icon_url=アイコン URL
|
||||
settings.slack_color=カラー
|
||||
settings.event_desc=どのイベントをこの Webhook のトリガーにしますか?
|
||||
@@ -860,8 +860,8 @@ settings.add_key_success=新しいデプロイキー '%s'が正常に追加さ
|
||||
settings.deploy_key_deletion=デプロイキーを削除
|
||||
settings.deploy_key_deletion_desc=このデプロイキーを削除すると、このリポジトリに関連するすべてのアクセス権も削除されます。続行しますか。
|
||||
settings.deploy_key_deletion_success=デプロイキーが正常に削除された!
|
||||
settings.description_desc=Description of repository. Maximum 512 characters length.
|
||||
settings.description_length=Available characters
|
||||
settings.description_desc=リポジトリの説明(512文字以内)
|
||||
settings.description_length=利用可能な文字
|
||||
|
||||
diff.browse_source=ソースを参照
|
||||
diff.parent=親
|
||||
@@ -989,7 +989,7 @@ teams.add_nonexistent_repo=追加しようとしているリポジトリは存
|
||||
|
||||
[admin]
|
||||
dashboard=ダッシュボード
|
||||
users=ユーザ
|
||||
users=ユーザー
|
||||
organizations=組織
|
||||
repositories=リポジトリ
|
||||
authentication=認証
|
||||
@@ -1003,7 +1003,7 @@ total=合計: %d
|
||||
dashboard.statistic=統計
|
||||
dashboard.operations=操作
|
||||
dashboard.system_status=システム モニターのステータス
|
||||
dashboard.statistic_info=Gogs データベースは <b>%d</b> ユーザー, <b>%d</b> 組織, <b>%d</b> 公開鍵, <b>%d</b> リポジトリ, <b>%d</b> ウォッチ, <b>%d</b> スター, <b>%d</b> 行動, <b>%d</b> アクセス, <b>%d</b> 課題, <b>%d</b> コメント, <b>%d</b> ソーシャルアカウント, <b>%d</b> フォロー, <b>%d</b> ミラー, <b>%d</b> リリース, <b>%d</b> ログイン元, <b>%d</b> webhook, <b>%d</b> マイルストーン, <b>%d</b> ラベル, <b>%d</b> フックタスク, <b>%d</b> チーム, <b>%d</b> アップデートタスク, <b>%d</b> 添付ファイル の情報を持っています。
|
||||
dashboard.statistic_info=Gogs データベースは <b>%d</b> 人のユーザー、<b>%d</b> 個の組織、<b>%d</b> 個の公開鍵、<b>%d</b> 個のリポジトリ、<b>%d</b> 個のウォッチ、<b>%d</b> 個のスター、<b>%d</b> 回のアクション、<b>%d</b> 回のアクセス、<b>%d</b> 個の課題、<b>%d</b> 個のコメント、<b>%d</b> 個のソーシャルアカウント、<b>%d</b> 個のフォロー、<b>%d</b> 個のミラー、<b>%d</b> 個のリリース、<b>%d</b> 個のログイン元、<b>%d</b> 個のwebフック、<b>%d</b> 個のマイルストーン、<b>%d</b> 個のラベル、<b>%d</b> 個のフックタスク、<b>%d</b> 個のチーム、<b>%d</b> 更新タスク、<b>%d</b> 個の添付ファイルの情報を保持しています。
|
||||
dashboard.operation_name=操作の名前
|
||||
dashboard.operation_switch=スイッチ
|
||||
dashboard.operation_run=実行
|
||||
@@ -1092,17 +1092,17 @@ repos.repo_manage_panel=リポジトリの管理パネル
|
||||
repos.owner=オーナー
|
||||
repos.name=名前
|
||||
repos.private=非公開
|
||||
repos.watches=Watches
|
||||
repos.stars=Stars
|
||||
repos.watches=ウォッチ
|
||||
repos.stars=スター
|
||||
repos.issues=課題
|
||||
repos.size=容量
|
||||
|
||||
auths.auth_sources=Authentication Sources
|
||||
auths.auth_sources=認証ソース
|
||||
auths.new=新しいソースを追加
|
||||
auths.name=名前
|
||||
auths.type=タイプ
|
||||
auths.enabled=有効
|
||||
auths.default=Default
|
||||
auths.default=デフォルト
|
||||
auths.updated=更新しました
|
||||
auths.auth_type=認証タイプ
|
||||
auths.auth_name=認証名
|
||||
@@ -1114,7 +1114,7 @@ auths.bind_dn=バインド DN
|
||||
auths.bind_dn_helper='%s'はユーザー名のプレースホルダとして使用できます。 例)DOM \%s
|
||||
auths.bind_password=バインド パスワード
|
||||
auths.bind_password_helper=警告: このパスワードは暗号化されずに格納されます。特権を持つアカウントに使用しないでください。
|
||||
auths.user_base=ユーザ検索ベース
|
||||
auths.user_base=ユーザー検索ベース
|
||||
auths.user_dn=User DN
|
||||
auths.attribute_username=ユーザー名属性
|
||||
auths.attribute_username_placeholder=ログインフォームの値を使う場合は空にしてください。
|
||||
@@ -1127,7 +1127,7 @@ auths.group_filter=グループ フィルター
|
||||
auths.group_attribute_contain_user_list=ユーザーのリストを含むグループ属性
|
||||
auths.user_attribute_listed_in_group=グループのユーザー属性
|
||||
auths.attributes_in_bind=属性をバインドDNのコンテクストから取得する
|
||||
auths.filter=User フィルター
|
||||
auths.filter=ユーザーフィルター
|
||||
auths.admin_filter=Admin フィルター
|
||||
auths.ms_ad_sa=Ms Ad SA
|
||||
auths.smtp_auth=SMTP 認証の種類
|
||||
@@ -1141,7 +1141,7 @@ auths.pam_service_name=PAMサービス名
|
||||
auths.enable_auto_register=自動登録を有効にする
|
||||
auths.edit=認証設定を編集
|
||||
auths.activated=認証の有効化
|
||||
auths.default_auth=This authentication is default login source
|
||||
auths.default_auth=この認証を、既定のログイン ソースとする
|
||||
auths.new_success=新しい認証 '%s' が正常に追加されました。
|
||||
auths.update_success=認証の設定が正常に更新されました。
|
||||
auths.update=認証設定を更新
|
||||
@@ -1160,12 +1160,12 @@ config.app_url=アプリケーションの URL
|
||||
config.domain=ドメイン
|
||||
config.offline_mode=オフラインモード
|
||||
config.disable_router_log=ルーターのログを無効にする
|
||||
config.run_user=実行ユーザ
|
||||
config.run_user=実行ユーザー
|
||||
config.run_mode=実行モード
|
||||
config.git_version=Git バージョン
|
||||
config.static_file_root_path=静的ファイルのルートパス
|
||||
config.log_file_root_path=ログファイルのルートパス
|
||||
config.reverse_auth_user=リバース認証ユーザ
|
||||
config.reverse_auth_user=リバース認証ユーザー
|
||||
|
||||
config.ssh_config=SSH設定
|
||||
config.ssh_enabled=有効
|
||||
@@ -1197,7 +1197,7 @@ config.db_config=データベース設定
|
||||
config.db_type=タイプ
|
||||
config.db_host=ホスト
|
||||
config.db_name=名前
|
||||
config.db_user=ユーザ
|
||||
config.db_user=ユーザー
|
||||
config.db_ssl_mode=SSL モード
|
||||
config.db_ssl_mode_helper=(「postgres」のみ)
|
||||
config.db_path=パス
|
||||
@@ -1224,7 +1224,7 @@ config.mailer_enabled=有効にした
|
||||
config.mailer_disable_helo=HELOコマンド無効
|
||||
config.mailer_subject_prefix=件名プレフィックス
|
||||
config.mailer_host=ホスト
|
||||
config.mailer_user=ユーザ
|
||||
config.mailer_user=ユーザー
|
||||
config.send_test_mail=テストメールの送信
|
||||
config.test_mail_failed='%s' 宛のテストメールの送信に失敗しました: %v
|
||||
config.test_mail_sent=テストメールが '%s' に送信されました。
|
||||
@@ -1313,7 +1313,7 @@ push_tag=が <a href="%[1]s">%[3]s</a> にタグ <a href="%[1]s/src/%[2]s">%[2]s
|
||||
delete_tag=<a href="%[1]s">%[3]s</a> のタグ <code>%[2]s</code> を削除しました
|
||||
fork_repo=リポジトリを <a href="%s">%s</a> にフォークしました
|
||||
mirror_sync_push=synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
|
||||
mirror_sync_create=synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
|
||||
mirror_sync_create=新しい参照<a href="%s/src/%s">%[2]s</a>を<a href="%[1]s">%[3]s</a>にミラーから反映しました
|
||||
mirror_sync_delete=synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
|
||||
|
||||
[tool]
|
||||
|
||||
@@ -151,7 +151,7 @@ register_hepler_msg=이미 계정을 가지고 계신가요? 로그인하세요!
|
||||
social_register_hepler_msg=계정을 가지고 계신가요? 연결하세요!
|
||||
disable_register_prompt=죄송합니다, 가입이 비활성화 되어있습니다. 사이트 관리자에게 문의 해주세요.
|
||||
disable_register_mail=죄송합니다. 메일 등록이 비활성화 되었습니다.
|
||||
auth_source=Authentication Source
|
||||
auth_source=인증 소스 편집
|
||||
local=로컬
|
||||
remember_me=자동 로그인
|
||||
forgot_password=비밀번호 찾기
|
||||
@@ -231,7 +231,7 @@ org_name_been_taken=이미 사용중인 조직 이름입니다.
|
||||
team_name_been_taken=이미 사용중인 팀 이름입니다.
|
||||
email_been_used=이미 사용중인 이메일 주소입니다.
|
||||
username_password_incorrect=사용자 이름이나 비밀번호가 올바르지 않습니다.
|
||||
auth_source_mismatch=The authentication source selected is not associated with the user.
|
||||
auth_source_mismatch=선택 인증 소스는 사용자와 연결 됩니다.
|
||||
enterred_invalid_repo_name=입력한 저장소 이름이 올바른지 확인하십시오.
|
||||
enterred_invalid_owner_name=입력한 사용자 이름이 올바른지 확인하십시오.
|
||||
enterred_invalid_password=입력한 비밀번호가 올바른지 확인하십시오.
|
||||
|
||||
@@ -119,7 +119,7 @@ sqlite3_not_available=Jūsu versija neatbalsta SQLite3, lūdzu lejupielādējiet
|
||||
invalid_db_setting=Datu bāzes iestatījums nav pareizs: %v
|
||||
invalid_repo_path=Repozitorija atrašanās vieta ir nekorekta: %v
|
||||
run_user_not_match=Izpildes lietotājs nav pašreizējais lietotājs: %s -> %s
|
||||
smtp_host_missing_port=SMTP Host is missing port in address.
|
||||
smtp_host_missing_port=SMTP adresē nav norādīts ports.
|
||||
invalid_smtp_from=SMTP sūtītāja lauks ir nekorekts: %v
|
||||
save_config_failed=Neizdevās saglabāt konfigurāciju: %v
|
||||
invalid_admin_setting=Nekorekts admin konta iestatījums: %v
|
||||
@@ -151,7 +151,7 @@ register_hepler_msg=Jau ir konts? Pieraksties tagad!
|
||||
social_register_hepler_msg=Jau ir konts? Sasaisti tagad!
|
||||
disable_register_prompt=Atvainojiet, reģistrācija ir atspējota. Lūdzu, sazinieties ar vietnes administratoru.
|
||||
disable_register_mail=Atvainojiet, reģistrācijas e-pasta apstiprināšana ir atspējota.
|
||||
auth_source=Authentication Source
|
||||
auth_source=Autentificēšanas avots
|
||||
local=Local
|
||||
remember_me=Atcerēties mani
|
||||
forgot_password=Aizmirsu paroli
|
||||
@@ -214,7 +214,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.`
|
||||
alpha_dash_dot_slash_error=` drīkst saturēt tikai latīņu alfabēta burtus, ciparus, domuzīmes (-_), slīpsvītru vai punktu.`
|
||||
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ā.`
|
||||
@@ -231,7 +231,7 @@ org_name_been_taken=Organizācijas nosaukums ir jau aizņemts.
|
||||
team_name_been_taken=Komandas nosaukums ir jau aizņemts.
|
||||
email_been_used=E-pasta adrese jau tiek izmantota.
|
||||
username_password_incorrect=Lietotājvārds vai parole nav pareiza.
|
||||
auth_source_mismatch=The authentication source selected is not associated with the user.
|
||||
auth_source_mismatch=Izvēlētais autentificēšanas avots nav saistīts ar lietotāju.
|
||||
enterred_invalid_repo_name=Lūdzu, pārliecinieties, vai ievadītā repozitorija nosaukums ir pareizs.
|
||||
enterred_invalid_owner_name=Lūdzu, pārliecinieties, vai ievadītā īpašnieka vārds ir pareizs.
|
||||
enterred_invalid_password=Lūdzu pārliecinieties, vai Jūsu ievadītā parole ir pareiza.
|
||||
@@ -350,9 +350,9 @@ two_factor_scan_qr=Please use your authentication application to scan the image:
|
||||
two_factor_or_enter_secret=Vai ievadiet noslēpumu:
|
||||
two_factor_then_enter_passcode=Pēc tam ievadiet kodu:
|
||||
two_factor_verify=Pārbaudīt
|
||||
two_factor_invalid_passcode=The passcode you entered is not valid, please try again!
|
||||
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
|
||||
two_factor_enable_error=Enable Two-factor authentication failed: %v
|
||||
two_factor_invalid_passcode=Ievadītais piekļuves kods nav derīgs. Lūdzu mēģiniet vēlreiz!
|
||||
two_factor_reused_passcode=Ievadītais piekļuves kods jau ir izmantots. Lūdzu mēģiniet citu!
|
||||
two_factor_enable_error=Divu faktoru autentifikācijas iespējošana neizdevās: %v
|
||||
two_factor_enable_success=Two-factor authentication has enabled for your account successfully!
|
||||
two_factor_recovery_codes_title=Two-factor Authentication Recovery Codes
|
||||
two_factor_recovery_codes_desc=Recovery codes are used when you temporarily lose access to your authentication application. Each recovery code can only be used once, <b>please keep these codes in a safe place</b>.
|
||||
@@ -361,7 +361,7 @@ two_factor_regenerate_recovery_codes_error=Regenerate recovery codes failed: %v
|
||||
two_factor_regenerate_recovery_codes_success=New recovery codes has been generated successfully!
|
||||
two_factor_disable_title=Atspējot divu faktoru autentifikāciju
|
||||
two_factor_disable_desc=Your account security level will decrease after disabled two-factor authentication. Do you want to continue?
|
||||
two_factor_disable_success=Two-factor authentication has disabled successfully!
|
||||
two_factor_disable_success=Divu faktoru autentificēšana ir atspējota!
|
||||
|
||||
manage_access_token=Pārvaldīt personīgos piekļuves talonus
|
||||
generate_new_token=Ģenerēt jaunu talonu
|
||||
@@ -375,7 +375,7 @@ access_token_deletion=Personīgā piekļuves talona dzēšana
|
||||
access_token_deletion_desc=Dzēšot personīgo piekļuves talonu, tiks liegta piekļuve aplikācijām, kas to izmanto. Vai vēlaties turpināt?
|
||||
delete_token_success=Personīgās piekļuves talons veiksmīgi izdzēsts! Neaizmirstiet nomainīt uz citu aplikācijās, kas to izmantoja.
|
||||
|
||||
orgs.none=You are not a member of any organizations.
|
||||
orgs.none=Jūs neesat nevienas organizācijas dalībnieks.
|
||||
orgs.leave_title=Pamest organizāciju
|
||||
orgs.leave_desc=You will lose access to all repositories and teams after you left the organization. Do you want to continue?
|
||||
|
||||
@@ -421,8 +421,8 @@ mirror_last_synced=Pēdējo reizi sinhronizēts
|
||||
watchers=Novērotāji
|
||||
stargazers=Zvaigžņdevēji
|
||||
forks=Atdalītie repozitoriji
|
||||
repo_description_helper=Description of repository. Maximum 512 characters length.
|
||||
repo_description_length=Available characters
|
||||
repo_description_helper=Repozitorija apraksts. Maksimālais garums 512 rakstzīmes.
|
||||
repo_description_length=Pieejamās rakstzīmes
|
||||
|
||||
form.reach_limit_of_creation=Īpašnieks sasniedza maksimālu pieļaujamo (%d) izveidoto repozitoriju skaitu.
|
||||
form.name_reserved=Repozitorija nosaukums '%s' ir rezervēts.
|
||||
@@ -476,13 +476,13 @@ file_history=Vēsture
|
||||
file_view_raw=Rādīt neapstrādātu
|
||||
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.
|
||||
video_not_supported_in_browser=Jūsu pārlūks neatbalsta HTML5 video.
|
||||
|
||||
branches.overview=Pārskats
|
||||
branches.active_branches=Aktīvie atzari
|
||||
branches.stale_branches=Pamests atzars
|
||||
branches.all=Visi atzari
|
||||
branches.updated_by=Updated %[1]s by %[2]s
|
||||
branches.updated_by=%[2]s atjaunoja %[1]s
|
||||
branches.change_default_branch=Mainīt noklusēto atzaru
|
||||
|
||||
editor.new_file=Jauns fails
|
||||
@@ -520,7 +520,7 @@ editor.file_changed_while_editing=Faila saturs ir mainījies kopš brīža, kad
|
||||
editor.file_already_exists=Fails ar nosaukumu '%s' repozitorijā jau eksistē.
|
||||
editor.no_changes_to_show=Nav izmaiņu, ko rādīt.
|
||||
editor.fail_to_update_file=Neizdevās izmainīt/izveidot failu '%s', kļūda: %v
|
||||
editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
|
||||
editor.fail_to_delete_file=Neizdevās dzēst failu '%s', kļūda: %v
|
||||
editor.add_subdir=Pievienot apakšdirektoriju...
|
||||
editor.unable_to_upload_files=Neizdevās augšupielādēt failus uz direktoriju '%s', kļūda: %v
|
||||
editor.upload_files_to_dir=Augšupielādēt failus uz direktoriju '%s'
|
||||
@@ -747,7 +747,7 @@ settings.tracker_issue_style.numeric=Cipari
|
||||
settings.tracker_issue_style.alphanumeric=Burti un cipari
|
||||
settings.tracker_url_format_desc=Jūs varat izmantot <code>{user}{repo}{index}</code> lietotājvārdam, repozitorija nosaukumam un problēmas identifikātoram.
|
||||
settings.pulls_desc=Enable pull requests to accept contributions between repositories and branches
|
||||
settings.pulls.ignore_whitespace=Ignore changes in whitespace
|
||||
settings.pulls.ignore_whitespace=Ignorēt atstarpju izmaiņas
|
||||
settings.pulls.allow_rebase_merge=Allow use rebase to merge commits
|
||||
settings.danger_zone=Bīstamā zona
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
@@ -769,7 +769,7 @@ settings.wiki_deletion_success=Repozitorija Vikivietnes dati tika veiksmīgi izd
|
||||
settings.delete=Dzēst šo repozitoriju
|
||||
settings.delete_desc=Dzēšot repozitoriju, tā datus vairs nebūs iespējams atgūt. Pirms dzēšanas pārliecinieites vai patiešām vēlaties to darīt.
|
||||
settings.delete_notices_1=- Šī darbība ir <strong>NEATGRIEZENISKA</strong>.
|
||||
settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
|
||||
settings.delete_notices_2=- Šī darbība neatgriezeniski izdzēsīs visus šī repozitorija datus, tai skaitā Git datus, problēmu ziņojumus, komentārus un definētās piekļuves tiesības.
|
||||
settings.delete_notices_fork_1=- Visi atdalītie repozitoriji kļūs neatkarīgi pēc dzēšanas.
|
||||
settings.deletion_success=Repozitorijs tika veiksmīgi dzēsts!
|
||||
settings.update_settings_success=Repozitorija opcijas ir veiksmīgi saglabātas.
|
||||
@@ -1118,11 +1118,11 @@ auths.user_base=Lietotāja pamatnosacījumi
|
||||
auths.user_dn=Lietotāja DN
|
||||
auths.attribute_username=Lietotājvārda atribūts
|
||||
auths.attribute_username_placeholder=Atstājiet tukšu, lai izmantotu lietotājvārdu ar kuru autorizējaties.
|
||||
auths.attribute_name=First Name Attribute
|
||||
auths.attribute_name=Vārda atribūts
|
||||
auths.attribute_surname=Uzvārda atribūts
|
||||
auths.attribute_mail=E-pasta atribūts
|
||||
auths.verify_group_membership=Verify group membership
|
||||
auths.group_search_base_dn=Group Search Base DN
|
||||
auths.verify_group_membership=Pārbaudīt grupas piederību
|
||||
auths.group_search_base_dn=Grupas meklēšanas pamata DN
|
||||
auths.group_filter=Group Filter
|
||||
auths.group_attribute_contain_user_list=Group Attribute Containing List of Users
|
||||
auths.user_attribute_listed_in_group=User Attribute Listed in Group
|
||||
@@ -1152,7 +1152,7 @@ auths.still_in_used=Daži lietotāji joprojām izmanto šo autentifikācijas vei
|
||||
auths.deletion_success=Autentifikācija tika veiksmīgi izdzēsta!
|
||||
auths.login_source_exist=Pieteikšanās avots '%s' jau eksistē.
|
||||
|
||||
config.not_set=(not set)
|
||||
config.not_set=(nav noteikts)
|
||||
config.server_config=Servera konfigurācija
|
||||
config.app_name=Lietotnes nosaukums
|
||||
config.app_ver=Lietotnes versija
|
||||
@@ -1190,7 +1190,7 @@ config.disable_http_git=Atspējot HTTP Git
|
||||
config.enable_local_path_migration=Atļaut migrāciju no lokāla ceļa
|
||||
config.commits_fetch_concurrency=Commits Fetch Concurrency
|
||||
|
||||
config.http_config=HTTP Configuration
|
||||
config.http_config=HTTP konfigurācija
|
||||
config.http_access_control_allow_origin=Access Control Allow Origin
|
||||
|
||||
config.db_config=Datu bāzes konfigurācija
|
||||
|
||||
@@ -643,7 +643,7 @@ pulls.create_merge_commit=Criar um commit de merge
|
||||
pulls.rebase_before_merging=Rebase antes de merging
|
||||
pulls.commit_description=Descrição de Commit
|
||||
pulls.merge_pull_request=Solicitar merge de Pull Request
|
||||
pulls.open_unmerged_pull_exists=`You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
|
||||
pulls.open_unmerged_pull_exists=`Não pode executar a operação de reabrir porque já existe um Pull request (#%d) do mesmo repositório com as mesmas informações de merge que está a aguardar pelo merge.`
|
||||
pulls.delete_branch=Excluir Branch
|
||||
pulls.delete_branch_has_new_commits=O branch não pode ser excluído por possuir novos commits após o merge.
|
||||
|
||||
@@ -751,27 +751,27 @@ settings.pulls.ignore_whitespace=Ignorar alterações com espaço em branco
|
||||
settings.pulls.allow_rebase_merge=Permitir rebase para commits via merge
|
||||
settings.danger_zone=Zona de perigo
|
||||
settings.cannot_fork_to_same_owner=Não pode realizar fork de um repositório para o seu dono original.
|
||||
settings.new_owner_has_same_repo=The new owner already has a repository with same name. Please choose another name.
|
||||
settings.convert=Convert To Regular Repository
|
||||
settings.convert_desc=You can convert this mirror to a regular repository. This cannot be reversed.
|
||||
settings.convert_notices_1=- This operation will convert this repository mirror into a regular repository and cannot be undone.
|
||||
settings.convert_confirm=Confirm Conversion
|
||||
settings.convert_succeed=Repository has been converted to regular type successfully.
|
||||
settings.new_owner_has_same_repo=O novo dono já tem um repositório com o mesmo nome. Por favor, escolha outro nome.
|
||||
settings.convert=Converter para Repositório Tradicional
|
||||
settings.convert_desc=Pode converter este Mirror num repositório tradicional. Esta ação não pode ser revertida.
|
||||
settings.convert_notices_1=- Esta operação vai converter este repositório Mirror num repositório tradicional e esta ação não pode ser revertida.
|
||||
settings.convert_confirm=Confirmar Conversão
|
||||
settings.convert_succeed=Repositório Mirror convertido para tradicional com sucesso.
|
||||
settings.transfer=Transferir Propriedade
|
||||
settings.transfer_desc=Transfer this repository to another user or to an organization in which you have admin rights.
|
||||
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
|
||||
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title=Please enter following information to confirm your operation:
|
||||
settings.transfer_desc=Transferir este repositório para outro utilizador ou organização onde tem direitos de administrador.
|
||||
settings.transfer_notices_1=- Irá perder o acesso se o novo dono for um utilizador individual.
|
||||
settings.transfer_notices_2=- Irá manter acesso se o novo dono é uma organização e se é um dos donos.
|
||||
settings.transfer_form_title=Por favor Informe a seguinte informação para confirmar a sua operação:
|
||||
settings.wiki_delete=Apagar dados da Wiki
|
||||
settings.wiki_delete_desc=Once you erase wiki data there is no going back. Please be certain.
|
||||
settings.wiki_delete_notices_1=- This will delete and disable the wiki for %s
|
||||
settings.wiki_deletion_success=Repository wiki data have been erased successfully.
|
||||
settings.delete=Delete This Repository
|
||||
settings.delete_desc=Once you delete a repository, there is no going back. Please be certain.
|
||||
settings.delete_notices_1=- This operation <strong>CANNOT</strong> be undone.
|
||||
settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
|
||||
settings.delete_notices_fork_1=- All forks will become independent after deletion.
|
||||
settings.deletion_success=Repository has been deleted successfully!
|
||||
settings.wiki_delete_desc=Uma vez que apague os dados da wiki, não e possível reverte-los. Por favor, certifique-se.
|
||||
settings.wiki_delete_notices_1=- Isto irá excluir e desativar o wiki para %s
|
||||
settings.wiki_deletion_success=Os dados da wiki do repositório foram apagados com sucesso.
|
||||
settings.delete=Apagar Este Repositório
|
||||
settings.delete_desc=Uma vez que remova um repositório, não e possível reverte-lo. Por favor certifique-se.
|
||||
settings.delete_notices_1=Esta operação <strong>NÃO PODERÁ</strong> ser desfeita.
|
||||
settings.delete_notices_2=- Esta operação irá apagar permanentemente tudo neste repositório, incluindo dados do Git, commits, issues, comentários, o wiki e acesso dos colaboradores.
|
||||
settings.delete_notices_fork_1=-Todos os forks ficarão independentes após a exclusão.
|
||||
settings.deletion_success=Repositório excluído com sucesso!
|
||||
settings.update_settings_success=As opções do repositório foram atualizadas com sucesso.
|
||||
settings.transfer_owner=Novo proprietário
|
||||
settings.make_transfer=Fazer transferência
|
||||
@@ -834,7 +834,7 @@ settings.event_issue_comment_desc=Comentário do problema criado, editado ou exc
|
||||
settings.event_release=Lançamento
|
||||
settings.event_release_desc=Lançamento publicado no repositório.
|
||||
settings.active=Ativo
|
||||
settings.active_helper=Details regarding the event which triggered the hook will be delivered as well.
|
||||
settings.active_helper=Enviaremos detalhes do evento quando este hook for ativado.
|
||||
settings.add_hook_success=Novos webhook foram adicionados.
|
||||
settings.update_webhook=Atualizar Webhook
|
||||
settings.update_hook_success=Webhook atualizado.
|
||||
@@ -847,70 +847,70 @@ settings.add_dingtalk_hook_desc=Adicionar integração do <a href="%s">Dingtalk<
|
||||
settings.slack_token=Token
|
||||
settings.slack_domain=Domínio
|
||||
settings.slack_channel=Canal
|
||||
settings.deploy_keys=Deploy Keys
|
||||
settings.deploy_keys=Chaves de Deploy
|
||||
settings.deploy_keys_helper=<b>Common Gotcha!</b> Se estiver a tentar adicionar chaves públicas pessoais, faça-o nas suas <a href="%s%s">configurações da conta</a>.
|
||||
settings.add_deploy_key=Add Deploy Key
|
||||
settings.deploy_key_desc=Deploy keys have read-only access. They are not the same as personal account SSH keys.
|
||||
settings.no_deploy_keys=You haven't added any deploy keys.
|
||||
settings.add_deploy_key=Adicionar Chave de Deploy
|
||||
settings.deploy_key_desc=Chave de Deploy só tem acesso de leitura. Não é igual as chaves SSH da conta pessoal.
|
||||
settings.no_deploy_keys=Ainda não adicionou nenhuma chave de Deploy.
|
||||
settings.title=Título
|
||||
settings.deploy_key_content=Conteúdo
|
||||
settings.key_been_used=Deploy key content has been used.
|
||||
settings.key_name_used=Deploy key with the same name already exists.
|
||||
settings.add_key_success=New deploy key '%s' has been added successfully!
|
||||
settings.deploy_key_deletion=Delete Deploy Key
|
||||
settings.deploy_key_deletion_desc=Deleting this deploy key will remove all related accesses for this repository. Do you want to continue?
|
||||
settings.deploy_key_deletion_success=Deploy key has been deleted successfully!
|
||||
settings.description_desc=Description of repository. Maximum 512 characters length.
|
||||
settings.description_length=Available characters
|
||||
settings.key_been_used=Conteúdo da Chave de Deploy foi utilizado.
|
||||
settings.key_name_used=Uma chave de Deploy já existe com este nome.
|
||||
settings.add_key_success=Nova chave de Deploy '%s' foi adicionada com sucesso!
|
||||
settings.deploy_key_deletion=Apagar chave de Deploy
|
||||
settings.deploy_key_deletion_desc=Excluir esta chave de Deploy removerá permissões de acesso a este repositório. Deseja continuar?
|
||||
settings.deploy_key_deletion_success=Chave de Deploy excluída com sucesso!
|
||||
settings.description_desc=Descrição do repositório. Máximo de 512 caracteres.
|
||||
settings.description_length=Caracteres disponíveis
|
||||
|
||||
diff.browse_source=Browse Source
|
||||
diff.parent=parent
|
||||
diff.browse_source=Ver Fonte
|
||||
diff.parent=pai
|
||||
diff.commit=commit
|
||||
diff.data_not_available=Diff Data Not Available.
|
||||
diff.show_diff_stats=Show Diff Stats
|
||||
diff.show_split_view=Split View
|
||||
diff.show_unified_view=Unified View
|
||||
diff.stats_desc=<strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
|
||||
diff.data_not_available=Dados Diff Não Disponíveis.
|
||||
diff.show_diff_stats=Mostrar Estatísticas Diff
|
||||
diff.show_split_view=Visão Dividida
|
||||
diff.show_unified_view=Visão Unificada
|
||||
diff.stats_desc=<strong> %d ficheiros alterados</strong> com <strong>%d adições</strong> e <strong>%d exclusões</strong>
|
||||
diff.bin=BIN
|
||||
diff.view_file=Ver Ficheiro
|
||||
diff.file_suppressed=File diff suppressed because it is too large
|
||||
diff.too_many_files=Some files were not shown because too many files changed in this diff
|
||||
diff.file_suppressed=Diff do ficheiro suprimidas por serem muito extensas
|
||||
diff.too_many_files=Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff
|
||||
|
||||
release.releases=Lançamentos
|
||||
release.new_release=Novos lançamentos
|
||||
release.draft=Rascunho
|
||||
release.prerelease=Pre-Release
|
||||
release.prerelease=Versão Prévia
|
||||
release.edit=editar
|
||||
release.ahead=<strong>%d</strong> commits to %s since this release
|
||||
release.source_code=Source Code
|
||||
release.new_subheader=Publish releases to iterate product.
|
||||
release.edit_subheader=Detailed change log can help users understand what has been improved.
|
||||
release.ahead=<strong>%d</strong> commits para %s depois desta versão
|
||||
release.source_code=Código Fonte
|
||||
release.new_subheader=Publicar versões para iterar o produto.
|
||||
release.edit_subheader=Um changelog detalhado pode ajudar utilizadores a entenderem o que foi melhorado.
|
||||
release.tag_name=Nome da etiqueta
|
||||
release.target=Destino
|
||||
release.tag_helper=Choose an existing tag, or create a new tag on publish.
|
||||
release.tag_helper=Escolha uma tag existente, ou crie uma nova tag em publicar.
|
||||
release.title=Título
|
||||
release.content=Conteúdo
|
||||
release.write=Escrever
|
||||
release.preview=Pré-visualizar
|
||||
release.loading=A carregar...
|
||||
release.prerelease_desc=This is a pre-release
|
||||
release.prerelease_helper=We'll point out that this release is not production-ready.
|
||||
release.prerelease_desc=Esta é uma versão prévia
|
||||
release.prerelease_helper=Salientamos que esta versão não esta pronta para produção.
|
||||
release.cancel=Cancelar
|
||||
release.publish=Publish Release
|
||||
release.publish=Publicar Versão
|
||||
release.save_draft=Guardar Rascunho
|
||||
release.edit_release=Edit Release
|
||||
release.delete_release=Delete This Release
|
||||
release.deletion=Release Deletion
|
||||
release.deletion_desc=Deleting this release will delete the corresponding Git tag. Do you want to continue?
|
||||
release.deletion_success=Release has been deleted successfully!
|
||||
release.tag_name_already_exist=Release with this tag name already exists.
|
||||
release.tag_name_invalid=Tag name is not valid.
|
||||
release.edit_release=Editar Versão
|
||||
release.delete_release=Apagar esta Versão
|
||||
release.deletion=Exclusão de Versão
|
||||
release.deletion_desc=Apagar esta versão vai remover a tag do git correspondente. Deseja continuar?
|
||||
release.deletion_success=A versão foi removida com sucesso!
|
||||
release.tag_name_already_exist=Já existe uma versão com este nome de tag.
|
||||
release.tag_name_invalid=Nome de tag não é válido.
|
||||
release.downloads=Transferências
|
||||
|
||||
[org]
|
||||
org_name_holder=Nome da organização
|
||||
org_full_name_holder=Nome completo da organização
|
||||
org_name_helper=Great organization names are short and memorable.
|
||||
org_name_helper=Nomes de grandes organizações são curtos e memoráveis.
|
||||
create_org=Criar Organização
|
||||
repo_updated=Atualizado
|
||||
people=Membros
|
||||
@@ -922,18 +922,18 @@ create_new_team=Criar equipa
|
||||
org_desc=Descrição
|
||||
team_name=Nome da equipa
|
||||
team_desc=Descrição
|
||||
team_name_helper=You'll use this name to mention this team in conversations.
|
||||
team_desc_helper=What is this team all about?
|
||||
team_permission_desc=What permission level should this team have?
|
||||
team_name_helper=Utilizara este nome para mencionar esta equipa em conversas.
|
||||
team_desc_helper=Do que se trata essa equipa?
|
||||
team_permission_desc=Que nível de permissão esta equipa deve ter?
|
||||
|
||||
form.name_reserved=Organization name '%s' is reserved.
|
||||
form.name_pattern_not_allowed=Organization name pattern '%s' is not allowed.
|
||||
form.team_name_reserved=Team name '%s' is reserved.
|
||||
form.name_reserved=O nome de organização '%s' está reservado.
|
||||
form.name_pattern_not_allowed=Não é permitido utilizar o padrão '%s' para o nome de organização.
|
||||
form.team_name_reserved=O nome nome de equipa '%s' está reservado.
|
||||
|
||||
settings=Settings
|
||||
settings.options=Options
|
||||
settings.full_name=Full Name
|
||||
settings.website=Website
|
||||
settings=Configurações
|
||||
settings.options=Opções
|
||||
settings.full_name=Nome Completo
|
||||
settings.website=WebSite
|
||||
settings.location=Localização
|
||||
settings.update_settings=Atualizar Configurações
|
||||
settings.update_setting_success=Configuração da organização foi atualizada com sucesso.
|
||||
@@ -1030,60 +1030,60 @@ dashboard.current_memory_usage=Utilização de memória atual
|
||||
dashboard.total_memory_allocated=Total de memória alocada
|
||||
dashboard.memory_obtained=Memória obtida
|
||||
dashboard.pointer_lookup_times=Nº Consulta de Ponteiros
|
||||
dashboard.memory_allocate_times=Memory Allocate Times
|
||||
dashboard.memory_free_times=Memory Free Times
|
||||
dashboard.current_heap_usage=Current Heap Usage
|
||||
dashboard.heap_memory_obtained=Heap Memory Obtained
|
||||
dashboard.heap_memory_idle=Heap Memory Idle
|
||||
dashboard.heap_memory_in_use=Heap Memory In Use
|
||||
dashboard.heap_memory_released=Heap Memory Released
|
||||
dashboard.heap_objects=Heap Objects
|
||||
dashboard.bootstrap_stack_usage=Bootstrap Stack Usage
|
||||
dashboard.stack_memory_obtained=Stack Memory Obtained
|
||||
dashboard.mspan_structures_usage=MSpan Structures Usage
|
||||
dashboard.mspan_structures_obtained=MSpan Structures Obtained
|
||||
dashboard.mcache_structures_usage=MCache Structures Usage
|
||||
dashboard.mcache_structures_obtained=MCache Structures Obtained
|
||||
dashboard.profiling_bucket_hash_table_obtained=Profiling Bucket Hash Table Obtained
|
||||
dashboard.gc_metadata_obtained=GC Metadata Obtained
|
||||
dashboard.other_system_allocation_obtained=Other System Allocation Obtained
|
||||
dashboard.next_gc_recycle=Next GC Recycle
|
||||
dashboard.last_gc_time=Since Last GC Time
|
||||
dashboard.total_gc_time=Total GC Pause
|
||||
dashboard.total_gc_pause=Total GC Pause
|
||||
dashboard.last_gc_pause=Last GC Pause
|
||||
dashboard.gc_times=GC Times
|
||||
dashboard.memory_allocate_times=Nº Alocações de Memória
|
||||
dashboard.memory_free_times=Nº de Libertações de Memória
|
||||
dashboard.current_heap_usage=Uso Atual da Heap
|
||||
dashboard.heap_memory_obtained=Memória de Heap Obtida
|
||||
dashboard.heap_memory_idle=Memória da Heap Idle
|
||||
dashboard.heap_memory_in_use=Memória da Heap em Uso
|
||||
dashboard.heap_memory_released=Memória da Heap Libertada
|
||||
dashboard.heap_objects=Objetos na Heap
|
||||
dashboard.bootstrap_stack_usage=Uso de Bootstrap Stack
|
||||
dashboard.stack_memory_obtained=Memória de Stack Obtida
|
||||
dashboard.mspan_structures_usage=Utilização de Estruturas de MSpan
|
||||
dashboard.mspan_structures_obtained=Estruturas de MSpan Obtidas
|
||||
dashboard.mcache_structures_usage=Utilização de Estruturas MCache
|
||||
dashboard.mcache_structures_obtained=Estruturas de MCache Obtidas
|
||||
dashboard.profiling_bucket_hash_table_obtained=Perfil Obtido da Bucket Hash Table
|
||||
dashboard.gc_metadata_obtained=Metadados do GC Obtidos
|
||||
dashboard.other_system_allocation_obtained=Outra Alocação de Sistema Obtida
|
||||
dashboard.next_gc_recycle=Próxima Reciclagem do GC
|
||||
dashboard.last_gc_time=Desde da Ultima Vez do GC
|
||||
dashboard.total_gc_time=Pausa Total do GC
|
||||
dashboard.total_gc_pause=Pausa Total do GC
|
||||
dashboard.last_gc_pause=Última Pausa do GC
|
||||
dashboard.gc_times=Nº Execuções do GC
|
||||
|
||||
users.user_manage_panel=User Manage Panel
|
||||
users.new_account=Create New Account
|
||||
users.user_manage_panel=Painel de Gestão de Utilizador
|
||||
users.new_account=Criar Nova Conta
|
||||
users.name=Nome
|
||||
users.activated=Ativado
|
||||
users.admin=Admin
|
||||
users.repos=Repos
|
||||
users.created=Criado
|
||||
users.send_register_notify=Send Registration Notification To User
|
||||
users.new_success=New account '%s' has been created successfully.
|
||||
users.send_register_notify=Enviar Notificação de Registo ao Utilizador
|
||||
users.new_success=Nova conta '%s' foi criada com sucesso.
|
||||
users.edit=Editar
|
||||
users.auth_source=Fontes de autenticação
|
||||
users.local=Local
|
||||
users.auth_login_name=Autenticação de nome de usuário
|
||||
users.password_helper=Leave it empty to remain unchanged.
|
||||
users.update_profile_success=Account profile has been updated successfully.
|
||||
users.password_helper=Deixe em branco para não alterar.
|
||||
users.update_profile_success=O perfil da conta foi atualizado com sucesso.
|
||||
users.edit_account=Editar conta
|
||||
users.max_repo_creation=Maximum Repository Creation Limit
|
||||
users.max_repo_creation_desc=(Set -1 to use global default limit)
|
||||
users.is_activated=This account is activated
|
||||
users.prohibit_login=This account is prohibited to login
|
||||
users.is_admin=This account has administrator permissions
|
||||
users.allow_git_hook=This account has permissions to create Git hooks
|
||||
users.allow_import_local=This account has permissions to import local repositories
|
||||
users.max_repo_creation=Limite Máximo de Criação de Repositórios
|
||||
users.max_repo_creation_desc=(Utilize "-1" para utilizar o limite padrão)
|
||||
users.is_activated=Esta conta está ativada
|
||||
users.prohibit_login=Esta conta está proibida de efetuar login
|
||||
users.is_admin=Esta conta tem permissões de administrador
|
||||
users.allow_git_hook=Esta conta tem permissões para criar hooks do Git
|
||||
users.allow_import_local=Esta conta tem permissões para importar repositórios locais
|
||||
users.update_profile=Atualizar perfil
|
||||
users.delete_account=Apagar Conta
|
||||
users.still_own_repo=This account still has ownership over at least one repository, you have to delete or transfer them first.
|
||||
users.still_has_org=This account still has membership in at least one organization, you have to leave or delete the organizations first.
|
||||
users.deletion_success=Account has been deleted successfully!
|
||||
users.still_own_repo=Esta conta ainda é proprietária de pelo menos um repositório, deve excluir ou transferi-lo primeiro.
|
||||
users.still_has_org=Esta conta ainda faz parte de pelo menos uma organização, deve sair ou excluí-la primeiro.
|
||||
users.deletion_success=Conta foi excluída com sucesso!
|
||||
|
||||
orgs.org_manage_panel=Organization Manage Panel
|
||||
orgs.org_manage_panel=Painel de Gestão de Organização
|
||||
orgs.name=Nome
|
||||
orgs.teams=Equipas
|
||||
orgs.members=Membros
|
||||
@@ -1110,88 +1110,88 @@ auths.security_protocol=Protocolo de segurança
|
||||
auths.domain=Domínio
|
||||
auths.host=Anfitrião
|
||||
auths.port=Porta
|
||||
auths.bind_dn=Bind DN
|
||||
auths.bind_dn_helper=You can use '%s' as placeholder for username, e.g. DOM\%s
|
||||
auths.bind_password=Bind Password
|
||||
auths.bind_password_helper=Warning: This password is stored in plain text. Do not use a high privileged account.
|
||||
auths.user_base=User Search Base
|
||||
auths.user_dn=User DN
|
||||
auths.attribute_username=Username Attribute
|
||||
auths.attribute_username_placeholder=Leave empty to use sign-in form field value for user name.
|
||||
auths.attribute_name=First Name Attribute
|
||||
auths.attribute_surname=Surname Attribute
|
||||
auths.attribute_mail=Email Attribute
|
||||
auths.verify_group_membership=Verify group membership
|
||||
auths.group_search_base_dn=Group Search Base DN
|
||||
auths.group_filter=Group Filter
|
||||
auths.group_attribute_contain_user_list=Group Attribute Containing List of Users
|
||||
auths.user_attribute_listed_in_group=User Attribute Listed in Group
|
||||
auths.attributes_in_bind=Fetch attributes in Bind DN context
|
||||
auths.filter=User Filter
|
||||
auths.admin_filter=Admin Filter
|
||||
auths.ms_ad_sa=Ms Ad SA
|
||||
auths.smtp_auth=SMTP Authentication Type
|
||||
auths.bind_dn=Vincular DN
|
||||
auths.bind_dn_helper=Pode utilizar '%s' como placeholder para o nome de utilizador, por exemplo, DOM\%s
|
||||
auths.bind_password=Vincular Senha
|
||||
auths.bind_password_helper=Atenção: Esta senha é armazenada texto. Não utilize uma conta com privilégios elevados.
|
||||
auths.user_base=Base de Pesquisa de Utilizador
|
||||
auths.user_dn=Utilizador do DN
|
||||
auths.attribute_username=Atributo do Utilizador
|
||||
auths.attribute_username_placeholder=Deixe vazio para utilizar o valor do campo do formulário de entrada do nome de utilizador.
|
||||
auths.attribute_name=Atributo do Primeiro Nome
|
||||
auths.attribute_surname=Atributo do Sobrenome
|
||||
auths.attribute_mail=Atributo do e-mail
|
||||
auths.verify_group_membership=Verificar associação a grupo
|
||||
auths.group_search_base_dn=Base Pesquisa de grupo DN
|
||||
auths.group_filter=Filtro de Grupo
|
||||
auths.group_attribute_contain_user_list=Atributos de Grupo com Lista de Utilizadores
|
||||
auths.user_attribute_listed_in_group=Atributo de Utilizador Listado no Grupo
|
||||
auths.attributes_in_bind=Procurar atributos no contexto de Vinculo DN
|
||||
auths.filter=Filtro de Utilizador
|
||||
auths.admin_filter=Filtro de Administrador
|
||||
auths.ms_ad_sa=Microsoft Active Directory SA
|
||||
auths.smtp_auth=Tipo de Autenticação SMTP
|
||||
auths.smtphost=Anfitrião SMTP
|
||||
auths.smtpport=Porta SMTP
|
||||
auths.allowed_domains=Allowed Domains
|
||||
auths.allowed_domains_helper=Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','.
|
||||
auths.allowed_domains=Domínios Permitidos
|
||||
auths.allowed_domains_helper=Deixe em branco para permitir qualquer domínio. Vários domínios devem ser separados por vírgula ','.
|
||||
auths.enable_tls=Ativar encriptação TLS
|
||||
auths.skip_tls_verify=Skip TLS Verify
|
||||
auths.pam_service_name=PAM Service Name
|
||||
auths.enable_auto_register=Enable Auto Registration
|
||||
auths.edit=Edit Authentication Setting
|
||||
auths.activated=This authentication is activated
|
||||
auths.default_auth=This authentication is default login source
|
||||
auths.new_success=New authentication '%s' has been added successfully.
|
||||
auths.update_success=Authentication setting has been updated successfully.
|
||||
auths.update=Update Authentication Setting
|
||||
auths.delete=Delete This Authentication
|
||||
auths.delete_auth_title=Authentication Deletion
|
||||
auths.delete_auth_desc=This authentication is going to be deleted, do you want to continue?
|
||||
auths.still_in_used=This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success=Authentication has been deleted successfully!
|
||||
auths.login_source_exist=Login source '%s' already exists.
|
||||
auths.skip_tls_verify=Ignorar Verificação TLS
|
||||
auths.pam_service_name=Nome do Serviço PAM
|
||||
auths.enable_auto_register=Ativar Registo Automático
|
||||
auths.edit=Editar Configuração de Autenticação
|
||||
auths.activated=Esta Autenticação foi Ativada
|
||||
auths.default_auth=Essa autenticação é a fonte de login padrão
|
||||
auths.new_success=Nova autenticação '%s' foi adicionada com sucesso.
|
||||
auths.update_success=A configuração da autenticação foi atualizada com sucesso.
|
||||
auths.update=Atualizar Configuração de Autenticação
|
||||
auths.delete=Apagar Esta Autenticação
|
||||
auths.delete_auth_title=Exclusão da Autenticação
|
||||
auths.delete_auth_desc=Esta autenticação esta prestes a ser excluída, deseja continuar?
|
||||
auths.still_in_used=Esta autenticação ainda é utilizada por alguns utilizadores. Por favor remova ou converta esses utilizadores para outro tipo de login primeiro.
|
||||
auths.deletion_success=Autenticação foi excluída com sucesso!
|
||||
auths.login_source_exist=A fonte de login '%s" já existe.
|
||||
|
||||
config.not_set=(not set)
|
||||
config.server_config=Server Configuration
|
||||
config.app_name=Application Name
|
||||
config.app_ver=Application Version
|
||||
config.app_url=Application URL
|
||||
config.domain=Domain
|
||||
config.offline_mode=Offline Mode
|
||||
config.disable_router_log=Disable Router Log
|
||||
config.not_set=(não definido)
|
||||
config.server_config=Configuração do Servidor
|
||||
config.app_name=Nome da Aplicação
|
||||
config.app_ver=Versão da Aplicação
|
||||
config.app_url=URL da Aplicação
|
||||
config.domain=Domínio
|
||||
config.offline_mode=Modo Offline
|
||||
config.disable_router_log=Desativar o Log do Router
|
||||
config.run_user=Utilizador de execução
|
||||
config.run_mode=Mode de execução
|
||||
config.git_version=Versão Git
|
||||
config.static_file_root_path=Caminho Root Estático
|
||||
config.log_file_root_path=Log File Root Path
|
||||
config.reverse_auth_user=Reverse Authentication User
|
||||
config.log_file_root_path=Caminho Raiz para Ficheiro Log
|
||||
config.reverse_auth_user=Utilizador de Autenticação Inversa
|
||||
|
||||
config.ssh_config=Configuração SSH
|
||||
config.ssh_enabled=Ativado
|
||||
config.ssh_start_builtin_server=Start Builtin Server
|
||||
config.ssh_start_builtin_server=Iniciar Servidor Embutido
|
||||
config.ssh_domain=Domínio
|
||||
config.ssh_port=Porta
|
||||
config.ssh_listen_port=Porta
|
||||
config.ssh_root_path=Caminho para raiz
|
||||
config.ssh_rewrite_authorized_keys_at_start=Reescrever authorized_keys no inicio
|
||||
config.ssh_key_test_path=Key Test Path
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check=Minimum Key Size Check
|
||||
config.ssh_key_test_path=Caminho da Chave de Teste
|
||||
config.ssh_keygen_path=Caminho do Keygen ('ssh-keygen')
|
||||
config.ssh_minimum_key_size_check=Verificar Tamanho Mínimo da Chave
|
||||
config.ssh_minimum_key_sizes=Tamanho minimo de chave
|
||||
|
||||
config.repo_config=Configuração de repositório
|
||||
config.repo_root_path=Repository Root Path
|
||||
config.repo_root_path=Caminho Raiz do Repositório
|
||||
config.script_type=Tipo de Script
|
||||
config.repo_force_private=Forçar Privado
|
||||
config.max_creation_limit=Limite Maximo de Criação
|
||||
config.preferred_licenses=Licensas preferenciais
|
||||
config.disable_http_git=Desativar HTTP Git
|
||||
config.enable_local_path_migration=Enable Local Path Migration
|
||||
config.commits_fetch_concurrency=Commits Fetch Concurrency
|
||||
config.enable_local_path_migration=Permitir a Migração de Caminho Local
|
||||
config.commits_fetch_concurrency=Concorrência de Commits Fetch
|
||||
|
||||
config.http_config=Configuração HTTP
|
||||
config.http_access_control_allow_origin=Access Control Allow Origin
|
||||
config.http_access_control_allow_origin=Controle de Acesso Allow Origin
|
||||
|
||||
config.db_config=Configuração da base de dados
|
||||
config.db_type=Tipo
|
||||
@@ -1207,27 +1207,27 @@ config.service_config=Configuração do Servidor
|
||||
config.register_email_confirm=Requer confirmação por email
|
||||
config.disable_register=Desactivar registo
|
||||
config.show_registration_button=Mostrar botão de registo
|
||||
config.require_sign_in_view=Require Sign In View
|
||||
config.mail_notify=Mail Notification
|
||||
config.disable_key_size_check=Disable Minimum Key Size Check
|
||||
config.require_sign_in_view=Requerer Entrar Para Visualizar
|
||||
config.mail_notify=Notificação de e-mail
|
||||
config.disable_key_size_check=Desativar Verificação de Tamanho Mínimo da Chave
|
||||
config.enable_captcha=Activar o Captcha
|
||||
config.active_code_lives=Active Code Lives
|
||||
config.reset_password_code_lives=Reset Password Code Lives
|
||||
config.active_code_lives=Code Lives Ativos
|
||||
config.reset_password_code_lives=Redefinir Senha de Code Lives
|
||||
|
||||
config.webhook_config=Webhook Configuration
|
||||
config.queue_length=Queue Length
|
||||
config.deliver_timeout=Deliver Timeout
|
||||
config.skip_tls_verify=Skip TLS Verify
|
||||
config.webhook_config=Configuração de WebHook
|
||||
config.queue_length=Tamanho da Fila
|
||||
config.deliver_timeout=Tempo Limite de Entrega
|
||||
config.skip_tls_verify=Pular Verificação de TLS
|
||||
|
||||
config.mailer_config=Mailer Configuration
|
||||
config.mailer_config=Configuração de E-mail
|
||||
config.mailer_enabled=Ativado
|
||||
config.mailer_disable_helo=Desativar HELO
|
||||
config.mailer_subject_prefix=Prefixo de assunto
|
||||
config.mailer_host=Anfitrião
|
||||
config.mailer_user=Utilizador
|
||||
config.send_test_mail=Enviar email de teste
|
||||
config.test_mail_failed=Fail to send test email to '%s': %v
|
||||
config.test_mail_sent=Test email has been sent to '%s'.
|
||||
config.test_mail_failed=Falhou o envio do email de teste para '%s': %v
|
||||
config.test_mail_sent=O email de teste foi enviado para '%s'.
|
||||
|
||||
config.oauth_config=Configuração OAuth
|
||||
config.oauth_enabled=Ativado
|
||||
@@ -1242,98 +1242,98 @@ config.session_provider=Provedor de sessão
|
||||
config.provider_config=Provedor Config
|
||||
config.cookie_name=Nome do cookie
|
||||
config.enable_set_cookie=Ativar Set Cookie
|
||||
config.gc_interval_time=GC Interval Time
|
||||
config.gc_interval_time=Tempo de Intervalo do GC
|
||||
config.session_life_time=Duração de sessão
|
||||
config.https_only=Apenas HTTPS
|
||||
config.cookie_life_time=Tempo de Vida do Cookie
|
||||
|
||||
config.picture_config=Configuração de imagem
|
||||
config.picture_service=Serviço de imagem
|
||||
config.disable_gravatar=Disable Gravatar
|
||||
config.enable_federated_avatar=Enable Federated Avatars
|
||||
config.disable_gravatar=Desativar Gravatar
|
||||
config.enable_federated_avatar=Ativar Avatares Federados
|
||||
|
||||
config.git_config=Configuração Git
|
||||
config.git_disable_diff_highlight=Disable Diff Syntax Highlight
|
||||
config.git_max_diff_lines=Max Diff Lines (for a single file)
|
||||
config.git_max_diff_line_characters=Max Diff Characters (for a single line)
|
||||
config.git_max_diff_files=Max Diff Files (to be shown)
|
||||
config.git_disable_diff_highlight=Desativar Realce de Sintaxe no diff
|
||||
config.git_max_diff_lines=Numero Máximo de Linhas no diff (para um único ficheiro)
|
||||
config.git_max_diff_line_characters=Numero Máximo de Caracteres no diff (para uma única linha)
|
||||
config.git_max_diff_files=Numero Máximo de Ficheiros no diff (a serem mostrados)
|
||||
config.git_gc_args=Argumentos GC
|
||||
config.git_migrate_timeout=Tempo de migrção
|
||||
config.git_mirror_timeout=Mirror Update Timeout
|
||||
config.git_clone_timeout=Clone Operation Timeout
|
||||
config.git_pull_timeout=Pull Operation Timeout
|
||||
config.git_gc_timeout=GC Operation Timeout
|
||||
config.git_mirror_timeout=Tempo Limite para Atualização de Mirror
|
||||
config.git_clone_timeout=Tempo Limite para Operação de Clone
|
||||
config.git_pull_timeout=Tempo Limite para Operação de Pull
|
||||
config.git_gc_timeout=Tempo Limite para Execução do GC
|
||||
|
||||
config.log_config=Log Configuration
|
||||
config.log_config=Configuração de Log
|
||||
config.log_mode=Modo
|
||||
config.log_options=Opções
|
||||
|
||||
monitor.cron=Cron Tasks
|
||||
monitor.cron=Tarefas Cron
|
||||
monitor.name=Nome
|
||||
monitor.schedule=Programa
|
||||
monitor.next=Próxima vez
|
||||
monitor.previous=Vez anterior
|
||||
monitor.execute_times=Tempos de Execução
|
||||
monitor.process=Running Processes
|
||||
monitor.process=Processos em Execução
|
||||
monitor.desc=Descrição
|
||||
monitor.start=Hora de início
|
||||
monitor.execute_time=Tempo de Execução
|
||||
|
||||
notices.system_notice_list=System Notices
|
||||
notices.view_detail_header=View Notice Detail
|
||||
notices.system_notice_list=Sistema de Notificações
|
||||
notices.view_detail_header=Ver Detalhe de Notificações
|
||||
notices.actions=Ações
|
||||
notices.select_all=Selecionar Todas
|
||||
notices.deselect_all=Desselecionar Todas
|
||||
notices.inverse_selection=Inverse Selection
|
||||
notices.inverse_selection=Inverter Seleção
|
||||
notices.delete_selected=Apagar Seleção
|
||||
notices.delete_all=Apagar todas as notificações
|
||||
notices.type=Tipo
|
||||
notices.type_1=Repositório
|
||||
notices.desc=Descrição
|
||||
notices.op=Op.
|
||||
notices.delete_success=System notices have been deleted successfully.
|
||||
notices.delete_success=Notificações do sistema foram apagados com sucesso.
|
||||
|
||||
[action]
|
||||
create_repo=created repository <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>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]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>
|
||||
delete_tag=deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
fork_repo=forked a repository to <a href="%s">%s</a>
|
||||
mirror_sync_push=synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
|
||||
mirror_sync_create=synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
|
||||
mirror_sync_delete=synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
|
||||
create_repo=repositório criado <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 para estes %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 a questão <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`criou pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request=`fechou pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request=`reabriu pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`mesclou pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
create_branch=criado novo branch <a href="%[1]s/src/%[2]s">%[3]s</a> em <a href="%[1]s">%[4]s</a>
|
||||
delete_branch=apagado branch <code>%[2]s</code> em <a href="%[1]s">%[3]s</a>
|
||||
push_tag=feito push tag <a href="%s/src/%s">%[2]s</a> para <a href="%[1]s">%[3]s</a>
|
||||
delete_tag=apagada tag <code>%[2]s</code> em <a href="%[1]s">%[3]s</a>
|
||||
fork_repo=forked repositório para <a href="%s"> %s</a>
|
||||
mirror_sync_push=sincronizados commits para <a href="%[1]s/src/%[2]s">%[3]s</a> em <a href="%[1]s">%[4]s</a> do mirror
|
||||
mirror_sync_create=nova referência sincronizada <a href="%s/src/%s">%[2]s</a> para <a href="%[1]s">%[3]s</a> do mirror
|
||||
mirror_sync_delete=referência sincronizada e apagada <code>%[2]s</code> em <a href="%[1]s">%[3]s</a> do mirror
|
||||
|
||||
[tool]
|
||||
ago=atrás
|
||||
from_now=a partir de agora
|
||||
now=agora
|
||||
1s=1 segundo %s
|
||||
1m=1 minute %s
|
||||
1h=1 hour %s
|
||||
1d=1 day %s
|
||||
1w=1 week %s
|
||||
1mon=1 month %s
|
||||
1y=1 year %s
|
||||
seconds=%d seconds %s
|
||||
minutes=%d minutes %s
|
||||
hours=%d hours %s
|
||||
days=%d days %s
|
||||
weeks=%d weeks %s
|
||||
months=%d months %s
|
||||
years=%d years %s
|
||||
1m=há 1 minuto %s
|
||||
1h=há 1 hora %s
|
||||
1d=há 1 dia %s
|
||||
1w=há 1 semana %s
|
||||
1mon=há 1 mês %s
|
||||
1y=há 1 ano %s
|
||||
seconds=há %d segundos %s
|
||||
minutes=há %d minutos %s
|
||||
hours=há %d horas %s
|
||||
days=há %d dias %s
|
||||
weeks=há %d semanas %s
|
||||
months=há %d meses %s
|
||||
years=há %d anos %s
|
||||
raw_seconds=segundos
|
||||
raw_minutes=minutos
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ url_error=` не является допустимым URL-адресом.`
|
||||
include_error=` должен содержать '%s'.`
|
||||
unknown_error=Неизвестная ошибка:
|
||||
captcha_incorrect=Капча не пройдена.
|
||||
password_not_match=Пароли не совпадают.
|
||||
password_not_match=Пароль и подтверждение отличаются.
|
||||
|
||||
username_been_taken=Имя пользователя занято.
|
||||
repo_name_been_taken=Имя репозитория занято.
|
||||
|
||||
@@ -1222,7 +1222,7 @@ config.skip_tls_verify=Preskočiť overenie TLS
|
||||
config.mailer_config=Nastavenie mailera
|
||||
config.mailer_enabled=Povolený
|
||||
config.mailer_disable_helo=Zakázať HELO
|
||||
config.mailer_subject_prefix=Subject Prefix
|
||||
config.mailer_subject_prefix=Predpona predmetu
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Používateľ
|
||||
config.send_test_mail=Odoslať testovací E-mail
|
||||
|
||||
@@ -421,8 +421,8 @@ mirror_last_synced=Задње синхронизовано
|
||||
watchers=Посматрачи
|
||||
stargazers=Пратиоци
|
||||
forks=Огранци
|
||||
repo_description_helper=Description of repository. Maximum 512 characters length.
|
||||
repo_description_length=Available characters
|
||||
repo_description_helper=Опис спремишта. Максимум 512 карактера.
|
||||
repo_description_length=Доступни карактери
|
||||
|
||||
form.reach_limit_of_creation=Власник има максимум број %d спремишта.
|
||||
form.name_reserved=Име спремишта '%s' је резервирано.
|
||||
@@ -520,7 +520,7 @@ editor.file_changed_while_editing=Садржај датотеке је пром
|
||||
editor.file_already_exists=Датотека са именом '%s' већ постоји у овом спремишту.
|
||||
editor.no_changes_to_show=Нема никаквих промена.
|
||||
editor.fail_to_update_file=Промена над '%s' није успело са грешком: %v
|
||||
editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
|
||||
editor.fail_to_delete_file=Фајл '%s' није успешно обрисан, разлог грешке: %v
|
||||
editor.add_subdir=Додај поддиректоријуми...
|
||||
editor.unable_to_upload_files=Учитање датотеке '%s' није успело са грешкном: %v
|
||||
editor.upload_files_to_dir=Пошаљи датотеке на '%s'
|
||||
@@ -641,7 +641,7 @@ pulls.cannot_auto_merge_desc=Овај захтев за спајање не мо
|
||||
pulls.cannot_auto_merge_helper=Молимо вас, обавите спајање ручно да би сте разрешили сукобе.
|
||||
pulls.create_merge_commit=Направите спајање
|
||||
pulls.rebase_before_merging=Поврат пре обједињавања
|
||||
pulls.commit_description=Commit Description
|
||||
pulls.commit_description=Опис ревизије
|
||||
pulls.merge_pull_request=Обави спајање
|
||||
pulls.open_unmerged_pull_exists=`Неможете поново отворити јер већ постоји захтев за спајање (#%d) из истог спремишта са истим информацијама о спајању и чека спајање.`
|
||||
pulls.delete_branch=Избришите грану
|
||||
@@ -860,8 +860,8 @@ settings.add_key_success=Нови кључ распоређивање '%s' је
|
||||
settings.deploy_key_deletion=Уклони кључ распоређивањa
|
||||
settings.deploy_key_deletion_desc=Брисање овог кључа за распоређивање ће довести до укидање приступ на овом спремишту. Да ли желите да наставите?
|
||||
settings.deploy_key_deletion_success=Кључ за распоређивање је успешно обрисан!
|
||||
settings.description_desc=Description of repository. Maximum 512 characters length.
|
||||
settings.description_length=Available characters
|
||||
settings.description_desc=Опис спремишта. Максимум 512 карактера.
|
||||
settings.description_length=Доступни карактери
|
||||
|
||||
diff.browse_source=Преглед изворни кода
|
||||
diff.parent=родитељ
|
||||
|
||||
@@ -151,8 +151,8 @@ register_hepler_msg=Bir hesabınız var mı? Şimdi giriş yapın!
|
||||
social_register_hepler_msg=Zaten bir hesabınız var mı? Şimdi bağlanın!
|
||||
disable_register_prompt=Üzgünüz, kaydolma devre dışı bırakıldı. Lütfen site yöneticisiyle irtibata geçin.
|
||||
disable_register_mail=Üzgünüz, kayıt doğrulama e-postası devre dışı bırakıldı.
|
||||
auth_source=Authentication Source
|
||||
local=Local
|
||||
auth_source=Yetkilendirme Kaynağı
|
||||
local=Yerel
|
||||
remember_me=Beni Hatırla
|
||||
forgot_password=Parolamı Unuttum
|
||||
forget_password=Parolanızı mı unuttunuz?
|
||||
@@ -231,7 +231,7 @@ org_name_been_taken=Bu organizasyon adı zaten alınmış.
|
||||
team_name_been_taken=Bu takım adı zaten alınmış.
|
||||
email_been_used=Bu e-posta adresi zaten kullanımda.
|
||||
username_password_incorrect=Kullanıcı adı veya parola hatalı.
|
||||
auth_source_mismatch=The authentication source selected is not associated with the user.
|
||||
auth_source_mismatch=Seçilen kimlik doğrulama kaynağı kullanıcı ile ilişkili değil.
|
||||
enterred_invalid_repo_name=Lütfen girdiğiniz depo isminin doğru olduğundan emin olun.
|
||||
enterred_invalid_owner_name=Lütfen girdiğiniz depo sahibi isminin doğru olduğundan emin olun.
|
||||
enterred_invalid_password=Lütfen girdiğiniz parolanın doğru olduğundan emin olun.
|
||||
@@ -351,7 +351,7 @@ two_factor_or_enter_secret=Veya parola girin:
|
||||
two_factor_then_enter_passcode=Daha sonra şifre kodunu girin:
|
||||
two_factor_verify=Doğrula
|
||||
two_factor_invalid_passcode=Girdiğiniz şifre kodu geçersiz,lütfen tekrar deneyin!
|
||||
two_factor_reused_passcode=The passcode you entered has already been used, please try another one!
|
||||
two_factor_reused_passcode=Girdiğiniz şifre zaten kullanılmış, lütfen başka bir tane deneyin!
|
||||
two_factor_enable_error=İki faktörlü kimlik doğrulama etkinleştirmesi başarısız :%v
|
||||
two_factor_enable_success=Hesabınız için iki faktörlü kimlik doğrulama başarıyla devre dışı bırakıldı!
|
||||
two_factor_recovery_codes_title=İki faktörlü Kimlik doğrulama Kurtarma Kodları
|
||||
@@ -421,8 +421,8 @@ mirror_last_synced=Son Eşzamanlama
|
||||
watchers=İzleyenler
|
||||
stargazers=Yıldızlayanlar
|
||||
forks=Çatallamalar
|
||||
repo_description_helper=Description of repository. Maximum 512 characters length.
|
||||
repo_description_length=Available characters
|
||||
repo_description_helper=Depo açıklaması. Maksimum 512 karakter uzunluğu.
|
||||
repo_description_length=Mevcut karakterler
|
||||
|
||||
form.reach_limit_of_creation=Sahip, maksimum %d depo oluşturma limitine ulaşmıştır.
|
||||
form.name_reserved=Depo ismi '%s' başkasına ayrılmış.
|
||||
@@ -520,7 +520,7 @@ editor.file_changed_while_editing=Düzenlemeye başladıktan sonra dosya içeri
|
||||
editor.file_already_exists='% s ' adlı bir dosya mevcutta zaten var.
|
||||
editor.no_changes_to_show=Gösterilecek bir değişiklik mevcut değil.
|
||||
editor.fail_to_update_file='%s' dosyası güncellenemedi / oluşturulamadı : %v hatasıyla
|
||||
editor.fail_to_delete_file=Failed to delete file '%s' with error: %v
|
||||
editor.fail_to_delete_file='%s' dosyası hatalı bir şekilde silinemedi: %v
|
||||
editor.add_subdir=Alt dizin Ekle...
|
||||
editor.unable_to_upload_files='%s' dosyası yüklenemedi : %v hatasıyla
|
||||
editor.upload_files_to_dir=Dosyaları '%s' ye yükle
|
||||
@@ -641,7 +641,7 @@ pulls.cannot_auto_merge_desc=Çakışmalardan dolayı bu değişiklik isteği ot
|
||||
pulls.cannot_auto_merge_helper=Çakışmaları çözmek için lütfen elle birleştirin.
|
||||
pulls.create_merge_commit=Birleştirme işlemi oluşturma
|
||||
pulls.rebase_before_merging=Birleştirmeden önce yenidenreferans al
|
||||
pulls.commit_description=Commit Description
|
||||
pulls.commit_description=Taahhüt Açıklaması
|
||||
pulls.merge_pull_request=Değişiklik İsteğini Birleştir
|
||||
pulls.open_unmerged_pull_exists=`Yeniden açma işlemini gerçekleştiremezsiniz. Çünkü zaten aynı depodan, aynı birleştirme bilgisiyle açık olan bir değişiklik isteği var (#%d) ve birleştirme bekliyor.`
|
||||
pulls.delete_branch=Şubeyi Sil
|
||||
@@ -740,17 +740,17 @@ settings.use_internal_issue_tracker=Yerleşik hafif sorun izleyici kullanma
|
||||
settings.allow_public_issues_desc=Depo özel olduğunda toplulukların herkese açık olarak erişmesine izin ver
|
||||
settings.use_external_issue_tracker=Harici sorun takipçisi kullan
|
||||
settings.external_tracker_url=Harici Konu İzleyici URL'si
|
||||
settings.external_tracker_url_desc=Visitors will be redirected to URL when they click on the tab.
|
||||
settings.external_tracker_url_desc=Ziyaretçiler, sekmeye tıkladıklarında bağlantıya yönlendirilecektir.
|
||||
settings.tracker_url_format=Harici Sorun Takipçisi Bağlantı Formatı
|
||||
settings.tracker_issue_style=Harici Hata İzleyicisi Adlandırma Stili:
|
||||
settings.tracker_issue_style.numeric=Sayısal
|
||||
settings.tracker_issue_style.alphanumeric=Alfanumerik
|
||||
settings.tracker_url_format_desc=Kullanıcı adı, depo ismi ve hata indeksi için <code>{kullanıcı} {depo} {indeks}</code> tutucusunu kullanabilirsiniz.
|
||||
settings.pulls_desc=Enable pull requests to accept contributions between repositories and branches
|
||||
settings.pulls.ignore_whitespace=Ignore changes in whitespace
|
||||
settings.pulls.allow_rebase_merge=Allow use rebase to merge commits
|
||||
settings.pulls_desc=Depolar ve Şubeler arasındaki katkıları kabul etmek için çekme isteklerini etkinleştir
|
||||
settings.pulls.ignore_whitespace=Boşluktaki değişiklikleri yoksay
|
||||
settings.pulls.allow_rebase_merge=Taahhütleri birleştirmek için yeniden tabanın kullanmasına izin ver
|
||||
settings.danger_zone=Tehlike Alanı
|
||||
settings.cannot_fork_to_same_owner=You cannot fork a repository to its original owner.
|
||||
settings.cannot_fork_to_same_owner=Bir depoyu orijinal sahibine ayıramazsınız.
|
||||
settings.new_owner_has_same_repo=Yeni sahibin aynı isimde başka bir deposu var. Lütfen farklı bir isim seçin.
|
||||
settings.convert=Düzenli Depoya Dönüştür
|
||||
settings.convert_desc=Bu yansıyı düzenli bir depoya dönüştürebilirsiniz. Bu işlem geri alınamaz.
|
||||
@@ -769,7 +769,7 @@ settings.wiki_deletion_success=Deponun Wiki verisi başarıyla silindi.
|
||||
settings.delete=Bu Depoyu Sil
|
||||
settings.delete_desc=Bir depoyu bir kez sildiğiniz taktirde geri getiremezsiniz. Lütfen emin olun.
|
||||
settings.delete_notices_1=- Bu işlem geri <strong>ALINAMAZ</strong>.
|
||||
settings.delete_notices_2=- This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
|
||||
settings.delete_notices_2=- Bu işlem, git verileri, sorunlar, yorumlar ve işbirlikçi erişimi de dahil olmak üzere bu depodaki her şeyi kalıcı olarak siler.
|
||||
settings.delete_notices_fork_1=Silme işleminden sonra bütün çatallar bağımsız hale gelir.
|
||||
settings.deletion_success=Depo başarıyla silindi!
|
||||
settings.update_settings_success=Depo seçenekleri başarıyla güncellendi.
|
||||
@@ -793,8 +793,8 @@ settings.webhook_deletion_success=Web isteği başarıyla silindi!
|
||||
settings.webhook.test_delivery=Test Dağıtımı
|
||||
settings.webhook.test_delivery_desc=Web isteği ayarlarınızı test etmek için sahte bir anlık olay gönderin
|
||||
settings.webhook.test_delivery_success=Test web isteği, dağıtım kuyruğuna eklendi. Bunun dağıtım geçmişinde görünmesi birkaç saniye sürebilir.
|
||||
settings.webhook.redelivery=Redelivery
|
||||
settings.webhook.redelivery_success=Hook task '%s' has been readded to delivery queue. It may take few seconds to update delivery status in history.
|
||||
settings.webhook.redelivery=Yeniden teslimat
|
||||
settings.webhook.redelivery_success=Kanca görev '%s' teslim kuyruğuna eklenmiştir. Bu tarihte teslim durumunu güncellemek birkaç saniye sürebilir.
|
||||
settings.webhook.request=İstekler
|
||||
settings.webhook.response=Cevaplar
|
||||
settings.webhook.headers=Başlıklar
|
||||
@@ -809,7 +809,7 @@ settings.add_webhook_desc=Gogs, meydana gelen olay ile birlikte belirttiğiniz b
|
||||
settings.payload_url=Yük Bağlantısı
|
||||
settings.content_type=İçerik Türü
|
||||
settings.secret=Gizli
|
||||
settings.secret_desc=Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.secret_desc=Gizli, <code>X-Gogs-Signature</code> başlığı ile SHA256 hmac hexdigest yükü olarak gönderilecektir.
|
||||
settings.slack_username=Kullanıcı Adı
|
||||
settings.slack_icon_url=Simge Bağlantısı
|
||||
settings.slack_color=Renk
|
||||
@@ -819,20 +819,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_delete=Delete
|
||||
settings.event_delete_desc=Branch or tag deleted
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository forked
|
||||
settings.event_delete=Sil
|
||||
settings.event_delete_desc=Dal veya etiket silindi
|
||||
settings.event_fork=Çatalla
|
||||
settings.event_fork_desc=Depo çatallandı
|
||||
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_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_issue_comment=Issue Comment
|
||||
settings.event_issue_comment_desc=Issue comment created, edited, or deleted.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release published in a repository.
|
||||
settings.event_issues=Sorunlar
|
||||
settings.event_issues_desc=Sorun açıldı, kapatıldı, yeniden açıldı, düzenlendi, atandı, atanmadı, etiket güncellendi, etiket silindi, dönüm noktası yapıldı ya da iptal edildi.
|
||||
settings.event_pull_request=İstek Çek
|
||||
settings.event_pull_request_desc=Çekme isteği açıldı, kapatıldı, yeniden açıldı, düzenlendi, atandı, atanmamış, etiket güncellendi, etiket silindi, kilometre taşları, dönüm noktası veya senkronize edildi.
|
||||
settings.event_issue_comment=Sorun Yorumu
|
||||
settings.event_issue_comment_desc=Konu yorumu eklendi, düzenlendi veya silindi.
|
||||
settings.event_release=Yayın
|
||||
settings.event_release_desc=Bir depoda yayınlanan sürüm.
|
||||
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.
|
||||
@@ -842,13 +842,13 @@ settings.delete_webhook=Web İsteğini Sil
|
||||
settings.recent_deliveries=Son Dağıtımlar
|
||||
settings.hook_type=İstek Türü
|
||||
settings.add_slack_hook_desc=Deponuza <a href="%s">Slack</a> entegrasyonunu ekleyin.
|
||||
settings.add_discord_hook_desc=Add <a href="%s">Discord</a> integration to your repository.
|
||||
settings.add_dingtalk_hook_desc=Add <a href="%s">Dingtalk</a> integration to your repository.
|
||||
settings.add_discord_hook_desc=Deponuza <a href="%s">Discord</a> entegrasyonu ekleyin.
|
||||
settings.add_dingtalk_hook_desc=Deponuza <a href="%s">Dingtalk</a> entegrasyonu ekleyin.
|
||||
settings.slack_token=Erişim Anahtarı
|
||||
settings.slack_domain=Alan Adı
|
||||
settings.slack_channel=Kanal
|
||||
settings.deploy_keys=Dağıtım Anahtarları
|
||||
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>Ortak Gotcha!</b> Kişisel ortak anahtarlar eklemek istiyorsanız lütfen bunları <a href="%s%s">hesap ayarlarınıza</a> ekleyin.
|
||||
settings.add_deploy_key=Dağıtım Anahtarı Ekle
|
||||
settings.deploy_key_desc=Dağıtım anahtarlarının yalnızca okuma izni vardır. Kişisel hesapların SSH anahtarlarıyla aynı değillerdir.
|
||||
settings.no_deploy_keys=Herhangi bir dağıtım anahtarı eklemediniz.
|
||||
@@ -860,8 +860,8 @@ settings.add_key_success=Yeni dağıtım anahtarı '%s' başarıyla eklendi!
|
||||
settings.deploy_key_deletion=Dağıtım Anahtarını Sil
|
||||
settings.deploy_key_deletion_desc=Bu dağıtım anahtarını silerseniz bu depoya ilişkin tüm erişimler de kaldırılacaktır. Devam etmek istiyor musunuz?
|
||||
settings.deploy_key_deletion_success=Dağıtım anahtarı başarıyla silindi!
|
||||
settings.description_desc=Description of repository. Maximum 512 characters length.
|
||||
settings.description_length=Available characters
|
||||
settings.description_desc=Depo açıklaması. Maksimum 512 karakter uzunluğu.
|
||||
settings.description_length=Mevcut karakterler
|
||||
|
||||
diff.browse_source=Kaynağa Gözat
|
||||
diff.parent=ebeveyn
|
||||
@@ -928,7 +928,7 @@ team_permission_desc=Bu takım, ne gibi bir izin seviyesine sahiptir?
|
||||
|
||||
form.name_reserved=Organizasyon adı '%s' başka birisine ayrılmış.
|
||||
form.name_pattern_not_allowed=Organizasyon adı modeli '%s' geçersiz.
|
||||
form.team_name_reserved=Team name '%s' is reserved.
|
||||
form.team_name_reserved='%s' takım ismi başka birine ayrılmış.
|
||||
|
||||
settings=Ayarlar
|
||||
settings.options=Seçenekler
|
||||
@@ -1019,8 +1019,8 @@ dashboard.git_gc_repos=Depolarda çöp toplama işlemini gerçekleştir
|
||||
dashboard.git_gc_repos_success=Tüm depolarda çöp toplama işlemi başarıyla gerçekleştirildi.
|
||||
dashboard.resync_all_sshkeys='.ssh/authorized_keys' dosyasını yeniden yaz (dikkat: Gogs'un olmayan anahtarlar silinecektir)
|
||||
dashboard.resync_all_sshkeys_success=Tüm genel anahtarlar başarıyla yeniden yazıldı.
|
||||
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=Tüm depoların yeniden alımı, güncellemesi ve gönderi alım kancalarını yeniden senkronize et
|
||||
dashboard.resync_all_hooks_success=Tüm depoların önceden alımı, güncellemesi ve gönderi alımı kancaları başarıyla senkronize edildi.
|
||||
dashboard.reinit_missing_repos=Git dosyalarını kaybetmiş tüm depoları yeniden oluştur
|
||||
dashboard.reinit_missing_repos_success=Git dosyalarını kaybetmiş tüm depolar başarıyla yeniden oluşturuldu.
|
||||
|
||||
@@ -1095,14 +1095,14 @@ repos.private=Özel
|
||||
repos.watches=İzlemeler
|
||||
repos.stars=Yıldızlar
|
||||
repos.issues=Sorunlar
|
||||
repos.size=Size
|
||||
repos.size=Boyut
|
||||
|
||||
auths.auth_sources=Authentication Sources
|
||||
auths.auth_sources=Yetkilendirme Kaynakları
|
||||
auths.new=Yeni Kaynak Ekle
|
||||
auths.name=İsim
|
||||
auths.type=Tür
|
||||
auths.enabled=Aktifleştirilmiş
|
||||
auths.default=Default
|
||||
auths.default=Varsayılan
|
||||
auths.updated=Güncellendi
|
||||
auths.auth_type=Yetki Türü
|
||||
auths.auth_name=Yetki İsmi
|
||||
@@ -1111,21 +1111,21 @@ auths.domain=Alan Adı
|
||||
auths.host=Sunucu
|
||||
auths.port=Port
|
||||
auths.bind_dn=Bağlama DN'i
|
||||
auths.bind_dn_helper=You can use '%s' as placeholder for username, e.g. DOM\%s
|
||||
auths.bind_dn_helper=Kullanıcı adı için yer tutucu olarak '%s' kullanabilirsiniz, Örneğin DOM\%s
|
||||
auths.bind_password=Bağlama Parolası
|
||||
auths.bind_password_helper=Uyarı: Bu parola, ham halde bir metin dosyası içerisinde saklanacaktır. Yüksek izinli bir hesap kullanmayın.
|
||||
auths.user_base=Kullanıcı Arama Tabanı
|
||||
auths.user_dn=Kullanıcı DN'i
|
||||
auths.attribute_username=Kullanıcı özelliği
|
||||
auths.attribute_username_placeholder=Kullanıcı adı için giriş yapma form alanı kullanmak için boş bırakın.
|
||||
auths.attribute_name=First Name Attribute
|
||||
auths.attribute_name=İlk Ad Özelliği
|
||||
auths.attribute_surname=Soyad özelliği
|
||||
auths.attribute_mail=E-posta özelliği
|
||||
auths.verify_group_membership=Verify group membership
|
||||
auths.group_search_base_dn=Group Search Base DN
|
||||
auths.group_filter=Group Filter
|
||||
auths.group_attribute_contain_user_list=Group Attribute Containing List of Users
|
||||
auths.user_attribute_listed_in_group=User Attribute Listed in Group
|
||||
auths.verify_group_membership=Grup üyeliğini doğrula
|
||||
auths.group_search_base_dn=Grup Arama Tabanı DN
|
||||
auths.group_filter=Grup Filtresi
|
||||
auths.group_attribute_contain_user_list=Kullanıcı Listesi İçeren Grup Özelliği
|
||||
auths.user_attribute_listed_in_group=Grupta Listelenen Kullanıcı Özelliği
|
||||
auths.attributes_in_bind=Bağlı DN tabanındaki özellikleri çek
|
||||
auths.filter=Kullanıcı Filtresi
|
||||
auths.admin_filter=Yönetici Filtresi
|
||||
@@ -1141,7 +1141,7 @@ auths.pam_service_name=PAM Servis Adı
|
||||
auths.enable_auto_register=Otomatik Kaydolmayı Aktifleştir
|
||||
auths.edit=Yetkilendirme Ayarlarını Düzenle
|
||||
auths.activated=Bu yetkilendirme aktif
|
||||
auths.default_auth=This authentication is default login source
|
||||
auths.default_auth=Bu kimlik doğrulama varsayılan giriş kaynağıdır
|
||||
auths.new_success=Yeni yetkilendirme '%s' başarıyla eklendi.
|
||||
auths.update_success=Yetkilendirme ayarları başarıyla güncellendi.
|
||||
auths.update=Yetkilendirme Ayarlarını Güncelle
|
||||
@@ -1150,9 +1150,9 @@ auths.delete_auth_title=Yetkilendirme Silme
|
||||
auths.delete_auth_desc=Bu yetkilendirme silinecek. Devam etmek istiyor musunuz?
|
||||
auths.still_in_used=Bu yetkilendirme hala bazı kullanıcılar tarafından kullanılıyor. Lütfen öncelikle bunları silin ya da başka oturum açma türlerine çevirin.
|
||||
auths.deletion_success=Yetkilendirme başarıyla silindi!
|
||||
auths.login_source_exist=Login source '%s' already exists.
|
||||
auths.login_source_exist='%s' giriş kaynağı zaten mevcut.
|
||||
|
||||
config.not_set=(not set)
|
||||
config.not_set=(ayarlı değil)
|
||||
config.server_config=Sunucu Yapılandırması
|
||||
config.app_name=Uygulama Adı
|
||||
config.app_ver=Uygulama Sürümü
|
||||
@@ -1162,7 +1162,7 @@ config.offline_mode=Çevrim Dışı Modu
|
||||
config.disable_router_log=Yönlendirici Log'larını Devre Dışı Bırak
|
||||
config.run_user=Çalıştırma Kullanıcısı
|
||||
config.run_mode=Çalıştırma Modu
|
||||
config.git_version=Git Version
|
||||
config.git_version=Git Sürümü
|
||||
config.static_file_root_path=Sabit Dosya Kök Yolu
|
||||
config.log_file_root_path=Log Dosyası Kök Yolu
|
||||
config.reverse_auth_user=Tersine Yetkilendirme Kullanıcısı
|
||||
@@ -1174,24 +1174,24 @@ config.ssh_domain=Alan Adı
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Port'u Dinle
|
||||
config.ssh_root_path=Kök Yol
|
||||
config.ssh_rewrite_authorized_keys_at_start=Rewrite authorized_keys At Start
|
||||
config.ssh_rewrite_authorized_keys_at_start=Başlangıçta yetkili anahtarları yeniden yaz
|
||||
config.ssh_key_test_path=Anahtar Test Yolu
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Yolu
|
||||
config.ssh_minimum_key_size_check=Minimum Anahtar Uzunluğu Kontrolü
|
||||
config.ssh_minimum_key_sizes=Minimum Anahtar Uzunlukları
|
||||
|
||||
config.repo_config=Repository Configuration
|
||||
config.repo_config=Depo Yapılandırması
|
||||
config.repo_root_path=Depo Kök Yolu
|
||||
config.script_type=Betik Türü
|
||||
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=Özel Kuvvet
|
||||
config.max_creation_limit=Maksimum Oluşturma Sınırı
|
||||
config.preferred_licenses=Tercih Edilen Lisanslar
|
||||
config.disable_http_git=HTTP Git'i devre dışı bırak
|
||||
config.enable_local_path_migration=Yerel Yol Geçişi Etkinleştir
|
||||
config.commits_fetch_concurrency=Eşzamanlılık Alma Taahhüdü
|
||||
|
||||
config.http_config=HTTP Configuration
|
||||
config.http_access_control_allow_origin=Access Control Allow Origin
|
||||
config.http_config=HTTP Yapılandırması
|
||||
config.http_access_control_allow_origin=Erişim Kontrolü Kaynağına İzin Ver
|
||||
|
||||
config.db_config=Veritabanı Yapılandırması
|
||||
config.db_type=Türü
|
||||
@@ -1222,7 +1222,7 @@ config.skip_tls_verify=TLS Doğrulamasını Atla
|
||||
config.mailer_config=Mailer Yapılandırması
|
||||
config.mailer_enabled=Aktif
|
||||
config.mailer_disable_helo=HELO'yu Devre Dışı Bırak
|
||||
config.mailer_subject_prefix=Subject Prefix
|
||||
config.mailer_subject_prefix=Konu Öneki
|
||||
config.mailer_host=Sunucu
|
||||
config.mailer_user=Kullanıcı
|
||||
config.send_test_mail=Test E-Postası Gönder
|
||||
@@ -1250,9 +1250,9 @@ config.cookie_life_time=Çerez Yaşam Zamanı
|
||||
config.picture_config=Resim Yapılandırması
|
||||
config.picture_service=Resim Servisi
|
||||
config.disable_gravatar=Gravatar Hizmet Dışı
|
||||
config.enable_federated_avatar=Enable Federated Avatars
|
||||
config.enable_federated_avatar=Birleştirilmiş Avatarları Etkinleştir
|
||||
|
||||
config.git_config=Git Configuration
|
||||
config.git_config=Git Yapılandırması
|
||||
config.git_disable_diff_highlight=Diff İşlemi Sözdizimini Devre Dışı Bırak
|
||||
config.git_max_diff_lines=Maksimum Ayırma Hatları (tek bir dosya için)
|
||||
config.git_max_diff_line_characters=Maksimum Ayırma Karakterleri(tek bir hat için)
|
||||
|
||||
@@ -19,8 +19,8 @@ ln -sfn /data/gogs/data ./data
|
||||
# Backward Compatibility with Gogs Container v0.6.15
|
||||
ln -sfn /data/git /home/git
|
||||
|
||||
# Only chown for the first time, '/data/gogs/conf/app.ini' must exist inside Docker after installation
|
||||
if ! test -d /data/gogs/conf/app.ini; then
|
||||
# Only chown for the first time, owner of '/data' is 'git' inside Docker after installation
|
||||
if [ $(stat -c '%U' /data) != 'git' ]; then
|
||||
chown -R git:git /data /app/gogs ~git/
|
||||
fi
|
||||
chmod 0755 /data /data/gogs ~git/
|
||||
|
||||
@@ -11,6 +11,5 @@ HostKey /data/ssh/ssh_host_ed25519_key
|
||||
PermitRootLogin no
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
PasswordAuthentication no
|
||||
UsePrivilegeSeparation no
|
||||
PermitUserEnvironment yes
|
||||
AllowUsers git
|
||||
|
||||
6
gogs.go
6
gogs.go
@@ -16,17 +16,17 @@ import (
|
||||
"github.com/gogs/gogs/pkg/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.11.86.0130"
|
||||
const Version = "0.11.91.0811"
|
||||
|
||||
func init() {
|
||||
setting.AppVer = APP_VER
|
||||
setting.AppVer = Version
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
app.Name = "Gogs"
|
||||
app.Usage = "A painless self-hosted Git service"
|
||||
app.Version = APP_VER
|
||||
app.Version = Version
|
||||
app.Commands = []cli.Command{
|
||||
cmd.Web,
|
||||
cmd.Serv,
|
||||
|
||||
@@ -59,7 +59,7 @@ type Access struct {
|
||||
Mode AccessMode
|
||||
}
|
||||
|
||||
func accessLevel(e Engine, userID int64, repo *Repository) (AccessMode, error) {
|
||||
func userAccessMode(e Engine, userID int64, repo *Repository) (AccessMode, error) {
|
||||
mode := ACCESS_MODE_NONE
|
||||
// Everyone has read access to public repository
|
||||
if !repo.IsPrivate {
|
||||
@@ -84,14 +84,13 @@ func accessLevel(e Engine, userID int64, repo *Repository) (AccessMode, error) {
|
||||
return access.Mode, nil
|
||||
}
|
||||
|
||||
// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
|
||||
// user does not have access.
|
||||
func AccessLevel(userID int64, repo *Repository) (AccessMode, error) {
|
||||
return accessLevel(x, userID, repo)
|
||||
// UserAccessMode returns the access mode of given user to the repository.
|
||||
func UserAccessMode(userID int64, repo *Repository) (AccessMode, error) {
|
||||
return userAccessMode(x, userID, repo)
|
||||
}
|
||||
|
||||
func hasAccess(e Engine, userID int64, repo *Repository, testMode AccessMode) (bool, error) {
|
||||
mode, err := accessLevel(e, userID, repo)
|
||||
mode, err := userAccessMode(e, userID, repo)
|
||||
return mode >= testMode, err
|
||||
}
|
||||
|
||||
|
||||
@@ -604,6 +604,7 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||
if err = PrepareWebhooks(repo, HOOK_EVENT_CREATE, &api.CreatePayload{
|
||||
Ref: refName,
|
||||
RefType: "tag",
|
||||
Sha: opts.NewCommitID,
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
Repo: apiRepo,
|
||||
Sender: apiPusher,
|
||||
|
||||
@@ -92,7 +92,7 @@ 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.
|
||||
// 1. Repository watchers, users who participated in comments and the assignee.
|
||||
// 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 {
|
||||
@@ -142,6 +142,12 @@ func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string)
|
||||
tos = append(tos, participants[i].Email)
|
||||
names = append(names, participants[i].Name)
|
||||
}
|
||||
if issue.Assignee != nil && issue.Assignee.ID != doer.ID {
|
||||
if !com.IsSliceContainsStr(names, issue.Assignee.Name) {
|
||||
tos = append(tos, issue.Assignee.Email)
|
||||
names = append(names, issue.Assignee.Name)
|
||||
}
|
||||
}
|
||||
mailer.SendIssueCommentMail(NewMailerIssue(issue), NewMailerRepo(issue.Repo), NewMailerUser(doer), tos)
|
||||
|
||||
// Mail mentioned people and exclude watchers.
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
@@ -156,14 +157,14 @@ func getEngine() (*xorm.Engine, error) {
|
||||
connStr = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", host, port, DbCfg.Name, DbCfg.User, DbCfg.Passwd)
|
||||
case "sqlite3":
|
||||
if !EnableSQLite3 {
|
||||
return nil, errors.New("This binary version does not build support for SQLite3.")
|
||||
return nil, errors.New("this binary version does not build support for SQLite3")
|
||||
}
|
||||
if err := os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm); err != nil {
|
||||
return nil, fmt.Errorf("Fail to create directories: %v", err)
|
||||
return nil, fmt.Errorf("create directories: %v", err)
|
||||
}
|
||||
connStr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc"
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
|
||||
return nil, fmt.Errorf("unknown database type: %s", DbCfg.Type)
|
||||
}
|
||||
return xorm.NewEngine(DbCfg.Type, connStr)
|
||||
}
|
||||
@@ -171,7 +172,7 @@ func getEngine() (*xorm.Engine, error) {
|
||||
func NewTestEngine(x *xorm.Engine) (err error) {
|
||||
x, err = getEngine()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Connect to database: %v", err)
|
||||
return fmt.Errorf("connect to database: %v", err)
|
||||
}
|
||||
|
||||
x.SetMapper(core.GonicMapper{})
|
||||
@@ -181,7 +182,7 @@ func NewTestEngine(x *xorm.Engine) (err error) {
|
||||
func SetEngine() (err error) {
|
||||
x, err = getEngine()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Fail to connect to database: %v", err)
|
||||
return fmt.Errorf("connect to database: %v", err)
|
||||
}
|
||||
|
||||
x.SetMapper(core.GonicMapper{})
|
||||
@@ -197,9 +198,14 @@ func SetEngine() (err error) {
|
||||
MaxDays: sec.Key("MAX_DAYS").MustInt64(3),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Fail to create 'xorm.log': %v", err)
|
||||
return fmt.Errorf("create 'xorm.log': %v", err)
|
||||
}
|
||||
|
||||
// To prevent mystery "MySQL: invalid connection" error,
|
||||
// see https://github.com/gogs/gogs/issues/5532.
|
||||
x.SetMaxIdleConns(0)
|
||||
x.SetConnMaxLifetime(time.Second)
|
||||
|
||||
if setting.ProdMode {
|
||||
x.SetLogger(xorm.NewSimpleLogger3(logger, xorm.DEFAULT_LOG_PREFIX, xorm.DEFAULT_LOG_FLAG, core.LOG_WARNING))
|
||||
} else {
|
||||
@@ -219,7 +225,7 @@ func NewEngine() (err error) {
|
||||
}
|
||||
|
||||
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
|
||||
return fmt.Errorf("sync database struct error: %v\n", err)
|
||||
return fmt.Errorf("sync structs to database tables: %v\n", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -281,14 +287,14 @@ func DumpDatabase(dirPath string) (err error) {
|
||||
tableFile := path.Join(dirPath, tableName+".json")
|
||||
f, err := os.Create(tableFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to create JSON file: %v", err)
|
||||
return fmt.Errorf("create JSON file: %v", err)
|
||||
}
|
||||
|
||||
if err = x.Asc("id").Iterate(table, func(idx int, bean interface{}) (err error) {
|
||||
return jsoniter.NewEncoder(f).Encode(bean)
|
||||
}); err != nil {
|
||||
f.Close()
|
||||
return fmt.Errorf("fail to dump table '%s': %v", tableName, err)
|
||||
return fmt.Errorf("dump table '%s': %v", tableName, err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
||||
@@ -1924,7 +1924,7 @@ func GitFsck() {
|
||||
repo := bean.(*Repository)
|
||||
repoPath := repo.RepoPath()
|
||||
if err := git.Fsck(repoPath, setting.Cron.RepoHealthCheck.Timeout, setting.Cron.RepoHealthCheck.Args...); err != nil {
|
||||
desc := fmt.Sprintf("Fail to health check repository '%s': %v", repoPath, err)
|
||||
desc := fmt.Sprintf("Failed to perform health check on repository '%s': %v", repoPath, err)
|
||||
log.Warn(desc)
|
||||
if err = CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error(3, "CreateRepositoryNotice: %v", err)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -25,8 +25,8 @@ type APIContext struct {
|
||||
Org *APIOrganization
|
||||
}
|
||||
|
||||
// FIXME: move to github.com/gogs/go-gogs-client
|
||||
const DOC_URL = "https://github.com/gogs/docs-api"
|
||||
// FIXME: move this constant to github.com/gogs/go-gogs-client
|
||||
const DocURL = "https://github.com/gogs/docs-api"
|
||||
|
||||
// Error responses error message to client with given message.
|
||||
// If status is 500, also it prints error to log.
|
||||
@@ -44,7 +44,7 @@ func (c *APIContext) Error(status int, title string, obj interface{}) {
|
||||
|
||||
c.JSON(status, map[string]string{
|
||||
"message": message,
|
||||
"url": DOC_URL,
|
||||
"url": DocURL,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -327,6 +327,8 @@ func Contexter() macaron.Handler {
|
||||
c.Data["ShowFooterBranding"] = setting.ShowFooterBranding
|
||||
c.Data["ShowFooterVersion"] = setting.ShowFooterVersion
|
||||
|
||||
c.renderNoticeBanner()
|
||||
|
||||
ctx.Map(c)
|
||||
}
|
||||
}
|
||||
|
||||
62
pkg/context/notice.go
Normal file
62
pkg/context/notice.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2019 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 context
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
"github.com/gogs/gogs/pkg/markup"
|
||||
"github.com/gogs/gogs/pkg/setting"
|
||||
"github.com/gogs/gogs/pkg/tool"
|
||||
)
|
||||
|
||||
// renderNoticeBanner checks if a notice banner file exists and loads the message to display
|
||||
// on all pages.
|
||||
func (c *Context) renderNoticeBanner() {
|
||||
fpath := path.Join(setting.CustomPath, "notice", "banner.md")
|
||||
if !com.IsExist(fpath) {
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Open(fpath)
|
||||
if err != nil {
|
||||
log.Error(2, "Failed to open file %q: %v", fpath, err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
log.Error(2, "Failed to stat file %q: %v", fpath, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Limit size to prevent very large messages from breaking pages
|
||||
var maxSize int64 = 1024
|
||||
|
||||
if fi.Size() > maxSize { // Refuse to print very long messages
|
||||
log.Warn("Notice banner file %q size too large [%d > %d]: refusing to render", fpath, fi.Size(), maxSize)
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, maxSize)
|
||||
n, err := f.Read(buf)
|
||||
if err != nil {
|
||||
log.Error(2, "Failed to read file %q: %v", fpath, err)
|
||||
return
|
||||
}
|
||||
buf = buf[:n]
|
||||
|
||||
if !tool.IsTextFile(buf) {
|
||||
log.Warn("Notice banner file %q does not appear to be a text file: aborting", fpath)
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["ServerNotice"] = string(markup.RawMarkdown(buf, ""))
|
||||
}
|
||||
@@ -160,9 +160,9 @@ func RepoAssignment(pages ...bool) macaron.Handler {
|
||||
if c.IsLogged && c.User.IsAdmin {
|
||||
c.Repo.AccessMode = models.ACCESS_MODE_OWNER
|
||||
} else {
|
||||
mode, err := models.AccessLevel(c.UserID(), repo)
|
||||
mode, err := models.UserAccessMode(c.UserID(), repo)
|
||||
if err != nil {
|
||||
c.ServerError("AccessLevel", err)
|
||||
c.ServerError("UserAccessMode", err)
|
||||
return
|
||||
}
|
||||
c.Repo.AccessMode = mode
|
||||
|
||||
@@ -173,7 +173,7 @@ func composeTplData(subject, body, link string) map[string]interface{} {
|
||||
|
||||
func composeIssueMessage(issue Issue, repo Repository, doer User, tplName string, tos []string, info string) *Message {
|
||||
subject := issue.MailSubject()
|
||||
body := string(markup.RenderSpecialLink([]byte(issue.Content()), repo.HTMLURL(), repo.ComposeMetas()))
|
||||
body := string(markup.Markdown([]byte(issue.Content()), repo.HTMLURL(), repo.ComposeMetas()))
|
||||
data := composeTplData(subject, body, issue.HTMLURL())
|
||||
data["Doer"] = doer
|
||||
content, err := mailRender.HTMLString(tplName, data)
|
||||
|
||||
@@ -33,6 +33,9 @@ func NewFuncMap() []template.FuncMap {
|
||||
"GoVer": func() string {
|
||||
return strings.Title(runtime.Version())
|
||||
},
|
||||
"Year": func() int {
|
||||
return time.Now().Year()
|
||||
},
|
||||
"UseHTTPS": func() bool {
|
||||
return strings.HasPrefix(setting.AppURL, "https")
|
||||
},
|
||||
@@ -94,13 +97,13 @@ func NewFuncMap() []template.FuncMap {
|
||||
}
|
||||
return str[start:end]
|
||||
},
|
||||
"Join": strings.Join,
|
||||
"EllipsisString": tool.EllipsisString,
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"ShortSHA1": tool.ShortSHA1,
|
||||
"MD5": tool.MD5,
|
||||
"Join": strings.Join,
|
||||
"EllipsisString": tool.EllipsisString,
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"ShortSHA1": tool.ShortSHA1,
|
||||
"MD5": tool.MD5,
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"EscapePound": EscapePound,
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/gogs/gogs/routes/api/v1/user"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Administration-Organizations#create-a-new-organization
|
||||
func CreateOrg(c *context.APIContext, form api.CreateOrgOption) {
|
||||
org.CreateOrgForUser(c, form, user.GetUserByParams(c))
|
||||
}
|
||||
|
||||
@@ -13,11 +13,7 @@ import (
|
||||
func GetRepositoryByParams(c *context.APIContext) *models.Repository {
|
||||
repo, err := models.GetRepositoryByName(c.Org.Team.OrgID, c.Params(":reponame"))
|
||||
if err != nil {
|
||||
if errors.IsRepoNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetRepositoryByName", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetRepositoryByName", errors.IsRepoNotExist, err)
|
||||
return nil
|
||||
}
|
||||
return repo
|
||||
@@ -29,11 +25,11 @@ func AddTeamRepository(c *context.APIContext) {
|
||||
return
|
||||
}
|
||||
if err := c.Org.Team.AddRepository(repo); err != nil {
|
||||
c.Error(500, "AddRepository", err)
|
||||
c.ServerError("AddRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
func RemoveTeamRepository(c *context.APIContext) {
|
||||
@@ -42,9 +38,9 @@ func RemoveTeamRepository(c *context.APIContext) {
|
||||
return
|
||||
}
|
||||
if err := c.Org.Team.RemoveRepository(repo.ID); err != nil {
|
||||
c.Error(500, "RemoveRepository", err)
|
||||
c.ServerError("RemoveRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
@@ -22,14 +24,14 @@ func CreateTeam(c *context.APIContext, form api.CreateTeamOption) {
|
||||
}
|
||||
if err := models.NewTeam(team); err != nil {
|
||||
if models.IsErrTeamAlreadyExist(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "NewTeam", err)
|
||||
c.ServerError("NewTeam", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(201, convert.ToTeam(team))
|
||||
c.JSON(http.StatusCreated, convert.ToTeam(team))
|
||||
}
|
||||
|
||||
func AddTeamMember(c *context.APIContext) {
|
||||
@@ -38,11 +40,11 @@ func AddTeamMember(c *context.APIContext) {
|
||||
return
|
||||
}
|
||||
if err := c.Org.Team.AddMember(u.ID); err != nil {
|
||||
c.Error(500, "AddMember", err)
|
||||
c.ServerError("AddMember", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
func RemoveTeamMember(c *context.APIContext) {
|
||||
@@ -52,9 +54,9 @@ func RemoveTeamMember(c *context.APIContext) {
|
||||
}
|
||||
|
||||
if err := c.Org.Team.RemoveMember(u.ID); err != nil {
|
||||
c.Error(500, "RemoveMember", err)
|
||||
c.ServerError("RemoveMember", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/gogs/gogs/routes/api/v1/user"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Administration-Repositories#create-a-new-repository
|
||||
func CreateRepo(c *context.APIContext, form api.CreateRepoOption) {
|
||||
owner := user.GetUserByParams(c)
|
||||
if c.Written() {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
log "gopkg.in/clog.v1"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -25,9 +27,9 @@ func parseLoginSource(c *context.APIContext, u *models.User, sourceID int64, log
|
||||
source, err := models.GetLoginSourceByID(sourceID)
|
||||
if err != nil {
|
||||
if errors.IsLoginSourceNotExist(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "GetLoginSourceByID", err)
|
||||
c.ServerError("GetLoginSourceByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -37,7 +39,6 @@ func parseLoginSource(c *context.APIContext, u *models.User, sourceID int64, log
|
||||
u.LoginName = loginName
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Administration-Users#create-a-new-user
|
||||
func CreateUser(c *context.APIContext, form api.CreateUserOption) {
|
||||
u := &models.User{
|
||||
Name: form.Username,
|
||||
@@ -58,23 +59,22 @@ func CreateUser(c *context.APIContext, form api.CreateUserOption) {
|
||||
models.IsErrEmailAlreadyUsed(err) ||
|
||||
models.IsErrNameReserved(err) ||
|
||||
models.IsErrNamePatternNotAllowed(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "CreateUser", err)
|
||||
c.ServerError("CreateUser", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account created by admin (%s): %s", c.User.Name, u.Name)
|
||||
log.Trace("Account created by admin %q: %s", c.User.Name, u.Name)
|
||||
|
||||
// Send email notification.
|
||||
if form.SendNotify && setting.MailService != nil {
|
||||
mailer.SendRegisterNotifyMail(c.Context.Context, models.NewMailerUser(u))
|
||||
}
|
||||
|
||||
c.JSON(201, u.APIFormat())
|
||||
c.JSON(http.StatusCreated, u.APIFormat())
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Administration-Users#edit-an-existing-user
|
||||
func EditUser(c *context.APIContext, form api.EditUserOption) {
|
||||
u := user.GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -90,7 +90,7 @@ func EditUser(c *context.APIContext, form api.EditUserOption) {
|
||||
u.Passwd = form.Password
|
||||
var err error
|
||||
if u.Salt, err = models.GetUserSalt(); err != nil {
|
||||
c.Error(500, "UpdateUser", err)
|
||||
c.ServerError("GetUserSalt", err)
|
||||
return
|
||||
}
|
||||
u.EncodePasswd()
|
||||
@@ -119,18 +119,17 @@ func EditUser(c *context.APIContext, form api.EditUserOption) {
|
||||
|
||||
if err := models.UpdateUser(u); err != nil {
|
||||
if models.IsErrEmailAlreadyUsed(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "UpdateUser", err)
|
||||
c.ServerError("UpdateUser", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account profile updated by admin (%s): %s", c.User.Name, u.Name)
|
||||
log.Trace("Account profile updated by admin %q: %s", c.User.Name, u.Name)
|
||||
|
||||
c.JSON(200, u.APIFormat())
|
||||
c.JSONSuccess(u.APIFormat())
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Administration-Users#delete-a-user
|
||||
func DeleteUser(c *context.APIContext) {
|
||||
u := user.GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -140,18 +139,17 @@ func DeleteUser(c *context.APIContext) {
|
||||
if err := models.DeleteUser(u); err != nil {
|
||||
if models.IsErrUserOwnRepos(err) ||
|
||||
models.IsErrUserHasOrgs(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "DeleteUser", err)
|
||||
c.ServerError("DeleteUser", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("Account deleted by admin(%s): %s", c.User.Name, u.Name)
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Administration-Users#create-a-public-key-for-user
|
||||
func CreatePublicKey(c *context.APIContext, form api.CreateKeyOption) {
|
||||
u := user.GetUserByParams(c)
|
||||
if c.Written() {
|
||||
|
||||
@@ -24,21 +24,21 @@ import (
|
||||
"github.com/gogs/gogs/routes/api/v1/user"
|
||||
)
|
||||
|
||||
// repoAssignment extracts information from URL parameters to retrieve the repository,
|
||||
// and makes sure the context user has at least the read access to the repository.
|
||||
func repoAssignment() macaron.Handler {
|
||||
return func(c *context.APIContext) {
|
||||
userName := c.Params(":username")
|
||||
repoName := c.Params(":reponame")
|
||||
username := c.Params(":username")
|
||||
reponame := c.Params(":reponame")
|
||||
|
||||
var (
|
||||
owner *models.User
|
||||
err error
|
||||
)
|
||||
var err error
|
||||
var owner *models.User
|
||||
|
||||
// Check if the user is the same as the repository owner.
|
||||
if c.IsLogged && c.User.LowerName == strings.ToLower(userName) {
|
||||
// Check if the context user is the repository owner.
|
||||
if c.IsLogged && c.User.LowerName == strings.ToLower(username) {
|
||||
owner = c.User
|
||||
} else {
|
||||
owner, err = models.GetUserByName(userName)
|
||||
owner, err = models.GetUserByName(username)
|
||||
if err != nil {
|
||||
c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
|
||||
return
|
||||
@@ -46,11 +46,11 @@ func repoAssignment() macaron.Handler {
|
||||
}
|
||||
c.Repo.Owner = owner
|
||||
|
||||
repo, err := models.GetRepositoryByName(owner.ID, repoName)
|
||||
r, err := models.GetRepositoryByName(owner.ID, reponame)
|
||||
if err != nil {
|
||||
c.NotFoundOrServerError("GetRepositoryByName", errors.IsRepoNotExist, err)
|
||||
return
|
||||
} else if err = repo.GetOwner(); err != nil {
|
||||
} else if err = r.GetOwner(); err != nil {
|
||||
c.ServerError("GetOwner", err)
|
||||
return
|
||||
}
|
||||
@@ -58,9 +58,9 @@ func repoAssignment() macaron.Handler {
|
||||
if c.IsTokenAuth && c.User.IsAdmin {
|
||||
c.Repo.AccessMode = models.ACCESS_MODE_OWNER
|
||||
} else {
|
||||
mode, err := models.AccessLevel(c.UserID(), repo)
|
||||
mode, err := models.UserAccessMode(c.UserID(), r)
|
||||
if err != nil {
|
||||
c.ServerError("AccessLevel", err)
|
||||
c.ServerError("UserAccessMode", err)
|
||||
return
|
||||
}
|
||||
c.Repo.AccessMode = mode
|
||||
@@ -71,47 +71,11 @@ func repoAssignment() macaron.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
c.Repo.Repository = repo
|
||||
}
|
||||
}
|
||||
|
||||
// Contexter middleware already checks token for user sign in process.
|
||||
func reqToken() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.IsTokenAuth {
|
||||
c.Error(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func reqBasicAuth() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.IsBasicAuth {
|
||||
c.Error(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func reqAdmin() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.IsLogged || !c.User.IsAdmin {
|
||||
c.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func reqRepoWriter() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
c.Repo.Repository = r
|
||||
}
|
||||
}
|
||||
|
||||
// orgAssignment extracts information from URL parameters to retrieve the organization or team.
|
||||
func orgAssignment(args ...bool) macaron.Handler {
|
||||
var (
|
||||
assignOrg bool
|
||||
@@ -145,6 +109,56 @@ func orgAssignment(args ...bool) macaron.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// reqToken makes sure the context user is authorized via access token.
|
||||
func reqToken() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.IsTokenAuth {
|
||||
c.Error(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reqBasicAuth makes sure the context user is authorized via HTTP Basic Auth.
|
||||
func reqBasicAuth() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.IsBasicAuth {
|
||||
c.Error(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reqAdmin makes sure the context user is a site admin.
|
||||
func reqAdmin() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.IsLogged || !c.User.IsAdmin {
|
||||
c.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reqRepoWriter makes sure the context user has at least write access to the repository.
|
||||
func reqRepoWriter() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reqRepoWriter makes sure the context user has at least admin access to the repository.
|
||||
func reqRepoAdmin() macaron.Handler {
|
||||
return func(c *context.Context) {
|
||||
if !c.Repo.IsAdmin() {
|
||||
c.Error(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mustEnableIssues(c *context.APIContext) {
|
||||
if !c.Repo.Repository.EnableIssues || c.Repo.Repository.EnableExternalTracker {
|
||||
c.NotFound()
|
||||
@@ -152,7 +166,7 @@ func mustEnableIssues(c *context.APIContext) {
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterRoutes registers all v1 APIs routes to web application.
|
||||
// RegisterRoutes registers all routes in API v1 to the web application.
|
||||
// FIXME: custom form error response
|
||||
func RegisterRoutes(m *macaron.Macaron) {
|
||||
bind := binding.Bind
|
||||
@@ -173,7 +187,8 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Get("", user.GetInfo)
|
||||
|
||||
m.Group("/tokens", func() {
|
||||
m.Combo("").Get(user.ListAccessTokens).
|
||||
m.Combo("").
|
||||
Get(user.ListAccessTokens).
|
||||
Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken)
|
||||
}, reqBasicAuth())
|
||||
})
|
||||
@@ -193,30 +208,37 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
|
||||
m.Group("/user", func() {
|
||||
m.Get("", user.GetAuthenticatedUser)
|
||||
m.Combo("/emails").Get(user.ListEmails).
|
||||
m.Combo("/emails").
|
||||
Get(user.ListEmails).
|
||||
Post(bind(api.CreateEmailOption{}), user.AddEmail).
|
||||
Delete(bind(api.CreateEmailOption{}), user.DeleteEmail)
|
||||
|
||||
m.Get("/followers", user.ListMyFollowers)
|
||||
m.Group("/following", func() {
|
||||
m.Get("", user.ListMyFollowing)
|
||||
m.Combo("/:username").Get(user.CheckMyFollowing).Put(user.Follow).Delete(user.Unfollow)
|
||||
m.Combo("/:username").
|
||||
Get(user.CheckMyFollowing).
|
||||
Put(user.Follow).
|
||||
Delete(user.Unfollow)
|
||||
})
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(user.ListMyPublicKeys).
|
||||
m.Combo("").
|
||||
Get(user.ListMyPublicKeys).
|
||||
Post(bind(api.CreateKeyOption{}), user.CreatePublicKey)
|
||||
m.Combo("/:id").Get(user.GetPublicKey).
|
||||
m.Combo("/:id").
|
||||
Get(user.GetPublicKey).
|
||||
Delete(user.DeletePublicKey)
|
||||
})
|
||||
|
||||
m.Combo("/issues").Get(repo.ListUserIssues)
|
||||
m.Get("/issues", repo.ListUserIssues)
|
||||
}, reqToken())
|
||||
|
||||
// Repositories
|
||||
m.Get("/users/:username/repos", reqToken(), repo.ListUserRepositories)
|
||||
m.Get("/orgs/:org/repos", reqToken(), repo.ListOrgRepositories)
|
||||
m.Combo("/user/repos", reqToken()).Get(repo.ListMyRepos).
|
||||
m.Combo("/user/repos", reqToken()).
|
||||
Get(repo.ListMyRepos).
|
||||
Post(bind(api.CreateRepoOption{}), repo.Create)
|
||||
m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo)
|
||||
|
||||
@@ -232,16 +254,22 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("/hooks", func() {
|
||||
m.Combo("").Get(repo.ListHooks).
|
||||
m.Combo("").
|
||||
Get(repo.ListHooks).
|
||||
Post(bind(api.CreateHookOption{}), repo.CreateHook)
|
||||
m.Combo("/:id").Patch(bind(api.EditHookOption{}), repo.EditHook).
|
||||
m.Combo("/:id").
|
||||
Patch(bind(api.EditHookOption{}), repo.EditHook).
|
||||
Delete(repo.DeleteHook)
|
||||
})
|
||||
}, reqRepoAdmin())
|
||||
|
||||
m.Group("/collaborators", func() {
|
||||
m.Get("", repo.ListCollaborators)
|
||||
m.Combo("/:collaborator").Get(repo.IsCollaborator).Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
|
||||
m.Combo("/:collaborator").
|
||||
Get(repo.IsCollaborator).
|
||||
Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
|
||||
Delete(repo.DeleteCollaborator)
|
||||
})
|
||||
}, reqRepoAdmin())
|
||||
|
||||
m.Get("/raw/*", context.RepoRef(), repo.GetRawFile)
|
||||
m.Get("/archive/*", repo.GetArchive)
|
||||
m.Get("/forks", repo.ListForks)
|
||||
@@ -249,59 +277,77 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Get("", repo.ListBranches)
|
||||
m.Get("/*", repo.GetBranch)
|
||||
})
|
||||
|
||||
m.Group("/commits", func() {
|
||||
m.Get("/:sha", repo.GetSingleCommit)
|
||||
m.Get("/*", repo.GetReferenceSHA)
|
||||
})
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo.ListDeployKeys).
|
||||
m.Combo("").
|
||||
Get(repo.ListDeployKeys).
|
||||
Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
|
||||
m.Combo("/:id").Get(repo.GetDeployKey).
|
||||
m.Combo("/:id").
|
||||
Get(repo.GetDeployKey).
|
||||
Delete(repo.DeleteDeploykey)
|
||||
})
|
||||
}, reqRepoAdmin())
|
||||
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("").Get(repo.ListIssues).Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
|
||||
m.Combo("").
|
||||
Get(repo.ListIssues).
|
||||
Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
|
||||
m.Group("/comments", func() {
|
||||
m.Get("", repo.ListRepoIssueComments)
|
||||
m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
|
||||
m.Patch("/:id", bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
|
||||
})
|
||||
m.Group("/:index", func() {
|
||||
m.Combo("").Get(repo.GetIssue).Patch(bind(api.EditIssueOption{}), repo.EditIssue)
|
||||
m.Combo("").
|
||||
Get(repo.GetIssue).
|
||||
Patch(bind(api.EditIssueOption{}), repo.EditIssue)
|
||||
|
||||
m.Group("/comments", func() {
|
||||
m.Combo("").Get(repo.ListIssueComments).Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
|
||||
m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
|
||||
m.Combo("").
|
||||
Get(repo.ListIssueComments).
|
||||
Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
|
||||
m.Combo("/:id").
|
||||
Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
|
||||
Delete(repo.DeleteIssueComment)
|
||||
})
|
||||
|
||||
m.Get("/labels", repo.ListIssueLabels)
|
||||
m.Group("/labels", func() {
|
||||
m.Combo("").Get(repo.ListIssueLabels).
|
||||
m.Combo("").
|
||||
Post(bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
|
||||
Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
|
||||
Delete(repo.ClearIssueLabels)
|
||||
m.Delete("/:id", repo.DeleteIssueLabel)
|
||||
})
|
||||
|
||||
}, reqRepoWriter())
|
||||
})
|
||||
}, mustEnableIssues)
|
||||
|
||||
m.Group("/labels", func() {
|
||||
m.Combo("").Get(repo.ListLabels).
|
||||
Post(bind(api.CreateLabelOption{}), repo.CreateLabel)
|
||||
m.Combo("/:id").Get(repo.GetLabel).Patch(bind(api.EditLabelOption{}), repo.EditLabel).
|
||||
m.Get("", repo.ListLabels)
|
||||
m.Get("/:id", repo.GetLabel)
|
||||
})
|
||||
m.Group("/labels", func() {
|
||||
m.Post("", bind(api.CreateLabelOption{}), repo.CreateLabel)
|
||||
m.Combo("/:id").
|
||||
Patch(bind(api.EditLabelOption{}), repo.EditLabel).
|
||||
Delete(repo.DeleteLabel)
|
||||
}, reqRepoWriter())
|
||||
|
||||
m.Group("/milestones", func() {
|
||||
m.Get("", repo.ListMilestones)
|
||||
m.Get("/:id", repo.GetMilestone)
|
||||
})
|
||||
m.Group("/milestones", func() {
|
||||
m.Combo("").Get(repo.ListMilestones).
|
||||
Post(reqRepoWriter(), bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
|
||||
m.Combo("/:id").Get(repo.GetMilestone).
|
||||
Patch(reqRepoWriter(), bind(api.EditMilestoneOption{}), repo.EditMilestone).
|
||||
Delete(reqRepoWriter(), repo.DeleteMilestone)
|
||||
})
|
||||
m.Post("", bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
|
||||
m.Combo("/:id").
|
||||
Patch(bind(api.EditMilestoneOption{}), repo.EditMilestone).
|
||||
Delete(repo.DeleteMilestone)
|
||||
}, reqRepoWriter())
|
||||
|
||||
m.Patch("/issue-tracker", bind(api.EditIssueTrackerOption{}), repo.IssueTracker)
|
||||
m.Post("/mirror-sync", repo.MirrorSync)
|
||||
m.Patch("/issue-tracker", reqRepoWriter(), bind(api.EditIssueTrackerOption{}), repo.IssueTracker)
|
||||
m.Post("/mirror-sync", reqRepoWriter(), repo.MirrorSync)
|
||||
m.Get("/editorconfig/:filename", context.RepoRef(), repo.GetEditorconfig)
|
||||
}, repoAssignment())
|
||||
}, reqToken())
|
||||
@@ -309,24 +355,25 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Get("/issues", reqToken(), repo.ListUserIssues)
|
||||
|
||||
// Organizations
|
||||
m.Combo("/user/orgs", reqToken()).Get(org.ListMyOrgs).Post(bind(api.CreateOrgOption{}), org.CreateMyOrg)
|
||||
m.Combo("/user/orgs", reqToken()).
|
||||
Get(org.ListMyOrgs).
|
||||
Post(bind(api.CreateOrgOption{}), org.CreateMyOrg)
|
||||
|
||||
m.Get("/users/:username/orgs", org.ListUserOrgs)
|
||||
m.Group("/orgs/:orgname", func() {
|
||||
m.Combo("").Get(org.Get).Patch(bind(api.EditOrgOption{}), org.Edit)
|
||||
m.Combo("/teams").Get(org.ListTeams)
|
||||
m.Combo("").
|
||||
Get(org.Get).
|
||||
Patch(bind(api.EditOrgOption{}), org.Edit)
|
||||
m.Get("/teams", org.ListTeams)
|
||||
}, orgAssignment(true))
|
||||
|
||||
m.Any("/*", func(c *context.Context) {
|
||||
c.NotFound()
|
||||
})
|
||||
|
||||
m.Group("/admin", func() {
|
||||
m.Group("/users", func() {
|
||||
m.Post("", bind(api.CreateUserOption{}), admin.CreateUser)
|
||||
|
||||
m.Group("/:username", func() {
|
||||
m.Combo("").Patch(bind(api.EditUserOption{}), admin.EditUser).
|
||||
m.Combo("").
|
||||
Patch(bind(api.EditUserOption{}), admin.EditUser).
|
||||
Delete(admin.DeleteUser)
|
||||
m.Post("/keys", bind(api.CreateKeyOption{}), admin.CreatePublicKey)
|
||||
m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
|
||||
@@ -339,12 +386,21 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
m.Post("", orgAssignment(true), bind(api.CreateTeamOption{}), admin.CreateTeam)
|
||||
})
|
||||
})
|
||||
|
||||
m.Group("/teams", func() {
|
||||
m.Group("/:teamid", func() {
|
||||
m.Combo("/members/:username").Put(admin.AddTeamMember).Delete(admin.RemoveTeamMember)
|
||||
m.Combo("/repos/:reponame").Put(admin.AddTeamRepository).Delete(admin.RemoveTeamRepository)
|
||||
m.Combo("/members/:username").
|
||||
Put(admin.AddTeamMember).
|
||||
Delete(admin.RemoveTeamMember)
|
||||
m.Combo("/repos/:reponame").
|
||||
Put(admin.AddTeamRepository).
|
||||
Delete(admin.RemoveTeamRepository)
|
||||
}, orgAssignment(false, true))
|
||||
})
|
||||
}, reqAdmin())
|
||||
|
||||
m.Any("/*", func(c *context.Context) {
|
||||
c.NotFound()
|
||||
})
|
||||
}, context.APIContexter())
|
||||
}
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
package misc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
"github.com/gogs/gogs/pkg/context"
|
||||
"github.com/gogs/gogs/pkg/markup"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Miscellaneous#render-an-arbitrary-markdown-document
|
||||
func Markdown(c *context.APIContext, form api.MarkdownOption) {
|
||||
if c.HasApiError() {
|
||||
c.Error(422, "", c.GetErrMsg())
|
||||
c.Error(http.StatusUnprocessableEntity, "", c.GetErrMsg())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -31,11 +32,10 @@ func Markdown(c *context.APIContext, form api.MarkdownOption) {
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Miscellaneous#render-a-markdown-document-in-raw-mode
|
||||
func MarkdownRaw(c *context.APIContext) {
|
||||
body, err := c.Req.Body().Bytes()
|
||||
if err != nil {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
return
|
||||
}
|
||||
c.Write(markup.RawMarkdown(body, ""))
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
@@ -31,9 +33,9 @@ func CreateOrgForUser(c *context.APIContext, apiForm api.CreateOrgOption, user *
|
||||
if models.IsErrUserAlreadyExist(err) ||
|
||||
models.IsErrNameReserved(err) ||
|
||||
models.IsErrNamePatternNotAllowed(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "CreateOrganization", err)
|
||||
c.ServerError("CreateOrganization", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -43,7 +45,7 @@ func CreateOrgForUser(c *context.APIContext, apiForm api.CreateOrgOption, user *
|
||||
|
||||
func listUserOrgs(c *context.APIContext, u *models.User, all bool) {
|
||||
if err := u.GetOrganizations(all); err != nil {
|
||||
c.Error(500, "GetOrganizations", err)
|
||||
c.ServerError("GetOrganizations", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,20 +53,17 @@ func listUserOrgs(c *context.APIContext, u *models.User, all bool) {
|
||||
for i := range u.Orgs {
|
||||
apiOrgs[i] = convert.ToOrganization(u.Orgs[i])
|
||||
}
|
||||
c.JSON(200, &apiOrgs)
|
||||
c.JSONSuccess(&apiOrgs)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Organizations#list-your-organizations
|
||||
func ListMyOrgs(c *context.APIContext) {
|
||||
listUserOrgs(c, c.User, true)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Organizations#create-your-organization
|
||||
func CreateMyOrg(c *context.APIContext, apiForm api.CreateOrgOption) {
|
||||
CreateOrgForUser(c, apiForm, c.User)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Organizations#list-user-organizations
|
||||
func ListUserOrgs(c *context.APIContext) {
|
||||
u := user.GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -73,16 +72,14 @@ func ListUserOrgs(c *context.APIContext) {
|
||||
listUserOrgs(c, u, false)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Organizations#get-an-organization
|
||||
func Get(c *context.APIContext) {
|
||||
c.JSON(200, convert.ToOrganization(c.Org.Organization))
|
||||
c.JSONSuccess(convert.ToOrganization(c.Org.Organization))
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Organizations#edit-an-organization
|
||||
func Edit(c *context.APIContext, form api.EditOrgOption) {
|
||||
org := c.Org.Organization
|
||||
if !org.IsOwnedBy(c.User.ID) {
|
||||
c.Status(403)
|
||||
c.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -91,9 +88,9 @@ func Edit(c *context.APIContext, form api.EditOrgOption) {
|
||||
org.Website = form.Website
|
||||
org.Location = form.Location
|
||||
if err := models.UpdateUser(org); err != nil {
|
||||
c.Error(500, "UpdateUser", err)
|
||||
c.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, convert.ToOrganization(org))
|
||||
c.JSONSuccess(convert.ToOrganization(org))
|
||||
}
|
||||
|
||||
@@ -12,38 +12,32 @@ import (
|
||||
"github.com/gogs/gogs/routes/repo"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Contents#download-raw-content
|
||||
func GetRawFile(c *context.APIContext) {
|
||||
if !c.Repo.HasAccess() {
|
||||
c.Status(404)
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if c.Repo.Repository.IsBare {
|
||||
c.Status(404)
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
blob, err := c.Repo.Commit.GetBlobByPath(c.Repo.TreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetBlobByPath", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetBlobByPath", git.IsErrNotExist, err)
|
||||
return
|
||||
}
|
||||
if err = repo.ServeBlob(c.Context, blob); err != nil {
|
||||
c.Error(500, "ServeBlob", err)
|
||||
c.ServerError("ServeBlob", err)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Contents#download-archive
|
||||
func GetArchive(c *context.APIContext) {
|
||||
repoPath := models.RepoPath(c.Params(":username"), c.Params(":reponame"))
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
c.Error(500, "OpenRepository", err)
|
||||
c.ServerError("OpenRepository", err)
|
||||
return
|
||||
}
|
||||
c.Repo.GitRepo = gitRepo
|
||||
@@ -54,19 +48,15 @@ func GetArchive(c *context.APIContext) {
|
||||
func GetEditorconfig(c *context.APIContext) {
|
||||
ec, err := c.Repo.GetEditorconfig()
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
c.Error(404, "GetEditorconfig", err)
|
||||
} else {
|
||||
c.Error(500, "GetEditorconfig", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetEditorconfig", git.IsErrNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
fileName := c.Params("filename")
|
||||
def := ec.GetDefinitionForFilename(fileName)
|
||||
if def == nil {
|
||||
c.Error(404, "GetDefinitionForFilename", err)
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
c.JSON(200, def)
|
||||
c.JSONSuccess(def)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -19,13 +20,13 @@ import (
|
||||
func listIssues(c *context.APIContext, opts *models.IssuesOptions) {
|
||||
issues, err := models.Issues(opts)
|
||||
if err != nil {
|
||||
c.Error(500, "Issues", err)
|
||||
c.ServerError("Issues", err)
|
||||
return
|
||||
}
|
||||
|
||||
count, err := models.IssuesCount(opts)
|
||||
if err != nil {
|
||||
c.Error(500, "IssuesCount", err)
|
||||
c.ServerError("IssuesCount", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -33,14 +34,14 @@ func listIssues(c *context.APIContext, opts *models.IssuesOptions) {
|
||||
apiIssues := make([]*api.Issue, len(issues))
|
||||
for i := range issues {
|
||||
if err = issues[i].LoadAttributes(); err != nil {
|
||||
c.Error(500, "LoadAttributes", err)
|
||||
c.ServerError("LoadAttributes", err)
|
||||
return
|
||||
}
|
||||
apiIssues[i] = issues[i].APIFormat()
|
||||
}
|
||||
|
||||
c.SetLinkHeader(int(count), setting.UI.IssuePagingNum)
|
||||
c.JSON(200, &apiIssues)
|
||||
c.JSONSuccess(&apiIssues)
|
||||
}
|
||||
|
||||
func ListUserIssues(c *context.APIContext) {
|
||||
@@ -66,14 +67,10 @@ func ListIssues(c *context.APIContext) {
|
||||
func GetIssue(c *context.APIContext) {
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, issue.APIFormat())
|
||||
c.JSONSuccess(issue.APIFormat())
|
||||
}
|
||||
|
||||
func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
|
||||
@@ -90,9 +87,9 @@ func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
|
||||
assignee, err := models.GetUserByName(form.Assignee)
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", form.Assignee))
|
||||
c.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("assignee does not exist: [name: %s]", form.Assignee))
|
||||
} else {
|
||||
c.Error(500, "GetUserByName", err)
|
||||
c.ServerError("GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -104,13 +101,13 @@ func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
|
||||
}
|
||||
|
||||
if err := models.NewIssue(c.Repo.Repository, issue, form.Labels, nil); err != nil {
|
||||
c.Error(500, "NewIssue", err)
|
||||
c.ServerError("NewIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
if form.Closed {
|
||||
if err := issue.ChangeStatus(c.User, c.Repo.Repository, true); err != nil {
|
||||
c.Error(500, "ChangeStatus", err)
|
||||
c.ServerError("ChangeStatus", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -119,25 +116,21 @@ func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
|
||||
var err error
|
||||
issue, err = models.GetIssueByID(issue.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetIssueByID", err)
|
||||
c.ServerError("GetIssueByID", err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, issue.APIFormat())
|
||||
c.JSON(http.StatusCreated, issue.APIFormat())
|
||||
}
|
||||
|
||||
func EditIssue(c *context.APIContext, form api.EditIssueOption) {
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !issue.IsPoster(c.User.ID) && !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
c.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -156,9 +149,9 @@ func EditIssue(c *context.APIContext, form api.EditIssueOption) {
|
||||
assignee, err := models.GetUserByName(*form.Assignee)
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Error(422, "", fmt.Sprintf("assignee does not exist: [name: %s]", *form.Assignee))
|
||||
c.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("assignee does not exist: [name: %s]", *form.Assignee))
|
||||
} else {
|
||||
c.Error(500, "GetUserByName", err)
|
||||
c.ServerError("GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -166,7 +159,7 @@ func EditIssue(c *context.APIContext, form api.EditIssueOption) {
|
||||
}
|
||||
|
||||
if err = models.UpdateIssueUserByAssignee(issue); err != nil {
|
||||
c.Error(500, "UpdateIssueUserByAssignee", err)
|
||||
c.ServerError("UpdateIssueUserByAssignee", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -175,18 +168,18 @@ func EditIssue(c *context.APIContext, form api.EditIssueOption) {
|
||||
oldMilestoneID := issue.MilestoneID
|
||||
issue.MilestoneID = *form.Milestone
|
||||
if err = models.ChangeMilestoneAssign(c.User, issue, oldMilestoneID); err != nil {
|
||||
c.Error(500, "ChangeMilestoneAssign", err)
|
||||
c.ServerError("ChangeMilestoneAssign", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = models.UpdateIssue(issue); err != nil {
|
||||
c.Error(500, "UpdateIssue", err)
|
||||
c.ServerError("UpdateIssue", err)
|
||||
return
|
||||
}
|
||||
if form.State != nil {
|
||||
if err = issue.ChangeStatus(c.User, c.Repo.Repository, api.STATE_CLOSED == api.StateType(*form.State)); err != nil {
|
||||
c.Error(500, "ChangeStatus", err)
|
||||
c.ServerError("ChangeStatus", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -194,8 +187,8 @@ func EditIssue(c *context.APIContext, form api.EditIssueOption) {
|
||||
// Refetch from database to assign some automatic values
|
||||
issue, err = models.GetIssueByID(issue.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetIssueByID", err)
|
||||
c.ServerError("GetIssueByID", err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, issue.APIFormat())
|
||||
c.JSON(http.StatusCreated, issue.APIFormat())
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -18,7 +19,7 @@ func ListIssueComments(c *context.APIContext) {
|
||||
var err error
|
||||
since, err = time.Parse(time.RFC3339, c.Query("since"))
|
||||
if err != nil {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -26,13 +27,13 @@ func ListIssueComments(c *context.APIContext) {
|
||||
// comments,err:=models.GetCommentsByIssueIDSince(, since)
|
||||
issue, err := models.GetRawIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
c.Error(500, "GetRawIssueByIndex", err)
|
||||
c.ServerError("GetRawIssueByIndex", err)
|
||||
return
|
||||
}
|
||||
|
||||
comments, err := models.GetCommentsByIssueIDSince(issue.ID, since.Unix())
|
||||
if err != nil {
|
||||
c.Error(500, "GetCommentsByIssueIDSince", err)
|
||||
c.ServerError("GetCommentsByIssueIDSince", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +41,7 @@ func ListIssueComments(c *context.APIContext) {
|
||||
for i := range comments {
|
||||
apiComments[i] = comments[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiComments)
|
||||
c.JSONSuccess(&apiComments)
|
||||
}
|
||||
|
||||
func ListRepoIssueComments(c *context.APIContext) {
|
||||
@@ -49,14 +50,14 @@ func ListRepoIssueComments(c *context.APIContext) {
|
||||
var err error
|
||||
since, err = time.Parse(time.RFC3339, c.Query("since"))
|
||||
if err != nil {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
comments, err := models.GetCommentsByRepoIDSince(c.Repo.Repository.ID, since.Unix())
|
||||
if err != nil {
|
||||
c.Error(500, "GetCommentsByRepoIDSince", err)
|
||||
c.ServerError("GetCommentsByRepoIDSince", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -64,75 +65,67 @@ func ListRepoIssueComments(c *context.APIContext) {
|
||||
for i := range comments {
|
||||
apiComments[i] = comments[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiComments)
|
||||
c.JSONSuccess(&apiComments)
|
||||
}
|
||||
|
||||
func CreateIssueComment(c *context.APIContext, form api.CreateIssueCommentOption) {
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
c.ServerError("GetIssueByIndex", err)
|
||||
return
|
||||
}
|
||||
|
||||
comment, err := models.CreateIssueComment(c.User, c.Repo.Repository, issue, form.Body, nil)
|
||||
if err != nil {
|
||||
c.Error(500, "CreateIssueComment", err)
|
||||
c.ServerError("CreateIssueComment", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(201, comment.APIFormat())
|
||||
c.JSON(http.StatusCreated, comment.APIFormat())
|
||||
}
|
||||
|
||||
func EditIssueComment(c *context.APIContext, form api.EditIssueCommentOption) {
|
||||
comment, err := models.GetCommentByID(c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrCommentNotExist(err) {
|
||||
c.Error(404, "GetCommentByID", err)
|
||||
} else {
|
||||
c.Error(500, "GetCommentByID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() {
|
||||
c.Status(403)
|
||||
c.Status(http.StatusForbidden)
|
||||
return
|
||||
} else if comment.Type != models.COMMENT_TYPE_COMMENT {
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
return
|
||||
}
|
||||
|
||||
oldContent := comment.Content
|
||||
comment.Content = form.Body
|
||||
if err := models.UpdateComment(c.User, comment, oldContent); err != nil {
|
||||
c.Error(500, "UpdateComment", err)
|
||||
c.ServerError("UpdateComment", err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, comment.APIFormat())
|
||||
c.JSONSuccess(comment.APIFormat())
|
||||
}
|
||||
|
||||
func DeleteIssueComment(c *context.APIContext) {
|
||||
comment, err := models.GetCommentByID(c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrCommentNotExist(err) {
|
||||
c.Error(404, "GetCommentByID", err)
|
||||
} else {
|
||||
c.Error(500, "GetCommentByID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
if c.User.ID != comment.PosterID && !c.Repo.IsAdmin() {
|
||||
c.Status(403)
|
||||
c.Status(http.StatusForbidden)
|
||||
return
|
||||
} else if comment.Type != models.COMMENT_TYPE_COMMENT {
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DeleteCommentByID(c.User, comment.ID); err != nil {
|
||||
c.Error(500, "DeleteCommentByID", err)
|
||||
c.ServerError("DeleteCommentByID", err)
|
||||
return
|
||||
}
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
@@ -15,11 +17,7 @@ import (
|
||||
func ListIssueLabels(c *context.APIContext) {
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -27,39 +25,30 @@ func ListIssueLabels(c *context.APIContext) {
|
||||
for i := range issue.Labels {
|
||||
apiLabels[i] = issue.Labels[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiLabels)
|
||||
c.JSONSuccess(&apiLabels)
|
||||
}
|
||||
|
||||
func AddIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
labels, err := models.GetLabelsInRepoByIDs(c.Repo.Repository.ID, form.Labels)
|
||||
if err != nil {
|
||||
c.Error(500, "GetLabelsInRepoByIDs", err)
|
||||
c.ServerError("GetLabelsInRepoByIDs", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = issue.AddLabels(c.User, labels); err != nil {
|
||||
c.Error(500, "AddLabels", err)
|
||||
c.ServerError("AddLabels", err)
|
||||
return
|
||||
}
|
||||
|
||||
labels, err = models.GetLabelsByIssueID(issue.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetLabelsByIssueID", err)
|
||||
c.ServerError("GetLabelsByIssueID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -67,73 +56,55 @@ func AddIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
|
||||
for i := range labels {
|
||||
apiLabels[i] = issue.Labels[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiLabels)
|
||||
c.JSONSuccess(&apiLabels)
|
||||
}
|
||||
|
||||
func DeleteIssueLabel(c *context.APIContext) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
label, err := models.GetLabelOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrLabelNotExist(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "GetLabelInRepoByID", err)
|
||||
c.ServerError("GetLabelInRepoByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteIssueLabel(issue, label); err != nil {
|
||||
c.Error(500, "DeleteIssueLabel", err)
|
||||
c.ServerError("DeleteIssueLabel", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
func ReplaceIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
labels, err := models.GetLabelsInRepoByIDs(c.Repo.Repository.ID, form.Labels)
|
||||
if err != nil {
|
||||
c.Error(500, "GetLabelsInRepoByIDs", err)
|
||||
c.ServerError("GetLabelsInRepoByIDs", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := issue.ReplaceLabels(labels); err != nil {
|
||||
c.Error(500, "ReplaceLabels", err)
|
||||
c.ServerError("ReplaceLabels", err)
|
||||
return
|
||||
}
|
||||
|
||||
labels, err = models.GetLabelsByIssueID(issue.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetLabelsByIssueID", err)
|
||||
c.ServerError("GetLabelsByIssueID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -141,29 +112,20 @@ func ReplaceIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
|
||||
for i := range labels {
|
||||
apiLabels[i] = issue.Labels[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiLabels)
|
||||
c.JSONSuccess(&apiLabels)
|
||||
}
|
||||
|
||||
func ClearIssueLabels(c *context.APIContext) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if errors.IsIssueNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetIssueByIndex", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetIssueByIndex", errors.IsIssueNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := issue.ClearLabels(c.User); err != nil {
|
||||
c.Error(500, "ClearLabels", err)
|
||||
c.ServerError("ClearLabels", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -16,7 +18,7 @@ import (
|
||||
func ListLabels(c *context.APIContext) {
|
||||
labels, err := models.GetLabelsByRepoID(c.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetLabelsByRepoID", err)
|
||||
c.ServerError("GetLabelsByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -24,7 +26,7 @@ func ListLabels(c *context.APIContext) {
|
||||
for i := range labels {
|
||||
apiLabels[i] = labels[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiLabels)
|
||||
c.JSONSuccess(&apiLabels)
|
||||
}
|
||||
|
||||
func GetLabel(c *context.APIContext) {
|
||||
@@ -37,48 +39,30 @@ func GetLabel(c *context.APIContext) {
|
||||
label, err = models.GetLabelOfRepoByName(c.Repo.Repository.ID, idStr)
|
||||
}
|
||||
if err != nil {
|
||||
if models.IsErrLabelNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetLabelByRepoID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetLabel", models.IsErrLabelNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, label.APIFormat())
|
||||
c.JSONSuccess(label.APIFormat())
|
||||
}
|
||||
|
||||
func CreateLabel(c *context.APIContext, form api.CreateLabelOption) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
label := &models.Label{
|
||||
Name: form.Name,
|
||||
Color: form.Color,
|
||||
RepoID: c.Repo.Repository.ID,
|
||||
}
|
||||
if err := models.NewLabels(label); err != nil {
|
||||
c.Error(500, "NewLabel", err)
|
||||
c.ServerError("NewLabel", err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, label.APIFormat())
|
||||
c.JSON(http.StatusCreated, label.APIFormat())
|
||||
}
|
||||
|
||||
func EditLabel(c *context.APIContext, form api.EditLabelOption) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
label, err := models.GetLabelOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrLabelNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetLabelByRepoID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetLabelOfRepoByID", models.IsErrLabelNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -89,22 +73,17 @@ func EditLabel(c *context.APIContext, form api.EditLabelOption) {
|
||||
label.Color = *form.Color
|
||||
}
|
||||
if err := models.UpdateLabel(label); err != nil {
|
||||
c.Handle(500, "UpdateLabel", err)
|
||||
c.ServerError("UpdateLabel", err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, label.APIFormat())
|
||||
c.JSONSuccess(label.APIFormat())
|
||||
}
|
||||
|
||||
func DeleteLabel(c *context.APIContext) {
|
||||
if !c.Repo.IsWriter() {
|
||||
c.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteLabel(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
|
||||
c.Error(500, "DeleteLabel", err)
|
||||
c.ServerError("DeleteLabel", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
func ListMilestones(c *context.APIContext) {
|
||||
milestones, err := models.GetMilestonesByRepoID(c.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetMilestonesByRepoID", err)
|
||||
c.ServerError("GetMilestonesByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -24,20 +25,16 @@ func ListMilestones(c *context.APIContext) {
|
||||
for i := range milestones {
|
||||
apiMilestones[i] = milestones[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiMilestones)
|
||||
c.JSONSuccess(&apiMilestones)
|
||||
}
|
||||
|
||||
func GetMilestone(c *context.APIContext) {
|
||||
milestone, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrMilestoneNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetMilestoneByRepoID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetMilestoneByRepoID", models.IsErrMilestoneNotExist, err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, milestone.APIFormat())
|
||||
c.JSONSuccess(milestone.APIFormat())
|
||||
}
|
||||
|
||||
func CreateMilestone(c *context.APIContext, form api.CreateMilestoneOption) {
|
||||
@@ -54,20 +51,16 @@ func CreateMilestone(c *context.APIContext, form api.CreateMilestoneOption) {
|
||||
}
|
||||
|
||||
if err := models.NewMilestone(milestone); err != nil {
|
||||
c.Error(500, "NewMilestone", err)
|
||||
c.ServerError("NewMilestone", err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, milestone.APIFormat())
|
||||
c.JSON(http.StatusCreated, milestone.APIFormat())
|
||||
}
|
||||
|
||||
func EditMilestone(c *context.APIContext, form api.EditMilestoneOption) {
|
||||
milestone, err := models.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrMilestoneNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetMilestoneByRepoID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetMilestoneByRepoID", models.IsErrMilestoneNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,21 +76,21 @@ func EditMilestone(c *context.APIContext, form api.EditMilestoneOption) {
|
||||
|
||||
if form.State != nil {
|
||||
if err = milestone.ChangeStatus(api.STATE_CLOSED == api.StateType(*form.State)); err != nil {
|
||||
c.Error(500, "ChangeStatus", err)
|
||||
c.ServerError("ChangeStatus", err)
|
||||
return
|
||||
}
|
||||
} else if err = models.UpdateMilestone(milestone); err != nil {
|
||||
c.Handle(500, "UpdateMilestone", err)
|
||||
c.ServerError("UpdateMilestone", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, milestone.APIFormat())
|
||||
c.JSONSuccess(milestone.APIFormat())
|
||||
}
|
||||
|
||||
func DeleteMilestone(c *context.APIContext) {
|
||||
if err := models.DeleteMilestoneOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
|
||||
c.Error(500, "DeleteMilestoneByRepoID", err)
|
||||
c.ServerError("DeleteMilestoneByRepoID", err)
|
||||
return
|
||||
}
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
log "gopkg.in/clog.v1"
|
||||
@@ -19,7 +21,6 @@ import (
|
||||
"github.com/gogs/gogs/routes/api/v1/convert"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories#search-repositories
|
||||
func Search(c *context.APIContext) {
|
||||
opts := &models.SearchRepoOptions{
|
||||
Keyword: path.Base(c.Query("q")),
|
||||
@@ -35,7 +36,7 @@ func Search(c *context.APIContext) {
|
||||
} else {
|
||||
u, err := models.GetUserByID(opts.OwnerID)
|
||||
if err != nil {
|
||||
c.JSON(500, map[string]interface{}{
|
||||
c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
@@ -50,7 +51,7 @@ func Search(c *context.APIContext) {
|
||||
|
||||
repos, count, err := models.SearchRepositoryByName(opts)
|
||||
if err != nil {
|
||||
c.JSON(500, map[string]interface{}{
|
||||
c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
@@ -58,7 +59,7 @@ func Search(c *context.APIContext) {
|
||||
}
|
||||
|
||||
if err = models.RepositoryList(repos).LoadAttributes(); err != nil {
|
||||
c.JSON(500, map[string]interface{}{
|
||||
c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
@@ -71,7 +72,7 @@ func Search(c *context.APIContext) {
|
||||
}
|
||||
|
||||
c.SetLinkHeader(int(count), opts.PageSize)
|
||||
c.JSON(200, map[string]interface{}{
|
||||
c.JSONSuccess(map[string]interface{}{
|
||||
"ok": true,
|
||||
"data": results,
|
||||
})
|
||||
@@ -98,12 +99,12 @@ func listUserRepositories(c *context.APIContext, username string) {
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
c.Error(500, "GetUserRepositories", err)
|
||||
c.ServerError("GetUserRepositories", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.RepositoryList(ownRepos).LoadAttributes(); err != nil {
|
||||
c.Error(500, "LoadAttributes(ownRepos)", err)
|
||||
c.ServerError("LoadAttributes(ownRepos)", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -113,13 +114,13 @@ func listUserRepositories(c *context.APIContext, username string) {
|
||||
for i := range ownRepos {
|
||||
repos[i] = ownRepos[i].APIFormat(&api.Permission{true, true, true})
|
||||
}
|
||||
c.JSON(200, &repos)
|
||||
c.JSONSuccess(&repos)
|
||||
return
|
||||
}
|
||||
|
||||
accessibleRepos, err := user.GetRepositoryAccesses()
|
||||
if err != nil {
|
||||
c.Error(500, "GetRepositoryAccesses", err)
|
||||
c.ServerError("GetRepositoryAccesses", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -139,7 +140,7 @@ func listUserRepositories(c *context.APIContext, username string) {
|
||||
i++
|
||||
}
|
||||
|
||||
c.JSON(200, &repos)
|
||||
c.JSONSuccess(&repos)
|
||||
}
|
||||
|
||||
func ListMyRepos(c *context.APIContext) {
|
||||
@@ -168,14 +169,14 @@ func CreateUserRepo(c *context.APIContext, owner *models.User, opt api.CreateRep
|
||||
if models.IsErrRepoAlreadyExist(err) ||
|
||||
models.IsErrNameReserved(err) ||
|
||||
models.IsErrNamePatternNotAllowed(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
if repo != nil {
|
||||
if err = models.DeleteRepository(c.User.ID, repo.ID); err != nil {
|
||||
log.Error(2, "DeleteRepository: %v", err)
|
||||
}
|
||||
}
|
||||
c.Error(500, "CreateRepository", err)
|
||||
c.ServerError("CreateRepository", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -183,11 +184,10 @@ func CreateUserRepo(c *context.APIContext, owner *models.User, opt api.CreateRep
|
||||
c.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories#create
|
||||
func Create(c *context.APIContext, opt api.CreateRepoOption) {
|
||||
// Shouldn't reach this condition, but just in case.
|
||||
if c.User.IsOrganization() {
|
||||
c.Error(422, "", "not allowed creating repository for organization")
|
||||
c.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization")
|
||||
return
|
||||
}
|
||||
CreateUserRepo(c, c.User, opt)
|
||||
@@ -196,22 +196,17 @@ func Create(c *context.APIContext, opt api.CreateRepoOption) {
|
||||
func CreateOrgRepo(c *context.APIContext, opt api.CreateRepoOption) {
|
||||
org, err := models.GetOrgByName(c.Params(":org"))
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Error(422, "", err)
|
||||
} else {
|
||||
c.Error(500, "GetOrgByName", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetOrgByName", errors.IsUserNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !org.IsOwnedBy(c.User.ID) {
|
||||
c.Error(403, "", "Given user is not owner of organization.")
|
||||
c.Error(http.StatusForbidden, "", "given user is not owner of organization")
|
||||
return
|
||||
}
|
||||
CreateUserRepo(c, org, opt)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories#migrate
|
||||
func Migrate(c *context.APIContext, f form.MigrateRepo) {
|
||||
ctxUser := c.User
|
||||
// Not equal means context user is an organization,
|
||||
@@ -220,27 +215,27 @@ func Migrate(c *context.APIContext, f form.MigrateRepo) {
|
||||
org, err := models.GetUserByID(f.Uid)
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "GetUserByID", err)
|
||||
c.Error(http.StatusInternalServerError, "GetUserByID", err)
|
||||
}
|
||||
return
|
||||
} else if !org.IsOrganization() && !c.User.IsAdmin {
|
||||
c.Error(403, "", "Given user is not an organization")
|
||||
c.Error(http.StatusForbidden, "", "given user is not an organization")
|
||||
return
|
||||
}
|
||||
ctxUser = org
|
||||
}
|
||||
|
||||
if c.HasError() {
|
||||
c.Error(422, "", c.GetErrMsg())
|
||||
c.Error(http.StatusUnprocessableEntity, "", c.GetErrMsg())
|
||||
return
|
||||
}
|
||||
|
||||
if ctxUser.IsOrganization() && !c.User.IsAdmin {
|
||||
// Check ownership of organization.
|
||||
if !ctxUser.IsOwnedBy(c.User.ID) {
|
||||
c.Error(403, "", "Given user is not owner of organization")
|
||||
c.Error(http.StatusForbidden, "", "Given user is not owner of organization")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -251,16 +246,16 @@ func Migrate(c *context.APIContext, f form.MigrateRepo) {
|
||||
addrErr := err.(models.ErrInvalidCloneAddr)
|
||||
switch {
|
||||
case addrErr.IsURLError:
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
case addrErr.IsPermissionDenied:
|
||||
c.Error(422, "", "You are not allowed to import local repositories")
|
||||
c.Error(http.StatusUnprocessableEntity, "", "you are not allowed to import local repositories")
|
||||
case addrErr.IsInvalidPath:
|
||||
c.Error(422, "", "Invalid local path, it does not exist or not a directory")
|
||||
c.Error(http.StatusUnprocessableEntity, "", "invalid local path, it does not exist or not a directory")
|
||||
default:
|
||||
c.Error(500, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error())
|
||||
c.ServerError("ParseRemoteAddr", fmt.Errorf("unknown error type (ErrInvalidCloneAddr): %v", err))
|
||||
}
|
||||
} else {
|
||||
c.Error(500, "ParseRemoteAddr", err)
|
||||
c.ServerError("ParseRemoteAddr", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -280,9 +275,9 @@ func Migrate(c *context.APIContext, f form.MigrateRepo) {
|
||||
}
|
||||
|
||||
if errors.IsReachLimitOfRepo(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "MigrateRepository", models.HandleMirrorCredentials(err.Error(), true))
|
||||
c.ServerError("MigrateRepository", errors.New(models.HandleMirrorCredentials(err.Error(), true)))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -291,46 +286,40 @@ func Migrate(c *context.APIContext, f form.MigrateRepo) {
|
||||
c.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
|
||||
}
|
||||
|
||||
// FIXME: Inject to *context.APIContext
|
||||
// FIXME: inject in the handler chain
|
||||
func parseOwnerAndRepo(c *context.APIContext) (*models.User, *models.Repository) {
|
||||
owner, err := models.GetUserByName(c.Params(":username"))
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Error(422, "", err)
|
||||
c.Error(http.StatusUnprocessableEntity, "", err)
|
||||
} else {
|
||||
c.Error(500, "GetUserByName", err)
|
||||
c.ServerError("GetUserByName", err)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
repo, err := models.GetRepositoryByName(owner.ID, c.Params(":reponame"))
|
||||
if err != nil {
|
||||
if errors.IsRepoNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetRepositoryByName", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetRepositoryByName", errors.IsRepoNotExist, err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return owner, repo
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories#get
|
||||
func Get(c *context.APIContext) {
|
||||
_, repo := parseOwnerAndRepo(c)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, repo.APIFormat(&api.Permission{
|
||||
c.JSONSuccess(repo.APIFormat(&api.Permission{
|
||||
Admin: c.Repo.IsAdmin(),
|
||||
Push: c.Repo.IsWriter(),
|
||||
Pull: true,
|
||||
}))
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories#delete
|
||||
func Delete(c *context.APIContext) {
|
||||
owner, repo := parseOwnerAndRepo(c)
|
||||
if c.Written() {
|
||||
@@ -338,30 +327,30 @@ func Delete(c *context.APIContext) {
|
||||
}
|
||||
|
||||
if owner.IsOrganization() && !owner.IsOwnedBy(c.User.ID) {
|
||||
c.Error(403, "", "Given user is not owner of organization.")
|
||||
c.Error(http.StatusForbidden, "", "given user is not owner of organization")
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteRepository(owner.ID, repo.ID); err != nil {
|
||||
c.Error(500, "DeleteRepository", err)
|
||||
c.ServerError("DeleteRepository", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("Repository deleted: %s/%s", owner.Name, repo.Name)
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
func ListForks(c *context.APIContext) {
|
||||
forks, err := c.Repo.Repository.GetForks()
|
||||
if err != nil {
|
||||
c.Error(500, "GetForks", err)
|
||||
c.ServerError("GetForks", err)
|
||||
return
|
||||
}
|
||||
|
||||
apiForks := make([]*api.Repository, len(forks))
|
||||
for i := range forks {
|
||||
if err := forks[i].GetOwner(); err != nil {
|
||||
c.Error(500, "GetOwner", err)
|
||||
c.ServerError("GetOwner", err)
|
||||
return
|
||||
}
|
||||
apiForks[i] = forks[i].APIFormat(&api.Permission{
|
||||
@@ -371,7 +360,7 @@ func ListForks(c *context.APIContext) {
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(200, &apiForks)
|
||||
c.JSONSuccess(&apiForks)
|
||||
}
|
||||
|
||||
func IssueTracker(c *context.APIContext, form api.EditIssueTrackerOption) {
|
||||
@@ -409,10 +398,10 @@ func MirrorSync(c *context.APIContext) {
|
||||
if c.Written() {
|
||||
return
|
||||
} else if !repo.IsMirror {
|
||||
c.Status(404)
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
go models.MirrorQueue.Add(repo.ID)
|
||||
c.Status(202)
|
||||
c.Status(http.StatusAccepted)
|
||||
}
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
"github.com/gogs/gogs/pkg/context"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users#list-access-tokens-for-a-user
|
||||
func ListAccessTokens(c *context.APIContext) {
|
||||
tokens, err := models.ListAccessTokens(c.User.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "ListAccessTokens", err)
|
||||
c.ServerError("ListAccessTokens", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23,18 +24,17 @@ func ListAccessTokens(c *context.APIContext) {
|
||||
for i := range tokens {
|
||||
apiTokens[i] = &api.AccessToken{tokens[i].Name, tokens[i].Sha1}
|
||||
}
|
||||
c.JSON(200, &apiTokens)
|
||||
c.JSONSuccess(&apiTokens)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users#create-a-access-token
|
||||
func CreateAccessToken(c *context.APIContext, form api.CreateAccessTokenOption) {
|
||||
t := &models.AccessToken{
|
||||
UID: c.User.ID,
|
||||
Name: form.Name,
|
||||
}
|
||||
if err := models.NewAccessToken(t); err != nil {
|
||||
c.Error(500, "NewAccessToken", err)
|
||||
c.ServerError("NewAccessToken", err)
|
||||
return
|
||||
}
|
||||
c.JSON(201, &api.AccessToken{t.Name, t.Sha1})
|
||||
c.JSON(http.StatusCreated, &api.AccessToken{t.Name, t.Sha1})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
@@ -13,24 +15,22 @@ import (
|
||||
"github.com/gogs/gogs/routes/api/v1/convert"
|
||||
)
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Emails#list-email-addresses-for-a-user
|
||||
func ListEmails(c *context.APIContext) {
|
||||
emails, err := models.GetEmailAddresses(c.User.ID)
|
||||
if err != nil {
|
||||
c.Error(500, "GetEmailAddresses", err)
|
||||
c.ServerError("GetEmailAddresses", err)
|
||||
return
|
||||
}
|
||||
apiEmails := make([]*api.Email, len(emails))
|
||||
for i := range emails {
|
||||
apiEmails[i] = convert.ToEmail(emails[i])
|
||||
}
|
||||
c.JSON(200, &apiEmails)
|
||||
c.JSONSuccess(&apiEmails)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Emails#add-email-addresses
|
||||
func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
|
||||
if len(form.Emails) == 0 {
|
||||
c.Status(422)
|
||||
c.Status(http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
|
||||
|
||||
if err := models.AddEmailAddresses(emails); err != nil {
|
||||
if models.IsErrEmailAlreadyUsed(err) {
|
||||
c.Error(422, "", "Email address has been used: "+err.(models.ErrEmailAlreadyUsed).Email)
|
||||
c.Error(http.StatusUnprocessableEntity, "", "email address has been used: "+err.(models.ErrEmailAlreadyUsed).Email)
|
||||
} else {
|
||||
c.Error(500, "AddEmailAddresses", err)
|
||||
c.Error(http.StatusInternalServerError, "AddEmailAddresses", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -56,13 +56,12 @@ func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
|
||||
for i := range emails {
|
||||
apiEmails[i] = convert.ToEmail(emails[i])
|
||||
}
|
||||
c.JSON(201, &apiEmails)
|
||||
c.JSON(http.StatusCreated, &apiEmails)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Emails#delete-email-addresses
|
||||
func DeleteEmail(c *context.APIContext, form api.CreateEmailOption) {
|
||||
if len(form.Emails) == 0 {
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -75,8 +74,8 @@ func DeleteEmail(c *context.APIContext, form api.CreateEmailOption) {
|
||||
}
|
||||
|
||||
if err := models.DeleteEmailAddresses(emails); err != nil {
|
||||
c.Error(500, "DeleteEmailAddresses", err)
|
||||
c.Error(http.StatusInternalServerError, "DeleteEmailAddresses", err)
|
||||
return
|
||||
}
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@ func responseApiUsers(c *context.APIContext, users []*models.User) {
|
||||
for i := range users {
|
||||
apiUsers[i] = users[i].APIFormat()
|
||||
}
|
||||
c.JSON(200, &apiUsers)
|
||||
c.JSONSuccess(&apiUsers)
|
||||
}
|
||||
|
||||
func listUserFollowers(c *context.APIContext, u *models.User) {
|
||||
users, err := u.GetFollowers(c.QueryInt("page"))
|
||||
if err != nil {
|
||||
c.Error(500, "GetUserFollowers", err)
|
||||
c.ServerError("GetUserFollowers", err)
|
||||
return
|
||||
}
|
||||
responseApiUsers(c, users)
|
||||
@@ -32,7 +32,6 @@ func ListMyFollowers(c *context.APIContext) {
|
||||
listUserFollowers(c, c.User)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Followers#list-followers-of-a-user
|
||||
func ListFollowers(c *context.APIContext) {
|
||||
u := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -44,7 +43,7 @@ func ListFollowers(c *context.APIContext) {
|
||||
func listUserFollowing(c *context.APIContext, u *models.User) {
|
||||
users, err := u.GetFollowing(c.QueryInt("page"))
|
||||
if err != nil {
|
||||
c.Error(500, "GetFollowing", err)
|
||||
c.ServerError("GetFollowing", err)
|
||||
return
|
||||
}
|
||||
responseApiUsers(c, users)
|
||||
@@ -54,7 +53,6 @@ func ListMyFollowing(c *context.APIContext) {
|
||||
listUserFollowing(c, c.User)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Followers#list-users-followed-by-another-user
|
||||
func ListFollowing(c *context.APIContext) {
|
||||
u := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -65,13 +63,12 @@ func ListFollowing(c *context.APIContext) {
|
||||
|
||||
func checkUserFollowing(c *context.APIContext, u *models.User, followID int64) {
|
||||
if u.IsFollowing(followID) {
|
||||
c.Status(204)
|
||||
c.NotFound()
|
||||
} else {
|
||||
c.Status(404)
|
||||
c.NotFound()
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Followers#check-if-you-are-following-a-user
|
||||
func CheckMyFollowing(c *context.APIContext) {
|
||||
target := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -80,7 +77,6 @@ func CheckMyFollowing(c *context.APIContext) {
|
||||
checkUserFollowing(c, c.User, target.ID)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Followers#check-if-one-user-follows-another
|
||||
func CheckFollowing(c *context.APIContext) {
|
||||
u := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -93,28 +89,26 @@ func CheckFollowing(c *context.APIContext) {
|
||||
checkUserFollowing(c, u, target.ID)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Followers#follow-a-user
|
||||
func Follow(c *context.APIContext) {
|
||||
target := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
if err := models.FollowUser(c.User.ID, target.ID); err != nil {
|
||||
c.Error(500, "FollowUser", err)
|
||||
c.ServerError("FollowUser", err)
|
||||
return
|
||||
}
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Followers#unfollow-a-user
|
||||
func Unfollow(c *context.APIContext) {
|
||||
target := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
return
|
||||
}
|
||||
if err := models.UnfollowUser(c.User.ID, target.ID); err != nil {
|
||||
c.Error(500, "UnfollowUser", err)
|
||||
c.ServerError("UnfollowUser", err)
|
||||
return
|
||||
}
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package user
|
||||
|
||||
import (
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
"net/http"
|
||||
|
||||
"github.com/gogs/gogs/models"
|
||||
"github.com/gogs/gogs/models/errors"
|
||||
@@ -18,11 +19,7 @@ import (
|
||||
func GetUserByParamsName(c *context.APIContext, name string) *models.User {
|
||||
user, err := models.GetUserByName(c.Params(name))
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetUserByName", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
|
||||
return nil
|
||||
}
|
||||
return user
|
||||
@@ -40,7 +37,7 @@ func composePublicKeysAPILink() string {
|
||||
func listPublicKeys(c *context.APIContext, uid int64) {
|
||||
keys, err := models.ListPublicKeys(uid)
|
||||
if err != nil {
|
||||
c.Error(500, "ListPublicKeys", err)
|
||||
c.ServerError("ListPublicKeys", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -50,15 +47,13 @@ func listPublicKeys(c *context.APIContext, uid int64) {
|
||||
apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
|
||||
}
|
||||
|
||||
c.JSON(200, &apiKeys)
|
||||
c.JSONSuccess(&apiKeys)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Public-Keys#list-your-public-keys
|
||||
func ListMyPublicKeys(c *context.APIContext) {
|
||||
listPublicKeys(c, c.User.ID)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Public-Keys#list-public-keys-for-a-user
|
||||
func ListPublicKeys(c *context.APIContext) {
|
||||
user := GetUserByParams(c)
|
||||
if c.Written() {
|
||||
@@ -67,20 +62,15 @@ func ListPublicKeys(c *context.APIContext) {
|
||||
listPublicKeys(c, user.ID)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Public-Keys#get-a-single-public-key
|
||||
func GetPublicKey(c *context.APIContext) {
|
||||
key, err := models.GetPublicKeyByID(c.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrKeyNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetPublicKeyByID", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetPublicKeyByID", models.IsErrKeyNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
apiLink := composePublicKeysAPILink()
|
||||
c.JSON(200, convert.ToPublicKey(apiLink, key))
|
||||
c.JSONSuccess(convert.ToPublicKey(apiLink, key))
|
||||
}
|
||||
|
||||
// CreateUserPublicKey creates new public key to given user by ID.
|
||||
@@ -97,24 +87,22 @@ func CreateUserPublicKey(c *context.APIContext, form api.CreateKeyOption, uid in
|
||||
return
|
||||
}
|
||||
apiLink := composePublicKeysAPILink()
|
||||
c.JSON(201, convert.ToPublicKey(apiLink, key))
|
||||
c.JSON(http.StatusCreated, convert.ToPublicKey(apiLink, key))
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Public-Keys#create-a-public-key
|
||||
func CreatePublicKey(c *context.APIContext, form api.CreateKeyOption) {
|
||||
CreateUserPublicKey(c, form, c.User.ID)
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Users-Public-Keys#delete-a-public-key
|
||||
func DeletePublicKey(c *context.APIContext) {
|
||||
if err := models.DeletePublicKey(c.User, c.ParamsInt64(":id")); err != nil {
|
||||
if models.IsErrKeyAccessDenied(err) {
|
||||
c.Error(403, "", "You do not have access to this key")
|
||||
c.Error(http.StatusForbidden, "", "you do not have access to this key")
|
||||
} else {
|
||||
c.Error(500, "DeletePublicKey", err)
|
||||
c.Error(http.StatusInternalServerError, "DeletePublicKey", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
c.NoContent()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -27,7 +29,7 @@ func Search(c *context.APIContext) {
|
||||
|
||||
users, _, err := models.SearchUserByName(opts)
|
||||
if err != nil {
|
||||
c.JSON(500, map[string]interface{}{
|
||||
c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
||||
"ok": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
@@ -47,7 +49,7 @@ func Search(c *context.APIContext) {
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, map[string]interface{}{
|
||||
c.JSONSuccess(map[string]interface{}{
|
||||
"ok": true,
|
||||
"data": results,
|
||||
})
|
||||
@@ -56,11 +58,7 @@ func Search(c *context.APIContext) {
|
||||
func GetInfo(c *context.APIContext) {
|
||||
u, err := models.GetUserByName(c.Params(":username"))
|
||||
if err != nil {
|
||||
if errors.IsUserNotExist(err) {
|
||||
c.Status(404)
|
||||
} else {
|
||||
c.Error(500, "GetUserByName", err)
|
||||
}
|
||||
c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,9 +66,9 @@ func GetInfo(c *context.APIContext) {
|
||||
if !c.IsLogged {
|
||||
u.Email = ""
|
||||
}
|
||||
c.JSON(200, u.APIFormat())
|
||||
c.JSONSuccess(u.APIFormat())
|
||||
}
|
||||
|
||||
func GetAuthenticatedUser(c *context.APIContext) {
|
||||
c.JSON(200, c.User.APIFormat())
|
||||
c.JSONSuccess(c.User.APIFormat())
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ func HTTPContexter() macaron.Handler {
|
||||
return
|
||||
}
|
||||
token.Updated = time.Now()
|
||||
// TODO: verify or update token.Updated in database
|
||||
|
||||
authUser, err = models.GetUserByID(token.UID)
|
||||
if err != nil {
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.11.86.0130
|
||||
0.11.91.0811
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<footer>
|
||||
<div class="ui container">
|
||||
<div class="ui left">
|
||||
© 2018 Gogs {{if (or .ShowFooterVersion .PageIsAdmin)}}{{.i18n.Tr "version"}}: {{AppVer}}{{end}} {{if ShowFooterTemplateLoadTime}}{{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> {{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong>{{end}}
|
||||
© {{Year}} Gogs {{if (or .ShowFooterVersion .PageIsAdmin)}}{{.i18n.Tr "version"}}: {{AppVer}}{{end}} {{if ShowFooterTemplateLoadTime}}{{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> {{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong>{{end}}
|
||||
</div>
|
||||
<div class="ui right links">
|
||||
{{if .ShowFooterBranding}}
|
||||
|
||||
@@ -192,6 +192,14 @@
|
||||
</div><!-- end container -->
|
||||
</div><!-- end bar -->
|
||||
{{end}}
|
||||
|
||||
{{if .ServerNotice}}
|
||||
<div class="ui container grid warning message">
|
||||
<div class="content">
|
||||
{{.ServerNotice | Str2HTML}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{/*
|
||||
</div>
|
||||
</body>
|
||||
|
||||
1
vendor/github.com/gogs/go-gogs-client/repo_hook.go
generated
vendored
1
vendor/github.com/gogs/go-gogs-client/repo_hook.go
generated
vendored
@@ -114,6 +114,7 @@ var (
|
||||
type CreatePayload struct {
|
||||
Ref string `json:"ref"`
|
||||
RefType string `json:"ref_type"`
|
||||
Sha string `json:"sha"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Repo *Repository `json:"repository"`
|
||||
Sender *User `json:"sender"`
|
||||
|
||||
115
vendor/github.com/jtolds/gls/context.go
generated
vendored
115
vendor/github.com/jtolds/gls/context.go
generated
vendored
@@ -5,12 +5,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
maxCallers = 64
|
||||
)
|
||||
|
||||
var (
|
||||
stackTagPool = &idPool{}
|
||||
mgrRegistry = make(map[*ContextManager]bool)
|
||||
mgrRegistryMtx sync.RWMutex
|
||||
)
|
||||
@@ -25,7 +20,7 @@ type Values map[interface{}]interface{}
|
||||
// class of context variables. You should use NewContextManager for
|
||||
// construction.
|
||||
type ContextManager struct {
|
||||
mtx sync.RWMutex
|
||||
mtx sync.Mutex
|
||||
values map[uint]Values
|
||||
}
|
||||
|
||||
@@ -62,63 +57,77 @@ func (m *ContextManager) SetValues(new_values Values, context_call func()) {
|
||||
return
|
||||
}
|
||||
|
||||
tags := readStackTags(1)
|
||||
mutated_keys := make([]interface{}, 0, len(new_values))
|
||||
mutated_vals := make(Values, len(new_values))
|
||||
|
||||
m.mtx.Lock()
|
||||
values := new_values
|
||||
for _, tag := range tags {
|
||||
if existing_values, ok := m.values[tag]; ok {
|
||||
// oh, we found existing values, let's make a copy
|
||||
values = make(Values, len(existing_values)+len(new_values))
|
||||
for key, val := range existing_values {
|
||||
values[key] = val
|
||||
}
|
||||
for key, val := range new_values {
|
||||
values[key] = val
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
new_tag := stackTagPool.Acquire()
|
||||
m.values[new_tag] = values
|
||||
m.mtx.Unlock()
|
||||
defer func() {
|
||||
EnsureGoroutineId(func(gid uint) {
|
||||
m.mtx.Lock()
|
||||
delete(m.values, new_tag)
|
||||
state, found := m.values[gid]
|
||||
if !found {
|
||||
state = make(Values, len(new_values))
|
||||
m.values[gid] = state
|
||||
}
|
||||
m.mtx.Unlock()
|
||||
stackTagPool.Release(new_tag)
|
||||
}()
|
||||
|
||||
addStackTag(new_tag, context_call)
|
||||
for key, new_val := range new_values {
|
||||
mutated_keys = append(mutated_keys, key)
|
||||
if old_val, ok := state[key]; ok {
|
||||
mutated_vals[key] = old_val
|
||||
}
|
||||
state[key] = new_val
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if !found {
|
||||
m.mtx.Lock()
|
||||
delete(m.values, gid)
|
||||
m.mtx.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
for _, key := range mutated_keys {
|
||||
if val, ok := mutated_vals[key]; ok {
|
||||
state[key] = val
|
||||
} else {
|
||||
delete(state, key)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
context_call()
|
||||
})
|
||||
}
|
||||
|
||||
// GetValue will return a previously set value, provided that the value was set
|
||||
// by SetValues somewhere higher up the stack. If the value is not found, ok
|
||||
// will be false.
|
||||
func (m *ContextManager) GetValue(key interface{}) (value interface{}, ok bool) {
|
||||
|
||||
tags := readStackTags(1)
|
||||
m.mtx.RLock()
|
||||
defer m.mtx.RUnlock()
|
||||
for _, tag := range tags {
|
||||
if values, ok := m.values[tag]; ok {
|
||||
value, ok := values[key]
|
||||
return value, ok
|
||||
}
|
||||
func (m *ContextManager) GetValue(key interface{}) (
|
||||
value interface{}, ok bool) {
|
||||
gid, ok := GetGoroutineId()
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return "", false
|
||||
|
||||
m.mtx.Lock()
|
||||
state, found := m.values[gid]
|
||||
m.mtx.Unlock()
|
||||
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
value, ok = state[key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
func (m *ContextManager) getValues() Values {
|
||||
tags := readStackTags(2)
|
||||
m.mtx.RLock()
|
||||
defer m.mtx.RUnlock()
|
||||
for _, tag := range tags {
|
||||
if values, ok := m.values[tag]; ok {
|
||||
return values
|
||||
}
|
||||
gid, ok := GetGoroutineId()
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
m.mtx.Lock()
|
||||
state, _ := m.values[gid]
|
||||
m.mtx.Unlock()
|
||||
return state
|
||||
}
|
||||
|
||||
// Go preserves ContextManager values and Goroutine-local-storage across new
|
||||
@@ -131,12 +140,12 @@ func Go(cb func()) {
|
||||
mgrRegistryMtx.RLock()
|
||||
defer mgrRegistryMtx.RUnlock()
|
||||
|
||||
for mgr, _ := range mgrRegistry {
|
||||
for mgr := range mgrRegistry {
|
||||
values := mgr.getValues()
|
||||
if len(values) > 0 {
|
||||
mgr_copy := mgr
|
||||
cb_copy := cb
|
||||
cb = func() { mgr_copy.SetValues(values, cb_copy) }
|
||||
cb = func(mgr *ContextManager, cb func()) func() {
|
||||
return func() { mgr.SetValues(values, cb) }
|
||||
}(mgr, cb)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
vendor/github.com/jtolds/gls/gen_sym.go
generated
vendored
14
vendor/github.com/jtolds/gls/gen_sym.go
generated
vendored
@@ -1,13 +1,21 @@
|
||||
package gls
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
symPool = &idPool{}
|
||||
keyMtx sync.Mutex
|
||||
keyCounter uint64
|
||||
)
|
||||
|
||||
// ContextKey is a throwaway value you can use as a key to a ContextManager
|
||||
type ContextKey struct{ id uint }
|
||||
type ContextKey struct{ id uint64 }
|
||||
|
||||
// GenSym will return a brand new, never-before-used ContextKey
|
||||
func GenSym() ContextKey {
|
||||
return ContextKey{id: symPool.Acquire()}
|
||||
keyMtx.Lock()
|
||||
defer keyMtx.Unlock()
|
||||
keyCounter += 1
|
||||
return ContextKey{id: keyCounter}
|
||||
}
|
||||
|
||||
25
vendor/github.com/jtolds/gls/gid.go
generated
vendored
Normal file
25
vendor/github.com/jtolds/gls/gid.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package gls
|
||||
|
||||
var (
|
||||
stackTagPool = &idPool{}
|
||||
)
|
||||
|
||||
// Will return this goroutine's identifier if set. If you always need a
|
||||
// goroutine identifier, you should use EnsureGoroutineId which will make one
|
||||
// if there isn't one already.
|
||||
func GetGoroutineId() (gid uint, ok bool) {
|
||||
return readStackTag()
|
||||
}
|
||||
|
||||
// Will call cb with the current goroutine identifier. If one hasn't already
|
||||
// been generated, one will be created and set first. The goroutine identifier
|
||||
// might be invalid after cb returns.
|
||||
func EnsureGoroutineId(cb func(gid uint)) {
|
||||
if gid, ok := readStackTag(); ok {
|
||||
cb(gid)
|
||||
return
|
||||
}
|
||||
gid := stackTagPool.Acquire()
|
||||
defer stackTagPool.Release(gid)
|
||||
addStackTag(gid, func() { cb(gid) })
|
||||
}
|
||||
146
vendor/github.com/jtolds/gls/stack_tags.go
generated
vendored
146
vendor/github.com/jtolds/gls/stack_tags.go
generated
vendored
@@ -3,36 +3,105 @@ package gls
|
||||
// so, basically, we're going to encode integer tags in base-16 on the stack
|
||||
|
||||
const (
|
||||
bitWidth = 4
|
||||
bitWidth = 4
|
||||
stackBatchSize = 16
|
||||
)
|
||||
|
||||
var (
|
||||
pc_lookup = make(map[uintptr]int8, 17)
|
||||
mark_lookup [16]func(uint, func())
|
||||
)
|
||||
|
||||
func init() {
|
||||
setEntries := func(f func(uint, func()), v int8) {
|
||||
var ptr uintptr
|
||||
f(0, func() {
|
||||
ptr = findPtr()
|
||||
})
|
||||
pc_lookup[ptr] = v
|
||||
if v >= 0 {
|
||||
mark_lookup[v] = f
|
||||
}
|
||||
}
|
||||
setEntries(github_com_jtolds_gls_markS, -0x1)
|
||||
setEntries(github_com_jtolds_gls_mark0, 0x0)
|
||||
setEntries(github_com_jtolds_gls_mark1, 0x1)
|
||||
setEntries(github_com_jtolds_gls_mark2, 0x2)
|
||||
setEntries(github_com_jtolds_gls_mark3, 0x3)
|
||||
setEntries(github_com_jtolds_gls_mark4, 0x4)
|
||||
setEntries(github_com_jtolds_gls_mark5, 0x5)
|
||||
setEntries(github_com_jtolds_gls_mark6, 0x6)
|
||||
setEntries(github_com_jtolds_gls_mark7, 0x7)
|
||||
setEntries(github_com_jtolds_gls_mark8, 0x8)
|
||||
setEntries(github_com_jtolds_gls_mark9, 0x9)
|
||||
setEntries(github_com_jtolds_gls_markA, 0xa)
|
||||
setEntries(github_com_jtolds_gls_markB, 0xb)
|
||||
setEntries(github_com_jtolds_gls_markC, 0xc)
|
||||
setEntries(github_com_jtolds_gls_markD, 0xd)
|
||||
setEntries(github_com_jtolds_gls_markE, 0xe)
|
||||
setEntries(github_com_jtolds_gls_markF, 0xf)
|
||||
}
|
||||
|
||||
func addStackTag(tag uint, context_call func()) {
|
||||
if context_call == nil {
|
||||
return
|
||||
}
|
||||
markS(tag, context_call)
|
||||
github_com_jtolds_gls_markS(tag, context_call)
|
||||
}
|
||||
|
||||
func markS(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark0(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark1(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark2(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark3(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark4(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark5(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark6(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark7(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark8(tag uint, cb func()) { _m(tag, cb) }
|
||||
func mark9(tag uint, cb func()) { _m(tag, cb) }
|
||||
func markA(tag uint, cb func()) { _m(tag, cb) }
|
||||
func markB(tag uint, cb func()) { _m(tag, cb) }
|
||||
func markC(tag uint, cb func()) { _m(tag, cb) }
|
||||
func markD(tag uint, cb func()) { _m(tag, cb) }
|
||||
func markE(tag uint, cb func()) { _m(tag, cb) }
|
||||
func markF(tag uint, cb func()) { _m(tag, cb) }
|
||||
// these private methods are named this horrendous name so gopherjs support
|
||||
// is easier. it shouldn't add any runtime cost in non-js builds.
|
||||
|
||||
var pc_lookup = make(map[uintptr]int8, 17)
|
||||
var mark_lookup [16]func(uint, func())
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markS(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark0(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark1(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark2(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark3(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark4(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark5(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark6(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark7(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark8(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_mark9(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markA(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markB(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markC(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markD(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markE(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
//go:noinline
|
||||
func github_com_jtolds_gls_markF(tag uint, cb func()) { _m(tag, cb) }
|
||||
|
||||
func _m(tag_remainder uint, cb func()) {
|
||||
if tag_remainder == 0 {
|
||||
@@ -41,3 +110,38 @@ func _m(tag_remainder uint, cb func()) {
|
||||
mark_lookup[tag_remainder&0xf](tag_remainder>>bitWidth, cb)
|
||||
}
|
||||
}
|
||||
|
||||
func readStackTag() (tag uint, ok bool) {
|
||||
var current_tag uint
|
||||
offset := 0
|
||||
for {
|
||||
batch, next_offset := getStack(offset, stackBatchSize)
|
||||
for _, pc := range batch {
|
||||
val, ok := pc_lookup[pc]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if val < 0 {
|
||||
return current_tag, true
|
||||
}
|
||||
current_tag <<= bitWidth
|
||||
current_tag += uint(val)
|
||||
}
|
||||
if next_offset == 0 {
|
||||
break
|
||||
}
|
||||
offset = next_offset
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (m *ContextManager) preventInlining() {
|
||||
// dunno if findPtr or getStack are likely to get inlined in a future release
|
||||
// of go, but if they are inlined and their callers are inlined, that could
|
||||
// hork some things. let's do our best to explain to the compiler that we
|
||||
// really don't want those two functions inlined by saying they could change
|
||||
// at any time. assumes preventInlining doesn't get compiled out.
|
||||
// this whole thing is probably overkill.
|
||||
findPtr = m.values[0][0].(func() uintptr)
|
||||
getStack = m.values[0][1].(func(int, int) ([]uintptr, int))
|
||||
}
|
||||
|
||||
138
vendor/github.com/jtolds/gls/stack_tags_js.go
generated
vendored
138
vendor/github.com/jtolds/gls/stack_tags_js.go
generated
vendored
@@ -2,100 +2,74 @@
|
||||
|
||||
package gls
|
||||
|
||||
// This file is used for GopherJS builds, which don't have normal runtime support
|
||||
// This file is used for GopherJS builds, which don't have normal runtime
|
||||
// stack trace support
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
)
|
||||
|
||||
var stackRE = regexp.MustCompile("\\s+at (\\S*) \\([^:]+:(\\d+):(\\d+)")
|
||||
const (
|
||||
jsFuncNamePrefix = "github_com_jtolds_gls_mark"
|
||||
)
|
||||
|
||||
func findPtr() uintptr {
|
||||
jsStack := js.Global.Get("Error").New().Get("stack").Call("split", "\n")
|
||||
for i := 1; i < jsStack.Get("length").Int(); i++ {
|
||||
item := jsStack.Index(i).String()
|
||||
matches := stackRE.FindAllStringSubmatch(item, -1)
|
||||
if matches == nil {
|
||||
return 0
|
||||
}
|
||||
pkgPath := matches[0][1]
|
||||
if strings.HasPrefix(pkgPath, "$packages.github.com/jtolds/gls.mark") {
|
||||
line, _ := strconv.Atoi(matches[0][2])
|
||||
char, _ := strconv.Atoi(matches[0][3])
|
||||
x := (uintptr(line) << 16) | uintptr(char)
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
setEntries := func(f func(uint, func()), v int8) {
|
||||
var ptr uintptr
|
||||
f(0, func() {
|
||||
ptr = findPtr()
|
||||
})
|
||||
pc_lookup[ptr] = v
|
||||
if v >= 0 {
|
||||
mark_lookup[v] = f
|
||||
}
|
||||
}
|
||||
setEntries(markS, -0x1)
|
||||
setEntries(mark0, 0x0)
|
||||
setEntries(mark1, 0x1)
|
||||
setEntries(mark2, 0x2)
|
||||
setEntries(mark3, 0x3)
|
||||
setEntries(mark4, 0x4)
|
||||
setEntries(mark5, 0x5)
|
||||
setEntries(mark6, 0x6)
|
||||
setEntries(mark7, 0x7)
|
||||
setEntries(mark8, 0x8)
|
||||
setEntries(mark9, 0x9)
|
||||
setEntries(markA, 0xa)
|
||||
setEntries(markB, 0xb)
|
||||
setEntries(markC, 0xc)
|
||||
setEntries(markD, 0xd)
|
||||
setEntries(markE, 0xe)
|
||||
setEntries(markF, 0xf)
|
||||
}
|
||||
|
||||
func currentStack(skip int) (stack []uintptr) {
|
||||
jsStack := js.Global.Get("Error").New().Get("stack").Call("split", "\n")
|
||||
for i := skip + 2; i < jsStack.Get("length").Int(); i++ {
|
||||
item := jsStack.Index(i).String()
|
||||
matches := stackRE.FindAllStringSubmatch(item, -1)
|
||||
if matches == nil {
|
||||
return stack
|
||||
}
|
||||
line, _ := strconv.Atoi(matches[0][2])
|
||||
char, _ := strconv.Atoi(matches[0][3])
|
||||
x := (uintptr(line) << 16) | uintptr(char)&0xffff
|
||||
stack = append(stack, x)
|
||||
}
|
||||
|
||||
return stack
|
||||
}
|
||||
|
||||
func readStackTags(skip int) (tags []uint) {
|
||||
stack := currentStack(skip)
|
||||
var current_tag uint
|
||||
for _, pc := range stack {
|
||||
val, ok := pc_lookup[pc]
|
||||
if !ok {
|
||||
func jsMarkStack() (f []uintptr) {
|
||||
lines := strings.Split(
|
||||
js.Global.Get("Error").New().Get("stack").String(), "\n")
|
||||
f = make([]uintptr, 0, len(lines))
|
||||
for i, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
if val < 0 {
|
||||
tags = append(tags, current_tag)
|
||||
current_tag = 0
|
||||
if i == 0 {
|
||||
if line != "Error" {
|
||||
panic("didn't understand js stack trace")
|
||||
}
|
||||
continue
|
||||
}
|
||||
current_tag <<= bitWidth
|
||||
current_tag += uint(val)
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 2 || fields[0] != "at" {
|
||||
panic("didn't understand js stack trace")
|
||||
}
|
||||
|
||||
pos := strings.Index(fields[1], jsFuncNamePrefix)
|
||||
if pos < 0 {
|
||||
continue
|
||||
}
|
||||
pos += len(jsFuncNamePrefix)
|
||||
if pos >= len(fields[1]) {
|
||||
panic("didn't understand js stack trace")
|
||||
}
|
||||
char := string(fields[1][pos])
|
||||
switch char {
|
||||
case "S":
|
||||
f = append(f, uintptr(0))
|
||||
default:
|
||||
val, err := strconv.ParseUint(char, 16, 8)
|
||||
if err != nil {
|
||||
panic("didn't understand js stack trace")
|
||||
}
|
||||
f = append(f, uintptr(val)+1)
|
||||
}
|
||||
}
|
||||
return
|
||||
return f
|
||||
}
|
||||
|
||||
// variables to prevent inlining
|
||||
var (
|
||||
findPtr = func() uintptr {
|
||||
funcs := jsMarkStack()
|
||||
if len(funcs) == 0 {
|
||||
panic("failed to find function pointer")
|
||||
}
|
||||
return funcs[0]
|
||||
}
|
||||
|
||||
getStack = func(offset, amount int) (stack []uintptr, next_offset int) {
|
||||
return jsMarkStack(), 0
|
||||
}
|
||||
)
|
||||
|
||||
63
vendor/github.com/jtolds/gls/stack_tags_main.go
generated
vendored
63
vendor/github.com/jtolds/gls/stack_tags_main.go
generated
vendored
@@ -2,60 +2,29 @@
|
||||
|
||||
package gls
|
||||
|
||||
// This file is used for standard Go builds, which have the expected runtime support
|
||||
// This file is used for standard Go builds, which have the expected runtime
|
||||
// support
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setEntries := func(f func(uint, func()), v int8) {
|
||||
pc_lookup[reflect.ValueOf(f).Pointer()] = v
|
||||
if v >= 0 {
|
||||
mark_lookup[v] = f
|
||||
var (
|
||||
findPtr = func() uintptr {
|
||||
var pc [1]uintptr
|
||||
n := runtime.Callers(4, pc[:])
|
||||
if n != 1 {
|
||||
panic("failed to find function pointer")
|
||||
}
|
||||
return pc[0]
|
||||
}
|
||||
setEntries(markS, -0x1)
|
||||
setEntries(mark0, 0x0)
|
||||
setEntries(mark1, 0x1)
|
||||
setEntries(mark2, 0x2)
|
||||
setEntries(mark3, 0x3)
|
||||
setEntries(mark4, 0x4)
|
||||
setEntries(mark5, 0x5)
|
||||
setEntries(mark6, 0x6)
|
||||
setEntries(mark7, 0x7)
|
||||
setEntries(mark8, 0x8)
|
||||
setEntries(mark9, 0x9)
|
||||
setEntries(markA, 0xa)
|
||||
setEntries(markB, 0xb)
|
||||
setEntries(markC, 0xc)
|
||||
setEntries(markD, 0xd)
|
||||
setEntries(markE, 0xe)
|
||||
setEntries(markF, 0xf)
|
||||
}
|
||||
|
||||
func currentStack(skip int) []uintptr {
|
||||
stack := make([]uintptr, maxCallers)
|
||||
return stack[:runtime.Callers(3+skip, stack)]
|
||||
}
|
||||
|
||||
func readStackTags(skip int) (tags []uint) {
|
||||
stack := currentStack(skip)
|
||||
var current_tag uint
|
||||
for _, pc := range stack {
|
||||
pc = runtime.FuncForPC(pc).Entry()
|
||||
val, ok := pc_lookup[pc]
|
||||
if !ok {
|
||||
continue
|
||||
getStack = func(offset, amount int) (stack []uintptr, next_offset int) {
|
||||
stack = make([]uintptr, amount)
|
||||
stack = stack[:runtime.Callers(offset, stack)]
|
||||
if len(stack) < amount {
|
||||
return stack, 0
|
||||
}
|
||||
if val < 0 {
|
||||
tags = append(tags, current_tag)
|
||||
current_tag = 0
|
||||
continue
|
||||
}
|
||||
current_tag <<= bitWidth
|
||||
current_tag += uint(val)
|
||||
return stack, offset + len(stack)
|
||||
}
|
||||
return
|
||||
}
|
||||
)
|
||||
|
||||
12
vendor/github.com/smartystreets/assertions/CONTRIBUTING.md
generated
vendored
Normal file
12
vendor/github.com/smartystreets/assertions/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Contributing
|
||||
|
||||
In general, the code posted to the [SmartyStreets github organization](https://github.com/smartystreets) is created to solve specific problems at SmartyStreets that are ancillary to our core products in the address verification industry and may or may not be useful to other organizations or developers. Our reason for posting said code isn't necessarily to solicit feedback or contributions from the community but more as a showcase of some of the approaches to solving problems we have adopted.
|
||||
|
||||
Having stated that, we do consider issues raised by other githubbers as well as contributions submitted via pull requests. When submitting such a pull request, please follow these guidelines:
|
||||
|
||||
- _Look before you leap:_ If the changes you plan to make are significant, it's in everyone's best interest for you to discuss them with a SmartyStreets team member prior to opening a pull request.
|
||||
- _License and ownership:_ If modifying the `LICENSE.md` file, limit your changes to fixing typographical mistakes. Do NOT modify the actual terms in the license or the copyright by **SmartyStreets, LLC**. Code submitted to SmartyStreets projects becomes property of SmartyStreets and must be compatible with the associated license.
|
||||
- _Testing:_ If the code you are submitting resides in packages/modules covered by automated tests, be sure to add passing tests that cover your changes and assert expected behavior and state. Submit the additional test cases as part of your change set.
|
||||
- _Style:_ Match your approach to **naming** and **formatting** with the surrounding code. Basically, the code you submit shouldn't stand out.
|
||||
- "Naming" refers to such constructs as variables, methods, functions, classes, structs, interfaces, packages, modules, directories, files, etc...
|
||||
- "Formatting" refers to such constructs as whitespace, horizontal line length, vertical function length, vertical file length, indentation, curly braces, etc...
|
||||
2
vendor/github.com/smartystreets/assertions/LICENSE.md
generated
vendored
2
vendor/github.com/smartystreets/assertions/LICENSE.md
generated
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2015 SmartyStreets, LLC
|
||||
Copyright (c) 2016 SmartyStreets, LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
11
vendor/github.com/smartystreets/assertions/Makefile
generated
vendored
Executable file
11
vendor/github.com/smartystreets/assertions/Makefile
generated
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
test:
|
||||
go test -timeout=1s -short ./...
|
||||
|
||||
compile:
|
||||
go build ./...
|
||||
|
||||
build: test compile
|
||||
|
||||
.PHONY: test compile build
|
||||
54
vendor/github.com/smartystreets/assertions/README.md
generated
vendored
54
vendor/github.com/smartystreets/assertions/README.md
generated
vendored
@@ -1,3 +1,5 @@
|
||||
[](https://travis-ci.org/smartystreets/assertions)
|
||||
|
||||
# assertions
|
||||
--
|
||||
import "github.com/smartystreets/assertions"
|
||||
@@ -8,6 +10,8 @@ referenced in goconvey's `convey` package
|
||||
(github.com/smartystreets/gunit) for use with the So(...) method. They can also
|
||||
be used in traditional Go test functions and even in applications.
|
||||
|
||||
https://smartystreets.com
|
||||
|
||||
Many of the assertions lean heavily on work done by Aaron Jacobs in his
|
||||
excellent oglematchers library. (https://github.com/jacobsa/oglematchers) The
|
||||
ShouldResemble assertion leans heavily on work done by Daniel Jacques in his
|
||||
@@ -25,7 +29,7 @@ the assertions in this package from the convey package JSON results are very
|
||||
helpful and can be rendered in a DIFF view. In that case, this function will be
|
||||
called with a true value to enable the JSON serialization. By default, the
|
||||
assertions in this package will not serializer a JSON result, making standalone
|
||||
ussage more convenient.
|
||||
usage more convenient.
|
||||
|
||||
#### func ShouldAlmostEqual
|
||||
|
||||
@@ -67,7 +71,7 @@ to "".
|
||||
```go
|
||||
func ShouldBeChronological(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldBeChronological receives a []time.Time slice and asserts that the are in
|
||||
ShouldBeChronological receives a []time.Time slice and asserts that they are in
|
||||
chronological order starting with the first time.Time as the earliest.
|
||||
|
||||
#### func ShouldBeEmpty
|
||||
@@ -79,6 +83,15 @@ ShouldBeEmpty receives a single parameter (actual) and determines whether or not
|
||||
calling len(actual) would return `0`. It obeys the rules specified by the len
|
||||
function for determining length: http://golang.org/pkg/builtin/#len
|
||||
|
||||
#### func ShouldBeError
|
||||
|
||||
```go
|
||||
func ShouldBeError(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldBeError asserts that the first argument implements the error interface. It
|
||||
also compares the first argument against the second argument if provided (which
|
||||
must be an error message string or another error value).
|
||||
|
||||
#### func ShouldBeFalse
|
||||
|
||||
```go
|
||||
@@ -187,7 +200,19 @@ ends with the second.
|
||||
```go
|
||||
func ShouldEqual(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldEqual receives exactly two parameters and does an equality check.
|
||||
ShouldEqual receives exactly two parameters and does an equality check using the
|
||||
following semantics: 1. If the expected and actual values implement an Equal
|
||||
method in the form `func (this T) Equal(that T) bool` then call the method. If
|
||||
true, they are equal. 2. The expected and actual values are judged equal or not
|
||||
by oglematchers.Equals.
|
||||
|
||||
#### func ShouldEqualJSON
|
||||
|
||||
```go
|
||||
func ShouldEqualJSON(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldEqualJSON receives exactly two parameters and does an equality check by
|
||||
marshalling to JSON
|
||||
|
||||
#### func ShouldEqualTrimSpace
|
||||
|
||||
@@ -322,6 +347,14 @@ func ShouldNotBeBlank(actual interface{}, expected ...interface{}) string
|
||||
ShouldNotBeBlank receives exactly 1 string parameter and ensures that it is
|
||||
equal to "".
|
||||
|
||||
#### func ShouldNotBeChronological
|
||||
|
||||
```go
|
||||
func ShouldNotBeChronological(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldNotBeChronological receives a []time.Time slice and asserts that they are
|
||||
NOT in chronological order.
|
||||
|
||||
#### func ShouldNotBeEmpty
|
||||
|
||||
```go
|
||||
@@ -349,6 +382,14 @@ func ShouldNotBeNil(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldNotBeNil receives a single parameter and ensures that it is not nil.
|
||||
|
||||
#### func ShouldNotBeZeroValue
|
||||
|
||||
```go
|
||||
func ShouldNotBeZeroValue(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldBeZeroValue receives a single parameter and ensures that it is NOT the Go
|
||||
equivalent of the default value, or "zero" value.
|
||||
|
||||
#### func ShouldNotContain
|
||||
|
||||
```go
|
||||
@@ -386,7 +427,8 @@ does not end with the second.
|
||||
```go
|
||||
func ShouldNotEqual(actual interface{}, expected ...interface{}) string
|
||||
```
|
||||
ShouldNotEqual receives exactly two parameters and does an inequality check.
|
||||
ShouldNotEqual receives exactly two parameters and does an inequality check. See
|
||||
ShouldEqual for details on how equality is determined.
|
||||
|
||||
#### func ShouldNotHappenOnOrBetween
|
||||
|
||||
@@ -521,6 +563,10 @@ Example:
|
||||
log.Println(message)
|
||||
}
|
||||
|
||||
For an alternative implementation of So (that provides more flexible return
|
||||
options) see the `So` function in the package at
|
||||
github.com/smartystreets/assertions/assert.
|
||||
|
||||
#### type Assertion
|
||||
|
||||
```go
|
||||
|
||||
3
vendor/github.com/smartystreets/assertions/assertions.goconvey
generated
vendored
3
vendor/github.com/smartystreets/assertions/assertions.goconvey
generated
vendored
@@ -1,3 +0,0 @@
|
||||
#ignore
|
||||
-timeout=1s
|
||||
-coverpkg=github.com/smartystreets/assertions,github.com/smartystreets/assertions/internal/oglematchers
|
||||
4
vendor/github.com/smartystreets/assertions/collections.go
generated
vendored
4
vendor/github.com/smartystreets/assertions/collections.go
generated
vendored
@@ -227,7 +227,7 @@ func ShouldHaveLength(actual interface{}, expected ...interface{}) string {
|
||||
if int64(value.Len()) == expectedLen {
|
||||
return success
|
||||
} else {
|
||||
return fmt.Sprintf(shouldHaveHadLength, actual, value.Len(), expectedLen)
|
||||
return fmt.Sprintf(shouldHaveHadLength, expectedLen, value.Len(), actual)
|
||||
}
|
||||
case reflect.Ptr:
|
||||
elem := value.Elem()
|
||||
@@ -236,7 +236,7 @@ func ShouldHaveLength(actual interface{}, expected ...interface{}) string {
|
||||
if int64(elem.Len()) == expectedLen {
|
||||
return success
|
||||
} else {
|
||||
return fmt.Sprintf(shouldHaveHadLength, actual, elem.Len(), expectedLen)
|
||||
return fmt.Sprintf(shouldHaveHadLength, expectedLen, elem.Len(), actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/github.com/smartystreets/assertions/doc.go
generated
vendored
6
vendor/github.com/smartystreets/assertions/doc.go
generated
vendored
@@ -5,6 +5,8 @@
|
||||
// They can also be used in traditional Go test functions and even in
|
||||
// applications.
|
||||
//
|
||||
// https://smartystreets.com
|
||||
//
|
||||
// Many of the assertions lean heavily on work done by Aaron Jacobs in his excellent oglematchers library.
|
||||
// (https://github.com/jacobsa/oglematchers)
|
||||
// The ShouldResemble assertion leans heavily on work done by Daniel Jacques in his very helpful go-render library.
|
||||
@@ -26,7 +28,7 @@ var serializer Serializer = new(noopSerializer)
|
||||
// are very helpful and can be rendered in a DIFF view. In that case, this function
|
||||
// will be called with a true value to enable the JSON serialization. By default,
|
||||
// the assertions in this package will not serializer a JSON result, making
|
||||
// standalone ussage more convenient.
|
||||
// standalone usage more convenient.
|
||||
func GoConveyMode(yes bool) {
|
||||
if yes {
|
||||
serializer = newSerializer()
|
||||
@@ -82,6 +84,8 @@ func (this *Assertion) So(actual interface{}, assert assertion, expected ...inte
|
||||
// log.Println(message)
|
||||
// }
|
||||
//
|
||||
// For an alternative implementation of So (that provides more flexible return options)
|
||||
// see the `So` function in the package at github.com/smartystreets/assertions/assert.
|
||||
func So(actual interface{}, assert assertion, expected ...interface{}) (bool, string) {
|
||||
if result := so(actual, assert, expected...); len(result) == 0 {
|
||||
return true, result
|
||||
|
||||
75
vendor/github.com/smartystreets/assertions/equal_method.go
generated
vendored
Normal file
75
vendor/github.com/smartystreets/assertions/equal_method.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
package assertions
|
||||
|
||||
import "reflect"
|
||||
|
||||
type equalityMethodSpecification struct {
|
||||
a interface{}
|
||||
b interface{}
|
||||
|
||||
aType reflect.Type
|
||||
bType reflect.Type
|
||||
|
||||
equalMethod reflect.Value
|
||||
}
|
||||
|
||||
func newEqualityMethodSpecification(a, b interface{}) *equalityMethodSpecification {
|
||||
return &equalityMethodSpecification{
|
||||
a: a,
|
||||
b: b,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *equalityMethodSpecification) IsSatisfied() bool {
|
||||
if !this.bothAreSameType() {
|
||||
return false
|
||||
}
|
||||
if !this.typeHasEqualMethod() {
|
||||
return false
|
||||
}
|
||||
if !this.equalMethodReceivesSameTypeForComparison() {
|
||||
return false
|
||||
}
|
||||
if !this.equalMethodReturnsBool() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *equalityMethodSpecification) bothAreSameType() bool {
|
||||
this.aType = reflect.TypeOf(this.a)
|
||||
if this.aType == nil {
|
||||
return false
|
||||
}
|
||||
if this.aType.Kind() == reflect.Ptr {
|
||||
this.aType = this.aType.Elem()
|
||||
}
|
||||
this.bType = reflect.TypeOf(this.b)
|
||||
return this.aType == this.bType
|
||||
}
|
||||
func (this *equalityMethodSpecification) typeHasEqualMethod() bool {
|
||||
aInstance := reflect.ValueOf(this.a)
|
||||
this.equalMethod = aInstance.MethodByName("Equal")
|
||||
return this.equalMethod != reflect.Value{}
|
||||
}
|
||||
|
||||
func (this *equalityMethodSpecification) equalMethodReceivesSameTypeForComparison() bool {
|
||||
signature := this.equalMethod.Type()
|
||||
return signature.NumIn() == 1 && signature.In(0) == this.aType
|
||||
}
|
||||
|
||||
func (this *equalityMethodSpecification) equalMethodReturnsBool() bool {
|
||||
signature := this.equalMethod.Type()
|
||||
return signature.NumOut() == 1 && signature.Out(0) == reflect.TypeOf(true)
|
||||
}
|
||||
|
||||
func (this *equalityMethodSpecification) AreEqual() bool {
|
||||
a := reflect.ValueOf(this.a)
|
||||
b := reflect.ValueOf(this.b)
|
||||
return areEqual(a, b) && areEqual(b, a)
|
||||
}
|
||||
func areEqual(receiver reflect.Value, argument reflect.Value) bool {
|
||||
equalMethod := receiver.MethodByName("Equal")
|
||||
argumentList := []reflect.Value{argument}
|
||||
result := equalMethod.Call(argumentList)
|
||||
return result[0].Bool()
|
||||
}
|
||||
103
vendor/github.com/smartystreets/assertions/equality.go
generated
vendored
103
vendor/github.com/smartystreets/assertions/equality.go
generated
vendored
@@ -1,20 +1,22 @@
|
||||
package assertions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/smartystreets/assertions/internal/oglematchers"
|
||||
"github.com/smartystreets/assertions/internal/go-render/render"
|
||||
"github.com/smartystreets/assertions/internal/oglematchers"
|
||||
)
|
||||
|
||||
// default acceptable delta for ShouldAlmostEqual
|
||||
const defaultDelta = 0.0000000001
|
||||
|
||||
// ShouldEqual receives exactly two parameters and does an equality check.
|
||||
// ShouldEqual receives exactly two parameters and does an equality check
|
||||
// using the following semantics:
|
||||
// 1. If the expected and actual values implement an Equal method in the form
|
||||
// `func (this T) Equal(that T) bool` then call the method. If true, they are equal.
|
||||
// 2. The expected and actual values are judged equal or not by oglematchers.Equals.
|
||||
func ShouldEqual(actual interface{}, expected ...interface{}) string {
|
||||
if message := need(1, expected); message != success {
|
||||
return message
|
||||
@@ -24,27 +26,35 @@ func ShouldEqual(actual interface{}, expected ...interface{}) string {
|
||||
func shouldEqual(actual, expected interface{}) (message string) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual))
|
||||
return
|
||||
message = serializer.serialize(expected, actual, composeEqualityMismatchMessage(expected, actual))
|
||||
}
|
||||
}()
|
||||
|
||||
if matchError := oglematchers.Equals(expected).Matches(actual); matchError != nil {
|
||||
expectedSyntax := fmt.Sprintf("%v", expected)
|
||||
actualSyntax := fmt.Sprintf("%v", actual)
|
||||
if expectedSyntax == actualSyntax && reflect.TypeOf(expected) != reflect.TypeOf(actual) {
|
||||
message = fmt.Sprintf(shouldHaveBeenEqualTypeMismatch, expected, expected, actual, actual)
|
||||
} else {
|
||||
message = fmt.Sprintf(shouldHaveBeenEqual, expected, actual)
|
||||
}
|
||||
message = serializer.serialize(expected, actual, message)
|
||||
return
|
||||
if spec := newEqualityMethodSpecification(expected, actual); spec.IsSatisfied() && spec.AreEqual() {
|
||||
return success
|
||||
} else if matchError := oglematchers.Equals(expected).Matches(actual); matchError == nil {
|
||||
return success
|
||||
}
|
||||
|
||||
return success
|
||||
return serializer.serialize(expected, actual, composeEqualityMismatchMessage(expected, actual))
|
||||
}
|
||||
func composeEqualityMismatchMessage(expected, actual interface{}) string {
|
||||
var (
|
||||
renderedExpected = fmt.Sprintf("%v", expected)
|
||||
renderedActual = fmt.Sprintf("%v", actual)
|
||||
)
|
||||
|
||||
if renderedExpected != renderedActual {
|
||||
return fmt.Sprintf(shouldHaveBeenEqual+composePrettyDiff(renderedExpected, renderedActual), expected, actual)
|
||||
} else if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
|
||||
return fmt.Sprintf(shouldHaveBeenEqualTypeMismatch, expected, expected, actual, actual)
|
||||
} else {
|
||||
return fmt.Sprintf(shouldHaveBeenEqualNoResemblance, renderedExpected)
|
||||
}
|
||||
}
|
||||
|
||||
// ShouldNotEqual receives exactly two parameters and does an inequality check.
|
||||
// See ShouldEqual for details on how equality is determined.
|
||||
func ShouldNotEqual(actual interface{}, expected ...interface{}) string {
|
||||
if fail := need(1, expected); fail != success {
|
||||
return fail
|
||||
@@ -95,7 +105,7 @@ func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64
|
||||
delta, err := getFloat(expected[1])
|
||||
|
||||
if err != nil {
|
||||
return 0.0, 0.0, 0.0, "delta must be a numerical type"
|
||||
return 0.0, 0.0, 0.0, "The delta value " + err.Error()
|
||||
}
|
||||
|
||||
deltaFloat = delta
|
||||
@@ -104,15 +114,13 @@ func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64
|
||||
}
|
||||
|
||||
actualFloat, err := getFloat(actual)
|
||||
|
||||
if err != nil {
|
||||
return 0.0, 0.0, 0.0, err.Error()
|
||||
return 0.0, 0.0, 0.0, "The actual value " + err.Error()
|
||||
}
|
||||
|
||||
expectedFloat, err := getFloat(expected[0])
|
||||
|
||||
if err != nil {
|
||||
return 0.0, 0.0, 0.0, err.Error()
|
||||
return 0.0, 0.0, 0.0, "The comparison value " + err.Error()
|
||||
}
|
||||
|
||||
return actualFloat, expectedFloat, deltaFloat, ""
|
||||
@@ -139,10 +147,38 @@ func getFloat(num interface{}) (float64, error) {
|
||||
numKind == reflect.Float64 {
|
||||
return numValue.Float(), nil
|
||||
} else {
|
||||
return 0.0, errors.New("must be a numerical type, but was " + numKind.String())
|
||||
return 0.0, errors.New("must be a numerical type, but was: " + numKind.String())
|
||||
}
|
||||
}
|
||||
|
||||
// ShouldEqualJSON receives exactly two parameters and does an equality check by marshalling to JSON
|
||||
func ShouldEqualJSON(actual interface{}, expected ...interface{}) string {
|
||||
if message := need(1, expected); message != success {
|
||||
return message
|
||||
}
|
||||
|
||||
expectedString, expectedErr := remarshal(expected[0].(string))
|
||||
if expectedErr != nil {
|
||||
return "Expected value not valid JSON: " + expectedErr.Error()
|
||||
}
|
||||
|
||||
actualString, actualErr := remarshal(actual.(string))
|
||||
if actualErr != nil {
|
||||
return "Actual value not valid JSON: " + actualErr.Error()
|
||||
}
|
||||
|
||||
return ShouldEqual(actualString, expectedString)
|
||||
}
|
||||
func remarshal(value string) (string, error) {
|
||||
var structured interface{}
|
||||
err := json.Unmarshal([]byte(value), &structured)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
canonical, _ := json.Marshal(structured)
|
||||
return string(canonical), nil
|
||||
}
|
||||
|
||||
// ShouldResemble receives exactly two parameters and does a deep equal check (see reflect.DeepEqual)
|
||||
func ShouldResemble(actual interface{}, expected ...interface{}) string {
|
||||
if message := need(1, expected); message != success {
|
||||
@@ -150,8 +186,10 @@ func ShouldResemble(actual interface{}, expected ...interface{}) string {
|
||||
}
|
||||
|
||||
if matchError := oglematchers.DeepEquals(expected[0]).Matches(actual); matchError != nil {
|
||||
return serializer.serializeDetailed(expected[0], actual,
|
||||
fmt.Sprintf(shouldHaveResembled, render.Render(expected[0]), render.Render(actual)))
|
||||
renderedExpected, renderedActual := render.Render(expected[0]), render.Render(actual)
|
||||
message := fmt.Sprintf(shouldHaveResembled, renderedExpected, renderedActual) +
|
||||
composePrettyDiff(renderedExpected, renderedActual)
|
||||
return serializer.serializeDetailed(expected[0], actual, message)
|
||||
}
|
||||
|
||||
return success
|
||||
@@ -278,3 +316,16 @@ func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string {
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
// ShouldBeZeroValue receives a single parameter and ensures that it is NOT
|
||||
// the Go equivalent of the default value, or "zero" value.
|
||||
func ShouldNotBeZeroValue(actual interface{}, expected ...interface{}) string {
|
||||
if fail := need(0, expected); fail != success {
|
||||
return fail
|
||||
}
|
||||
zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface()
|
||||
if reflect.DeepEqual(zeroVal, actual) {
|
||||
return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldNotHaveBeenZeroValue, actual))
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
37
vendor/github.com/smartystreets/assertions/equality_diff.go
generated
vendored
Normal file
37
vendor/github.com/smartystreets/assertions/equality_diff.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package assertions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch"
|
||||
)
|
||||
|
||||
func composePrettyDiff(expected, actual string) string {
|
||||
diff := diffmatchpatch.New()
|
||||
diffs := diff.DiffMain(expected, actual, false)
|
||||
if prettyDiffIsLikelyToBeHelpful(diffs) {
|
||||
return fmt.Sprintf("\nDiff: '%s'", diff.DiffPrettyText(diffs))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// prettyDiffIsLikelyToBeHelpful returns true if the diff listing contains
|
||||
// more 'equal' segments than 'deleted'/'inserted' segments.
|
||||
func prettyDiffIsLikelyToBeHelpful(diffs []diffmatchpatch.Diff) bool {
|
||||
equal, deleted, inserted := measureDiffTypeLengths(diffs)
|
||||
return equal > deleted && equal > inserted
|
||||
}
|
||||
|
||||
func measureDiffTypeLengths(diffs []diffmatchpatch.Diff) (equal, deleted, inserted int) {
|
||||
for _, segment := range diffs {
|
||||
switch segment.Type {
|
||||
case diffmatchpatch.DiffEqual:
|
||||
equal += len(segment.Text)
|
||||
case diffmatchpatch.DiffDelete:
|
||||
deleted += len(segment.Text)
|
||||
case diffmatchpatch.DiffInsert:
|
||||
inserted += len(segment.Text)
|
||||
}
|
||||
}
|
||||
return equal, deleted, inserted
|
||||
}
|
||||
10
vendor/github.com/smartystreets/assertions/filter.go
generated
vendored
10
vendor/github.com/smartystreets/assertions/filter.go
generated
vendored
@@ -6,6 +6,7 @@ const (
|
||||
success = ""
|
||||
needExactValues = "This assertion requires exactly %d comparison values (you provided %d)."
|
||||
needNonEmptyCollection = "This assertion requires at least 1 comparison value (you provided 0)."
|
||||
needFewerValues = "This assertion allows %d or fewer comparison values (you provided %d)."
|
||||
)
|
||||
|
||||
func need(needed int, expected []interface{}) string {
|
||||
@@ -16,8 +17,15 @@ func need(needed int, expected []interface{}) string {
|
||||
}
|
||||
|
||||
func atLeast(minimum int, expected []interface{}) string {
|
||||
if len(expected) < 1 {
|
||||
if len(expected) < minimum {
|
||||
return needNonEmptyCollection
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
func atMost(max int, expected []interface{}) string {
|
||||
if len(expected) > max {
|
||||
return fmt.Sprintf(needFewerValues, max, len(expected))
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
3
vendor/github.com/smartystreets/assertions/go.mod
generated
vendored
Normal file
3
vendor/github.com/smartystreets/assertions/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/smartystreets/assertions
|
||||
|
||||
go 1.12
|
||||
20
vendor/github.com/smartystreets/assertions/internal/go-diff/LICENSE
generated
vendored
Normal file
20
vendor/github.com/smartystreets/assertions/internal/go-diff/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2012-2016 The go-diff Authors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
1345
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/diff.go
generated
vendored
Normal file
1345
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/diff.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/diffmatchpatch.go
generated
vendored
Normal file
46
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/diffmatchpatch.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
|
||||
// https://github.com/sergi/go-diff
|
||||
// See the included LICENSE file for license details.
|
||||
//
|
||||
// go-diff is a Go implementation of Google's Diff, Match, and Patch library
|
||||
// Original library is Copyright (c) 2006 Google Inc.
|
||||
// http://code.google.com/p/google-diff-match-patch/
|
||||
|
||||
// Package diffmatchpatch offers robust algorithms to perform the operations required for synchronizing plain text.
|
||||
package diffmatchpatch
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DiffMatchPatch holds the configuration for diff-match-patch operations.
|
||||
type DiffMatchPatch struct {
|
||||
// Number of seconds to map a diff before giving up (0 for infinity).
|
||||
DiffTimeout time.Duration
|
||||
// Cost of an empty edit operation in terms of edit characters.
|
||||
DiffEditCost int
|
||||
// How far to search for a match (0 = exact location, 1000+ = broad match). A match this many characters away from the expected location will add 1.0 to the score (0.0 is a perfect match).
|
||||
MatchDistance int
|
||||
// When deleting a large block of text (over ~64 characters), how close do the contents have to be to match the expected contents. (0.0 = perfection, 1.0 = very loose). Note that MatchThreshold controls how closely the end points of a delete need to match.
|
||||
PatchDeleteThreshold float64
|
||||
// Chunk size for context length.
|
||||
PatchMargin int
|
||||
// The number of bits in an int.
|
||||
MatchMaxBits int
|
||||
// At what point is no match declared (0.0 = perfection, 1.0 = very loose).
|
||||
MatchThreshold float64
|
||||
}
|
||||
|
||||
// New creates a new DiffMatchPatch object with default parameters.
|
||||
func New() *DiffMatchPatch {
|
||||
// Defaults.
|
||||
return &DiffMatchPatch{
|
||||
DiffTimeout: time.Second,
|
||||
DiffEditCost: 4,
|
||||
MatchThreshold: 0.5,
|
||||
MatchDistance: 1000,
|
||||
PatchDeleteThreshold: 0.5,
|
||||
PatchMargin: 4,
|
||||
MatchMaxBits: 32,
|
||||
}
|
||||
}
|
||||
160
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/match.go
generated
vendored
Normal file
160
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/match.go
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
|
||||
// https://github.com/sergi/go-diff
|
||||
// See the included LICENSE file for license details.
|
||||
//
|
||||
// go-diff is a Go implementation of Google's Diff, Match, and Patch library
|
||||
// Original library is Copyright (c) 2006 Google Inc.
|
||||
// http://code.google.com/p/google-diff-match-patch/
|
||||
|
||||
package diffmatchpatch
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// MatchMain locates the best instance of 'pattern' in 'text' near 'loc'.
|
||||
// Returns -1 if no match found.
|
||||
func (dmp *DiffMatchPatch) MatchMain(text, pattern string, loc int) int {
|
||||
// Check for null inputs not needed since null can't be passed in C#.
|
||||
|
||||
loc = int(math.Max(0, math.Min(float64(loc), float64(len(text)))))
|
||||
if text == pattern {
|
||||
// Shortcut (potentially not guaranteed by the algorithm)
|
||||
return 0
|
||||
} else if len(text) == 0 {
|
||||
// Nothing to match.
|
||||
return -1
|
||||
} else if loc+len(pattern) <= len(text) && text[loc:loc+len(pattern)] == pattern {
|
||||
// Perfect match at the perfect spot! (Includes case of null pattern)
|
||||
return loc
|
||||
}
|
||||
// Do a fuzzy compare.
|
||||
return dmp.MatchBitap(text, pattern, loc)
|
||||
}
|
||||
|
||||
// MatchBitap locates the best instance of 'pattern' in 'text' near 'loc' using the Bitap algorithm.
|
||||
// Returns -1 if no match was found.
|
||||
func (dmp *DiffMatchPatch) MatchBitap(text, pattern string, loc int) int {
|
||||
// Initialise the alphabet.
|
||||
s := dmp.MatchAlphabet(pattern)
|
||||
|
||||
// Highest score beyond which we give up.
|
||||
scoreThreshold := dmp.MatchThreshold
|
||||
// Is there a nearby exact match? (speedup)
|
||||
bestLoc := indexOf(text, pattern, loc)
|
||||
if bestLoc != -1 {
|
||||
scoreThreshold = math.Min(dmp.matchBitapScore(0, bestLoc, loc,
|
||||
pattern), scoreThreshold)
|
||||
// What about in the other direction? (speedup)
|
||||
bestLoc = lastIndexOf(text, pattern, loc+len(pattern))
|
||||
if bestLoc != -1 {
|
||||
scoreThreshold = math.Min(dmp.matchBitapScore(0, bestLoc, loc,
|
||||
pattern), scoreThreshold)
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise the bit arrays.
|
||||
matchmask := 1 << uint((len(pattern) - 1))
|
||||
bestLoc = -1
|
||||
|
||||
var binMin, binMid int
|
||||
binMax := len(pattern) + len(text)
|
||||
lastRd := []int{}
|
||||
for d := 0; d < len(pattern); d++ {
|
||||
// Scan for the best match; each iteration allows for one more error. Run a binary search to determine how far from 'loc' we can stray at this error level.
|
||||
binMin = 0
|
||||
binMid = binMax
|
||||
for binMin < binMid {
|
||||
if dmp.matchBitapScore(d, loc+binMid, loc, pattern) <= scoreThreshold {
|
||||
binMin = binMid
|
||||
} else {
|
||||
binMax = binMid
|
||||
}
|
||||
binMid = (binMax-binMin)/2 + binMin
|
||||
}
|
||||
// Use the result from this iteration as the maximum for the next.
|
||||
binMax = binMid
|
||||
start := int(math.Max(1, float64(loc-binMid+1)))
|
||||
finish := int(math.Min(float64(loc+binMid), float64(len(text))) + float64(len(pattern)))
|
||||
|
||||
rd := make([]int, finish+2)
|
||||
rd[finish+1] = (1 << uint(d)) - 1
|
||||
|
||||
for j := finish; j >= start; j-- {
|
||||
var charMatch int
|
||||
if len(text) <= j-1 {
|
||||
// Out of range.
|
||||
charMatch = 0
|
||||
} else if _, ok := s[text[j-1]]; !ok {
|
||||
charMatch = 0
|
||||
} else {
|
||||
charMatch = s[text[j-1]]
|
||||
}
|
||||
|
||||
if d == 0 {
|
||||
// First pass: exact match.
|
||||
rd[j] = ((rd[j+1] << 1) | 1) & charMatch
|
||||
} else {
|
||||
// Subsequent passes: fuzzy match.
|
||||
rd[j] = ((rd[j+1]<<1)|1)&charMatch | (((lastRd[j+1] | lastRd[j]) << 1) | 1) | lastRd[j+1]
|
||||
}
|
||||
if (rd[j] & matchmask) != 0 {
|
||||
score := dmp.matchBitapScore(d, j-1, loc, pattern)
|
||||
// This match will almost certainly be better than any existing match. But check anyway.
|
||||
if score <= scoreThreshold {
|
||||
// Told you so.
|
||||
scoreThreshold = score
|
||||
bestLoc = j - 1
|
||||
if bestLoc > loc {
|
||||
// When passing loc, don't exceed our current distance from loc.
|
||||
start = int(math.Max(1, float64(2*loc-bestLoc)))
|
||||
} else {
|
||||
// Already passed loc, downhill from here on in.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if dmp.matchBitapScore(d+1, loc, loc, pattern) > scoreThreshold {
|
||||
// No hope for a (better) match at greater error levels.
|
||||
break
|
||||
}
|
||||
lastRd = rd
|
||||
}
|
||||
return bestLoc
|
||||
}
|
||||
|
||||
// matchBitapScore computes and returns the score for a match with e errors and x location.
|
||||
func (dmp *DiffMatchPatch) matchBitapScore(e, x, loc int, pattern string) float64 {
|
||||
accuracy := float64(e) / float64(len(pattern))
|
||||
proximity := math.Abs(float64(loc - x))
|
||||
if dmp.MatchDistance == 0 {
|
||||
// Dodge divide by zero error.
|
||||
if proximity == 0 {
|
||||
return accuracy
|
||||
}
|
||||
|
||||
return 1.0
|
||||
}
|
||||
return accuracy + (proximity / float64(dmp.MatchDistance))
|
||||
}
|
||||
|
||||
// MatchAlphabet initialises the alphabet for the Bitap algorithm.
|
||||
func (dmp *DiffMatchPatch) MatchAlphabet(pattern string) map[byte]int {
|
||||
s := map[byte]int{}
|
||||
charPattern := []byte(pattern)
|
||||
for _, c := range charPattern {
|
||||
_, ok := s[c]
|
||||
if !ok {
|
||||
s[c] = 0
|
||||
}
|
||||
}
|
||||
i := 0
|
||||
|
||||
for _, c := range charPattern {
|
||||
value := s[c] | int(uint(1)<<uint((len(pattern)-i-1)))
|
||||
s[c] = value
|
||||
i++
|
||||
}
|
||||
return s
|
||||
}
|
||||
23
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/mathutil.go
generated
vendored
Normal file
23
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/mathutil.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
|
||||
// https://github.com/sergi/go-diff
|
||||
// See the included LICENSE file for license details.
|
||||
//
|
||||
// go-diff is a Go implementation of Google's Diff, Match, and Patch library
|
||||
// Original library is Copyright (c) 2006 Google Inc.
|
||||
// http://code.google.com/p/google-diff-match-patch/
|
||||
|
||||
package diffmatchpatch
|
||||
|
||||
func min(x, y int) int {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func max(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
17
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/operation_string.go
generated
vendored
Normal file
17
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/operation_string.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Code generated by "stringer -type=Operation -trimprefix=Diff"; DO NOT EDIT.
|
||||
|
||||
package diffmatchpatch
|
||||
|
||||
import "fmt"
|
||||
|
||||
const _Operation_name = "DeleteEqualInsert"
|
||||
|
||||
var _Operation_index = [...]uint8{0, 6, 11, 17}
|
||||
|
||||
func (i Operation) String() string {
|
||||
i -= -1
|
||||
if i < 0 || i >= Operation(len(_Operation_index)-1) {
|
||||
return fmt.Sprintf("Operation(%d)", i+-1)
|
||||
}
|
||||
return _Operation_name[_Operation_index[i]:_Operation_index[i+1]]
|
||||
}
|
||||
556
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/patch.go
generated
vendored
Normal file
556
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/patch.go
generated
vendored
Normal file
@@ -0,0 +1,556 @@
|
||||
// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
|
||||
// https://github.com/sergi/go-diff
|
||||
// See the included LICENSE file for license details.
|
||||
//
|
||||
// go-diff is a Go implementation of Google's Diff, Match, and Patch library
|
||||
// Original library is Copyright (c) 2006 Google Inc.
|
||||
// http://code.google.com/p/google-diff-match-patch/
|
||||
|
||||
package diffmatchpatch
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"math"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Patch represents one patch operation.
|
||||
type Patch struct {
|
||||
diffs []Diff
|
||||
Start1 int
|
||||
Start2 int
|
||||
Length1 int
|
||||
Length2 int
|
||||
}
|
||||
|
||||
// String emulates GNU diff's format.
|
||||
// Header: @@ -382,8 +481,9 @@
|
||||
// Indices are printed as 1-based, not 0-based.
|
||||
func (p *Patch) String() string {
|
||||
var coords1, coords2 string
|
||||
|
||||
if p.Length1 == 0 {
|
||||
coords1 = strconv.Itoa(p.Start1) + ",0"
|
||||
} else if p.Length1 == 1 {
|
||||
coords1 = strconv.Itoa(p.Start1 + 1)
|
||||
} else {
|
||||
coords1 = strconv.Itoa(p.Start1+1) + "," + strconv.Itoa(p.Length1)
|
||||
}
|
||||
|
||||
if p.Length2 == 0 {
|
||||
coords2 = strconv.Itoa(p.Start2) + ",0"
|
||||
} else if p.Length2 == 1 {
|
||||
coords2 = strconv.Itoa(p.Start2 + 1)
|
||||
} else {
|
||||
coords2 = strconv.Itoa(p.Start2+1) + "," + strconv.Itoa(p.Length2)
|
||||
}
|
||||
|
||||
var text bytes.Buffer
|
||||
_, _ = text.WriteString("@@ -" + coords1 + " +" + coords2 + " @@\n")
|
||||
|
||||
// Escape the body of the patch with %xx notation.
|
||||
for _, aDiff := range p.diffs {
|
||||
switch aDiff.Type {
|
||||
case DiffInsert:
|
||||
_, _ = text.WriteString("+")
|
||||
case DiffDelete:
|
||||
_, _ = text.WriteString("-")
|
||||
case DiffEqual:
|
||||
_, _ = text.WriteString(" ")
|
||||
}
|
||||
|
||||
_, _ = text.WriteString(strings.Replace(url.QueryEscape(aDiff.Text), "+", " ", -1))
|
||||
_, _ = text.WriteString("\n")
|
||||
}
|
||||
|
||||
return unescaper.Replace(text.String())
|
||||
}
|
||||
|
||||
// PatchAddContext increases the context until it is unique, but doesn't let the pattern expand beyond MatchMaxBits.
|
||||
func (dmp *DiffMatchPatch) PatchAddContext(patch Patch, text string) Patch {
|
||||
if len(text) == 0 {
|
||||
return patch
|
||||
}
|
||||
|
||||
pattern := text[patch.Start2 : patch.Start2+patch.Length1]
|
||||
padding := 0
|
||||
|
||||
// Look for the first and last matches of pattern in text. If two different matches are found, increase the pattern length.
|
||||
for strings.Index(text, pattern) != strings.LastIndex(text, pattern) &&
|
||||
len(pattern) < dmp.MatchMaxBits-2*dmp.PatchMargin {
|
||||
padding += dmp.PatchMargin
|
||||
maxStart := max(0, patch.Start2-padding)
|
||||
minEnd := min(len(text), patch.Start2+patch.Length1+padding)
|
||||
pattern = text[maxStart:minEnd]
|
||||
}
|
||||
// Add one chunk for good luck.
|
||||
padding += dmp.PatchMargin
|
||||
|
||||
// Add the prefix.
|
||||
prefix := text[max(0, patch.Start2-padding):patch.Start2]
|
||||
if len(prefix) != 0 {
|
||||
patch.diffs = append([]Diff{Diff{DiffEqual, prefix}}, patch.diffs...)
|
||||
}
|
||||
// Add the suffix.
|
||||
suffix := text[patch.Start2+patch.Length1 : min(len(text), patch.Start2+patch.Length1+padding)]
|
||||
if len(suffix) != 0 {
|
||||
patch.diffs = append(patch.diffs, Diff{DiffEqual, suffix})
|
||||
}
|
||||
|
||||
// Roll back the start points.
|
||||
patch.Start1 -= len(prefix)
|
||||
patch.Start2 -= len(prefix)
|
||||
// Extend the lengths.
|
||||
patch.Length1 += len(prefix) + len(suffix)
|
||||
patch.Length2 += len(prefix) + len(suffix)
|
||||
|
||||
return patch
|
||||
}
|
||||
|
||||
// PatchMake computes a list of patches.
|
||||
func (dmp *DiffMatchPatch) PatchMake(opt ...interface{}) []Patch {
|
||||
if len(opt) == 1 {
|
||||
diffs, _ := opt[0].([]Diff)
|
||||
text1 := dmp.DiffText1(diffs)
|
||||
return dmp.PatchMake(text1, diffs)
|
||||
} else if len(opt) == 2 {
|
||||
text1 := opt[0].(string)
|
||||
switch t := opt[1].(type) {
|
||||
case string:
|
||||
diffs := dmp.DiffMain(text1, t, true)
|
||||
if len(diffs) > 2 {
|
||||
diffs = dmp.DiffCleanupSemantic(diffs)
|
||||
diffs = dmp.DiffCleanupEfficiency(diffs)
|
||||
}
|
||||
return dmp.PatchMake(text1, diffs)
|
||||
case []Diff:
|
||||
return dmp.patchMake2(text1, t)
|
||||
}
|
||||
} else if len(opt) == 3 {
|
||||
return dmp.PatchMake(opt[0], opt[2])
|
||||
}
|
||||
return []Patch{}
|
||||
}
|
||||
|
||||
// patchMake2 computes a list of patches to turn text1 into text2.
|
||||
// text2 is not provided, diffs are the delta between text1 and text2.
|
||||
func (dmp *DiffMatchPatch) patchMake2(text1 string, diffs []Diff) []Patch {
|
||||
// Check for null inputs not needed since null can't be passed in C#.
|
||||
patches := []Patch{}
|
||||
if len(diffs) == 0 {
|
||||
return patches // Get rid of the null case.
|
||||
}
|
||||
|
||||
patch := Patch{}
|
||||
charCount1 := 0 // Number of characters into the text1 string.
|
||||
charCount2 := 0 // Number of characters into the text2 string.
|
||||
// Start with text1 (prepatchText) and apply the diffs until we arrive at text2 (postpatchText). We recreate the patches one by one to determine context info.
|
||||
prepatchText := text1
|
||||
postpatchText := text1
|
||||
|
||||
for i, aDiff := range diffs {
|
||||
if len(patch.diffs) == 0 && aDiff.Type != DiffEqual {
|
||||
// A new patch starts here.
|
||||
patch.Start1 = charCount1
|
||||
patch.Start2 = charCount2
|
||||
}
|
||||
|
||||
switch aDiff.Type {
|
||||
case DiffInsert:
|
||||
patch.diffs = append(patch.diffs, aDiff)
|
||||
patch.Length2 += len(aDiff.Text)
|
||||
postpatchText = postpatchText[:charCount2] +
|
||||
aDiff.Text + postpatchText[charCount2:]
|
||||
case DiffDelete:
|
||||
patch.Length1 += len(aDiff.Text)
|
||||
patch.diffs = append(patch.diffs, aDiff)
|
||||
postpatchText = postpatchText[:charCount2] + postpatchText[charCount2+len(aDiff.Text):]
|
||||
case DiffEqual:
|
||||
if len(aDiff.Text) <= 2*dmp.PatchMargin &&
|
||||
len(patch.diffs) != 0 && i != len(diffs)-1 {
|
||||
// Small equality inside a patch.
|
||||
patch.diffs = append(patch.diffs, aDiff)
|
||||
patch.Length1 += len(aDiff.Text)
|
||||
patch.Length2 += len(aDiff.Text)
|
||||
}
|
||||
if len(aDiff.Text) >= 2*dmp.PatchMargin {
|
||||
// Time for a new patch.
|
||||
if len(patch.diffs) != 0 {
|
||||
patch = dmp.PatchAddContext(patch, prepatchText)
|
||||
patches = append(patches, patch)
|
||||
patch = Patch{}
|
||||
// Unlike Unidiff, our patch lists have a rolling context. http://code.google.com/p/google-diff-match-patch/wiki/Unidiff Update prepatch text & pos to reflect the application of the just completed patch.
|
||||
prepatchText = postpatchText
|
||||
charCount1 = charCount2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current character count.
|
||||
if aDiff.Type != DiffInsert {
|
||||
charCount1 += len(aDiff.Text)
|
||||
}
|
||||
if aDiff.Type != DiffDelete {
|
||||
charCount2 += len(aDiff.Text)
|
||||
}
|
||||
}
|
||||
|
||||
// Pick up the leftover patch if not empty.
|
||||
if len(patch.diffs) != 0 {
|
||||
patch = dmp.PatchAddContext(patch, prepatchText)
|
||||
patches = append(patches, patch)
|
||||
}
|
||||
|
||||
return patches
|
||||
}
|
||||
|
||||
// PatchDeepCopy returns an array that is identical to a given an array of patches.
|
||||
func (dmp *DiffMatchPatch) PatchDeepCopy(patches []Patch) []Patch {
|
||||
patchesCopy := []Patch{}
|
||||
for _, aPatch := range patches {
|
||||
patchCopy := Patch{}
|
||||
for _, aDiff := range aPatch.diffs {
|
||||
patchCopy.diffs = append(patchCopy.diffs, Diff{
|
||||
aDiff.Type,
|
||||
aDiff.Text,
|
||||
})
|
||||
}
|
||||
patchCopy.Start1 = aPatch.Start1
|
||||
patchCopy.Start2 = aPatch.Start2
|
||||
patchCopy.Length1 = aPatch.Length1
|
||||
patchCopy.Length2 = aPatch.Length2
|
||||
patchesCopy = append(patchesCopy, patchCopy)
|
||||
}
|
||||
return patchesCopy
|
||||
}
|
||||
|
||||
// PatchApply merges a set of patches onto the text. Returns a patched text, as well as an array of true/false values indicating which patches were applied.
|
||||
func (dmp *DiffMatchPatch) PatchApply(patches []Patch, text string) (string, []bool) {
|
||||
if len(patches) == 0 {
|
||||
return text, []bool{}
|
||||
}
|
||||
|
||||
// Deep copy the patches so that no changes are made to originals.
|
||||
patches = dmp.PatchDeepCopy(patches)
|
||||
|
||||
nullPadding := dmp.PatchAddPadding(patches)
|
||||
text = nullPadding + text + nullPadding
|
||||
patches = dmp.PatchSplitMax(patches)
|
||||
|
||||
x := 0
|
||||
// delta keeps track of the offset between the expected and actual location of the previous patch. If there are patches expected at positions 10 and 20, but the first patch was found at 12, delta is 2 and the second patch has an effective expected position of 22.
|
||||
delta := 0
|
||||
results := make([]bool, len(patches))
|
||||
for _, aPatch := range patches {
|
||||
expectedLoc := aPatch.Start2 + delta
|
||||
text1 := dmp.DiffText1(aPatch.diffs)
|
||||
var startLoc int
|
||||
endLoc := -1
|
||||
if len(text1) > dmp.MatchMaxBits {
|
||||
// PatchSplitMax will only provide an oversized pattern in the case of a monster delete.
|
||||
startLoc = dmp.MatchMain(text, text1[:dmp.MatchMaxBits], expectedLoc)
|
||||
if startLoc != -1 {
|
||||
endLoc = dmp.MatchMain(text,
|
||||
text1[len(text1)-dmp.MatchMaxBits:], expectedLoc+len(text1)-dmp.MatchMaxBits)
|
||||
if endLoc == -1 || startLoc >= endLoc {
|
||||
// Can't find valid trailing context. Drop this patch.
|
||||
startLoc = -1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
startLoc = dmp.MatchMain(text, text1, expectedLoc)
|
||||
}
|
||||
if startLoc == -1 {
|
||||
// No match found. :(
|
||||
results[x] = false
|
||||
// Subtract the delta for this failed patch from subsequent patches.
|
||||
delta -= aPatch.Length2 - aPatch.Length1
|
||||
} else {
|
||||
// Found a match. :)
|
||||
results[x] = true
|
||||
delta = startLoc - expectedLoc
|
||||
var text2 string
|
||||
if endLoc == -1 {
|
||||
text2 = text[startLoc:int(math.Min(float64(startLoc+len(text1)), float64(len(text))))]
|
||||
} else {
|
||||
text2 = text[startLoc:int(math.Min(float64(endLoc+dmp.MatchMaxBits), float64(len(text))))]
|
||||
}
|
||||
if text1 == text2 {
|
||||
// Perfect match, just shove the Replacement text in.
|
||||
text = text[:startLoc] + dmp.DiffText2(aPatch.diffs) + text[startLoc+len(text1):]
|
||||
} else {
|
||||
// Imperfect match. Run a diff to get a framework of equivalent indices.
|
||||
diffs := dmp.DiffMain(text1, text2, false)
|
||||
if len(text1) > dmp.MatchMaxBits && float64(dmp.DiffLevenshtein(diffs))/float64(len(text1)) > dmp.PatchDeleteThreshold {
|
||||
// The end points match, but the content is unacceptably bad.
|
||||
results[x] = false
|
||||
} else {
|
||||
diffs = dmp.DiffCleanupSemanticLossless(diffs)
|
||||
index1 := 0
|
||||
for _, aDiff := range aPatch.diffs {
|
||||
if aDiff.Type != DiffEqual {
|
||||
index2 := dmp.DiffXIndex(diffs, index1)
|
||||
if aDiff.Type == DiffInsert {
|
||||
// Insertion
|
||||
text = text[:startLoc+index2] + aDiff.Text + text[startLoc+index2:]
|
||||
} else if aDiff.Type == DiffDelete {
|
||||
// Deletion
|
||||
startIndex := startLoc + index2
|
||||
text = text[:startIndex] +
|
||||
text[startIndex+dmp.DiffXIndex(diffs, index1+len(aDiff.Text))-index2:]
|
||||
}
|
||||
}
|
||||
if aDiff.Type != DiffDelete {
|
||||
index1 += len(aDiff.Text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
x++
|
||||
}
|
||||
// Strip the padding off.
|
||||
text = text[len(nullPadding) : len(nullPadding)+(len(text)-2*len(nullPadding))]
|
||||
return text, results
|
||||
}
|
||||
|
||||
// PatchAddPadding adds some padding on text start and end so that edges can match something.
|
||||
// Intended to be called only from within patchApply.
|
||||
func (dmp *DiffMatchPatch) PatchAddPadding(patches []Patch) string {
|
||||
paddingLength := dmp.PatchMargin
|
||||
nullPadding := ""
|
||||
for x := 1; x <= paddingLength; x++ {
|
||||
nullPadding += string(x)
|
||||
}
|
||||
|
||||
// Bump all the patches forward.
|
||||
for i := range patches {
|
||||
patches[i].Start1 += paddingLength
|
||||
patches[i].Start2 += paddingLength
|
||||
}
|
||||
|
||||
// Add some padding on start of first diff.
|
||||
if len(patches[0].diffs) == 0 || patches[0].diffs[0].Type != DiffEqual {
|
||||
// Add nullPadding equality.
|
||||
patches[0].diffs = append([]Diff{Diff{DiffEqual, nullPadding}}, patches[0].diffs...)
|
||||
patches[0].Start1 -= paddingLength // Should be 0.
|
||||
patches[0].Start2 -= paddingLength // Should be 0.
|
||||
patches[0].Length1 += paddingLength
|
||||
patches[0].Length2 += paddingLength
|
||||
} else if paddingLength > len(patches[0].diffs[0].Text) {
|
||||
// Grow first equality.
|
||||
extraLength := paddingLength - len(patches[0].diffs[0].Text)
|
||||
patches[0].diffs[0].Text = nullPadding[len(patches[0].diffs[0].Text):] + patches[0].diffs[0].Text
|
||||
patches[0].Start1 -= extraLength
|
||||
patches[0].Start2 -= extraLength
|
||||
patches[0].Length1 += extraLength
|
||||
patches[0].Length2 += extraLength
|
||||
}
|
||||
|
||||
// Add some padding on end of last diff.
|
||||
last := len(patches) - 1
|
||||
if len(patches[last].diffs) == 0 || patches[last].diffs[len(patches[last].diffs)-1].Type != DiffEqual {
|
||||
// Add nullPadding equality.
|
||||
patches[last].diffs = append(patches[last].diffs, Diff{DiffEqual, nullPadding})
|
||||
patches[last].Length1 += paddingLength
|
||||
patches[last].Length2 += paddingLength
|
||||
} else if paddingLength > len(patches[last].diffs[len(patches[last].diffs)-1].Text) {
|
||||
// Grow last equality.
|
||||
lastDiff := patches[last].diffs[len(patches[last].diffs)-1]
|
||||
extraLength := paddingLength - len(lastDiff.Text)
|
||||
patches[last].diffs[len(patches[last].diffs)-1].Text += nullPadding[:extraLength]
|
||||
patches[last].Length1 += extraLength
|
||||
patches[last].Length2 += extraLength
|
||||
}
|
||||
|
||||
return nullPadding
|
||||
}
|
||||
|
||||
// PatchSplitMax looks through the patches and breaks up any which are longer than the maximum limit of the match algorithm.
|
||||
// Intended to be called only from within patchApply.
|
||||
func (dmp *DiffMatchPatch) PatchSplitMax(patches []Patch) []Patch {
|
||||
patchSize := dmp.MatchMaxBits
|
||||
for x := 0; x < len(patches); x++ {
|
||||
if patches[x].Length1 <= patchSize {
|
||||
continue
|
||||
}
|
||||
bigpatch := patches[x]
|
||||
// Remove the big old patch.
|
||||
patches = append(patches[:x], patches[x+1:]...)
|
||||
x--
|
||||
|
||||
Start1 := bigpatch.Start1
|
||||
Start2 := bigpatch.Start2
|
||||
precontext := ""
|
||||
for len(bigpatch.diffs) != 0 {
|
||||
// Create one of several smaller patches.
|
||||
patch := Patch{}
|
||||
empty := true
|
||||
patch.Start1 = Start1 - len(precontext)
|
||||
patch.Start2 = Start2 - len(precontext)
|
||||
if len(precontext) != 0 {
|
||||
patch.Length1 = len(precontext)
|
||||
patch.Length2 = len(precontext)
|
||||
patch.diffs = append(patch.diffs, Diff{DiffEqual, precontext})
|
||||
}
|
||||
for len(bigpatch.diffs) != 0 && patch.Length1 < patchSize-dmp.PatchMargin {
|
||||
diffType := bigpatch.diffs[0].Type
|
||||
diffText := bigpatch.diffs[0].Text
|
||||
if diffType == DiffInsert {
|
||||
// Insertions are harmless.
|
||||
patch.Length2 += len(diffText)
|
||||
Start2 += len(diffText)
|
||||
patch.diffs = append(patch.diffs, bigpatch.diffs[0])
|
||||
bigpatch.diffs = bigpatch.diffs[1:]
|
||||
empty = false
|
||||
} else if diffType == DiffDelete && len(patch.diffs) == 1 && patch.diffs[0].Type == DiffEqual && len(diffText) > 2*patchSize {
|
||||
// This is a large deletion. Let it pass in one chunk.
|
||||
patch.Length1 += len(diffText)
|
||||
Start1 += len(diffText)
|
||||
empty = false
|
||||
patch.diffs = append(patch.diffs, Diff{diffType, diffText})
|
||||
bigpatch.diffs = bigpatch.diffs[1:]
|
||||
} else {
|
||||
// Deletion or equality. Only take as much as we can stomach.
|
||||
diffText = diffText[:min(len(diffText), patchSize-patch.Length1-dmp.PatchMargin)]
|
||||
|
||||
patch.Length1 += len(diffText)
|
||||
Start1 += len(diffText)
|
||||
if diffType == DiffEqual {
|
||||
patch.Length2 += len(diffText)
|
||||
Start2 += len(diffText)
|
||||
} else {
|
||||
empty = false
|
||||
}
|
||||
patch.diffs = append(patch.diffs, Diff{diffType, diffText})
|
||||
if diffText == bigpatch.diffs[0].Text {
|
||||
bigpatch.diffs = bigpatch.diffs[1:]
|
||||
} else {
|
||||
bigpatch.diffs[0].Text =
|
||||
bigpatch.diffs[0].Text[len(diffText):]
|
||||
}
|
||||
}
|
||||
}
|
||||
// Compute the head context for the next patch.
|
||||
precontext = dmp.DiffText2(patch.diffs)
|
||||
precontext = precontext[max(0, len(precontext)-dmp.PatchMargin):]
|
||||
|
||||
postcontext := ""
|
||||
// Append the end context for this patch.
|
||||
if len(dmp.DiffText1(bigpatch.diffs)) > dmp.PatchMargin {
|
||||
postcontext = dmp.DiffText1(bigpatch.diffs)[:dmp.PatchMargin]
|
||||
} else {
|
||||
postcontext = dmp.DiffText1(bigpatch.diffs)
|
||||
}
|
||||
|
||||
if len(postcontext) != 0 {
|
||||
patch.Length1 += len(postcontext)
|
||||
patch.Length2 += len(postcontext)
|
||||
if len(patch.diffs) != 0 && patch.diffs[len(patch.diffs)-1].Type == DiffEqual {
|
||||
patch.diffs[len(patch.diffs)-1].Text += postcontext
|
||||
} else {
|
||||
patch.diffs = append(patch.diffs, Diff{DiffEqual, postcontext})
|
||||
}
|
||||
}
|
||||
if !empty {
|
||||
x++
|
||||
patches = append(patches[:x], append([]Patch{patch}, patches[x:]...)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return patches
|
||||
}
|
||||
|
||||
// PatchToText takes a list of patches and returns a textual representation.
|
||||
func (dmp *DiffMatchPatch) PatchToText(patches []Patch) string {
|
||||
var text bytes.Buffer
|
||||
for _, aPatch := range patches {
|
||||
_, _ = text.WriteString(aPatch.String())
|
||||
}
|
||||
return text.String()
|
||||
}
|
||||
|
||||
// PatchFromText parses a textual representation of patches and returns a List of Patch objects.
|
||||
func (dmp *DiffMatchPatch) PatchFromText(textline string) ([]Patch, error) {
|
||||
patches := []Patch{}
|
||||
if len(textline) == 0 {
|
||||
return patches, nil
|
||||
}
|
||||
text := strings.Split(textline, "\n")
|
||||
textPointer := 0
|
||||
patchHeader := regexp.MustCompile("^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$")
|
||||
|
||||
var patch Patch
|
||||
var sign uint8
|
||||
var line string
|
||||
for textPointer < len(text) {
|
||||
|
||||
if !patchHeader.MatchString(text[textPointer]) {
|
||||
return patches, errors.New("Invalid patch string: " + text[textPointer])
|
||||
}
|
||||
|
||||
patch = Patch{}
|
||||
m := patchHeader.FindStringSubmatch(text[textPointer])
|
||||
|
||||
patch.Start1, _ = strconv.Atoi(m[1])
|
||||
if len(m[2]) == 0 {
|
||||
patch.Start1--
|
||||
patch.Length1 = 1
|
||||
} else if m[2] == "0" {
|
||||
patch.Length1 = 0
|
||||
} else {
|
||||
patch.Start1--
|
||||
patch.Length1, _ = strconv.Atoi(m[2])
|
||||
}
|
||||
|
||||
patch.Start2, _ = strconv.Atoi(m[3])
|
||||
|
||||
if len(m[4]) == 0 {
|
||||
patch.Start2--
|
||||
patch.Length2 = 1
|
||||
} else if m[4] == "0" {
|
||||
patch.Length2 = 0
|
||||
} else {
|
||||
patch.Start2--
|
||||
patch.Length2, _ = strconv.Atoi(m[4])
|
||||
}
|
||||
textPointer++
|
||||
|
||||
for textPointer < len(text) {
|
||||
if len(text[textPointer]) > 0 {
|
||||
sign = text[textPointer][0]
|
||||
} else {
|
||||
textPointer++
|
||||
continue
|
||||
}
|
||||
|
||||
line = text[textPointer][1:]
|
||||
line = strings.Replace(line, "+", "%2b", -1)
|
||||
line, _ = url.QueryUnescape(line)
|
||||
if sign == '-' {
|
||||
// Deletion.
|
||||
patch.diffs = append(patch.diffs, Diff{DiffDelete, line})
|
||||
} else if sign == '+' {
|
||||
// Insertion.
|
||||
patch.diffs = append(patch.diffs, Diff{DiffInsert, line})
|
||||
} else if sign == ' ' {
|
||||
// Minor equality.
|
||||
patch.diffs = append(patch.diffs, Diff{DiffEqual, line})
|
||||
} else if sign == '@' {
|
||||
// Start of next patch.
|
||||
break
|
||||
} else {
|
||||
// WTF?
|
||||
return patches, errors.New("Invalid patch mode '" + string(sign) + "' in: " + string(line))
|
||||
}
|
||||
textPointer++
|
||||
}
|
||||
|
||||
patches = append(patches, patch)
|
||||
}
|
||||
return patches, nil
|
||||
}
|
||||
88
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/stringutil.go
generated
vendored
Normal file
88
vendor/github.com/smartystreets/assertions/internal/go-diff/diffmatchpatch/stringutil.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2012-2016 The go-diff authors. All rights reserved.
|
||||
// https://github.com/sergi/go-diff
|
||||
// See the included LICENSE file for license details.
|
||||
//
|
||||
// go-diff is a Go implementation of Google's Diff, Match, and Patch library
|
||||
// Original library is Copyright (c) 2006 Google Inc.
|
||||
// http://code.google.com/p/google-diff-match-patch/
|
||||
|
||||
package diffmatchpatch
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// unescaper unescapes selected chars for compatibility with JavaScript's encodeURI.
|
||||
// In speed critical applications this could be dropped since the receiving application will certainly decode these fine. Note that this function is case-sensitive. Thus "%3F" would not be unescaped. But this is ok because it is only called with the output of HttpUtility.UrlEncode which returns lowercase hex. Example: "%3f" -> "?", "%24" -> "$", etc.
|
||||
var unescaper = strings.NewReplacer(
|
||||
"%21", "!", "%7E", "~", "%27", "'",
|
||||
"%28", "(", "%29", ")", "%3B", ";",
|
||||
"%2F", "/", "%3F", "?", "%3A", ":",
|
||||
"%40", "@", "%26", "&", "%3D", "=",
|
||||
"%2B", "+", "%24", "$", "%2C", ",", "%23", "#", "%2A", "*")
|
||||
|
||||
// indexOf returns the first index of pattern in str, starting at str[i].
|
||||
func indexOf(str string, pattern string, i int) int {
|
||||
if i > len(str)-1 {
|
||||
return -1
|
||||
}
|
||||
if i <= 0 {
|
||||
return strings.Index(str, pattern)
|
||||
}
|
||||
ind := strings.Index(str[i:], pattern)
|
||||
if ind == -1 {
|
||||
return -1
|
||||
}
|
||||
return ind + i
|
||||
}
|
||||
|
||||
// lastIndexOf returns the last index of pattern in str, starting at str[i].
|
||||
func lastIndexOf(str string, pattern string, i int) int {
|
||||
if i < 0 {
|
||||
return -1
|
||||
}
|
||||
if i >= len(str) {
|
||||
return strings.LastIndex(str, pattern)
|
||||
}
|
||||
_, size := utf8.DecodeRuneInString(str[i:])
|
||||
return strings.LastIndex(str[:i+size], pattern)
|
||||
}
|
||||
|
||||
// runesIndexOf returns the index of pattern in target, starting at target[i].
|
||||
func runesIndexOf(target, pattern []rune, i int) int {
|
||||
if i > len(target)-1 {
|
||||
return -1
|
||||
}
|
||||
if i <= 0 {
|
||||
return runesIndex(target, pattern)
|
||||
}
|
||||
ind := runesIndex(target[i:], pattern)
|
||||
if ind == -1 {
|
||||
return -1
|
||||
}
|
||||
return ind + i
|
||||
}
|
||||
|
||||
func runesEqual(r1, r2 []rune) bool {
|
||||
if len(r1) != len(r2) {
|
||||
return false
|
||||
}
|
||||
for i, c := range r1 {
|
||||
if c != r2[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// runesIndex is the equivalent of strings.Index for rune slices.
|
||||
func runesIndex(r1, r2 []rune) int {
|
||||
last := len(r1) - len(r2)
|
||||
for i := 0; i <= last; i++ {
|
||||
if runesEqual(r1[i:i+len(r2)], r2) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
266
vendor/github.com/smartystreets/assertions/internal/go-render/render/render.go
generated
vendored
266
vendor/github.com/smartystreets/assertions/internal/go-render/render/render.go
generated
vendored
@@ -12,32 +12,46 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var implicitTypeMap = map[reflect.Kind]string{
|
||||
var builtinTypeMap = map[reflect.Kind]string{
|
||||
reflect.Bool: "bool",
|
||||
reflect.String: "string",
|
||||
reflect.Int: "int",
|
||||
reflect.Int8: "int8",
|
||||
reflect.Complex128: "complex128",
|
||||
reflect.Complex64: "complex64",
|
||||
reflect.Float32: "float32",
|
||||
reflect.Float64: "float64",
|
||||
reflect.Int16: "int16",
|
||||
reflect.Int32: "int32",
|
||||
reflect.Int64: "int64",
|
||||
reflect.Uint: "uint",
|
||||
reflect.Uint8: "uint8",
|
||||
reflect.Int8: "int8",
|
||||
reflect.Int: "int",
|
||||
reflect.String: "string",
|
||||
reflect.Uint16: "uint16",
|
||||
reflect.Uint32: "uint32",
|
||||
reflect.Uint64: "uint64",
|
||||
reflect.Float32: "float32",
|
||||
reflect.Float64: "float64",
|
||||
reflect.Complex64: "complex64",
|
||||
reflect.Complex128: "complex128",
|
||||
reflect.Uint8: "uint8",
|
||||
reflect.Uint: "uint",
|
||||
reflect.Uintptr: "uintptr",
|
||||
}
|
||||
|
||||
var builtinTypeSet = map[string]struct{}{}
|
||||
|
||||
func init() {
|
||||
for _, v := range builtinTypeMap {
|
||||
builtinTypeSet[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
var typeOfString = reflect.TypeOf("")
|
||||
var typeOfInt = reflect.TypeOf(int(1))
|
||||
var typeOfUint = reflect.TypeOf(uint(1))
|
||||
var typeOfFloat = reflect.TypeOf(10.1)
|
||||
|
||||
// Render converts a structure to a string representation. Unline the "%#v"
|
||||
// format string, this resolves pointer types' contents in structs, maps, and
|
||||
// slices/arrays and prints their field values.
|
||||
func Render(v interface{}) string {
|
||||
buf := bytes.Buffer{}
|
||||
s := (*traverseState)(nil)
|
||||
s.render(&buf, 0, reflect.ValueOf(v))
|
||||
s.render(&buf, 0, reflect.ValueOf(v), false)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
@@ -72,7 +86,7 @@ func (s *traverseState) forkFor(ptr uintptr) *traverseState {
|
||||
return fs
|
||||
}
|
||||
|
||||
func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) {
|
||||
func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value, implicit bool) {
|
||||
if v.Kind() == reflect.Invalid {
|
||||
buf.WriteString("nil")
|
||||
return
|
||||
@@ -107,49 +121,80 @@ func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) {
|
||||
s = s.forkFor(pe)
|
||||
if s == nil {
|
||||
buf.WriteString("<REC(")
|
||||
writeType(buf, ptrs, vt)
|
||||
if !implicit {
|
||||
writeType(buf, ptrs, vt)
|
||||
}
|
||||
buf.WriteString(")>")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
isAnon := func(t reflect.Type) bool {
|
||||
if t.Name() != "" {
|
||||
if _, ok := builtinTypeSet[t.Name()]; !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return t.Kind() != reflect.Interface
|
||||
}
|
||||
|
||||
switch vk {
|
||||
case reflect.Struct:
|
||||
writeType(buf, ptrs, vt)
|
||||
if !implicit {
|
||||
writeType(buf, ptrs, vt)
|
||||
}
|
||||
buf.WriteRune('{')
|
||||
for i := 0; i < vt.NumField(); i++ {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
buf.WriteString(vt.Field(i).Name)
|
||||
buf.WriteRune(':')
|
||||
if rendered, ok := renderTime(v); ok {
|
||||
buf.WriteString(rendered)
|
||||
} else {
|
||||
structAnon := vt.Name() == ""
|
||||
for i := 0; i < vt.NumField(); i++ {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
anon := structAnon && isAnon(vt.Field(i).Type)
|
||||
|
||||
s.render(buf, 0, v.Field(i))
|
||||
if !anon {
|
||||
buf.WriteString(vt.Field(i).Name)
|
||||
buf.WriteRune(':')
|
||||
}
|
||||
|
||||
s.render(buf, 0, v.Field(i), anon)
|
||||
}
|
||||
}
|
||||
buf.WriteRune('}')
|
||||
|
||||
case reflect.Slice:
|
||||
if v.IsNil() {
|
||||
writeType(buf, ptrs, vt)
|
||||
buf.WriteString("(nil)")
|
||||
if !implicit {
|
||||
writeType(buf, ptrs, vt)
|
||||
buf.WriteString("(nil)")
|
||||
} else {
|
||||
buf.WriteString("nil")
|
||||
}
|
||||
return
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case reflect.Array:
|
||||
writeType(buf, ptrs, vt)
|
||||
if !implicit {
|
||||
writeType(buf, ptrs, vt)
|
||||
}
|
||||
anon := vt.Name() == "" && isAnon(vt.Elem())
|
||||
buf.WriteString("{")
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
|
||||
s.render(buf, 0, v.Index(i))
|
||||
s.render(buf, 0, v.Index(i), anon)
|
||||
}
|
||||
buf.WriteRune('}')
|
||||
|
||||
case reflect.Map:
|
||||
writeType(buf, ptrs, vt)
|
||||
if !implicit {
|
||||
writeType(buf, ptrs, vt)
|
||||
}
|
||||
if v.IsNil() {
|
||||
buf.WriteString("(nil)")
|
||||
} else {
|
||||
@@ -158,14 +203,17 @@ func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) {
|
||||
mkeys := v.MapKeys()
|
||||
tryAndSortMapKeys(vt, mkeys)
|
||||
|
||||
kt := vt.Key()
|
||||
keyAnon := typeOfString.ConvertibleTo(kt) || typeOfInt.ConvertibleTo(kt) || typeOfUint.ConvertibleTo(kt) || typeOfFloat.ConvertibleTo(kt)
|
||||
valAnon := vt.Name() == "" && isAnon(vt.Elem())
|
||||
for i, mk := range mkeys {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
|
||||
s.render(buf, 0, mk)
|
||||
s.render(buf, 0, mk, keyAnon)
|
||||
buf.WriteString(":")
|
||||
s.render(buf, 0, v.MapIndex(mk))
|
||||
s.render(buf, 0, v.MapIndex(mk), valAnon)
|
||||
}
|
||||
buf.WriteRune('}')
|
||||
}
|
||||
@@ -176,11 +224,9 @@ func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) {
|
||||
case reflect.Interface:
|
||||
if v.IsNil() {
|
||||
writeType(buf, ptrs, v.Type())
|
||||
buf.WriteRune('(')
|
||||
fmt.Fprint(buf, "nil")
|
||||
buf.WriteRune(')')
|
||||
buf.WriteString("(nil)")
|
||||
} else {
|
||||
s.render(buf, ptrs, v.Elem())
|
||||
s.render(buf, ptrs, v.Elem(), false)
|
||||
}
|
||||
|
||||
case reflect.Chan, reflect.Func, reflect.UnsafePointer:
|
||||
@@ -191,7 +237,7 @@ func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) {
|
||||
|
||||
default:
|
||||
tstr := vt.String()
|
||||
implicit := ptrs == 0 && implicitTypeMap[vk] == tstr
|
||||
implicit = implicit || (ptrs == 0 && builtinTypeMap[vk] == tstr)
|
||||
if !implicit {
|
||||
writeType(buf, ptrs, vt)
|
||||
buf.WriteRune('(')
|
||||
@@ -206,7 +252,7 @@ func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
fmt.Fprintf(buf, "%d", v.Int())
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
fmt.Fprintf(buf, "%d", v.Uint())
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
@@ -288,40 +334,148 @@ func writeType(buf *bytes.Buffer, ptrs int, t reflect.Type) {
|
||||
}
|
||||
}
|
||||
|
||||
type cmpFn func(a, b reflect.Value) int
|
||||
|
||||
type sortableValueSlice struct {
|
||||
kind reflect.Kind
|
||||
cmp cmpFn
|
||||
elements []reflect.Value
|
||||
}
|
||||
|
||||
func (s *sortableValueSlice) Len() int {
|
||||
func (s sortableValueSlice) Len() int {
|
||||
return len(s.elements)
|
||||
}
|
||||
|
||||
func (s *sortableValueSlice) Less(i, j int) bool {
|
||||
switch s.kind {
|
||||
case reflect.String:
|
||||
return s.elements[i].String() < s.elements[j].String()
|
||||
|
||||
case reflect.Int:
|
||||
return s.elements[i].Int() < s.elements[j].Int()
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported sort kind: %s", s.kind))
|
||||
}
|
||||
func (s sortableValueSlice) Less(i, j int) bool {
|
||||
return s.cmp(s.elements[i], s.elements[j]) < 0
|
||||
}
|
||||
|
||||
func (s *sortableValueSlice) Swap(i, j int) {
|
||||
func (s sortableValueSlice) Swap(i, j int) {
|
||||
s.elements[i], s.elements[j] = s.elements[j], s.elements[i]
|
||||
}
|
||||
|
||||
func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) {
|
||||
// Try our stock sortable values.
|
||||
switch mt.Key().Kind() {
|
||||
case reflect.String, reflect.Int:
|
||||
vs := &sortableValueSlice{
|
||||
kind: mt.Key().Kind(),
|
||||
elements: k,
|
||||
// cmpForType returns a cmpFn which sorts the data for some type t in the same
|
||||
// order that a go-native map key is compared for equality.
|
||||
func cmpForType(t reflect.Type) cmpFn {
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.String(), bv.String()
|
||||
if a < b {
|
||||
return -1
|
||||
} else if a > b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
sort.Sort(vs)
|
||||
|
||||
case reflect.Bool:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.Bool(), bv.Bool()
|
||||
if !a && b {
|
||||
return -1
|
||||
} else if a && !b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.Int(), bv.Int()
|
||||
if a < b {
|
||||
return -1
|
||||
} else if a > b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
|
||||
reflect.Uint64, reflect.Uintptr, reflect.UnsafePointer:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.Uint(), bv.Uint()
|
||||
if a < b {
|
||||
return -1
|
||||
} else if a > b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.Float(), bv.Float()
|
||||
if a < b {
|
||||
return -1
|
||||
} else if a > b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.InterfaceData(), bv.InterfaceData()
|
||||
if a[0] < b[0] {
|
||||
return -1
|
||||
} else if a[0] > b[0] {
|
||||
return 1
|
||||
}
|
||||
if a[1] < b[1] {
|
||||
return -1
|
||||
} else if a[1] > b[1] {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.Complex(), bv.Complex()
|
||||
if real(a) < real(b) {
|
||||
return -1
|
||||
} else if real(a) > real(b) {
|
||||
return 1
|
||||
}
|
||||
if imag(a) < imag(b) {
|
||||
return -1
|
||||
} else if imag(a) > imag(b) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Ptr, reflect.Chan:
|
||||
return func(av, bv reflect.Value) int {
|
||||
a, b := av.Pointer(), bv.Pointer()
|
||||
if a < b {
|
||||
return -1
|
||||
} else if a > b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
cmpLst := make([]cmpFn, t.NumField())
|
||||
for i := range cmpLst {
|
||||
cmpLst[i] = cmpForType(t.Field(i).Type)
|
||||
}
|
||||
return func(a, b reflect.Value) int {
|
||||
for i, cmp := range cmpLst {
|
||||
if rslt := cmp(a.Field(i), b.Field(i)); rslt != 0 {
|
||||
return rslt
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) {
|
||||
if cmp := cmpForType(mt.Key()); cmp != nil {
|
||||
sort.Sort(sortableValueSlice{cmp, k})
|
||||
}
|
||||
}
|
||||
|
||||
26
vendor/github.com/smartystreets/assertions/internal/go-render/render/render_time.go
generated
vendored
Normal file
26
vendor/github.com/smartystreets/assertions/internal/go-render/render/render_time.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func renderTime(value reflect.Value) (string, bool) {
|
||||
if instant, ok := convertTime(value); !ok {
|
||||
return "", false
|
||||
} else if instant.IsZero() {
|
||||
return "0", true
|
||||
} else {
|
||||
return instant.String(), true
|
||||
}
|
||||
}
|
||||
|
||||
func convertTime(value reflect.Value) (t time.Time, ok bool) {
|
||||
if value.Type() == timeType {
|
||||
defer func() { recover() }()
|
||||
t, ok = value.Interface().(time.Time)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var timeType = reflect.TypeOf(time.Time{})
|
||||
70
vendor/github.com/smartystreets/assertions/internal/oglematchers/all_of.go
generated
vendored
70
vendor/github.com/smartystreets/assertions/internal/oglematchers/all_of.go
generated
vendored
@@ -1,70 +0,0 @@
|
||||
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AllOf accepts a set of matchers S and returns a matcher that follows the
|
||||
// algorithm below when considering a candidate c:
|
||||
//
|
||||
// 1. Return true if for every Matcher m in S, m matches c.
|
||||
//
|
||||
// 2. Otherwise, if there is a matcher m in S such that m returns a fatal
|
||||
// error for c, return that matcher's error message.
|
||||
//
|
||||
// 3. Otherwise, return false with the error from some wrapped matcher.
|
||||
//
|
||||
// This is akin to a logical AND operation for matchers.
|
||||
func AllOf(matchers ...Matcher) Matcher {
|
||||
return &allOfMatcher{matchers}
|
||||
}
|
||||
|
||||
type allOfMatcher struct {
|
||||
wrappedMatchers []Matcher
|
||||
}
|
||||
|
||||
func (m *allOfMatcher) Description() string {
|
||||
// Special case: the empty set.
|
||||
if len(m.wrappedMatchers) == 0 {
|
||||
return "is anything"
|
||||
}
|
||||
|
||||
// Join the descriptions for the wrapped matchers.
|
||||
wrappedDescs := make([]string, len(m.wrappedMatchers))
|
||||
for i, wrappedMatcher := range m.wrappedMatchers {
|
||||
wrappedDescs[i] = wrappedMatcher.Description()
|
||||
}
|
||||
|
||||
return strings.Join(wrappedDescs, ", and ")
|
||||
}
|
||||
|
||||
func (m *allOfMatcher) Matches(c interface{}) (err error) {
|
||||
for _, wrappedMatcher := range m.wrappedMatchers {
|
||||
if wrappedErr := wrappedMatcher.Matches(c); wrappedErr != nil {
|
||||
err = wrappedErr
|
||||
|
||||
// If the error is fatal, return immediately with this error.
|
||||
_, ok := wrappedErr.(*FatalError)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
32
vendor/github.com/smartystreets/assertions/internal/oglematchers/any.go
generated
vendored
32
vendor/github.com/smartystreets/assertions/internal/oglematchers/any.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
// Any returns a matcher that matches any value.
|
||||
func Any() Matcher {
|
||||
return &anyMatcher{}
|
||||
}
|
||||
|
||||
type anyMatcher struct {
|
||||
}
|
||||
|
||||
func (m *anyMatcher) Description() string {
|
||||
return "is anything"
|
||||
}
|
||||
|
||||
func (m *anyMatcher) Matches(c interface{}) error {
|
||||
return nil
|
||||
}
|
||||
2
vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go
generated
vendored
2
vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go
generated
vendored
@@ -28,7 +28,7 @@ func Contains(x interface{}) Matcher {
|
||||
var ok bool
|
||||
|
||||
if result.elementMatcher, ok = x.(Matcher); !ok {
|
||||
result.elementMatcher = Equals(x)
|
||||
result.elementMatcher = DeepEquals(x)
|
||||
}
|
||||
|
||||
return &result
|
||||
|
||||
91
vendor/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go
generated
vendored
91
vendor/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go
generated
vendored
@@ -1,91 +0,0 @@
|
||||
// Copyright 2012 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Given a list of arguments M, ElementsAre returns a matcher that matches
|
||||
// arrays and slices A where all of the following hold:
|
||||
//
|
||||
// * A is the same length as M.
|
||||
//
|
||||
// * For each i < len(A) where M[i] is a matcher, A[i] matches M[i].
|
||||
//
|
||||
// * For each i < len(A) where M[i] is not a matcher, A[i] matches
|
||||
// Equals(M[i]).
|
||||
//
|
||||
func ElementsAre(M ...interface{}) Matcher {
|
||||
// Copy over matchers, or convert to Equals(x) for non-matcher x.
|
||||
subMatchers := make([]Matcher, len(M))
|
||||
for i, x := range M {
|
||||
if matcher, ok := x.(Matcher); ok {
|
||||
subMatchers[i] = matcher
|
||||
continue
|
||||
}
|
||||
|
||||
subMatchers[i] = Equals(x)
|
||||
}
|
||||
|
||||
return &elementsAreMatcher{subMatchers}
|
||||
}
|
||||
|
||||
type elementsAreMatcher struct {
|
||||
subMatchers []Matcher
|
||||
}
|
||||
|
||||
func (m *elementsAreMatcher) Description() string {
|
||||
subDescs := make([]string, len(m.subMatchers))
|
||||
for i, sm := range m.subMatchers {
|
||||
subDescs[i] = sm.Description()
|
||||
}
|
||||
|
||||
return fmt.Sprintf("elements are: [%s]", strings.Join(subDescs, ", "))
|
||||
}
|
||||
|
||||
func (m *elementsAreMatcher) Matches(candidates interface{}) error {
|
||||
// The candidate must be a slice or an array.
|
||||
v := reflect.ValueOf(candidates)
|
||||
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
|
||||
return NewFatalError("which is not a slice or array")
|
||||
}
|
||||
|
||||
// The length must be correct.
|
||||
if v.Len() != len(m.subMatchers) {
|
||||
return errors.New(fmt.Sprintf("which is of length %d", v.Len()))
|
||||
}
|
||||
|
||||
// Check each element.
|
||||
for i, subMatcher := range m.subMatchers {
|
||||
c := v.Index(i)
|
||||
if matchErr := subMatcher.Matches(c.Interface()); matchErr != nil {
|
||||
// Return an errors indicating which element doesn't match. If the
|
||||
// matcher error was fatal, make this one fatal too.
|
||||
err := errors.New(fmt.Sprintf("whose element %d doesn't match", i))
|
||||
if _, isFatal := matchErr.(*FatalError); isFatal {
|
||||
err = NewFatalError(err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
51
vendor/github.com/smartystreets/assertions/internal/oglematchers/error.go
generated
vendored
51
vendor/github.com/smartystreets/assertions/internal/oglematchers/error.go
generated
vendored
@@ -1,51 +0,0 @@
|
||||
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
// Error returns a matcher that matches non-nil values implementing the
|
||||
// built-in error interface for whom the return value of Error() matches the
|
||||
// supplied matcher.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// err := errors.New("taco burrito")
|
||||
//
|
||||
// Error(Equals("taco burrito")) // matches err
|
||||
// Error(HasSubstr("taco")) // matches err
|
||||
// Error(HasSubstr("enchilada")) // doesn't match err
|
||||
//
|
||||
func Error(m Matcher) Matcher {
|
||||
return &errorMatcher{m}
|
||||
}
|
||||
|
||||
type errorMatcher struct {
|
||||
wrappedMatcher Matcher
|
||||
}
|
||||
|
||||
func (m *errorMatcher) Description() string {
|
||||
return "error " + m.wrappedMatcher.Description()
|
||||
}
|
||||
|
||||
func (m *errorMatcher) Matches(c interface{}) error {
|
||||
// Make sure that c is an error.
|
||||
e, ok := c.(error)
|
||||
if !ok {
|
||||
return NewFatalError("which is not an error")
|
||||
}
|
||||
|
||||
// Pass on the error text to the wrapped matcher.
|
||||
return m.wrappedMatcher.Matches(e.Error())
|
||||
}
|
||||
37
vendor/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go
generated
vendored
37
vendor/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go
generated
vendored
@@ -1,37 +0,0 @@
|
||||
// Copyright 2015 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// HasSameTypeAs returns a matcher that matches values with exactly the same
|
||||
// type as the supplied prototype.
|
||||
func HasSameTypeAs(p interface{}) Matcher {
|
||||
expected := reflect.TypeOf(p)
|
||||
pred := func(c interface{}) error {
|
||||
actual := reflect.TypeOf(c)
|
||||
if actual != expected {
|
||||
return fmt.Errorf("which has type %v", actual)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return NewMatcher(pred, fmt.Sprintf("has type %v", expected))
|
||||
}
|
||||
46
vendor/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go
generated
vendored
46
vendor/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HasSubstr returns a matcher that matches strings containing s as a
|
||||
// substring.
|
||||
func HasSubstr(s string) Matcher {
|
||||
return NewMatcher(
|
||||
func(c interface{}) error { return hasSubstr(s, c) },
|
||||
fmt.Sprintf("has substring \"%s\"", s))
|
||||
}
|
||||
|
||||
func hasSubstr(needle string, c interface{}) error {
|
||||
v := reflect.ValueOf(c)
|
||||
if v.Kind() != reflect.String {
|
||||
return NewFatalError("which is not a string")
|
||||
}
|
||||
|
||||
// Perform the substring search.
|
||||
haystack := v.String()
|
||||
if strings.Contains(haystack, needle) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New("")
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user