2023-03-06 17:33:36 +01:00
# -*- coding: utf-8 -*-
# Script to create Git repositories in a group from a list of names and
# email addresses in a CSV file (such as exported from SynapseS).
#
# Minimally tested. Seems to work. Use at your own risk.
#
# By James Eagan <james.eagan@telecom-paris.fr>
# https://james.eagan.fr
import csv
import gitlab
import sys
GITLAB_URL = ' https://gitlab.telecom-paris.fr '
def readNames ( fileName ) :
result = [ ]
with open ( fileName ) as fd :
sneakPeek = fd . read ( 1024 )
fd . seek ( 0 )
sniffer = csv . Sniffer ( )
dialect = sniffer . sniff ( sneakPeek )
hasHeader = sniffer . has_header ( sneakPeek )
reader = csv . reader ( fd , dialect )
# reader = csv.reader(fd, delimiter=';')
if hasHeader :
next ( reader )
for row in reader :
2023-10-05 17:08:24 +02:00
result . append ( ( row [ 0 ] , row [ 1 ] , row [ 2 ] , row [ 3 ] ) )
2023-03-06 17:33:36 +01:00
return result
def lookupUser ( email , gitlab ) :
2023-03-06 18:48:21 +01:00
""" Return the first found user; throw if not found """
2023-10-05 17:08:24 +02:00
matches = gitlab . users . list ( search = email )
if len ( matches ) == 1 :
return matches [ 0 ]
raise IndexError ( " Found {} matching users " . format ( len ( matches ) ) )
2023-03-06 17:33:36 +01:00
def createProject ( name , groupId , gitlab ) :
return gitlab . projects . create ( { ' name ' : name ,
' namespace_id ' : groupId } )
def addProjectMember ( project , userId , accessLevel ) :
return project . members . create ( { ' user_id ' : userId ,
' access_level ' : accessLevel } )
2023-03-06 18:48:21 +01:00
def makeProjectsInGroupId ( groupId , csvFile , token , options = { } ) :
2023-10-05 17:08:24 +02:00
# print(groupId, csvFile, options)
2023-03-06 18:48:21 +01:00
api = gitlab . Gitlab ( GITLAB_URL , token )
2023-10-05 17:08:24 +02:00
for ( lastName , firstName , email , login ) in readNames ( csvFile ) :
2023-03-06 17:33:36 +01:00
try :
2023-10-05 17:08:24 +02:00
user = lookupUser ( f " { lastName } { firstName } " , api )
print ( " ::: {} Creating project for {} {} < {} > -- {} ( {} )… " . format (
" Not " if options . dry_run else " " ,
2023-03-06 18:48:21 +01:00
lastName , firstName , email , user . name , user . id ) )
2023-10-05 17:08:24 +02:00
if options . dry_run :
continue
2023-03-06 17:33:36 +01:00
project = createProject ( ' {} {} ' . format ( lastName , firstName ) ,
groupId , api )
member = addProjectMember ( project , user . id ,
gitlab . MAINTAINER_ACCESS )
except IndexError as e :
2023-10-05 17:08:24 +02:00
print ( " !!! Skipping {} : User not found ( {} ) " . format ( email , e ) , file = sys . stderr )
2023-03-06 17:33:36 +01:00
except Exception as e :
# print("!!! Could not create user for {}: {}".format(email, e), file=sys.stderr)
2023-10-05 17:08:24 +02:00
print ( " !!! Error creating project for {} : {} " . format ( email , e ) , file = sys . stderr )
2023-03-06 17:33:36 +01:00
if __name__ == ' __main__ ' :
2023-03-06 18:48:21 +01:00
import argparse
# print("*** Usage: python {} <csv> <groupId> <token>".format(sys.argv[0]))
# print("*** csv: a CSV file exported from Synapses.")
# print("*** The first three columns are assumed to be ")
# print("*** last name, first name, email address.")
# print("*** groupId: The GitLab id where all the projects will")
# print("*** be added.")
# print("*** token: A GitLab API token as created at ")
# print("*** {}/-/profile/personal_access_tokens".format(GITLAB_URL))
# print("*** Be sure to enable API scope.")
# sys.exit(1)
def parse_args ( ) :
parser = argparse . ArgumentParser ( description = " Create GitLab repositories " )
2023-10-05 17:08:24 +02:00
parser . add_argument ( " csv " , help = " CSV file as exported from Synapses. The first four columns are assumed to be last name, first name, email address, login. " )
2023-03-06 18:48:21 +01:00
parser . add_argument ( " groupId " , help = " The GitLab id where all projects will be added. " )
parser . add_argument ( " -t " , " --token " , help = " GitLab API token as created at {} /-/profile/personal_access_tokens " . format ( GITLAB_URL ) )
2023-10-05 17:08:24 +02:00
parser . add_argument ( " -n " , " --dry-run " , help = " Do not actually create repositories. " , action = " store_true " )
2023-03-06 18:48:21 +01:00
# TODO: parser.add_argument("--extract-groups", help="Extract groups from the fourth column in the CSV file", action="store_true")
args = parser . parse_args ( )
return args
args = parse_args ( )
makeProjectsInGroupId ( args . groupId , args . csv , args . token , args )