+104
@@ -0,0 +1,104 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
import zipfile
|
||||
|
||||
|
||||
def filename(url):
|
||||
parsed = urllib.parse.urlparse(url)
|
||||
path = parsed.path
|
||||
filename = os.path.basename(path)
|
||||
|
||||
if not filename:
|
||||
raise ValueError("No filename found in URL")
|
||||
|
||||
return filename
|
||||
|
||||
|
||||
def download(url, output):
|
||||
subprocess.run(["curl", "-L", "-o", output, url], check=True)
|
||||
|
||||
|
||||
def tar_common_root(tar: tarfile.TarFile) -> str | None:
|
||||
root = None
|
||||
for member in tar.getmembers():
|
||||
this_root = member.path.split("/")[0]
|
||||
if root is None:
|
||||
root = this_root
|
||||
if this_root != root:
|
||||
return None
|
||||
return root
|
||||
|
||||
|
||||
def zip_common_root(zip_file: zipfile.ZipFile) -> str | None:
|
||||
members = zip_file.infolist()
|
||||
if not members:
|
||||
return None
|
||||
root = None
|
||||
for member in members:
|
||||
path = member.filename.replace('\\', '/').lstrip('./').lstrip('/')
|
||||
if not path:
|
||||
continue
|
||||
this_root = path.split('/')[0]
|
||||
if this_root in ('', '.', '..'):
|
||||
continue
|
||||
if root is None:
|
||||
root = this_root
|
||||
elif this_root != root:
|
||||
return None
|
||||
return root
|
||||
|
||||
|
||||
def sources_dir_name() -> str:
|
||||
with open("./target/sources.tag") as file:
|
||||
return file.read()
|
||||
|
||||
|
||||
def source_url(url: str):
|
||||
if os.path.exists("./target/sources.tag"):
|
||||
return
|
||||
download_path = f"./target/{filename(url)}"
|
||||
download(url, download_path)
|
||||
|
||||
if download_path.endswith(".zip"):
|
||||
with zipfile.ZipFile(download_path, "r") as zip:
|
||||
common_root = zip_common_root(zip)
|
||||
else:
|
||||
with tarfile.open(download_path, "r") as tar:
|
||||
common_root = tar_common_root(tar)
|
||||
|
||||
extract_dir = "./target"
|
||||
sources_dir = f"./target/{common_root}"
|
||||
if common_root in ["", ".", None]:
|
||||
extract_dir = "./target/sources"
|
||||
sources_dir = "./target/sources"
|
||||
|
||||
if download_path.endswith(".zip"):
|
||||
with zipfile.ZipFile(download_path, "r") as zip:
|
||||
zip.extractall(extract_dir)
|
||||
else:
|
||||
with tarfile.open(download_path, "r") as tar:
|
||||
tar.extractall(extract_dir)
|
||||
|
||||
with open("./target/sources.tag", "wt+") as file:
|
||||
file.write(sources_dir)
|
||||
|
||||
|
||||
def _git_repo_name(url: str) -> str:
|
||||
return url.split("/")[-1].replace(".git", "")
|
||||
|
||||
|
||||
def source_git(url: str, branch: str | None = None):
|
||||
source_path = os.getcwd() + "/target/" + _git_repo_name(url)
|
||||
if os.path.exists("./target/sources.tag"):
|
||||
return
|
||||
cmdline = ["git", "clone", "--depth=1"]
|
||||
if branch:
|
||||
cmdline += ["-b", branch]
|
||||
cmdline += [url, source_path]
|
||||
subprocess.run(cmdline, check=True)
|
||||
with open("./target/sources.tag", "wt+") as file:
|
||||
file.write(source_path)
|
||||
Reference in New Issue
Block a user