Skip to content
Snippets Groups Projects
Commit d48a6282 authored by Florent Gluck's avatar Florent Gluck
Browse files

Added a new command ("repos") to create repositories inside an existing gitlab group.

Updated README.md in consequence with a more concrete example as well.
parent d1ac2f6f
No related branches found
No related tags found
No related merge requests found
# Practical Work Manager (pwm) # Practical Work Manager (pwm)
Programme python pour gérer les travaux pratiques des étudiants avec la contrainte d'utiliser le gitlab d'HEPIA. Programme python pour gérer les travaux pratiques des étudiants avec la contrainte d'utiliser le gitlab d'HEPIA.
Ce script permet d'automatiser de nombreuses tâches, notamment la création de nombreuses repositories d'un coup, ou encore cloner toutes les repositories contenues dans un groupe, etc.
## TL;DR ## Utilisation
- Créer un groupe et les repositories en une seule commande, avec un repository "image" optionnel et un fichier d'emails (voir [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file) : - Créer un groupe et les repositories en une seule commande, avec un repository "image" optionnel et un fichier d'emails (voir [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file) :
```bash ```bash
python pwm -t TOKEN group_repos GROUP_NAME REPOS_FILE [-i IMPORT_URL] python pwm -t TOKEN group_repos GROUP_NAME REPOS_FILE [-i IMPORT_URL]
``` ```
- Créer, au sein d'un groupe existant, les repositories en une seule commande, avec un repository "image" optionnel et un fichier d'emails (voir [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file) :
```bash
python pwm -t TOKEN repos GROUP_ID REPOS_FILE [-i IMPORT_URL]
```
- Clone tous les projets des étudiants d'un groupe gitlab (`ID`) dans un répertoire créé à la volée : - Clone tous les projets des étudiants d'un groupe gitlab (`ID`) dans un répertoire créé à la volée :
```bash ```bash
python pwm -t TOKEN clone ID DIRECTORY python pwm -t TOKEN clone ID DIRECTORY
...@@ -18,10 +23,11 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra ...@@ -18,10 +23,11 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra
``` ```
- [Practical Work Manager (pwm)](#practical-work-manager-pwm) - [Practical Work Manager (pwm)](#practical-work-manager-pwm)
- [TL;DR](#tldr) - [Utilisation](#utilisation)
- [Workflow d'utilisation](#workflow-dutilisation) - [Workflow d'utilisation](#workflow-dutilisation)
- [Utilisation de pwm](#utilisation-de-pwm) - [Utilisation de pwm](#utilisation-de-pwm)
- [Création d'un groupe et des projets](#création-dun-groupe-et-des-projets) - [Création d'un groupe et des projets](#création-dun-groupe-et-des-projets)
- [Création des projets au sein d'un groupe existant](#création-des-projets-au-sein-dun-groupe-existant)
- [Création d'un groupe seulement](#création-dun-groupe-seulement) - [Création d'un groupe seulement](#création-dun-groupe-seulement)
- [Création d'un sous-projet dans le groupe](#création-dun-sous-projet-dans-le-groupe) - [Création d'un sous-projet dans le groupe](#création-dun-sous-projet-dans-le-groupe)
- [Clone de tous les repositories](#clone-de-tous-les-repositories) - [Clone de tous les repositories](#clone-de-tous-les-repositories)
...@@ -31,6 +37,7 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra ...@@ -31,6 +37,7 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra
- [Emails seulement](#emails-seulement) - [Emails seulement](#emails-seulement)
## Workflow d'utilisation ## Workflow d'utilisation
Pour expliquer la démarche d'utilisation, prenons le scénario suivant : Pour expliquer la démarche d'utilisation, prenons le scénario suivant :
- L'enseignant Michel Albuquerque prépare un nouveau travail pratique (TP). Il souhaite forcer les étudiants à utiliser git et gitedu pour qu'ils versionnent leur code et pour qu'il puisse visualiser et recevoir leur rendus. - L'enseignant Michel Albuquerque prépare un nouveau travail pratique (TP). Il souhaite forcer les étudiants à utiliser git et gitedu pour qu'ils versionnent leur code et pour qu'il puisse visualiser et recevoir leur rendus.
- Les TPs sont à faire par groupe ou de manière individuelle. - Les TPs sont à faire par groupe ou de manière individuelle.
...@@ -59,9 +66,13 @@ source .venv/bin/activate ...@@ -59,9 +66,13 @@ source .venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
``` ```
pwm se présente sous la forme d'une CLI. Il nécessite un `token` gitlab, pouvant être généré [sur cette page](https://gitedu.hesge.ch/profile/personal_access_tokens), en cochant la case "api". Ce `token` peut ensuite être utilisé de trois manières : pwm se présente sous la forme d'une CLI. Il nécessite un `token` gitlab, pouvant être généré [sur cette page](https://gitedu.hesge.ch/-/profile/personal_access_tokens), en cochant la case "api".
1. Écrit dans le fichier `~/.gitedu_token` **Attention** : une fois crée, le token est affiché une fois seulement sur la page et ne sera ensuite plus jamais visible.
Le `token` peut ensuite être utilisé de trois manières :
1. Écrit dans le fichier `~/.gitedu_token` (conseil : réaliser ensuite un `chmod 600 ~/.gitedu_token` pour en protéger l'accès)
2. Placé dans la variable d'environnement `GITEDU_TOKEN` 2. Placé dans la variable d'environnement `GITEDU_TOKEN`
3. Donné en argument de `pwm` avec l'option `-t` ou `--token` 3. Donné en argument de `pwm` avec l'option `-t` ou `--token`
...@@ -72,18 +83,64 @@ Selon les commandes, un `project_id` ou `group_id` est également nécessaire, i ...@@ -72,18 +83,64 @@ Selon les commandes, un `project_id` ou `group_id` est également nécessaire, i
L'exécution du programme sans arguments affiche l'aide et le détail pour chaque sous-commande. L'exécution du programme sans arguments affiche l'aide et le détail pour chaque sous-commande.
### Création d'un groupe et des projets ### Création d'un groupe et des projets
```bash ```bash
python pwm group_repos GROUP_NAME REPOS_FILE [-h] [--visibility VISIBILITY] [-i IMPORT_URL] [-x EXPIRES_AT] python pwm group_repos GROUP_NAME REPOS_FILE [-h] [--visibility VISIBILITY] [-i IMPORT_URL] [-x EXPIRES_AT]
``` ```
Exécute les opérations de création de groupe et de repositories à partir d'un fichier YAML (voir [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file)). Voir les sous-sections suivantes pour les détails des sous-commandes. Exécute les opérations de création de groupe et de repositories à partir d'un fichier YAML (voir [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file)). Voir les sous-sections suivantes pour les détails des sous-commandes.
### Création des projets au sein d'un groupe existant
```bash
python pwm repos GROUP_ID REPOS_FILE [-h] [-i IMPORT_URL] [-x EXPIRES_AT]
```
Exécute les opérations de création de repositories à partir d'un fichier YAML (voir [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file)). Voir les sous-sections suivantes pour les détails des sous-commandes.
#### Exemple d'utilisation
Soit le fichier `psa_groups.yml` qui defini les 3 groupes d'étudiants ci-dessous :
```
- name: group1
emails:
- prenom.nom11@hesge.ch
- prenom.nom12@hesge.ch
- name: group2
emails:
- prenom.nom21@hesge.ch
- prenom.nom22@hesge.ch
- name: group3
emails:
- prenom.nom31@hesge.ch
- prenom.nom32@hesge.ch
```
On commence par activer l'environnement python :
```
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
Ensuite, on exécute le script qui va créer les groupes définis dans le fichier yml ci-dessus dans le groupe gitlab 1458 existant et populer chaque repository avec la repo passé en argument (ici une repo vide sur github) :
```
python3 pwm repos 1458 psa_2022.yml -i https://github.com/florentgluck/empty.git
```
Comme aucun token n'est spécifié, le script utilise celui se trouvant dans le fichier `~/.gitedu_token`.
A noter qu'on pourrait également ajouter l'argument `-t <token>` avant l'argument `repos` pour spécifier le token sur la ligne de commande.
### Création d'un groupe seulement ### Création d'un groupe seulement
```bash ```bash
python pwm group [-h] [--visibility VISIBILITY] GROUP_NAME python pwm group [-h] [--visibility VISIBILITY] GROUP_NAME
``` ```
Crée un groupe au sens gitlab du terme, nommé `GROUP_NAME`, avec la visibilité optionnelle `VISIBILITY` (`private`, `internal` ou `public`), par défaut privée. Si le groupe existe déjà, ne fait rien. Retourne le `group_id` du groupe créé, nécessaire pour la création des sous-projets par exemple. Crée un groupe au sens gitlab du terme, nommé `GROUP_NAME`, avec la visibilité optionnelle `VISIBILITY` (`private`, `internal` ou `public`), par défaut privée. Si le groupe existe déjà, ne fait rien. Retourne le `group_id` du groupe créé, nécessaire pour la création des sous-projets par exemple.
### Création d'un sous-projet dans le groupe ### Création d'un sous-projet dans le groupe
```bash ```bash
python pwm repo [-h] [-n NAME] [-i IMPORT_URL] [-x EXPIRES_AT] GROUP_ID EMAILS python pwm repo [-h] [-n NAME] [-i IMPORT_URL] [-x EXPIRES_AT] GROUP_ID EMAILS
``` ```
...@@ -95,21 +152,25 @@ Crée un dépôt git (projet) au sein d'un groupe à partir de l'URL d'un projet ...@@ -95,21 +152,25 @@ Crée un dépôt git (projet) au sein d'un groupe à partir de l'URL d'un projet
- `EMAILS` : une liste d'emails des étudiants. Les emails sont séparés par une virgule. Peut contenir un seul email. - `EMAILS` : une liste d'emails des étudiants. Les emails sont séparés par une virgule. Peut contenir un seul email.
### Clone de tous les repositories ### Clone de tous les repositories
```bash ```bash
python pwm clone [-h] [-g | -f] [-u UNTIL_DATE] ID DIRECTORY python pwm clone [-h] [-g | -f] [-u UNTIL_DATE] ID DIRECTORY
``` ```
Clone tous les repositories d'un groupe (`-g`) ou tous les forks d'un projet (`-f`) selon l'id (`ID`) donné dans un répertoire nommé `DIRECTORY`. Si une date `UNTIL_DATE` (au format `YYYY-MM-DD hh:mm`) est donnée, exécute un `git checkout` sur le premier commit précédant cette date. Affiche sur la sortie standard les membres du groupe (avec un droit d'accès supérieur à *Reporter*), l'url web du repo et dans quel sous-répertoire se trouvent les fichiers. Clone tous les repositories d'un groupe (`-g`) ou tous les forks d'un projet (`-f`) selon l'id (`ID`) donné dans un répertoire nommé `DIRECTORY`. Si une date `UNTIL_DATE` (au format `YYYY-MM-DD hh:mm`) est donnée, exécute un `git checkout` sur le premier commit précédant cette date. Affiche sur la sortie standard les membres du groupe (avec un droit d'accès supérieur à *Reporter*), l'url web du repo et dans quel sous-répertoire se trouvent les fichiers.
### Liste des projets d'un groupe ou des membres d'un projet ### Liste des projets d'un groupe ou des membres d'un projet
```bash ```bash
python pwm list [-h] [-p | -m] [-s SHOW] ID python pwm list [-h] [-p | -m] [-s SHOW] ID
``` ```
Liste les projets d'un groupe ou les membres d'un projet selon l'id `ID`. L'argument `--show` (ou `-s`) permet de choisir quelles informations à afficher (par défaut le nom) : `[all | name | url | ssh]`. Liste les projets d'un groupe ou les membres d'un projet selon l'id `ID`. L'argument `--show` (ou `-s`) permet de choisir quelles informations à afficher (par défaut le nom) : `[all | name | url | ssh]`.
## Syntaxe du fichier YAML (REPOS_FILE) ## Syntaxe du fichier YAML (REPOS_FILE)
Le fichier YAML doit respecter une des deux syntaxes suivantes. Le fichier YAML doit respecter une des deux syntaxes suivantes.
### Noms et emails ### Noms et emails
Pour chaque projet créé, un nom et une liste d'emails doivent être renseignés : Pour chaque projet créé, un nom et une liste d'emails doivent être renseignés :
```yaml ```yaml
...@@ -128,6 +189,7 @@ Pour chaque projet créé, un nom et une liste d'emails doivent être renseigné ...@@ -128,6 +189,7 @@ Pour chaque projet créé, un nom et une liste d'emails doivent être renseigné
``` ```
### Emails seulement ### Emails seulement
Si uniquement les emails sont fournis, prend le premier nom de chaque email pour nom de projet : Si uniquement les emails sont fournis, prend le premier nom de chaque email pour nom de projet :
```yaml ```yaml
......
...@@ -246,6 +246,29 @@ def command_create_group_repos(args): ...@@ -246,6 +246,29 @@ def command_create_group_repos(args):
print() print()
def command_create_repos(args):
"""
Create a set of repositories inside the specified (existing) group. For each repository listed
in the given file, create a repository.
"""
group_id = args.group_id
with open(args.repos_file) as f:
repos = yaml.full_load(f)
for repo in repos:
if 'name' in repo:
name = repo['name']
elif 'emails' in repo:
name = repo['emails'][0].split('@')[0]
else:
print('YAML file not correct, exit and delete group')
delete_group(args.token, group_id)
exit(1)
create_repository(
args.token, group_id, repo['emails'], name, args.import_url, args.expires_at)
print()
def command_create_group(args): def command_create_group(args):
""" """
Call create_group Call create_group
...@@ -346,6 +369,18 @@ if __name__ == '__main__': ...@@ -346,6 +369,18 @@ if __name__ == '__main__':
help="Expiration date to kick off students from this project, at 00:00:00. YYYY-MM-DD format (optional).") help="Expiration date to kick off students from this project, at 00:00:00. YYYY-MM-DD format (optional).")
parser_group_repos.set_defaults(func=command_create_group_repos) parser_group_repos.set_defaults(func=command_create_group_repos)
parser_repos = subparsers.add_parser(
'repos', help='Create repos inside existing group')
parser_repos.add_argument(
"group_id", metavar="GROUP_ID", help="The existing group id.")
parser_repos.add_argument(
"repos_file", metavar="REPOS_FILE", help="YAML file with projects names and/or students emails.")
parser_repos.add_argument("-i", "--import_url",
help="Import the publicly accessible project by URL given here (optional).")
parser_repos.add_argument("-x", "--expires_at",
help="Expiration date to kick off students from this project, at 00:00:00. YYYY-MM-DD format (optional).")
parser_repos.set_defaults(func=command_create_repos)
parser_group = subparsers.add_parser('group', help='Create gitlab group') parser_group = subparsers.add_parser('group', help='Create gitlab group')
parser_group.add_argument( parser_group.add_argument(
"group_name", metavar="GROUP_NAME", help="The group name.") "group_name", metavar="GROUP_NAME", help="The group name.")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment