diff --git a/pyproject.toml b/pyproject.toml index 221b3fa..069d0e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,8 @@ classifiers = [ "Operating System :: OS Independent", ] dependencies = [ - "requests" + "prettytable", + "requests", ] [project.urls] diff --git a/src/gitea_gitlab_exporter/__init__.py b/src/gitea_gitlab_exporter/__init__.py index b5a8af4..fa7e287 100644 --- a/src/gitea_gitlab_exporter/__init__.py +++ b/src/gitea_gitlab_exporter/__init__.py @@ -1,18 +1,14 @@ """ -A skeleton for a python project. +A tool to copy a project from gitlab to gitea Copyright 2023 Neill Cox """ -import logging +from .cli import cli_list_projects, parse_args -def hello_world(): - logging.debug("hello_world called") - print("Hello World!") - - -if __name__ == "__main__": - hello_world() +def exporter(): + args = parse_args() + cli_list_projects(args) diff --git a/src/gitea_gitlab_exporter/api.py b/src/gitea_gitlab_exporter/api.py new file mode 100644 index 0000000..ef7e7d4 --- /dev/null +++ b/src/gitea_gitlab_exporter/api.py @@ -0,0 +1,49 @@ +import json +import logging + +from .utils import get, gitlab_url + + +def get_user(args): + logging.debug("get_user called") + + url = gitlab_url("/user") + + result = get(url, args) + + return result + + +def list_projects(args): + logging.debug("list_projects called") + user_id = get_user(args)["id"] + + url = gitlab_url( + f"/users/{user_id}/projects?pagination=offset&per_page=500&" + "order_by=name&sort=asc" + ) + + result = get(url, args) + + return result + + +def get_project_details(args): + user_id = get_user(args)["id"] + url = gitlab_url( + f"/users/{user_id}/projects?pagination=offset&per_page=500&" + "order_by=name&sort=asc" + ) + + response = get(url, args) + + project = [ + project + for project in response + if (project["name"] == args.project or project["id"] == args.project) + ][0] + + if not project: + raise KeyError(f"Project {args.project} not found") + + print(json.dumps(project)) diff --git a/src/gitea_gitlab_exporter/cli.py b/src/gitea_gitlab_exporter/cli.py new file mode 100644 index 0000000..0c60986 --- /dev/null +++ b/src/gitea_gitlab_exporter/cli.py @@ -0,0 +1,106 @@ +import argparse +import json +import logging +import os +import sys + +from prettytable import PrettyTable + +from .api import get_project_details, get_user, list_projects + + +def parse_args(): + """Parse the command line arguments""" + + parser = argparse.ArgumentParser() + parser.add_argument( + "-t", + "--gitlab-token", + help=( + "A private access token to access GitLab with. If not specified " + "will use $GL_TOKEN. Required." + ), + ) + parser.add_argument("--debug", action="store_true") + parser.add_argument("--log-file", default="gitlab2gitea.log") + parser.add_argument("-f", "--format", default="json") + + subparsers = parser.add_subparsers() + + lp_sp = subparsers.add_parser("list-projects") + lp_sp.set_defaults(func=list_projects) + + lp_sp = subparsers.add_parser("get-user") + lp_sp.set_defaults(func=cli_get_user) + + lp_sp = subparsers.add_parser("get-project-details") + lp_sp.add_argument("--project", required=True) + lp_sp.set_defaults(func=get_project_details) + + args = parser.parse_args() + + log_level = logging.INFO + if args.debug: + log_level = logging.DEBUG + + logging.basicConfig(filename=args.log_file, level=log_level) + + if args.gitlab_token is None: + args.gitlab_token = os.environ.get("GL_TOKEN") + + if args.gitlab_token is None: + err_str = "/".join( + [ac for ac in parser._actions if ac.dest == "gitlab_token"][ + 0 + ].option_strings + ) + parser.print_usage() + + print( + f"{parser.prog}: error: the following arguments are " + f"required: {err_str}" + ) + sys.exit(2) + + if "func" in args: + args.func(args) + + return args + + +def cli_get_user(args): + logging.debug("cli_get_user called") + + user = get_user(args) + + print(json.dumps(user)) + + +def cli_list_projects(args): + logging.debug("cli_list_projects called") + + projects = list_projects(args) + + if args.format == "table": + tbl = PrettyTable() + tbl.align = "l" + tbl.field_names = [ + "ID", + "Name", + # "Description" + ] + + for row in projects: + tbl.add_row( + [ + row["id"], + row["name"], + # row["description"][:50] if row["description"] else "" + ] + ) + + print(tbl) + elif args.format == "json": + print(json.dumps(projects)) + else: + print(projects) diff --git a/src/gitea_gitlab_exporter/utils.py b/src/gitea_gitlab_exporter/utils.py new file mode 100644 index 0000000..45a54d4 --- /dev/null +++ b/src/gitea_gitlab_exporter/utils.py @@ -0,0 +1,19 @@ +import logging + +import requests + + +def gitlab_url(path): + return "https://gitlab.com/api/v4" + path + + +def get(url, args): + logging.debug("get called") + logging.debug("url: %s", url) + + response = requests.get(url, headers={"PRIVATE-TOKEN": args.gitlab_token}) + + logging.debug("response.status: %s", response.status_code) + logging.debug("body: %s", response.text) + + return response.json()