Files
Digpkg/dig/publish.py

91 lines
3.7 KiB
Python
Raw Normal View History

2026-01-18 21:26:23 +11:00
import tarfile
import tempfile
import os, sys
import requests
from requests.auth import HTTPBasicAuth
from rich.console import Console
from rich.prompt import Prompt
console = Console()
def publish(args):
if not "@" in args.name:
console.print(f"[b red]digpkg: failed to publish mineral: please include the version number in the package name. e.g: request@1.0.0")
sys.exit(1)
split_name = args.name.split("@")
mineral_name = split_name[0]
version = split_name[1]
# sanity checks
if not os.path.isdir(args.folder_path):
console.print(f"[b red]digpkg: failed to publish mineral: \"{args.folder_path}\" is not a directory")
sys.exit(1)
if not os.path.isfile(os.path.join(args.folder_path, "mineral.ini")):
console.print(f"[b red]digpkg: failed to publish mineral: mineral has no \"mineral.ini\" file")
sys.exit(1)
if os.path.basename(os.path.normpath(args.folder_path)).endswith("_build"):
console.print(f"\n[b yellow]You didn't remove the \"_build\" suffix from your mineral's folder name!\n\nIf this is intentional you can ignore this message, however it is bad practice.\nIf this is not intentional, you will be unable to install your package properly using dig.[/]")
2026-01-18 21:26:23 +11:00
# ask for user and pass
console.print("[b]Please authenticate.\n[/]")
try:
username = Prompt.ask("Username", console=console)
password = Prompt.ask("Password (or PAT)", console=console, password=True)
except KeyboardInterrupt:
return
console.print()
with console.status("Authenticating...", spinner="bouncingBall", spinner_style="blue") as status:
# check if we have permission to link the package to the repo
repo_perms_request = requests.get(
url=f"https://chookspace.com/api/v1/users/{username}/orgs/ground/permissions",
auth=HTTPBasicAuth(username, password)
)
if repo_perms_request.status_code == 401:
console.print(f"[b red]digpkg: failed to publish mineral: checking authorization failed: invalid password[/b red]")
sys.exit(1)
elif not repo_perms_request.ok:
console.print(f"[b red]digpkg: failed to publish mineral: checking authorization failed: {repo_perms_request.content.decode()}[/b red]")
sys.exit(1)
2026-01-18 21:26:23 +11:00
# compress to a tar file
2026-01-20 07:47:15 +11:00
console.status("Compressing", spinner_style="green")
2026-01-18 21:35:26 +11:00
f = tempfile.TemporaryFile(mode="wb+")
with tarfile.open(fileobj=f, mode="w:gz") as tar_file:
2026-01-18 21:26:23 +11:00
tar_file.add(args.folder_path, arcname=os.path.basename(args.folder_path))
2026-01-18 21:35:26 +11:00
f.flush()
f.seek(0)
2026-01-18 21:26:23 +11:00
2026-01-18 21:35:26 +11:00
console.print("[d][:white_check_mark:] Compressed![/]")
# send the request
2026-01-20 07:47:15 +11:00
status.update("Uploading...", spinner_style="blue")
2026-01-18 21:35:26 +11:00
response = requests.put(
url=f"https://chookspace.com/api/packages/ground/generic/{mineral_name}/{version}/mineral.tar",
2026-01-18 21:35:26 +11:00
data=f,
auth=HTTPBasicAuth(username, password)
)
f.close()
match response.status_code:
case 401:
console.print("[b red]digpkg: failed to publish mineral: authentication failed[/]")
sys.exit(1)
case 400:
console.print("[b red]digpkg: failed to publish mineral: the package name or version number are invalid[/]")
sys.exit(1)
case 409:
console.print("[b red]digpkg: failed to publish mineral: that version number is already in use[/]")
sys.exit(1)
2026-01-18 21:35:26 +11:00
response.raise_for_status()
console.print("[d][:white_check_mark:] Uploaded![/]")
2026-01-19 06:32:18 +11:00
console.print("[:white_check_mark:] Done!")