Started refactoring to py-gitea
This commit is contained in:
36
domain/API.py
Normal file
36
domain/API.py
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
import gitea
|
||||
|
||||
|
||||
class API:
|
||||
|
||||
__DEFAULT_API_PATH = "/api/v1"
|
||||
|
||||
def __init__(self):
|
||||
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _make_api_base_url(hostname, port):
|
||||
|
||||
base = f"https://{hostname}"
|
||||
if port is not None:
|
||||
base += f":{port}"
|
||||
|
||||
return base
|
||||
|
||||
@staticmethod
|
||||
def factory(hostname, port, token) -> gitea.Gitea:
|
||||
|
||||
url = API._make_api_base_url(
|
||||
hostname=hostname,
|
||||
port=port
|
||||
)
|
||||
|
||||
g = gitea.Gitea(
|
||||
gitea_url=url,
|
||||
token_text=token
|
||||
)
|
||||
|
||||
return g
|
@ -1,6 +1,9 @@
|
||||
|
||||
|
||||
import giteapy
|
||||
from domain.API import API
|
||||
|
||||
|
||||
import gitea
|
||||
import logging
|
||||
import sys
|
||||
|
||||
@ -9,7 +12,6 @@ import certifi
|
||||
|
||||
class Migrator:
|
||||
|
||||
__DEFAULT_API_PATH = "/api/v1"
|
||||
__REPO_ORIGINAL_NAME_TOKEN = "%N%"
|
||||
|
||||
def __init__(
|
||||
@ -31,6 +33,17 @@ class Migrator:
|
||||
self.__destination_host = destination_host
|
||||
self.__destination_port = destination_port
|
||||
self.__destination_token = destination_token
|
||||
|
||||
self.__source_api = API.factory(
|
||||
hostname=self.__source_host,
|
||||
port=self.__source_port,
|
||||
token=self.__source_token
|
||||
)
|
||||
self.__destination_api = API.factory(
|
||||
hostname=self.__destination_host,
|
||||
port=self.__destination_port,
|
||||
token=self.__destination_token
|
||||
)
|
||||
|
||||
def _init_logger(self):
|
||||
|
||||
@ -41,6 +54,7 @@ class Migrator:
|
||||
|
||||
self.__logger = logger
|
||||
|
||||
"""
|
||||
def _get_user_api(self, hostname, port, token) -> giteapy.UserApi:
|
||||
|
||||
conf = giteapy.Configuration()
|
||||
@ -50,7 +64,9 @@ class Migrator:
|
||||
api = giteapy.UserApi(giteapy.ApiClient(conf))
|
||||
|
||||
return api
|
||||
|
||||
"""
|
||||
|
||||
"""
|
||||
def _get_repo_api(self, hostname, port, token) -> giteapy.RepositoryApi:
|
||||
|
||||
conf = giteapy.Configuration()
|
||||
@ -60,7 +76,9 @@ class Migrator:
|
||||
api = giteapy.RepositoryApi(giteapy.ApiClient(conf))
|
||||
|
||||
return api
|
||||
"""
|
||||
|
||||
"""
|
||||
def _get_org_apis(self) -> (giteapy.OrganizationApi, giteapy.OrganizationApi):
|
||||
|
||||
api_source = self._get_org_api(
|
||||
@ -73,7 +91,9 @@ class Migrator:
|
||||
)
|
||||
|
||||
return api_source, api_destination
|
||||
"""
|
||||
|
||||
"""
|
||||
def _get_org_api(self, hostname, port, token) -> giteapy.OrganizationApi:
|
||||
|
||||
conf = giteapy.Configuration()
|
||||
@ -83,17 +103,9 @@ class Migrator:
|
||||
api = giteapy.OrganizationApi(giteapy.ApiClient(conf))
|
||||
|
||||
return api
|
||||
"""
|
||||
|
||||
def _make_api_base(self, hostname, port):
|
||||
|
||||
base = f"https://{hostname}"
|
||||
if port is not None:
|
||||
base += f":{port}"
|
||||
base += self.__DEFAULT_API_PATH
|
||||
|
||||
return base
|
||||
|
||||
def _make_destination_repo_name(self, pattern: str, repo: giteapy.Repository):
|
||||
def _make_destination_repo_name(self, pattern: str, repo: gitea.Repository):
|
||||
|
||||
repo_name = pattern.replace(self.__REPO_ORIGINAL_NAME_TOKEN, repo.name)
|
||||
|
||||
@ -126,24 +138,34 @@ class Migrator:
|
||||
assert do_destination_copy_topics is not None, "Destination directive to copy source topics should be specified"
|
||||
|
||||
# api_source, api_destination = self._get_org_apis()
|
||||
api_source: giteapy.OrganizationApi
|
||||
api_destination: giteapy.OrganizationApi
|
||||
# api_source: giteapy.OrganizationApi
|
||||
# api_destination: giteapy.OrganizationApi
|
||||
|
||||
# Tattle on certify
|
||||
self.__logger.info(f"Certifi is currently using CA bundle: {certifi.where()}")
|
||||
|
||||
# Grab all org repos
|
||||
source_repos = self._fetch_all_org_repos(org=source_org)
|
||||
source_repos = self._fetch_all_org_repos(
|
||||
org_name=source_org
|
||||
)
|
||||
self.__logger.info(f"Found {len(source_repos)} repos on source:")
|
||||
for repo in source_repos:
|
||||
repo: giteapy.Repository
|
||||
self.__logger.info(f"- #{repo.id} {repo.full_name}")
|
||||
repo: gitea.Repository
|
||||
self.__logger.info(f"- {repo.get_full_name()}")
|
||||
|
||||
print()
|
||||
|
||||
# Filter
|
||||
source_repos = self._filter_repos_for_required_topics(repos=source_repos, topics=source_topics)
|
||||
source_repos = self._filter_repos_for_required_topics(
|
||||
repos=source_repos,
|
||||
topics_required=source_topics
|
||||
)
|
||||
print()
|
||||
self.__logger.info(f"Have {len(source_repos)} remaining repos after topic filtering:")
|
||||
for repo in source_repos:
|
||||
repo: gitea.Repository
|
||||
self.__logger.info(f"- {repo.get_full_name()}")
|
||||
assert False, "Poop"
|
||||
|
||||
repos_migrate = []
|
||||
repos_ignore = []
|
||||
@ -239,57 +261,58 @@ class Migrator:
|
||||
else:
|
||||
self.__logger.info("Confirmation not received; Won't do anything.")
|
||||
|
||||
def _fetch_all_org_repos(self, org: str):
|
||||
def _fetch_all_org_repos(self, org_name: str):
|
||||
|
||||
api_source, api_destination = self._get_org_apis()
|
||||
api_source: giteapy.OrganizationApi
|
||||
org = gitea.Organization.request(
|
||||
gitea=self.__source_api,
|
||||
name=org_name
|
||||
)
|
||||
|
||||
source_repos = []
|
||||
# Grabs all pages automatically
|
||||
repos = org.get_repositories()
|
||||
|
||||
page = 0
|
||||
while True:
|
||||
|
||||
page += 1 # Starts at 1 for some reason
|
||||
source_repos_page = api_source.org_list_repos(org, page=page, limit=25)
|
||||
|
||||
if len(source_repos_page) == 0:
|
||||
break
|
||||
|
||||
source_repos.extend(source_repos_page)
|
||||
|
||||
return source_repos
|
||||
return repos
|
||||
|
||||
def _filter_repos_for_required_topics(
|
||||
|
||||
self,
|
||||
repos: list[giteapy.Repository],
|
||||
topics: list[str]
|
||||
repos: list[gitea.Repository],
|
||||
topics_required: list[str]
|
||||
|
||||
) -> list[giteapy.Repository]:
|
||||
) -> list[gitea.Repository]:
|
||||
|
||||
self.__logger.info(f"Filtering source repos for required topics: {topics}")
|
||||
self.__logger.info(
|
||||
f"Filtering source repos for required topics: {topics_required}"
|
||||
)
|
||||
|
||||
repos_keep = []
|
||||
repos_reject = []
|
||||
repo_topics = {}
|
||||
|
||||
api_source_repos = self._get_repo_api(
|
||||
hostname=self.__source_host, port=self.__source_port,
|
||||
token=self.__source_token
|
||||
)
|
||||
|
||||
for repo in repos:
|
||||
|
||||
repo_topics[repo.id] = api_source_repos.repo_list_topics(owner=repo.owner.login, repo=repo.name)
|
||||
repo_topics[repo.id] = repo_topics[repo.id].topics
|
||||
repo: gitea.Repository
|
||||
|
||||
if self._check_required_topics(topics_present=repo_topics[repo.id], topics_required=topics):
|
||||
repo_key = repo.get_full_name()
|
||||
|
||||
topics_present = repo.get_topics()
|
||||
print(topics_present)
|
||||
repo_topics[repo_key] = topics_present["topics"]
|
||||
print(repo_topics[repo_key])
|
||||
|
||||
if self._check_required_topics(
|
||||
topics_present=repo_topics[repo_key],
|
||||
topics_required=topics_required
|
||||
):
|
||||
repos_keep.append(repo)
|
||||
else:
|
||||
repos_reject.append(repo)
|
||||
|
||||
self.__logger.info("")
|
||||
self.__logger.info(f"\nKeeping {len(repos_keep)} repos because they contain all required topics ({topics}):")
|
||||
self.__logger.info(
|
||||
f"\nKeeping {len(repos_keep)} repos"
|
||||
f" because they contain all required topics ({topics_required}):"
|
||||
)
|
||||
if len(repos_keep) > 0:
|
||||
for repo in repos_keep:
|
||||
self.__logger.info(f"> {repo.full_name}")
|
||||
@ -297,10 +320,12 @@ class Migrator:
|
||||
self.__logger.info("> None")
|
||||
|
||||
self.__logger.info("")
|
||||
self.__logger.info(f"Rejecting {len(repos_reject)} repos because they don't contain all required topics:")
|
||||
self.__logger.info(
|
||||
f"Rejecting {len(repos_reject)} repos because they don't contain all required topics:"
|
||||
)
|
||||
if len(repos_reject) > 0:
|
||||
for repo in repos_reject:
|
||||
self.__logger.info(f"> {repo.full_name} ({repo_topics[repo.id]})")
|
||||
self.__logger.info(f"> {repo.full_name}")
|
||||
else:
|
||||
self.__logger.info("> None")
|
||||
|
||||
@ -309,6 +334,9 @@ class Migrator:
|
||||
@staticmethod
|
||||
def _check_required_topics(topics_present: list[str], topics_required: list[str]) -> bool:
|
||||
|
||||
print("Required topics:", topics_required)
|
||||
print("Present topics:", topics_present)
|
||||
|
||||
for topic in topics_required:
|
||||
if topic not in topics_present:
|
||||
return False
|
||||
@ -358,9 +386,9 @@ class Migrator:
|
||||
labels=True, issues=True, pull_requests=True, releases=True, milestones=True, wiki=True
|
||||
)
|
||||
# TODO: These three lines represent feature request to giteapy authors
|
||||
migrate_body.auth_token = self.__source_token
|
||||
migrate_body.swagger_types["auth_token"] = "str"
|
||||
migrate_body.attribute_map["auth_token"] = "auth_token"
|
||||
#migrate_body.auth_token = self.__source_token
|
||||
#migrate_body.swagger_types["auth_token"] = "str"
|
||||
#migrate_body.attribute_map["auth_token"] = "auth_token"
|
||||
|
||||
self.__logger.debug("Migrate body:")
|
||||
self.__logger.debug(migrate_body)
|
||||
@ -416,7 +444,7 @@ class Migrator:
|
||||
|
||||
return source_repos_successful, source_repos_failed
|
||||
|
||||
def _delete_migrated_repos(self, source_org_name: str, repos: list[giteapy.Repository]):
|
||||
def _delete_migrated_repos(self, source_org_name: str, repos: list[gitea.Repository]):
|
||||
|
||||
if len(repos) == 0:
|
||||
self.__logger.warning(f"Cannot delete any migrated repos because none were successful!")
|
||||
|
Reference in New Issue
Block a user