Skip to content
Snippets Groups Projects
Verified Commit aff9af83 authored by steven.liatti's avatar steven.liatti
Browse files

Add list functionality

parent a99eb8f6
Branches
No related tags found
No related merge requests found
...@@ -4,8 +4,18 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra ...@@ -4,8 +4,18 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra
## TL;DR ## TL;DR
- Créer un groupe et les repositories en une seule commande (avec un repository "image" optionnel) : `python pwm -t TOKEN group_repos GROUP_NAME REPOS_FILE [-i IMPORT_URL]`, 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) :
- Clone tous les projets des étudiants d'un groupe gitlab (`ID`) dans un répertoire créé à la volée : `python pwm -t TOKEN clone ID DIRECTORY` ```bash
python pwm -t TOKEN group_repos GROUP_NAME REPOS_FILE [-i IMPORT_URL]
```
- Clone tous les projets des étudiants d'un groupe gitlab (`ID`) dans un répertoire créé à la volée :
```bash
python pwm -t TOKEN clone ID DIRECTORY
```
- Liste les noms des projets dans un groupe :
```bash
python pwm list ID
```
- [Practical Work Manager (pwm)](#practical-work-manager-pwm) - [Practical Work Manager (pwm)](#practical-work-manager-pwm)
- [TL;DR](#tldr) - [TL;DR](#tldr)
...@@ -15,6 +25,7 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra ...@@ -15,6 +25,7 @@ Programme python pour gérer les travaux pratiques des étudiants avec la contra
- [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)
- [Liste des projets d'un groupe ou des membres d'un projet](#liste-des-projets-dun-groupe-ou-des-membres-dun-projet)
- [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file) - [Syntaxe du fichier YAML (REPOS_FILE)](#syntaxe-du-fichier-yaml-repos_file)
- [Noms et emails](#noms-et-emails) - [Noms et emails](#noms-et-emails)
- [Emails seulement](#emails-seulement) - [Emails seulement](#emails-seulement)
...@@ -89,6 +100,12 @@ python pwm clone [-h] [-g | -f] [-u UNTIL_DATE] ID DIRECTORY ...@@ -89,6 +100,12 @@ 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
```bash
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]`.
## 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.
......
pwm 100755 → 100644
...@@ -8,11 +8,13 @@ Steven Liatti ...@@ -8,11 +8,13 @@ Steven Liatti
from argparse import Namespace from argparse import Namespace
import os import os
from typing import Dict, List, Optional from typing import Any, Dict, List, Optional
import requests import requests
import subprocess import subprocess
import argparse import argparse
from requests.models import Response
import yaml import yaml
import json
BASE_URL: str = 'https://gitedu.hesge.ch/api/v4' BASE_URL: str = 'https://gitedu.hesge.ch/api/v4'
...@@ -112,6 +114,59 @@ def create_repository(token: str, group_id: str, emails: List[str], name: str, i ...@@ -112,6 +114,59 @@ def create_repository(token: str, group_id: str, emails: List[str], name: str, i
print(out) print(out)
def paginate_responses(url: str, headers: Dict[str, str], params: Dict[str, Any]) -> List[Response]:
"""
Manage gitlab pagination, max 100 results by request
"""
responses = [requests.get(url, params=params, headers=headers)]
last_response = responses[len(responses) - 1]
while last_response.status_code == 200 and len(last_response.headers['X-Next-Page']) != 0:
next_page = last_response.headers['X-Next-Page']
params['page'] = next_page
responses.append(requests.get(url, params=params, headers=headers))
last_response = responses[len(responses) - 1]
return responses
def get_members(token: str, id: str) -> List:
"""
Return members list from given id
"""
url = BASE_URL + '/projects/' + id + '/members'
headers = {'PRIVATE-TOKEN': token}
params = {'simple': 'true', 'order_by': 'name',
'sort': 'asc', 'per_page': 100}
responses = paginate_responses(url, headers, params)
members = []
for r in responses:
members += r.json()
return members
def get_projects(token: str, id: str, source: str = 'group') -> List:
"""
Return projects list from given id and source ('group' or 'forks')
"""
if source == 'forks':
url = BASE_URL + '/projects/' + id + '/forks'
else:
url = BASE_URL + '/groups/' + id + '/projects'
headers = {'PRIVATE-TOKEN': token}
params = {'simple': 'true', 'order_by': 'name',
'sort': 'asc', 'per_page': 100}
responses = paginate_responses(url, headers, params)
projects = []
for r in responses:
projects += r.json()
return projects
def clone_all(token: str, id: str, directory: str, until_date: Optional[str], source: str = 'group'): def clone_all(token: str, id: str, directory: str, until_date: Optional[str], source: str = 'group'):
""" """
Clone all repositories (from a group or "forks of") from id (group or Clone all repositories (from a group or "forks of") from id (group or
...@@ -123,18 +178,8 @@ def clone_all(token: str, id: str, directory: str, until_date: Optional[str], so ...@@ -123,18 +178,8 @@ def clone_all(token: str, id: str, directory: str, until_date: Optional[str], so
print("Creation of the directory '%s' failed, exit\n" % directory) print("Creation of the directory '%s' failed, exit\n" % directory)
exit(1) exit(1)
params = {'simple': 'true', 'per_page': 100}
headers = {'PRIVATE-TOKEN': token} headers = {'PRIVATE-TOKEN': token}
repositories = get_projects(token, id, source)
if source == 'forks':
url = BASE_URL + '/projects/' + id + '/forks'
else:
url = BASE_URL + '/groups/' + id + '/projects'
repositories = requests.get(url, params=params, headers=headers).json()
if 'message' in repositories:
print('Error retrieving repositories: ' + repositories['message'])
exit(1)
for repo in repositories: for repo in repositories:
repo_url = BASE_URL + '/projects/' + str(repo['id']) + '/members' repo_url = BASE_URL + '/projects/' + str(repo['id']) + '/members'
...@@ -234,6 +279,50 @@ def command_clone_all(args): ...@@ -234,6 +279,50 @@ def command_clone_all(args):
clone_all(args.token, args.id, args.directory, args.until_date) clone_all(args.token, args.id, args.directory, args.until_date)
def command_list(args):
"""
Call get_projects or get_members
"""
if args.members:
members = get_members(args.token, args.id)
if args.show:
if args.show == 'all':
print(json.dumps(members, indent=2))
elif args.show == 'url':
results = list(map(lambda p: p['web_url'], members))
for r in results:
print(r)
else:
names = list(map(lambda p: p['username'], members))
for name in names:
print(name)
else:
names = list(map(lambda p: p['username'], members))
for name in names:
print(name)
else:
projects = get_projects(args.token, args.id)
if args.show:
if args.show == 'all':
print(json.dumps(projects, indent=2))
elif args.show == 'url':
results = list(map(lambda p: p['http_url_to_repo'], projects))
for r in results:
print(r)
elif args.show == 'ssh':
results = list(map(lambda p: p['ssh_url_to_repo'], projects))
for r in results:
print(r)
else:
names = list(map(lambda p: p['name'], projects))
for name in names:
print(name)
else:
names = list(map(lambda p: p['name'], projects))
for name in names:
print(name)
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Practical Work Manager - \ parser = argparse.ArgumentParser(description='Practical Work Manager - \
Manage students PW - Create group, projects or clone repositories') Manage students PW - Create group, projects or clone repositories')
...@@ -241,7 +330,7 @@ if __name__ == '__main__': ...@@ -241,7 +330,7 @@ if __name__ == '__main__':
parser.add_argument("-t", "--token", metavar="TOKEN", parser.add_argument("-t", "--token", metavar="TOKEN",
help="Create a token here: https://gitedu.hesge.ch/profile/personal_access_tokens") help="Create a token here: https://gitedu.hesge.ch/profile/personal_access_tokens")
subparsers = parser.add_subparsers( subparsers = parser.add_subparsers(
metavar='(group_repos | group | repo | clone)') metavar='(group_repos | group | repo | clone | list)')
parser_group_repos = subparsers.add_parser( parser_group_repos = subparsers.add_parser(
'group_repos', help='Create group and repos associated') 'group_repos', help='Create group and repos associated')
...@@ -292,6 +381,19 @@ if __name__ == '__main__': ...@@ -292,6 +381,19 @@ if __name__ == '__main__':
"-u", "--until_date", help="Do a git checkout for all repositories at given date, format \"YYYY-MM-DD hh:mm\" (optional).") "-u", "--until_date", help="Do a git checkout for all repositories at given date, format \"YYYY-MM-DD hh:mm\" (optional).")
parser_clone.set_defaults(func=command_clone_all) parser_clone.set_defaults(func=command_clone_all)
parser_list = subparsers.add_parser(
'list', help="List group's projects or project's members")
group_list = parser_list.add_mutually_exclusive_group()
group_list.add_argument(
"-p", "--projects", action="store_true", help="List group's projects (default")
group_list.add_argument(
"-m", "--members", action="store_true", help="List project's members")
parser_list.add_argument(
"id", metavar="ID", help="The group_id or the project_id (int).")
parser_list.add_argument(
"-s", "--show", help="Amount of informations (default name) : [all | name | url | ssh]")
parser_list.set_defaults(func=command_list)
args = parser.parse_args() args = parser.parse_args()
if not args.token: if not args.token:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment