Compare commits
No commits in common. "try-click" and "main" have entirely different histories.
6 changed files with 15 additions and 304 deletions
|
|
@ -17,7 +17,7 @@ repos:
|
||||||
rev: 5.12.0
|
rev: 5.12.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
args: ["--profile", "black", "-l", "79"]
|
args: ["--profile", "black"]
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 6.1.0
|
rev: 6.1.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@ classifiers = [
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"click",
|
"requests"
|
||||||
"prettytable",
|
|
||||||
"requests",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
@ -27,7 +25,7 @@ dependencies = [
|
||||||
"Bug Tracker" = "https://git.evatt.ingenious.com.au/neillc/gitea-gitlab-exporter"
|
"Bug Tracker" = "https://git.evatt.ingenious.com.au/neillc/gitea-gitlab-exporter"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
gl2gt = "gitea_gitlab_exporter.cli:cli"
|
gitlab2gitea = "gitea_gitlab_exporter:exporter"
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
"""
|
"""
|
||||||
A tool to copy a project from gitlab to gitea
|
A skeleton for a python project.
|
||||||
|
|
||||||
Copyright 2023 Neill Cox
|
Copyright 2023 Neill Cox
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
def hello_world():
|
||||||
|
logging.debug("hello_world called")
|
||||||
|
print("Hello World!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
hello_world()
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
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))
|
|
||||||
|
|
||||||
|
|
||||||
def get_issues(args):
|
|
||||||
project_id = args.project_id
|
|
||||||
url = gitlab_url(
|
|
||||||
f"/projects/{project_id}/issues?pagination=offset&per_page=500&"
|
|
||||||
)
|
|
||||||
|
|
||||||
response = get(url, args)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
def get_wiki(args):
|
|
||||||
url = gitlab_url(f"/projects/{args.project_id}/wikis?with_content=1")
|
|
||||||
response = get(url, args)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
@ -1,209 +0,0 @@
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import click
|
|
||||||
from prettytable import PrettyTable
|
|
||||||
from requests.exceptions import HTTPError
|
|
||||||
|
|
||||||
from .api import (
|
|
||||||
get_issues,
|
|
||||||
get_project_details,
|
|
||||||
get_user,
|
|
||||||
get_wiki,
|
|
||||||
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))
|
|
||||||
|
|
||||||
|
|
||||||
class Context:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
|
||||||
@click.option("--format", default="json")
|
|
||||||
@click.option("--log-file", default="json")
|
|
||||||
@click.option(
|
|
||||||
"-t",
|
|
||||||
"--gitlab-token",
|
|
||||||
help=(
|
|
||||||
"A private access token to access GitLab with. If not specified "
|
|
||||||
"will use $GL_TOKEN. Required."
|
|
||||||
),
|
|
||||||
envvar="GL2GT_GL_TOKEN",
|
|
||||||
required=True,
|
|
||||||
)
|
|
||||||
@click.option("--debug", is_flag=True)
|
|
||||||
@click.option("--log-file", default="gitlab2gitea.log")
|
|
||||||
@click.pass_context
|
|
||||||
def cli(ctx, format, gitlab_token, debug, log_file):
|
|
||||||
ctx.ensure_object(Context)
|
|
||||||
|
|
||||||
ctx.obj.format = format
|
|
||||||
ctx.obj.gitlab_token = gitlab_token
|
|
||||||
ctx.obj.debug = debug
|
|
||||||
ctx.obj.log_file = log_file
|
|
||||||
|
|
||||||
log_level = logging.INFO
|
|
||||||
if debug:
|
|
||||||
log_level = logging.DEBUG
|
|
||||||
|
|
||||||
logging.basicConfig(filename=log_file, level=log_level)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.pass_context
|
|
||||||
def list_projects_click(ctx):
|
|
||||||
format = ctx.obj.format
|
|
||||||
|
|
||||||
try:
|
|
||||||
projects = list_projects(ctx.obj)
|
|
||||||
except HTTPError as err:
|
|
||||||
if err.response.status_code == 401:
|
|
||||||
print("Invalid gitlab credentials")
|
|
||||||
sys.exit(2)
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
if 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 format == "json":
|
|
||||||
print(json.dumps(projects))
|
|
||||||
else:
|
|
||||||
print(projects)
|
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(list_projects_click)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.pass_context
|
|
||||||
def click_get_user(ctx):
|
|
||||||
logging.debug("cli_get_user called")
|
|
||||||
|
|
||||||
user = get_user(ctx.obj)
|
|
||||||
|
|
||||||
print(json.dumps(user))
|
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(click_get_user)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.option("--project", help="Project name or ID", required=True)
|
|
||||||
@click.pass_context
|
|
||||||
def export_project(ctx, project):
|
|
||||||
project_list = [
|
|
||||||
prj
|
|
||||||
for prj in list_projects(ctx.obj)
|
|
||||||
if (prj["id"] == project or prj["name"] == project)
|
|
||||||
]
|
|
||||||
|
|
||||||
if len(project_list) > 1:
|
|
||||||
print("Multiple projects found.")
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
if len(project_list) < 1:
|
|
||||||
print("No matching projects")
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
project_details = project_list[0]
|
|
||||||
|
|
||||||
ctx.obj.project_id = project_details["id"]
|
|
||||||
|
|
||||||
issues = get_issues(ctx.obj)
|
|
||||||
|
|
||||||
project_details["issues"] = issues
|
|
||||||
|
|
||||||
wiki_pages = get_wiki(ctx.obj)
|
|
||||||
project_details["wiki_pages"] = wiki_pages
|
|
||||||
|
|
||||||
print(json.dumps(project_details))
|
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(export_project)
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
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})
|
|
||||||
|
|
||||||
# if not response.ok:
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
logging.debug("response.status: %s", response.status_code)
|
|
||||||
logging.debug("body: %s", response.text)
|
|
||||||
|
|
||||||
return response.json()
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue