Merge branch 'master' of https://github.com/go-gitea/gitea
# Conflicts: # public/js/index.js
This commit is contained in:
commit
1fded52044
|
|
@ -48,9 +48,9 @@ getting free help.
|
|||
|
||||
## Discuss your design
|
||||
|
||||
The project welcomes submissions. If you want to change or add something,
|
||||
please let everyone know what you're working on—[file an issue](https://github.com/go-gitea/gitea/issues/new)!
|
||||
Significant changes must go through the change proposal process
|
||||
The project welcomes submissions. If you want to change or add something,
|
||||
please let everyone know what you're working on—[file an issue](https://github.com/go-gitea/gitea/issues/new)!
|
||||
Significant changes must go through the change proposal process
|
||||
before they can be accepted. To create a proposal, file an issue with
|
||||
your proposed changes documented, and make sure to note in the title
|
||||
of the issue that it is a proposal.
|
||||
|
|
@ -69,8 +69,8 @@ and keep the compatibility on upgrade. To make sure you are
|
|||
running the test suite exactly like we do, you should install
|
||||
the CLI for [Drone CI](https://github.com/drone/drone), as
|
||||
we are using the server for continous testing, following [these
|
||||
instructions](http://readme.drone.io/usage/getting-started-cli). After that,
|
||||
you can simply call `drone exec` within your working directory and it will try
|
||||
instructions](http://readme.drone.io/usage/getting-started-cli). After that,
|
||||
you can simply call `drone exec` within your working directory and it will try
|
||||
to run the test suite locally.
|
||||
|
||||
## Vendoring
|
||||
|
|
@ -100,7 +100,7 @@ Generally, the go build tools are installed as-needed in the `Makefile`.
|
|||
An exception are the tools to build the CSS and images.
|
||||
|
||||
- To build CSS: Install [Node.js](https://nodejs.org/en/download/package-manager)
|
||||
with `npm` and then run `npm install` and `make stylesheets`.
|
||||
with `npm` and then run `npm install` and `make generate-stylesheets`.
|
||||
- To build Images: ImageMagick, inkscape and zopflipng binaries must be
|
||||
available in your `PATH` to run `make generate-images`.
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ makes the change, even if they are an owner or a maintainer. We use GitHub's
|
|||
pull request workflow to do that. And, we also use [LGTM](http://lgtm.co)
|
||||
to ensure every PR is reviewed by at least 2 maintainers.
|
||||
|
||||
Please try to make your pull request easy to review for us. And, please read
|
||||
Please try to make your pull request easy to review for us. And, please read
|
||||
the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/devel/pull-requests.md#best-practices-for-faster-reviews)* guide;
|
||||
it has lots of useful tips for any project you may want to contribute.
|
||||
Some of the key points:
|
||||
|
|
@ -174,11 +174,11 @@ obtain a final version that is maintained in this branch. A release is
|
|||
maintained by issuing patch releases to only correct critical problems
|
||||
such as crashes or security issues.
|
||||
|
||||
Major release cycles are bimonthly. They always begin on the 25th and end on
|
||||
the 24th (i.e., the 25th of December to February 24th).
|
||||
Major release cycles are bimonthly. They always begin on the 25th and end on
|
||||
the 24th (i.e., the 25th of December to February 24th).
|
||||
|
||||
During a development cycle, we may also publish any necessary minor releases
|
||||
for the previous version. For example, if the latest, published release is
|
||||
During a development cycle, we may also publish any necessary minor releases
|
||||
for the previous version. For example, if the latest, published release is
|
||||
v1.2, then minor changes for the previous release—e.g., v1.1.0 -> v1.1.1—are
|
||||
still possible.
|
||||
|
||||
|
|
|
|||
14
cmd/serv.go
14
cmd/serv.go
|
|
@ -158,18 +158,10 @@ func runServ(c *cli.Context) error {
|
|||
}
|
||||
os.Setenv(models.EnvRepoName, reponame)
|
||||
|
||||
repoUser, err := models.GetUserByName(username)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
fail("Repository owner does not exist", "Unregistered owner: %s", username)
|
||||
}
|
||||
fail("Internal error", "Failed to get repository owner (%s): %v", username, err)
|
||||
}
|
||||
|
||||
repo, err := models.GetRepositoryByName(repoUser.ID, reponame)
|
||||
repo, err := models.GetRepositoryByOwnerAndName(username, reponame)
|
||||
if err != nil {
|
||||
if models.IsErrRepoNotExist(err) {
|
||||
fail(accessDenied, "Repository does not exist: %s/%s", repoUser.Name, reponame)
|
||||
fail(accessDenied, "Repository does not exist: %s/%s", username, reponame)
|
||||
}
|
||||
fail("Internal error", "Failed to get repository: %v", err)
|
||||
}
|
||||
|
|
@ -263,7 +255,7 @@ func runServ(c *cli.Context) error {
|
|||
|
||||
//LFS token authentication
|
||||
if verb == lfsAuthenticateVerb {
|
||||
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, repoUser.Name, repo.Name)
|
||||
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, username, repo.Name)
|
||||
|
||||
now := time.Now()
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
|
|
|
|||
|
|
@ -234,3 +234,46 @@ languages:
|
|||
url: https://discourse.gitea.io/
|
||||
weight: 80
|
||||
pre: group
|
||||
|
||||
fr-fr:
|
||||
weight: 5
|
||||
languageName: Français
|
||||
menu:
|
||||
page:
|
||||
- name: Site
|
||||
url: /fr-fr/
|
||||
weight: 10
|
||||
pre: home
|
||||
post: active
|
||||
- name: Documentation
|
||||
url: https://docs.gitea.io/fr-fr/
|
||||
weight: 20
|
||||
pre: question
|
||||
- name: API
|
||||
url: https://try.gitea.io/api/swagger
|
||||
weight: 25
|
||||
pre: plug
|
||||
- name: Blog
|
||||
url: https://blog.gitea.io/
|
||||
weight: 30
|
||||
pre: rss
|
||||
- name: Code
|
||||
url: https://code.gitea.io/
|
||||
weight: 40
|
||||
pre: code
|
||||
- name: Téléchargement
|
||||
url: https://dl.gitea.io/
|
||||
weight: 50
|
||||
pre: download
|
||||
- name: GitHub
|
||||
url: https://github.com/go-gitea/
|
||||
weight: 60
|
||||
pre: github
|
||||
- name: Discord Chat
|
||||
url: https://discord.gg/NsatcWJ
|
||||
weight: 70
|
||||
pre: comment
|
||||
- name: Forum
|
||||
url: https://discourse.gitea.io/
|
||||
weight: 80
|
||||
pre: group
|
||||
|
|
|
|||
13
docs/content/doc/advanced.fr-fr.md
Executable file
13
docs/content/doc/advanced.fr-fr.md
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Avancé"
|
||||
slug: "advanced"
|
||||
weight: 30
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "Avancé"
|
||||
weight: 40
|
||||
identifier: "advanced"
|
||||
---
|
||||
44
docs/content/doc/advanced/make.fr-fr.md
Executable file
44
docs/content/doc/advanced/make.fr-fr.md
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Make"
|
||||
slug: "make"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "advanced"
|
||||
name: "Make"
|
||||
weight: 30
|
||||
identifier: "make"
|
||||
---
|
||||
|
||||
# Make
|
||||
|
||||
Gitea fait largement usage de Make pour automatiser les tâches et avoir un développement plus rapide. Ce guide explique comment installer Make.
|
||||
|
||||
### Linux
|
||||
|
||||
Vous pouvez installer Make avec votre gestionnaire de paquetages
|
||||
|
||||
Depuis Ubuntu/Debian:
|
||||
|
||||
```bash
|
||||
sudo apt-get install build-essential
|
||||
```
|
||||
|
||||
Depuis Fedora/RHEL/CentOS:
|
||||
|
||||
```bash
|
||||
sudo yum install make
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make:
|
||||
|
||||
- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez le quelque part et mettez à jour `PATH`.
|
||||
- [32-bits version](ftp://ftp.equation.com/make/32/make.exe)
|
||||
- [64-bits version](ftp://ftp.equation.com/make/64/make.exe)
|
||||
- [MinGW](http://www.mingw.org/) includes a build. The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to your `PATH`.
|
||||
- [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`
|
||||
|
|
@ -95,6 +95,17 @@ Both the LDAP via BindDN and the simple auth LDAP share the following fields:
|
|||
matching supplied login name against multiple attributes such as user
|
||||
identifier, email or even phone number.
|
||||
- Example: `(&(objectClass=Person)(|(uid=%[1]s)(mail=%[1]s)(mobile=%[1]s)))`
|
||||
- Enable user synchronization
|
||||
- This option enables a periodic task that synchronizes the Gitea users with
|
||||
the LDAP server. The default period is every 24 hours but that can be
|
||||
changed in the app.ini file. See the *cron.sync_external_users* section in
|
||||
the [sample
|
||||
app.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
||||
for detailed comments about that section. The *User Search Base* and *User
|
||||
Filter* settings described above will limit which users can use Gitea and
|
||||
which users will be synchronized. When initially run the task will create
|
||||
all LDAP users that match the given settings so take care if working with
|
||||
large Enterprise LDAP directories.
|
||||
|
||||
**LDAP using simple auth** adds the following fields:
|
||||
|
||||
|
|
|
|||
13
docs/content/doc/installation.fr-fr.md
Executable file
13
docs/content/doc/installation.fr-fr.md
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Installation"
|
||||
slug: "installation"
|
||||
weight: 10
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "Installation"
|
||||
weight: 10
|
||||
identifier: "installation"
|
||||
---
|
||||
45
docs/content/doc/installation/from-binary.fr-fr.md
Executable file
45
docs/content/doc/installation/from-binary.fr-fr.md
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Installation avec le binaire pré-compilé"
|
||||
slug: "install-from-binary"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Binaire pré-compilé"
|
||||
weight: 20
|
||||
identifier: "install-from-binary"
|
||||
---
|
||||
|
||||
# Installation avec le binaire pré-compilé
|
||||
|
||||
Tous les binaires sont livrés avec le support de SQLite, MySQL et PostgreSQL, et sont construits avec les ressources incorporées. Gardez à l'esprit que cela peut être différent pour les versions antérieures. L'installation basée sur nos binaires est assez simple, il suffit de choisir le fichier correspondant à votre plateforme à partir de la [page de téléchargement](https://dl.gitea.io/gitea). Copiez l'URL et remplacer l'URL dans les commandes suivantes par la nouvelle:
|
||||
|
||||
```
|
||||
wget -O gitea https://dl.gitea.io/gitea/1.0.1/gitea-1.0.1-linux-amd64
|
||||
chmod +x gitea
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
Après avoir suivi les étapes ci-dessus, vous aurez un binaire `gitea` dans votre répertoire de travail. En premier lieu, vous pouvez tester si le binaire fonctionne comme prévu et ensuite vous pouvez le copier vers la destination où vous souhaitez le stocker. Lorsque vous lancez Gitea manuellement à partir de votre CLI, vous pouvez toujours le tuer en appuyant sur `Ctrl + C`.
|
||||
|
||||
```
|
||||
./gitea web
|
||||
```
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Anciennes version de glibc
|
||||
|
||||
Les anciennes distributions Linux (comme Debian 7 ou CentOS 6) peuvent ne pas être capable d'exécuter le binaire Gitea, résultant généralement une erreur du type ```./gitea: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by ./gitea)```. Cette erreur est due au driver SQLite que nous intégrons dans le binaire Gitea. Dans le futur, nous fournirons des binaires sans la dépendance pour la bibliothèque glibc. En attendant, vous pouvez mettre à jour votre distribution ou installer Gitea depuis le [code source]({{< relref "from-source.fr-fr.md" >}}).
|
||||
|
||||
### Exécuter Gitea avec un autre port
|
||||
|
||||
Si vous obtenez l'erreur `702 runWeb()] [E] Failed to start server: listen tcp 0.0.0.0:3000: bind: address already in use`, Gitea à besoin d'utiliser un autre port. Vous pouvez changer le port par défaut en utilisant `./gitea web -p $PORT`.
|
||||
|
||||
## Il manque quelque chose ?
|
||||
|
||||
Est-ce que nous avons oublié quelque chose sur cette page ? N'hésitez pas à nous contacter sur notre [serveur Discord](https://discord.gg/NsatcWJ), vous obtiendrez des réponses à toute vos questions assez rapidement.
|
||||
57
docs/content/doc/installation/from-package.fr-fr.md
Executable file
57
docs/content/doc/installation/from-package.fr-fr.md
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "Installation depuis le gestionnaire de paquets"
|
||||
slug: "install-from-package"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Gestionnaire de paquets"
|
||||
weight: 20
|
||||
identifier: "install-from-package"
|
||||
---
|
||||
|
||||
# Installation depuis le gestionnaire de paquets
|
||||
|
||||
## Linux
|
||||
|
||||
Nous n'avons pas encore publié de paquet pour Linux, nous allons mettre à jour cette page directement lorsque nous commencerons à publier des paquets pour toutes distributions Linux. En attendant, vous devriez suivre les [instructions d'installation]({{< relref "from-binary.fr-fr.md" >}}) avec le binaire pré-compilé.
|
||||
|
||||
## Windows
|
||||
|
||||
Nous n'avons pas encore publié de paquet pour Windows, nous allons mettre à jour cette page directement lorsque nous commencerons à publier des paquets sous la forme de fichiers `MSI` ou via [Chocolatey](https://chocolatey.org/). En attendant, vous devriez suivre les [instructions d'installation]({{< relref "from-binary.fr-fr.md" >}}) avec le binaire pré-compilé.
|
||||
|
||||
## macOS
|
||||
|
||||
Actuellement, nous ne supportons que l'installation via `brew` pour macOS. Si vous n'utilisez pas [Homebrew](http://brew.sh/), vous pouvez suivre les [instructions d'installation]({{< relref "from-binary.fr-fr.md" >}}) avec le binaire pré-compilé. Pour installer Gitea depuis `brew`, utilisez les commandes suivantes :
|
||||
|
||||
```
|
||||
brew tap go-gitea/gitea
|
||||
brew install gitea
|
||||
```
|
||||
|
||||
## FreeBSD
|
||||
|
||||
Le portage FreeBSD `www/gitea` est disponible. Vous pouvez également installer le paquet pré-compilé avec la commande suivante:
|
||||
|
||||
```
|
||||
pkg install gitea
|
||||
```
|
||||
|
||||
Pour une version plus récente, ou pour les instructions de compilations, veuillez consulter la documentation officielle de FreeBSD : [install it from the port](https://www.freebsd.org/doc/handbook/ports-using.html)
|
||||
|
||||
```
|
||||
su -
|
||||
cd /usr/ports/www/gitea
|
||||
make install clean
|
||||
```
|
||||
|
||||
Le port utilise la schéma standard du système de fichiers FreeBSD : Les fichiers de configuration sont localisés dans le répertoire `/usr/local/etc/gitea`, les modèles, options, plugins et thèmes sont localisés dans le répertoire `/usr/local/share/gitea`, et le script de démarrage se situe dans `/usr/local/etc/rc.d/gitea`.
|
||||
|
||||
Pour exécuter Gitea en tant que service, utilisez la commande `sysrc gitea_enable=YES` et la commande `service gitea start` pour démarrer le service.
|
||||
|
||||
## Il manque quelque chose ?
|
||||
|
||||
Est-ce que nous avons oublié quelque chose sur cette page ? N'hésitez pas à nous contacter sur notre [serveur Discord](https://discord.gg/NsatcWJ), vous obtiendrez des réponses à toute vos questions assez rapidement.
|
||||
80
docs/content/doc/installation/from-source.fr-fr.md
Executable file
80
docs/content/doc/installation/from-source.fr-fr.md
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Installation depuis le code source"
|
||||
slug: "install-from-source"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Code source"
|
||||
weight: 30
|
||||
identifier: "install-from-source"
|
||||
---
|
||||
|
||||
# Installation depuis le code source
|
||||
|
||||
Nous ne couvrirons pas les bases de la configuration de Golang dans ce guide. Si vous ne savez pas comment démarrer un environnement fonctionnel, vous devrez suivre les [instructions d'installation](https://golang.org/doc/install) officielles.
|
||||
|
||||
**Attention**: La version 1.7 ou suppérieur de Go est nécessaire
|
||||
|
||||
## Téléchargement
|
||||
|
||||
Tout d'abord, vous devez récupérer le code source, la manière la plus simple est d'utiliser directement Go. Il suffit d'appeler les commandes suivantes pour récupérer le code source et passer au répertoire de travail.
|
||||
|
||||
```
|
||||
go get -d -u code.gitea.io/gitea
|
||||
cd $GOPATH/src/code.gitea.io/gitea
|
||||
```
|
||||
|
||||
Maintenant, il est temps de décider quelle version de Gitea vous souhaitez compiler et installer. Actuellement, ils existent plusieurs options possibles. Si vous voulez compiler notre branche `master`, vous pouvez directement passer à la [section compilation](#compilation), cette branche représente la dernière version en cours de développement et n'a pas vocation à être utiliser en production.
|
||||
|
||||
|
||||
Si vous souhaitez compiler la dernière version stable, utilisez les étiquettes ou les différentes branches disponibles. Vous pouvez voir les branches disponibles et comment utiliser cette branche avec ces commandes:
|
||||
|
||||
```
|
||||
git branch -a
|
||||
git checkout v1.0
|
||||
```
|
||||
|
||||
Si vous souhaitez valider une demande d'ajout (_Pull request_), vous devez activer cette branche en premier :
|
||||
|
||||
```
|
||||
git fetch origin pull/xyz/head:pr-xyz # xyz is PR value
|
||||
```
|
||||
|
||||
Enfin, vous pouvez directement utiliser les versions étiquettées (ex : `v1.0.0`). Pour utiliser les étiquettes, vous devez lister les étiquettes disponibles et choisir une étiquette spécifique avec les commandes suivantes :
|
||||
|
||||
```
|
||||
git tag -l
|
||||
git checkout v1.0.0
|
||||
git checkout pr-xyz
|
||||
```
|
||||
|
||||
## Compilation
|
||||
|
||||
Comme nous regroupons déjà toutes les bibliothèques requises pour compiler Gitea, vous pouvez continuer avec le processus de compilation lui-même. Nous fournissons diverses [tâches Make](https://github.com/go-gitea/gitea/blob/master/Makefile) pour rendre le processus de construction aussi simple que possible. <a href='{{< relref "doc/advanced/make.fr-fr.md" >}}'>Voyez ici comment obtenir Make</a>. Selon vos besoins, vous pourrez éventuellement ajouter diverses options de compilation, vous pouvez choisir entre ces options :
|
||||
|
||||
* `bindata`: Intègre toutes les ressources nécessaires à l'exécution d'une instance de Gitea, ce qui rend un déploiement facile car il n'est pas nécessaire de se préoccuper des fichiers supplémentaires.
|
||||
* `sqlite`: Active la prise en charge d'une base de données [SQLite3](https://sqlite.org/), ceci n'est recommandé que pour les petites installations de Gitea.
|
||||
* `tidb`: Active la prise en charge d'une base de données [TiDB](https://github.com/pingcap/tidb), c'est une base de données simplet et basée sur des fichiers. Elle est comparable à SQLite.
|
||||
* `pam`: Active la prise en charge de PAM (mLinux Pluggable Authentication Modules), très utile si vos utilisateurs doivent être authentifiés avec les comptes du système.
|
||||
|
||||
Il est temps de compiler le binaire, nous suggérons d'intégrer les ressources avec l'option de compilation `bindata`. Pour inclure les ressources, vous devrez également exécuter la tâche Make `generate`. Dans le cas échéant, les ressources ne pourront pas être intégrées:
|
||||
|
||||
```
|
||||
TAGS="bindata" make generate build
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
Après avoir suivi toutes les étapes, vous devriez avoir le binaire `gitea` dans votre répertoire courant. Dans un premier temps, vous pouvez tester qu'il fonctionne puis, dans un second temps, vous pouvez le copier dans la destination de votre choix. Lorsque vous lancez Gitea manuellement à partir de votre CLI, vous pouvez toujours le tuer en appuyant sur `Ctrl + C`.
|
||||
|
||||
```
|
||||
./gitea web
|
||||
```
|
||||
|
||||
## Il manque quelque chose ?
|
||||
|
||||
Est-ce que nous avons oublié quelque chose sur cette page ? N'hésitez pas à nous contacter sur notre [serveur Discord](https://discord.gg/NsatcWJ), vous obtiendrez des réponses à toute vos questions assez rapidement.
|
||||
34
docs/content/doc/installation/windows-service.fr-fr.md
Executable file
34
docs/content/doc/installation/windows-service.fr-fr.md
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Démarrer en tant que service Windows"
|
||||
slug: "windows-service"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Service Windows"
|
||||
weight: 30
|
||||
identifier: "windows-service"
|
||||
---
|
||||
|
||||
# Activer un service Windows
|
||||
|
||||
Pour activer le service Windows Gitea, ouvrez une `cmd` en tant qu'Administrateur puis utilisez la commande suivante :
|
||||
|
||||
```
|
||||
sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini""
|
||||
```
|
||||
|
||||
N'oubliez pas de remplacer `C:\gitea` par le chemin que vous avez utilisez pour votre installation.
|
||||
|
||||
Ensuite, ouvrez "Services Windows", puis recherchez le service `gitea`, faites un clique droit et selectionnez "Run". Si tout fonctionne, vous devriez être capable d'accèder à Gitea à l'URL `http://localhost:3000` (ou sur le port configuré si différent de 3000).
|
||||
|
||||
## Désactiver un service Windows
|
||||
|
||||
Pour désactiver le service Windows Gitea, ouvrez une `cmd` en tant qu'Administrateur puis utilisez la commande suivante :
|
||||
|
||||
```
|
||||
sc delete gitea
|
||||
```
|
||||
|
|
@ -183,6 +183,8 @@ To start this setup based on `docker-compose` you just have to execute `docker-c
|
|||
|
||||
If you want to shutdown the setup again just execute `docker-compose down`, this will stop and kill the containers, the volumes will still exist.
|
||||
|
||||
Notice: if you use a non 3000 port on http, you need change app.ini `LOCAL_ROOT_URL = http://localhost:3000/`.
|
||||
|
||||
## Install
|
||||
|
||||
After starting the Docker setup via `docker-compose` you should access Gitea with your favorite browser to finalize the installation. Please visit http://server-ip:3000 and follow the installation wizard. If you have started a database with the `docker-compose` setup as documented above please note that you have to use `db` as the database hostname.
|
||||
|
|
|
|||
110
docs/content/doc/installation/with-docker.fr-fr.md
Executable file
110
docs/content/doc/installation/with-docker.fr-fr.md
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Installation avec Docker"
|
||||
slug: "install-with-docker"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "installation"
|
||||
name: "Docker"
|
||||
weight: 10
|
||||
identifier: "install-with-docker"
|
||||
---
|
||||
|
||||
# Installation avec Docker
|
||||
|
||||
Nous fournissons des images Docker mises à jour automatiquement via le Docker Hub de notre organisation. C'est à vous, lors devotre déploiement, de vous assurez d'utiliser toujours la dernière version stable ou d'utiliser un autre service qui met à jour l'image Docker pour vous.
|
||||
|
||||
## Données stockées sur l'hôte
|
||||
|
||||
Tout d'abord, vous devez simplement récupérer l'image Docker avec la commande suivante :
|
||||
|
||||
```
|
||||
docker pull gitea/gitea:latest
|
||||
```
|
||||
|
||||
Pour garder vos dépôts et certaines autres données persistantes, vous devez créer un répertoire qui contiendra ces données à l'avenir.
|
||||
|
||||
```
|
||||
sudo mkdir -p /var/lib/gitea
|
||||
```
|
||||
|
||||
Il est temps de démarrer votre instance Docker, c'est un processus assez simple. Vous avez à définir le mappage des ports et le volume à utiliser pour la persistance de vos données :
|
||||
|
||||
```
|
||||
docker run -d --name=gitea -p 10022:22 -p 10080:3000 -v /var/lib/gitea:/data gitea/gitea:latest
|
||||
```
|
||||
|
||||
Vous devriez avoir une instance fonctionnelle de Gitea. Pour accèder à l'interface web, visitez l'adresse http://hostname:10080 avec votre navigateur web préféré. Si vous voulez clôner un dépôt, vous pouvez le faire avec la commande `git clone ssh://git@hostname:10022/username/repo.git`.
|
||||
|
||||
## Named Volumes
|
||||
|
||||
Ce guide aboutira à une installation avec les données Gita et PostgreSQL stockées dans des volumes nommés. Cela permet une sauvegarde, une restauration et des mises à niveau en toute simplicité.
|
||||
|
||||
### The Database
|
||||
|
||||
Création du volume nommé pour la base de données :
|
||||
|
||||
```
|
||||
$ docker volume create --name gitea-db-data
|
||||
```
|
||||
|
||||
Une fois votre volume pret, vous pouvez récupérer l'image Docker de PostgreSQL et créer une instance. Tout comme Gitea, c'est également une image Docker basée sur Alpine Linux, Le montage des données se fera sans aucun problème.
|
||||
|
||||
```
|
||||
$ docker pull postgres:alpine
|
||||
$ docker run -d --name gitea-db \
|
||||
-e POSTGRES_PASSWORD=<PASSWORD> \
|
||||
-v gitea-db-data:/var/lib/postgresql/data \
|
||||
-p 5432:5432 \
|
||||
postgres:alpine
|
||||
```
|
||||
|
||||
Maintenant que la base de données est démarrée, il faut la configurer. N'oubliez pas le mot de passe que vous avez choisi, vous en aurez besoin lors de l'installation de Gitea.
|
||||
|
||||
```
|
||||
$ docker exec -it gitea-db psql -U postgres
|
||||
psql (9.6.1)
|
||||
Type "help" for help.
|
||||
|
||||
postgres=# CREATE USER gitea WITH PASSWORD '<PASSWORD>';
|
||||
CREATE ROLE
|
||||
postgres=# CREATE DATABASE gitea OWNER gitea;
|
||||
CREATE DATABASE
|
||||
postgres=# \q
|
||||
$
|
||||
```
|
||||
|
||||
### Gitea
|
||||
|
||||
Premièrement, le volume nommé :
|
||||
|
||||
```
|
||||
$ docker volume create --name gitea-data
|
||||
```
|
||||
|
||||
Puis l'instance de Gitea :
|
||||
|
||||
```
|
||||
$ docker run -d --name gitea \
|
||||
--link gitea-db:gitea-db \
|
||||
--dns 10.12.10.160 \
|
||||
-p 11180:3000 \
|
||||
-p 8322:22 \
|
||||
-v gitea-data:/data \
|
||||
gitea/gitea:latest
|
||||
```
|
||||
|
||||
Vous devriez maintenant avoir deux conteneurs Docker pour Gitea et PostgreSQL plus deux volumes nommés Docker.
|
||||
|
||||
# Personnalisation
|
||||
|
||||
Les fichier personnalisés ([voir les instructions](https://docs.gitea.io/en-us/customizing-gitea/)) peuvent être placés dans le répertoire `/data/gitea`.
|
||||
|
||||
Le fichier de configuration sera sauvegardé à l'emplacement suivant : `/data/gitea/conf/app.ini`
|
||||
|
||||
## Il manque quelque chose ?
|
||||
|
||||
Est-ce que nous avons oublié quelque chose sur cette page ? N'hésitez pas à nous contacter sur notre [serveur Discord](https://discord.gg/NsatcWJ), vous obtiendrez des réponses à toute vos questions assez rapidement.
|
||||
|
|
@ -37,6 +37,8 @@ docker run -d --name=gitea -p 10022:22 -p 10080:3000 -v /var/lib/gitea:/data git
|
|||
|
||||
然后 容器已经运行成功,在浏览器中访问 http://hostname:10080 就可以看到界面了。你可以尝试在上面创建项目,clone操作 `git clone ssh://git@hostname:10022/username/repo.git`.
|
||||
|
||||
注意:目前端口改为非3000时,需要修改配置文件 `LOCAL_ROOT_URL = http://localhost:3000/`。
|
||||
|
||||
## 需要帮助?
|
||||
|
||||
如果从本页中没有找到你需要的内容,请访问 [帮助页面]({{< relref "seek-help.zh-cn.md" >}})
|
||||
|
|
|
|||
13
docs/content/doc/upgrade.fr-fr.md
Executable file
13
docs/content/doc/upgrade.fr-fr.md
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Mise à jour"
|
||||
slug: "upgrade"
|
||||
weight: 10
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "Mise à jour"
|
||||
weight: 20
|
||||
identifier: "upgrade"
|
||||
---
|
||||
80
docs/content/doc/upgrade/from-gogs.fr-fr.md
Executable file
80
docs/content/doc/upgrade/from-gogs.fr-fr.md
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Mise à jour depuis Gogs"
|
||||
slug: "upgrade-from-gogs"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "upgrade"
|
||||
name: "Depuis Gogs"
|
||||
weight: 10
|
||||
identifier: "upgrade-from-gogs"
|
||||
---
|
||||
|
||||
# Mise à jour depuis Gogs
|
||||
|
||||
À partir de la version 0.9.146 (schéma de la base de données : version 15) de Gogs, Il est possible de migrer vers Gitea simplement et sans encombre.
|
||||
|
||||
Veuillez suivre les étapes ci-dessous. Sur Unix, toute les commandes s'exécutent en tant que l'utilisateur utilisé pour votre installation de Gogs :
|
||||
|
||||
* Crééer une sauvegarde de Gogs avec la commande `gogs dump`. Le fichier nouvellement créé `gogs-dump-[timestamp].zip` contient toutes les données de votre instance de Gogs.
|
||||
* Téléchargez le fichier correspondant à votre plateforme à partir de la [page de téléchargements](https://dl.gitea.io/gitea).
|
||||
* Mettez la binaire dans le répertoire d'installation souhaité.
|
||||
* Copiez le fichier `gogs/custom/conf/app.ini` vers `gitea/custom/conf/app.ini`.
|
||||
* Si vous avez personnalisé les répertoires `templates, public` dans `gogs/custom/`, copiez-les vers `gitea/custom/`.
|
||||
* Si vous avez d'autres répertoires personnalisés comme `gitignore, label, license, locale, readme` dans `gogs/custom/conf` copiez-les vers `gitea/custom/options`.
|
||||
* Copiez le répertoire `gogs/data/` vers `gitea/data/`.
|
||||
* Vérifiez votre installation en exécutant Gitea avec la commande `gitea web`.
|
||||
* Connectez vous au panel d'administration de Gitea et exécutez l'action `Rewrite '.ssh/authorized_keys' file`, puis l'action `Rewrite all update hook of repositories` (obligatoire si le chemin menant à votre configuration personnalisée à changé).
|
||||
|
||||
### Modifier les informations spécifiques de gogs
|
||||
|
||||
* Renommez `gogs-repositories/` vers `gitea-repositories/`
|
||||
* Renommez `gogs-data/` to `gitea-data/`
|
||||
* Dans votre fichier `gitea/custom/conf/app.ini`, modifiez les éléments suivants:
|
||||
|
||||
DE :
|
||||
```
|
||||
[database]
|
||||
PATH = /home/:USER/gogs/data/:DATABASE.db
|
||||
[attachment]
|
||||
PATH = /home/:USER/gogs-data/attachments
|
||||
[picture]
|
||||
AVATAR_UPLOAD_PATH = /home/:USER/gogs-data/avatars
|
||||
[log]
|
||||
ROOT_PATH = /home/:USER/gogs/log
|
||||
```
|
||||
|
||||
VERS :
|
||||
```
|
||||
[database]
|
||||
PATH = /home/:USER/gitea/data/:DATABASE.db
|
||||
[attachment]
|
||||
PATH = /home/:USER/gitea-data/attachments
|
||||
[picture]
|
||||
AVATAR_UPLOAD_PATH = /home/:USER/gitea-data/avatars
|
||||
[log]
|
||||
ROOT_PATH = /home/:USER/gitea/log
|
||||
```
|
||||
|
||||
* Vérifiez votre installation en exécutant Gitea avec la commande `gitea web`.
|
||||
|
||||
### Dépannage
|
||||
|
||||
* Si vous rencontrez des erreurs relatives à des modèles personnalisés dans le dossier `gitea/custom/templates`, essayez de déplacer un par un les modèles provoquant les erreurs. Il est possible qu'ils ne soient pas compatibles avec Gitea.
|
||||
|
||||
### Démarrer automatiquement Gitea (Unix)
|
||||
|
||||
Distributions utilisant systemd:
|
||||
|
||||
* Copiez le script mis à jour vers `/etc/systemd/system/gitea.service`
|
||||
* Ajoutez le service avec la commande `sudo systemctl enable gitea`
|
||||
* Désactivez Gogs avec la commande `sudo systemctl disable gogs`
|
||||
|
||||
Distributions utilisant SysVinit:
|
||||
|
||||
* Copiez le script mis à jour vers `/etc/init.d/gitea`
|
||||
* Ajoutez le service avec la commande `sudo rc-update add gitea`
|
||||
* Désactivez Gogs avec la commande `sudo rc-update del gogs`
|
||||
278
docs/content/page/index.fr-fr.md
Executable file
278
docs/content/page/index.fr-fr.md
Executable file
|
|
@ -0,0 +1,278 @@
|
|||
---
|
||||
date: "2017-08-23T09:00:00+02:00"
|
||||
title: "Documentation"
|
||||
slug: "documentation"
|
||||
weight: 10
|
||||
toc: true
|
||||
draft: false
|
||||
---
|
||||
|
||||
# A propos de Gitea
|
||||
|
||||
Gitea est un service Git auto-hébergé très simple à installer et à utiliser. Il est similaire à GitHub, Bitbucket ou Gitlab. Le développement initial provient sur [Gogs] (http://gogs.io), mais nous l'avons forké puis renommé Gitea. Si vous souhaitez en savoir plus sur les raisons pour lesquelles nous avons fait cela, lisez [cette publication] (https://blog.gitea.io/2016/12/welcome-to-gitea/) sur le blog.
|
||||
|
||||
## Objectif
|
||||
|
||||
Le but de ce projet est de fournir de la manière la plus simple, la plus rapide et sans complication un service Git auto-hébergé. Grâce à Go, cela peut se faire via un binaire indépendant fonctionnant sur toutes les plateformes que Go prend en charge, y compris Linux, macOS et Windows, même sur des architectures comme ARM ou PowerPC.
|
||||
|
||||
## Fonctionalités
|
||||
|
||||
- Tableau de bord de l'utilisateur
|
||||
- Choix du contexte (organisation ou utilisateur actuel)
|
||||
- Chronologie de l'activité
|
||||
- Révisions (_Commits_)
|
||||
- Tickets
|
||||
- Demande d'ajout (_Pull request_)
|
||||
- Création de dépôts
|
||||
- Liste des dépôts
|
||||
- Liste de vos organisations
|
||||
- Liste des dépôts miroires
|
||||
- Tableau de bord des tickets
|
||||
- Choix du contexte (organisation ou utilisateur actuel)
|
||||
- Filtres
|
||||
- Ouvert
|
||||
- Fermé
|
||||
- Vos dépôts
|
||||
- Tickets assignés
|
||||
- Vos tickets
|
||||
- Dépôts
|
||||
- Options de tri
|
||||
- Plus vieux
|
||||
- Dernière mise à jour
|
||||
- Nombre de commentaires
|
||||
- Tableau de bord des demandes d'ajout
|
||||
- Identique au tableau de bord des tickets
|
||||
- Types de dépôt
|
||||
- Miroire
|
||||
- Normal
|
||||
- Migré
|
||||
- Notifications (courriel et web)
|
||||
- Lu
|
||||
- Non lu
|
||||
- Épinglé
|
||||
- Page d'exploration
|
||||
- Utilisateurs
|
||||
- Dépôts
|
||||
- Organisations
|
||||
- Moteur de recherche
|
||||
- Interface personnalisables
|
||||
- Fichiers publiques remplaçables (logo, css, etc)
|
||||
- Protection CSRF et XSS
|
||||
- Support d'HTTPS
|
||||
- Configuration des types et de la taille maximale des fichiers téléversés
|
||||
- Journalisation (_Log_)
|
||||
- Configuration
|
||||
- Base de données
|
||||
- MySQL
|
||||
- PostgreSQL
|
||||
- SQLite3
|
||||
- MSSQL
|
||||
- [TiDB](https://github.com/pingcap/tidb) (expérimental)
|
||||
- Fichier de configuration
|
||||
- Voir [ici](https://github.com/go-gitea/gitea/blob/master/conf/app.ini)
|
||||
- Panel d'administration
|
||||
- Statistiques
|
||||
- Actions
|
||||
- Suppression des comptes inactifs
|
||||
- Suppression des dépôts archivés
|
||||
- Suppression des dépôts pour lesquels il manque leurs fichiers
|
||||
- Exécution du _garbage collector_ sur les dépôts
|
||||
- Ré-écriture des clefs SSH
|
||||
- Resynchronisation des hooks
|
||||
- Recreation des dépôts manquants
|
||||
- Status du server
|
||||
- Temps de disponibilité
|
||||
- Mémoire
|
||||
- Nombre de goroutines
|
||||
- et bien plus...
|
||||
- Gestion des utilisateurs
|
||||
- Recherche
|
||||
- Tri
|
||||
- Dernière connexion
|
||||
- Méthode d'authentification
|
||||
- Nombre maximum de dépôts
|
||||
- Désactivation du compte
|
||||
- Permissions d'administration
|
||||
- Permission pour crééer des hooks
|
||||
- Permission pour crééer des organisations
|
||||
- Permission pour importer des dépôts
|
||||
- Gestion des organisations
|
||||
- Membres
|
||||
- Équipes
|
||||
- Avatar
|
||||
- Hooks
|
||||
- Gestion des depôts
|
||||
- Voir toutes les informations pour un dépôt donné et gérer tous les dépôts
|
||||
- Méthodes d'authentification
|
||||
- OAuth
|
||||
- PAM
|
||||
- LDAP
|
||||
- SMTP
|
||||
- Visualisation de la configuration
|
||||
- Tout ce que contient le fichier de configuration
|
||||
- Alertes du système
|
||||
- Quand quelque chose d'inattendu survient
|
||||
- Surveillance
|
||||
- Processus courrants
|
||||
- Tâches CRON
|
||||
- Mise à jour des dépôts miroires
|
||||
- Vérification de l'état des dépôts
|
||||
- Vérification des statistiques des dépôts
|
||||
- Nettoyage des anciennes archives
|
||||
- Variables d'environement
|
||||
- Options de ligne de commande
|
||||
- Internationalisation ([21 langues](https://github.com/go-gitea/gitea/tree/master/options/locale))
|
||||
- Courriel
|
||||
- Notifications
|
||||
- Confirmation d'inscription
|
||||
- Ré-initialisation du mot de passe
|
||||
- Support de _reverse proxy_
|
||||
- _subpaths_ inclus
|
||||
- Utilisateurs
|
||||
- Profil
|
||||
- Nom
|
||||
- Prénom
|
||||
- Courriel
|
||||
- Site internet
|
||||
- Date de création
|
||||
- Abonnés et abonnements
|
||||
- Organisations
|
||||
- Dépôts
|
||||
- Activité
|
||||
- Dépôts suivis
|
||||
- Paramètres
|
||||
- Identiques au profil avec en plus les éléments ci-dessous
|
||||
- Rendre l'adresse de courriel privée
|
||||
- Avatar
|
||||
- Gravatar
|
||||
- Libravatar
|
||||
- Personnalisé
|
||||
- Mot de passe
|
||||
- Courriels multiples
|
||||
- Clefs SSH
|
||||
- Applications connectées
|
||||
- Authentification à double facteurs
|
||||
- Identités OAuth2 attachées
|
||||
- Suppression du compte
|
||||
- Dépôts
|
||||
- Clone à partir de SSH / HTTP / HTTPS
|
||||
- Git LFS
|
||||
- Suivre, Voter, Fork
|
||||
- Voir les personnes qui suivent, les votes et les forks
|
||||
- Code
|
||||
- Navigation entre les branches
|
||||
- Création ou téléversement de fichier depuis le navigateur
|
||||
- URLs pour clôner le dépôt
|
||||
- Téléchargement
|
||||
- ZIP
|
||||
- TAR.GZ
|
||||
- Édition en ligne
|
||||
- Éditeur Markdown
|
||||
- Éditeur de texte
|
||||
- Coloration syntaxique
|
||||
- Visualisation des Diffs
|
||||
- Visualisation
|
||||
- Possibilité de choisir où sauvegarder la révision
|
||||
- Historiques des fichiers
|
||||
- Suppression de fichiers
|
||||
- Voir le fichier brut
|
||||
- Tickets
|
||||
- Modèle de ticket
|
||||
- Jalons
|
||||
- Étiquettes
|
||||
- Affecter des tickets
|
||||
- Filtres
|
||||
- Ouvert
|
||||
- Ferme
|
||||
- Personne assignée
|
||||
- Créer par vous
|
||||
- Qui vous mentionne
|
||||
- Tri
|
||||
- Plus vieux
|
||||
- Dernière mise à jour
|
||||
- Nombre de commentaires
|
||||
- Moteur de recherche
|
||||
- Commentaires
|
||||
- Joindre des fichiers
|
||||
- Demande d’ajout (_Pull request_)
|
||||
- Les mêmes fonctionnalités que pour les tickets
|
||||
- Révisions (_Commits_)
|
||||
- Representation graphique des révisions
|
||||
- Révisions par branches
|
||||
- Moteur de recherche
|
||||
- Voir les différences
|
||||
- Voir les numéro de révision SHA
|
||||
- Voir l'auteur
|
||||
- Naviguer dans les fichiers d'une révision donnée
|
||||
- Publication
|
||||
- Pièces jointes
|
||||
- Titre
|
||||
- Contenu
|
||||
- Suppression
|
||||
- Définir comme une pré-publication
|
||||
- Choix de la branche
|
||||
- Wiki
|
||||
- Import
|
||||
- Éditeur Markdown
|
||||
- Paramètres
|
||||
- Options
|
||||
- Nom
|
||||
- Description
|
||||
- Privé / Publique
|
||||
- Site internet
|
||||
- Wiki
|
||||
- Activé / Désactivé
|
||||
- Interne / externe
|
||||
- Tickets
|
||||
- Activé / Désactivé
|
||||
- Interne / externe
|
||||
- URL personnalisable pour une meilleur intégration avec un gestionnaire de tickets externe
|
||||
- Activer / désactiver les demandes d'ajout (_Pull request_)
|
||||
- Transfert du dépôt
|
||||
- Suppression du wiki
|
||||
- Suppression du dépôt
|
||||
- Collaboration
|
||||
- Lecture / Écriture / Administration
|
||||
- Branches
|
||||
- Branche par défaut
|
||||
- Protection
|
||||
- Webhooks
|
||||
- Git hooks
|
||||
- Clefs de déploiement
|
||||
|
||||
## Configuration requise
|
||||
|
||||
- Un simple Raspberry Pi est assez puissant pour les fonctionnalités de base.
|
||||
- Un processeur double coeurs et 1Gb de RAM est une bonne base pour une utilisation en équipe.
|
||||
- Gitea est censé être exécuté avec un compte utilisateur dédié et non root, aucun autre mode de fonctionnement n'est pris en charge. (**NOTE**: Dans le cas où vous l'exécutez avec votre propre compte d'utilisateur et que le serveur SSH intégré est désactivé, Gitea modifie le fichier `~ /.ssh /authorized_keys` afin que vous ne soyez **plus capable** de vous connecter interactivement).
|
||||
|
||||
## Navigateurs supportés
|
||||
|
||||
- Consultez [Semantic UI](https://github.com/Semantic-Org/Semantic-UI#browser-support) pour la liste des navigateurs supportés.
|
||||
- La taille minimale supportée officielement est de **1024*768**, l'interface utilisateur peut toujours fonctionner à une taille plus petite, mais ce n'est pas garanti et les problèmes remontés ne seront pas corrigés.
|
||||
|
||||
## Composants
|
||||
|
||||
* Framework web : [Macaron](http://go-macaron.com/)
|
||||
* ORM : [XORM](https://github.com/go-xorm/xorm)
|
||||
* Interface graphique :
|
||||
* [Semantic UI](http://semantic-ui.com/)
|
||||
* [GitHub Octicons](https://octicons.github.com/)
|
||||
* [Font Awesome](http://fontawesome.io/)
|
||||
* [DropzoneJS](http://www.dropzonejs.com/)
|
||||
* [Highlight](https://highlightjs.org/)
|
||||
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
||||
* [Emojify](https://github.com/Ranks/emojify.js)
|
||||
* [CodeMirror](https://codemirror.net/)
|
||||
* [jQuery Date Time Picker](https://github.com/xdan/datetimepicker)
|
||||
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
||||
* Connecteurs de base de données :
|
||||
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||
* [github.com/lib/pq](https://github.com/lib/pq)
|
||||
* [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
* [github.com/pingcap/tidb](https://github.com/pingcap/tidb)
|
||||
* [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
|
||||
## Logiciels et services
|
||||
|
||||
- [Drone](https://github.com/drone/drone) (Intégration continue)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
:80 {
|
||||
root /srv/www
|
||||
|
||||
locale en-US zh-CN zh-TW pt-BR nl-NL {
|
||||
locale en-US zh-CN zh-TW pt-BR nl-NL fr-FR {
|
||||
detect header
|
||||
}
|
||||
|
||||
|
|
@ -35,5 +35,10 @@
|
|||
to /nl-nl/{1}
|
||||
}
|
||||
|
||||
rewrite /fr-FR/ {
|
||||
regexp (.*)
|
||||
to /fr-fr/{1}
|
||||
}
|
||||
|
||||
header / Vary "Accept-Language"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ set -e
|
|||
#
|
||||
|
||||
declare -a LOCALES=(
|
||||
"fr-fr"
|
||||
"nl-nl"
|
||||
"pt-br"
|
||||
"zh-cn"
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ func TestCommitRepoAction(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, s := range samples {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
|
||||
user := AssertExistsAndLoadBean(t, &User{ID: s.userID}).(*User)
|
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: s.repositoryID, OwnerID: user.ID}).(*Repository)
|
||||
|
|
|
|||
|
|
@ -572,9 +572,10 @@ func (err ErrLFSLockAlreadyExist) Error() string {
|
|||
|
||||
// ErrRepoNotExist represents a "RepoNotExist" kind of error.
|
||||
type ErrRepoNotExist struct {
|
||||
ID int64
|
||||
UID int64
|
||||
Name string
|
||||
ID int64
|
||||
UID int64
|
||||
OwnerName string
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrRepoNotExist checks if an error is a ErrRepoNotExist.
|
||||
|
|
@ -584,7 +585,8 @@ func IsErrRepoNotExist(err error) bool {
|
|||
}
|
||||
|
||||
func (err ErrRepoNotExist) Error() string {
|
||||
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name)
|
||||
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, owner_name: %s, name: %s]",
|
||||
err.ID, err.UID, err.OwnerName, err.Name)
|
||||
}
|
||||
|
||||
// ErrRepoAlreadyExist represents a "RepoAlreadyExist" kind of error.
|
||||
|
|
|
|||
|
|
@ -964,7 +964,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
|
|||
// GetIssueByRef returns an Issue specified by a GFM reference.
|
||||
// See https://help.github.com/articles/writing-on-github#references for more information on the syntax.
|
||||
func GetIssueByRef(ref string) (*Issue, error) {
|
||||
n := strings.IndexByte(ref, byte('#'))
|
||||
n := strings.IndexByte(ref, '#')
|
||||
if n == -1 {
|
||||
return nil, errMissingIssueNumber
|
||||
}
|
||||
|
|
@ -974,7 +974,12 @@ func GetIssueByRef(ref string) (*Issue, error) {
|
|||
return nil, errInvalidIssueNumber
|
||||
}
|
||||
|
||||
repo, err := GetRepositoryByRef(ref[:n])
|
||||
i := strings.IndexByte(ref[:n], '/')
|
||||
if i < 2 {
|
||||
return nil, ErrInvalidReference
|
||||
}
|
||||
|
||||
repo, err := GetRepositoryByOwnerAndName(ref[:i], ref[i+1:n])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,8 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3" // for the test engine
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
@ -19,17 +13,5 @@ func TestFixturesAreConsistent(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if err := CreateTestEngine("fixtures/"); err != nil {
|
||||
fmt.Printf("Error creating test engine: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
setting.AppURL = "https://try.gitea.io/"
|
||||
setting.RunUser = "runuser"
|
||||
setting.SSH.Port = 3000
|
||||
setting.SSH.Domain = "try.gitea.io"
|
||||
setting.RepoRootPath = filepath.Join(os.TempDir(), "repos")
|
||||
setting.AppDataPath = filepath.Join(os.TempDir(), "appdata")
|
||||
|
||||
os.Exit(m.Run())
|
||||
MainTest(m, "..")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1744,13 +1744,13 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
|
|||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrRepoNotExist{repoID, uid, ""}
|
||||
return ErrRepoNotExist{repoID, uid, "", ""}
|
||||
}
|
||||
|
||||
if cnt, err := sess.ID(repoID).Delete(&Repository{}); err != nil {
|
||||
return err
|
||||
} else if cnt != 1 {
|
||||
return ErrRepoNotExist{repoID, uid, ""}
|
||||
return ErrRepoNotExist{repoID, uid, "", ""}
|
||||
}
|
||||
|
||||
if org.IsOrganization() {
|
||||
|
|
@ -1895,21 +1895,20 @@ func DeleteRepository(doer *User, uid, repoID int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetRepositoryByRef returns a Repository specified by a GFM reference.
|
||||
// See https://help.github.com/articles/writing-on-github#references for more information on the syntax.
|
||||
func GetRepositoryByRef(ref string) (*Repository, error) {
|
||||
n := strings.IndexByte(ref, byte('/'))
|
||||
if n < 2 {
|
||||
return nil, ErrInvalidReference
|
||||
}
|
||||
|
||||
userName, repoName := ref[:n], ref[n+1:]
|
||||
user, err := GetUserByName(userName)
|
||||
// GetRepositoryByOwnerAndName returns the repository by given ownername and reponame.
|
||||
func GetRepositoryByOwnerAndName(ownerName, repoName string) (*Repository, error) {
|
||||
var repo Repository
|
||||
has, err := x.Select("repository.*").
|
||||
Join("INNER", "user", "`user`.id = repository.owner_id").
|
||||
Where("repository.lower_name = ?", strings.ToLower(repoName)).
|
||||
And("`user`.lower_name = ?", strings.ToLower(ownerName)).
|
||||
Get(&repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrRepoNotExist{0, 0, ownerName, repoName}
|
||||
}
|
||||
|
||||
return GetRepositoryByName(user.ID, repoName)
|
||||
return &repo, nil
|
||||
}
|
||||
|
||||
// GetRepositoryByName returns the repository by given name under user if exists.
|
||||
|
|
@ -1922,7 +1921,7 @@ func GetRepositoryByName(ownerID int64, name string) (*Repository, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrRepoNotExist{0, ownerID, name}
|
||||
return nil, ErrRepoNotExist{0, ownerID, "", name}
|
||||
}
|
||||
return repo, err
|
||||
}
|
||||
|
|
@ -1933,7 +1932,7 @@ func getRepositoryByID(e Engine, id int64) (*Repository, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrRepoNotExist{id, 0, ""}
|
||||
return nil, ErrRepoNotExist{id, 0, "", ""}
|
||||
}
|
||||
return repo, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
|
@ -13,6 +15,7 @@ import (
|
|||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/go-xorm/xorm"
|
||||
_ "github.com/mattn/go-sqlite3" // for the test engine
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/testfixtures.v2"
|
||||
)
|
||||
|
|
@ -20,9 +23,30 @@ import (
|
|||
// NonexistentID an ID that will never exist
|
||||
const NonexistentID = 9223372036854775807
|
||||
|
||||
// CreateTestEngine create in-memory sqlite database for unit tests
|
||||
// Any package that calls this must import github.com/mattn/go-sqlite3
|
||||
func CreateTestEngine(fixturesDir string) error {
|
||||
// giteaRoot a path to the gitea root
|
||||
var giteaRoot string
|
||||
|
||||
// MainTest a reusable TestMain(..) function for unit tests that need to use a
|
||||
// test database. Creates the test database, and sets necessary settings.
|
||||
func MainTest(m *testing.M, pathToGiteaRoot string) {
|
||||
giteaRoot = pathToGiteaRoot
|
||||
fixturesDir := filepath.Join(pathToGiteaRoot, "models", "fixtures")
|
||||
if err := createTestEngine(fixturesDir); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error creating test engine: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
setting.AppURL = "https://try.gitea.io/"
|
||||
setting.RunUser = "runuser"
|
||||
setting.SSH.Port = 3000
|
||||
setting.SSH.Domain = "try.gitea.io"
|
||||
setting.RepoRootPath = filepath.Join(os.TempDir(), "repos")
|
||||
setting.AppDataPath = filepath.Join(os.TempDir(), "appdata")
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func createTestEngine(fixturesDir string) error {
|
||||
var err error
|
||||
x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||
if err != nil {
|
||||
|
|
@ -45,10 +69,13 @@ func PrepareTestDatabase() error {
|
|||
return LoadFixtures()
|
||||
}
|
||||
|
||||
func prepareTestEnv(t testing.TB) {
|
||||
// PrepareTestEnv prepares the environment for unit tests. Can only be called
|
||||
// by tests that use the above MainTest(..) function.
|
||||
func PrepareTestEnv(t testing.TB) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
|
||||
assert.NoError(t, com.CopyDir("../integrations/gitea-repositories-meta", setting.RepoRootPath))
|
||||
metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta")
|
||||
assert.NoError(t, com.CopyDir(metaPath, setting.RepoRootPath))
|
||||
}
|
||||
|
||||
type testCond struct {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,14 @@ func TestWikiFilenameToName(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.Expected, name)
|
||||
}
|
||||
for _, badFilename := range []string{
|
||||
"nofileextension",
|
||||
"wrongfileextension.txt",
|
||||
"badescaping%%.md",
|
||||
} {
|
||||
_, err := WikiFilenameToName(badFilename)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWikiNameToFilenameToName(t *testing.T) {
|
||||
|
|
@ -115,7 +123,7 @@ func TestRepository_WikiPath(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRepository_HasWiki(t *testing.T) {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
repo1 := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||
assert.True(t, repo1.HasWiki())
|
||||
repo2 := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
|
||||
|
|
@ -123,7 +131,7 @@ func TestRepository_HasWiki(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRepository_InitWiki(t *testing.T) {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
// repo1 already has a wiki
|
||||
repo1 := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||
assert.NoError(t, repo1.InitWiki())
|
||||
|
|
@ -135,7 +143,7 @@ func TestRepository_InitWiki(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRepository_LocalWikiPath(t *testing.T) {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||
expected := filepath.Join(setting.AppDataPath, "tmp/local-wiki/1")
|
||||
assert.Equal(t, expected, repo.LocalWikiPath())
|
||||
|
|
@ -150,11 +158,23 @@ func TestRepository_AddWikiPage(t *testing.T) {
|
|||
"Another page",
|
||||
"Here's a <tag> and a/slash",
|
||||
} {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
assert.NoError(t, repo.AddWikiPage(doer, wikiName, wikiContent, commitMsg))
|
||||
expectedPath := path.Join(repo.LocalWikiPath(), WikiNameToFilename(wikiName))
|
||||
assert.True(t, com.IsExist(expectedPath))
|
||||
}
|
||||
|
||||
// test for already-existing wiki name
|
||||
PrepareTestEnv(t)
|
||||
err := repo.AddWikiPage(doer, "Home", wikiContent, commitMsg)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrWikiAlreadyExist(err))
|
||||
|
||||
// test for reserved wiki name
|
||||
PrepareTestEnv(t)
|
||||
err = repo.AddWikiPage(doer, "_edit", wikiContent, commitMsg)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrWikiReservedName(err))
|
||||
}
|
||||
|
||||
func TestRepository_EditWikiPage(t *testing.T) {
|
||||
|
|
@ -163,20 +183,23 @@ func TestRepository_EditWikiPage(t *testing.T) {
|
|||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||
doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||
for _, newWikiName := range []string{
|
||||
"Home", // same name as before
|
||||
"New home",
|
||||
"New/name/with/slashes",
|
||||
} {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
assert.NoError(t, repo.EditWikiPage(doer, "Home", newWikiName, newWikiContent, commitMsg))
|
||||
newPath := path.Join(repo.LocalWikiPath(), WikiNameToFilename(newWikiName))
|
||||
assert.True(t, com.IsExist(newPath))
|
||||
oldPath := path.Join(repo.LocalWikiPath(), "Home.md")
|
||||
assert.False(t, com.IsExist(oldPath))
|
||||
if newWikiName != "Home" {
|
||||
oldPath := path.Join(repo.LocalWikiPath(), "Home.md")
|
||||
assert.False(t, com.IsExist(oldPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepository_DeleteWikiPage(t *testing.T) {
|
||||
prepareTestEnv(t)
|
||||
PrepareTestEnv(t)
|
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||
doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||
assert.NoError(t, repo.DeleteWikiPage(doer, "Home"))
|
||||
|
|
|
|||
|
|
@ -363,10 +363,9 @@ func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
|
|||
|
||||
// NewWikiForm form for creating wiki
|
||||
type NewWikiForm struct {
|
||||
OldTitle string
|
||||
Title string `binding:"Required"`
|
||||
Content string `binding:"Required"`
|
||||
Message string
|
||||
Title string `binding:"Required"`
|
||||
Content string `binding:"Required"`
|
||||
Message string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
|
|
|
|||
|
|
@ -176,12 +176,9 @@ func Contexter() macaron.Handler {
|
|||
repoName := c.Params(":reponame")
|
||||
branchName := "master"
|
||||
|
||||
owner, err := models.GetUserByName(ownerName)
|
||||
if err == nil {
|
||||
repo, err := models.GetRepositoryByName(owner.ID, repoName)
|
||||
if err == nil && len(repo.DefaultBranch) > 0 {
|
||||
branchName = repo.DefaultBranch
|
||||
}
|
||||
repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
|
||||
if err == nil && len(repo.DefaultBranch) > 0 {
|
||||
branchName = repo.DefaultBranch
|
||||
}
|
||||
prefix := setting.AppURL + path.Join(ownerName, repoName, "src", "branch", branchName)
|
||||
c.PlainText(http.StatusOK, []byte(com.Expand(`
|
||||
|
|
|
|||
|
|
@ -108,10 +108,9 @@ func ObjectOidHandler(ctx *context.Context) {
|
|||
}
|
||||
|
||||
func getAuthenticatedRepoAndMeta(ctx *context.Context, rv *RequestVars, requireWrite bool) (*models.LFSMetaObject, *models.Repository) {
|
||||
repositoryString := rv.User + "/" + rv.Repo
|
||||
repository, err := models.GetRepositoryByRef(repositoryString)
|
||||
repository, err := models.GetRepositoryByOwnerAndName(rv.User, rv.Repo)
|
||||
if err != nil {
|
||||
log.Debug("Could not find repository: %s - %s", repositoryString, err)
|
||||
log.Debug("Could not find repository: %s/%s - %s", rv.User, rv.Repo, err)
|
||||
writeStatus(ctx, 404)
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -197,7 +196,6 @@ func getMetaHandler(ctx *context.Context) {
|
|||
|
||||
// PostHandler instructs the client how to upload data
|
||||
func PostHandler(ctx *context.Context) {
|
||||
|
||||
if !setting.LFS.StartServer {
|
||||
writeStatus(ctx, 404)
|
||||
return
|
||||
|
|
@ -210,10 +208,9 @@ func PostHandler(ctx *context.Context) {
|
|||
|
||||
rv := unpack(ctx)
|
||||
|
||||
repositoryString := rv.User + "/" + rv.Repo
|
||||
repository, err := models.GetRepositoryByRef(repositoryString)
|
||||
repository, err := models.GetRepositoryByOwnerAndName(rv.User, rv.Repo)
|
||||
if err != nil {
|
||||
log.Debug("Could not find repository: %s - %s", repositoryString, err)
|
||||
log.Debug("Could not find repository: %s/%s - %s", rv.User, rv.Repo, err)
|
||||
writeStatus(ctx, 404)
|
||||
return
|
||||
}
|
||||
|
|
@ -261,12 +258,10 @@ func BatchHandler(ctx *context.Context) {
|
|||
|
||||
// Create a response object
|
||||
for _, object := range bv.Objects {
|
||||
|
||||
repositoryString := object.User + "/" + object.Repo
|
||||
repository, err := models.GetRepositoryByRef(repositoryString)
|
||||
repository, err := models.GetRepositoryByOwnerAndName(object.User, object.Repo)
|
||||
|
||||
if err != nil {
|
||||
log.Debug("Could not find repository: %s - %s", repositoryString, err)
|
||||
log.Debug("Could not find repository: %s/%s - %s", object.User, object.Repo, err)
|
||||
writeStatus(ctx, 404)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,6 +331,7 @@ var (
|
|||
LibravatarService *libravatar.Libravatar
|
||||
|
||||
// Log settings
|
||||
LogLevel string
|
||||
LogRootPath string
|
||||
LogModes []string
|
||||
LogConfigs []string
|
||||
|
|
@ -659,6 +660,7 @@ func NewContext() {
|
|||
}
|
||||
homeDir = strings.Replace(homeDir, "\\", "/", -1)
|
||||
|
||||
LogLevel = getLogLevel("log", "LEVEL", "Info")
|
||||
LogRootPath = Cfg.Section("log").Key("ROOT_PATH").MustString(path.Join(AppWorkPath, "log"))
|
||||
forcePathSeparator(LogRootPath)
|
||||
|
||||
|
|
@ -1194,6 +1196,11 @@ var logLevels = map[string]string{
|
|||
"Critical": "5",
|
||||
}
|
||||
|
||||
func getLogLevel(section string, key string, defaultValue string) string {
|
||||
validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"}
|
||||
return Cfg.Section(section).Key(key).In(defaultValue, validLevels)
|
||||
}
|
||||
|
||||
func newLogService() {
|
||||
log.Info("Gitea v%s%s", AppVer, AppBuiltWith)
|
||||
|
||||
|
|
@ -1218,11 +1225,8 @@ func newLogService() {
|
|||
sec, _ = Cfg.NewSection("log." + mode)
|
||||
}
|
||||
|
||||
validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"}
|
||||
// Log level.
|
||||
levelName := Cfg.Section("log."+mode).Key("LEVEL").In(
|
||||
Cfg.Section("log").Key("LEVEL").In("Trace", validLevels),
|
||||
validLevels)
|
||||
levelName := getLogLevel("log."+mode, "LEVEL", LogLevel)
|
||||
level, ok := logLevels[levelName]
|
||||
if !ok {
|
||||
log.Fatal(4, "Unknown log level: %s", levelName)
|
||||
|
|
@ -1286,11 +1290,8 @@ func NewXORMLogService(disableConsole bool) {
|
|||
sec, _ = Cfg.NewSection("log." + mode)
|
||||
}
|
||||
|
||||
validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"}
|
||||
// Log level.
|
||||
levelName := Cfg.Section("log."+mode).Key("LEVEL").In(
|
||||
Cfg.Section("log").Key("LEVEL").In("Trace", validLevels),
|
||||
validLevels)
|
||||
levelName := getLogLevel("log."+mode, "LEVEL", LogLevel)
|
||||
level, ok := logLevels[levelName]
|
||||
if !ok {
|
||||
log.Fatal(4, "Unknown log level: %s", levelName)
|
||||
|
|
|
|||
|
|
@ -110,8 +110,10 @@ func NewFuncMap() []template.FuncMap {
|
|||
"EscapePound": func(str string) string {
|
||||
return strings.NewReplacer("%", "%25", "#", "%23", " ", "%20", "?", "%3F").Replace(str)
|
||||
},
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
"RenderCommitMessageLink": RenderCommitMessageLink,
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
"RenderCommitMessageLink": RenderCommitMessageLink,
|
||||
"RenderCommitBody": RenderCommitBody,
|
||||
"IsMultilineCommitMessage": IsMultilineCommitMessage,
|
||||
"ThemeColorMetaTag": func() string {
|
||||
return setting.UI.ThemeColorMetaTag
|
||||
},
|
||||
|
|
@ -280,6 +282,29 @@ func renderCommitMessage(msg string, opts markup.RenderIssueIndexPatternOptions)
|
|||
return template.HTML(msgLines[0])
|
||||
}
|
||||
|
||||
// RenderCommitBody extracts the body of a commit message without its title.
|
||||
func RenderCommitBody(msg, urlPrefix string, metas map[string]string) template.HTML {
|
||||
return renderCommitBody(msg, markup.RenderIssueIndexPatternOptions{
|
||||
URLPrefix: urlPrefix,
|
||||
Metas: metas,
|
||||
})
|
||||
}
|
||||
|
||||
func renderCommitBody(msg string, opts markup.RenderIssueIndexPatternOptions) template.HTML {
|
||||
cleanMsg := template.HTMLEscapeString(msg)
|
||||
fullMessage := string(markup.RenderIssueIndexPattern([]byte(cleanMsg), opts))
|
||||
body := strings.Split(strings.TrimSpace(fullMessage), "\n")
|
||||
if len(body) == 0 {
|
||||
return template.HTML("")
|
||||
}
|
||||
return template.HTML(strings.Join(body[1:], "\n"))
|
||||
}
|
||||
|
||||
// IsMultilineCommitMessage checks to see if a commit message contains multiple lines.
|
||||
func IsMultilineCommitMessage(msg string) bool {
|
||||
return strings.Count(strings.TrimSpace(msg), "\n") > 1
|
||||
}
|
||||
|
||||
// Actioner describes an action
|
||||
type Actioner interface {
|
||||
GetOpType() models.ActionType
|
||||
|
|
|
|||
|
|
@ -9,33 +9,48 @@ import (
|
|||
"net/url"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
"github.com/go-macaron/session"
|
||||
_ "github.com/mattn/go-sqlite3" // for the test engine
|
||||
"github.com/stretchr/testify/assert"
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
// MockContext mock context for unit tests
|
||||
func MockContext(t *testing.T) *context.Context {
|
||||
var macaronContext *macaron.Context
|
||||
mac := macaron.New()
|
||||
mac.Get("*/", func(ctx *macaron.Context) {
|
||||
macaronContext = ctx
|
||||
})
|
||||
req, err := http.NewRequest("GET", "star", nil)
|
||||
assert.NoError(t, err)
|
||||
req.Form = url.Values{}
|
||||
mac.ServeHTTP(&mockResponseWriter{}, req)
|
||||
assert.NotNil(t, macaronContext)
|
||||
assert.EqualValues(t, req, macaronContext.Req.Request)
|
||||
func MockContext(t *testing.T, path string) *context.Context {
|
||||
var macaronContext macaron.Context
|
||||
macaronContext.ReplaceAllParams(macaron.Params{})
|
||||
macaronContext.Locale = &mockLocale{}
|
||||
requestURL, err := url.Parse(path)
|
||||
assert.NoError(t, err)
|
||||
macaronContext.Req = macaron.Request{Request: &http.Request{
|
||||
URL: requestURL,
|
||||
Form: url.Values{},
|
||||
}}
|
||||
macaronContext.Resp = &mockResponseWriter{}
|
||||
macaronContext.Render = &mockRender{ResponseWriter: macaronContext.Resp}
|
||||
macaronContext.Data = map[string]interface{}{}
|
||||
return &context.Context{
|
||||
Context: macaronContext,
|
||||
Context: &macaronContext,
|
||||
Flash: &session.Flash{
|
||||
Values: make(url.Values),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// LoadRepo load a repo into a test context.
|
||||
func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) {
|
||||
ctx.Repo = &context.Repository{}
|
||||
ctx.Repo.Repository = models.AssertExistsAndLoadBean(t, &models.Repository{ID: repoID}).(*models.Repository)
|
||||
}
|
||||
|
||||
// LoadUser load a user into a test context.
|
||||
func LoadUser(t *testing.T, ctx *context.Context, userID int64) {
|
||||
ctx.User = models.AssertExistsAndLoadBean(t, &models.User{ID: userID}).(*models.User)
|
||||
}
|
||||
|
||||
type mockLocale struct{}
|
||||
|
||||
func (l mockLocale) Language() string {
|
||||
|
|
@ -43,7 +58,7 @@ func (l mockLocale) Language() string {
|
|||
}
|
||||
|
||||
func (l mockLocale) Tr(s string, _ ...interface{}) string {
|
||||
return "test translation"
|
||||
return s
|
||||
}
|
||||
|
||||
type mockResponseWriter struct {
|
||||
|
|
@ -91,7 +106,8 @@ func (tr *mockRender) SetResponseWriter(rw http.ResponseWriter) {
|
|||
tr.ResponseWriter = rw
|
||||
}
|
||||
|
||||
func (tr *mockRender) JSON(int, interface{}) {
|
||||
func (tr *mockRender) JSON(status int, _ interface{}) {
|
||||
tr.Status(status)
|
||||
}
|
||||
|
||||
func (tr *mockRender) JSONString(interface{}) (string, error) {
|
||||
|
|
|
|||
|
|
@ -405,6 +405,7 @@ key_state_desc=Dieser Schlüssel wurde in den letzten 7 Tagen verwendet
|
|||
token_state_desc=Dieser Token wurde in den letzten 7 Tagen benutzt
|
||||
show_openid=Im Profil anzeigen
|
||||
hide_openid=Nicht im Profil anzeigen
|
||||
ssh_disabled=SSH ist deaktiviert
|
||||
|
||||
manage_social=Verknüpfte soziale Konten verwalten
|
||||
social_desc=Dies ist eine Liste der zugeordneten Konten von sozialen Netzwerken. Bitte stelle sicher, dass du alle dieser Accounts kennst, da sie benutzt werden können, um sich mit deinem Account anzumelden.
|
||||
|
|
@ -803,6 +804,7 @@ wiki.new_page_button=Neue Seite
|
|||
wiki.delete_page_button=Seite löschen
|
||||
wiki.delete_page_notice_1=Die Seite <code>"%s"</code> wird gelöscht. Bitte stelle sicher, dass das deine Absicht ist.
|
||||
wiki.page_already_exists=Eine Wiki-Seite mit dem gleichen Namen existiert bereits.
|
||||
wiki.reserved_page=Die Wiki-Seite namens %s ist reserviert, Bitte wähle einen anderen Namen.
|
||||
wiki.pages=Seiten
|
||||
wiki.last_updated=Zuletzt aktualisiert %s
|
||||
|
||||
|
|
@ -977,6 +979,7 @@ settings.slack_token=Token
|
|||
settings.slack_domain=Domain
|
||||
settings.slack_channel=Kanal
|
||||
settings.add_discord_hook_desc=<a href="%s">Discord</a>-Integration zu deinem Repository hinzufügen.
|
||||
settings.add_dingtalk_hook_desc=<a href="%s">Dingtalk</a>-Integration zu deinem Repository hinzufügen.
|
||||
settings.deploy_keys=Deploy-Schlüssel
|
||||
settings.add_deploy_key=Deploy-Schlüssel hinzufügen
|
||||
settings.deploy_key_desc=Deploy-Schlüssel haben nur lesenden Zugriff. Sie sind nicht identisch mit dem SSH-Schlüssel des persönlichen Kontos.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -2017,6 +2017,10 @@ function initFilterBranchTagDropdown(selector) {
|
|||
});
|
||||
}
|
||||
|
||||
$(".commit-button").click(function() {
|
||||
$(this).parent().find('.commit-body').toggle();
|
||||
});
|
||||
|
||||
function deleteDependencyModal(id, type) {
|
||||
$('.remove-dependency')
|
||||
.modal({
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
font-size: 13px;
|
||||
}
|
||||
.issue.title {
|
||||
line-height: 1.1em;
|
||||
width: 80%;
|
||||
}
|
||||
.push.news .content ul {
|
||||
|
|
|
|||
|
|
@ -1606,3 +1606,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody.commit-list {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.commit-body {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
|
|||
cfg.Section("session").Key("PROVIDER").SetValue("file")
|
||||
|
||||
cfg.Section("log").Key("MODE").SetValue("file")
|
||||
cfg.Section("log").Key("LEVEL").SetValue("Info")
|
||||
cfg.Section("log").Key("LEVEL").SetValue(setting.LogLevel)
|
||||
cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath)
|
||||
|
||||
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true")
|
||||
|
|
|
|||
|
|
@ -64,23 +64,9 @@ func HTTP(ctx *context.Context) {
|
|||
reponame = reponame[:len(reponame)-5]
|
||||
}
|
||||
|
||||
repoUser, err := models.GetUserByName(username)
|
||||
repo, err := models.GetRepositoryByOwnerAndName(username, reponame)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
ctx.Handle(http.StatusNotFound, "GetUserByName", nil)
|
||||
} else {
|
||||
ctx.Handle(http.StatusInternalServerError, "GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
repo, err := models.GetRepositoryByName(repoUser.ID, reponame)
|
||||
if err != nil {
|
||||
if models.IsErrRepoNotExist(err) {
|
||||
ctx.Handle(http.StatusNotFound, "GetRepositoryByName", nil)
|
||||
} else {
|
||||
ctx.Handle(http.StatusInternalServerError, "GetRepositoryByName", err)
|
||||
}
|
||||
ctx.NotFoundOrServerError("GetRepositoryByOwnerAndName", models.IsErrRepoNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
16
routers/repo/main_test.go
Normal file
16
routers/repo/main_test.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2017 The Gitea 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 repo
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
models.MainTest(m, filepath.Join("..", ".."))
|
||||
}
|
||||
171
routers/repo/wiki_test.go
Normal file
171
routers/repo/wiki_test.go
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
// Copyright 2017 The Gitea 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 repo
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/auth"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const content = "Wiki contents for unit tests"
|
||||
const message = "Wiki commit message for unit tests"
|
||||
|
||||
func wikiPath(repo *models.Repository, wikiName string) string {
|
||||
return filepath.Join(repo.LocalWikiPath(), models.WikiNameToFilename(wikiName))
|
||||
}
|
||||
|
||||
func wikiContent(t *testing.T, repo *models.Repository, wikiName string) string {
|
||||
bytes, err := ioutil.ReadFile(wikiPath(repo, wikiName))
|
||||
assert.NoError(t, err)
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func assertWikiExists(t *testing.T, repo *models.Repository, wikiName string) {
|
||||
assert.True(t, com.IsExist(wikiPath(repo, wikiName)))
|
||||
}
|
||||
|
||||
func assertWikiNotExists(t *testing.T, repo *models.Repository, wikiName string) {
|
||||
assert.False(t, com.IsExist(wikiPath(repo, wikiName)))
|
||||
}
|
||||
|
||||
func assertPagesMetas(t *testing.T, expectedNames []string, metas interface{}) {
|
||||
pageMetas, ok := metas.([]PageMeta)
|
||||
if !assert.True(t, ok) {
|
||||
return
|
||||
}
|
||||
if !assert.EqualValues(t, len(expectedNames), len(pageMetas)) {
|
||||
return
|
||||
}
|
||||
for i, pageMeta := range pageMetas {
|
||||
assert.EqualValues(t, expectedNames[i], pageMeta.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWiki(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_pages")
|
||||
ctx.SetParams(":page", "Home")
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
Wiki(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
||||
assertPagesMetas(t, []string{"Home"}, ctx.Data["Pages"])
|
||||
}
|
||||
|
||||
func TestWikiPages(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_pages")
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
WikiPages(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
assertPagesMetas(t, []string{"Home"}, ctx.Data["Pages"])
|
||||
}
|
||||
|
||||
func TestNewWiki(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
NewWiki(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
assert.EqualValues(t, ctx.Tr("repo.wiki.new_page"), ctx.Data["Title"])
|
||||
}
|
||||
|
||||
func TestNewWikiPost(t *testing.T) {
|
||||
for _, title := range []string{
|
||||
"New page",
|
||||
"&&&&",
|
||||
} {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
NewWikiPost(ctx, auth.NewWikiForm{
|
||||
Title: title,
|
||||
Content: content,
|
||||
Message: message,
|
||||
})
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assertWikiExists(t, ctx.Repo.Repository, title)
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, title), content)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewWikiPost_ReservedName(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
NewWikiPost(ctx, auth.NewWikiForm{
|
||||
Title: "_edit",
|
||||
Content: content,
|
||||
Message: message,
|
||||
})
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
assert.EqualValues(t, ctx.Tr("repo.wiki.reserved_page"), ctx.Flash.ErrorMsg)
|
||||
assertWikiNotExists(t, ctx.Repo.Repository, "_edit")
|
||||
}
|
||||
|
||||
func TestEditWiki(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_edit/Home")
|
||||
ctx.SetParams(":page", "Home")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
EditWiki(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"])
|
||||
}
|
||||
|
||||
func TestEditWikiPost(t *testing.T) {
|
||||
for _, title := range []string{
|
||||
"Home",
|
||||
"New/<page>",
|
||||
} {
|
||||
models.PrepareTestEnv(t)
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/_new/Home")
|
||||
ctx.SetParams(":page", "Home")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
EditWikiPost(ctx, auth.NewWikiForm{
|
||||
Title: title,
|
||||
Content: content,
|
||||
Message: message,
|
||||
})
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
assertWikiExists(t, ctx.Repo.Repository, title)
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, title), content)
|
||||
if title != "Home" {
|
||||
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteWikiPagePost(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
|
||||
ctx := test.MockContext(t, "user2/repo1/wiki/Home/delete")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
DeleteWikiPagePost(ctx)
|
||||
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
|
||||
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
|
||||
}
|
||||
|
|
@ -19,8 +19,8 @@ func TestIssues(t *testing.T) {
|
|||
setting.UI.IssuePagingNum = 1
|
||||
assert.NoError(t, models.LoadFixtures())
|
||||
|
||||
ctx := test.MockContext(t)
|
||||
ctx.User = models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||
ctx := test.MockContext(t, "issues")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
ctx.SetParams(":type", "issues")
|
||||
ctx.Req.Form.Set("state", "closed")
|
||||
Issues(ctx)
|
||||
|
|
|
|||
|
|
@ -5,29 +5,12 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3" // for the test engine
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if err := models.CreateTestEngine("../../models/fixtures/"); err != nil {
|
||||
fmt.Printf("Error creating test engine: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
setting.AppURL = "https://try.gitea.io/"
|
||||
setting.RunUser = "runuser"
|
||||
setting.SSH.Port = 3000
|
||||
setting.SSH.Domain = "try.gitea.io"
|
||||
setting.RepoRootPath = filepath.Join(os.TempDir(), "repos")
|
||||
setting.AppDataPath = filepath.Join(os.TempDir(), "appdata")
|
||||
|
||||
os.Exit(m.Run())
|
||||
models.MainTest(m, filepath.Join("..", ".."))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import (
|
|||
const (
|
||||
tplSettingsProfile base.TplName = "user/settings/profile"
|
||||
tplSettingsAvatar base.TplName = "user/settings/avatar"
|
||||
tplSettingsPassword base.TplName = "user/settings/password"
|
||||
tplSettingsEmails base.TplName = "user/settings/email"
|
||||
tplSettingsKeys base.TplName = "user/settings/keys"
|
||||
tplSettingsSocial base.TplName = "user/settings/social"
|
||||
|
|
@ -223,7 +222,9 @@ func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) {
|
|||
return
|
||||
}
|
||||
|
||||
if ctx.User.IsPasswordSet() && !ctx.User.ValidatePassword(form.OldPassword) {
|
||||
if len(form.Password) < setting.MinPasswordLength {
|
||||
ctx.Flash.Error(ctx.Tr("auth.password_too_short", setting.MinPasswordLength))
|
||||
} else if ctx.User.IsPasswordSet() && !ctx.User.ValidatePassword(form.OldPassword) {
|
||||
ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
|
||||
} else if form.Password != form.Retype {
|
||||
ctx.Flash.Error(ctx.Tr("form.password_not_match"))
|
||||
|
|
|
|||
68
routers/user/setting_test.go
Normal file
68
routers/user/setting_test.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2017 The Gitea 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 user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/auth"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestChangePassword(t *testing.T) {
|
||||
oldPassword := "password"
|
||||
setting.MinPasswordLength = 6
|
||||
|
||||
for _, req := range []struct {
|
||||
OldPassword string
|
||||
NewPassword string
|
||||
Retype string
|
||||
Message string
|
||||
}{
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "",
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "12345",
|
||||
Retype: "12345",
|
||||
Message: "auth.password_too_short",
|
||||
},
|
||||
{
|
||||
OldPassword: "12334",
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "settings.password_incorrect",
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "12345",
|
||||
Message: "form.password_not_match",
|
||||
},
|
||||
} {
|
||||
models.PrepareTestEnv(t)
|
||||
ctx := test.MockContext(t, "user/settings/security")
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
|
||||
SettingsSecurityPost(ctx, auth.ChangePasswordForm{
|
||||
OldPassword: req.OldPassword,
|
||||
Password: req.NewPassword,
|
||||
Retype: req.Retype,
|
||||
})
|
||||
|
||||
assert.EqualValues(t, req.Message, ctx.Flash.ErrorMsg)
|
||||
assert.EqualValues(t, http.StatusFound, ctx.Resp.Status())
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
<th class="three wide right aligned">{{.i18n.Tr "repo.commits.date"}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody class="commit-list">
|
||||
{{ $r:= List .Commits}}
|
||||
{{range $r}}
|
||||
<tr>
|
||||
|
|
@ -61,6 +61,10 @@
|
|||
</td>
|
||||
<td class="message collapsing">
|
||||
<span class="has-emoji{{if gt .ParentCount 1}} grey text{{end}}">{{RenderCommitMessage .Summary $.RepoLink $.Repository.ComposeMetas}}</span>
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<button class="basic compact mini ui icon button commit-button"><i class="ellipsis horizontal icon"></i></button>
|
||||
<pre class="commit-body" style="display: none;">{{RenderCommitBody .Message $.RepoLink $.Repository.ComposeMetas}}</pre>
|
||||
{{end}}
|
||||
{{template "repo/commit_status" .Status}}
|
||||
</td>
|
||||
<td class="grey text right aligned">{{TimeSince .Author.When $.Lang}}</td>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
{{.i18n.Tr "repo.diff.browse_source"}}
|
||||
</a>
|
||||
<h3>{{RenderCommitMessage .Commit.Message $.RepoLink $.Repository.ComposeMetas}}{{template "repo/commit_status" .CommitStatus}}</h3>
|
||||
{{if IsMultilineCommitMessage .Commit.Message}}
|
||||
<pre class="commit-body">{{RenderCommitBody .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</pre>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="ui attached info segment {{if .Commit.Signature}} isSigned {{if .Verification.Verified }} isVerified {{end}}{{end}}">
|
||||
{{if .Author}}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<div class="ui attached table segment">
|
||||
<div class="file-view {{if .IsMarkup}}markdown{{else if .IsRenderedHTML}}plain-text{{else if .IsTextFile}}code-view{{end}} has-emoji">
|
||||
{{if .IsMarkup}}
|
||||
{{if .FileContent}}{{.FileContent | Str2html}}{{end}}
|
||||
{{if .FileContent}}{{.FileContent | Safe}}{{end}}
|
||||
{{else if .IsRenderedHTML}}
|
||||
<pre>{{if .FileContent}}{{.FileContent | Str2html}}{{end}}</pre>
|
||||
{{else if not .IsTextFile}}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<table id="repo-files-table" class="ui fixed single line table">
|
||||
<thead>
|
||||
<tr>
|
||||
<tr class="commit-list">
|
||||
<th class="four wide">
|
||||
{{if .LatestCommitUser}}
|
||||
<img class="ui avatar image img-12" src="{{.LatestCommitUser.RelAvatarLink}}" />
|
||||
|
|
@ -28,6 +28,10 @@
|
|||
{{end}}
|
||||
</a>
|
||||
<span class="grey has-emoji">{{RenderCommitMessage .LatestCommit.Summary .RepoLink $.Repository.ComposeMetas}}
|
||||
{{if IsMultilineCommitMessage .LatestCommit.Message}}
|
||||
<button class="basic compact mini ui icon button commit-button"><i class="ellipsis horizontal icon"></i></button>
|
||||
<pre class="commit-body" style="display: none;">{{RenderCommitBody .LatestCommit.Message $.RepoLink $.Repository.ComposeMetas}}</pre>
|
||||
{{end}}
|
||||
{{template "repo/commit_status" .LatestCommitStatus}}</span>
|
||||
</th>
|
||||
<th class="nine wide">
|
||||
|
|
|
|||
|
|
@ -13,12 +13,11 @@
|
|||
</div>
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="old_title" value="{{.old_title}}">
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<input name="title" value="{{.title}}" autofocus required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<textarea id="edit_area" name="content" data-id="wiki-{{.old_title}}" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}/wiki">{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea required>
|
||||
<textarea id="edit_area" name="content" data-id="wiki-{{.title}}" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}/wiki">{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user