make install use tarballs and releases

This commit is contained in:
2026-06-20 17:09:35 +10:00
parent e6a7184c4a
commit dbd879c149
7 changed files with 93 additions and 20 deletions

View File

@@ -19,6 +19,10 @@ neb install packageName@1.0.0
(replace the number with the version number of the package you want to install) (replace the number with the version number of the package you want to install)
## Changelog ## Changelog
### 1.1.0
- Switched from getting the latest commit of packages to getting the latest release
- Added the `uninstall` subcommand
### 1.0.1 ### 1.0.1
- Fix long description hopefully - Fix long description hopefully

View File

@@ -3,11 +3,14 @@ from .util import libs_dir, comet_dir, get_package_index
import tempfile import tempfile
import subprocess import subprocess
import requests
import os import os
import sys import sys
import json import json
import shutil import shutil
import glob import glob
import io
import tarfile
def install(args): def install(args):
@@ -38,12 +41,41 @@ def install(args):
status.update(f"Downloading [b]{name}[/]...", spinner="moon") status.update(f"Downloading [b]{name}[/]...", spinner="moon")
with tempfile.TemporaryDirectory() as temp_dir: with tempfile.TemporaryDirectory() as temp_dir:
os.chdir(temp_dir) os.chdir(temp_dir)
result = subprocess.run(["git", "clone", package["repository"], temp_dir], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL)
if result.returncode != 0:
print_error_message(f"Failed to download \"{name}\": \"{result.stderr.decode()}\"")
sys.exit(1)
console.log(f"[d][:white_check_mark:] Downloaded {name}.[/]") result: requests.Response = None
if version == "latest":
result = requests.get(f"https://chookspace.com/api/v1/repos/{package["gitAuthor"]}/{name}/releases/latest")
else:
result = requests.get(f"https://chookspace.com/api/v1/repos/{package["gitAuthor"]}/{name}/releases/tags/{version}")
if result.status_code == 404:
print_error_message(f"That version was not found for the rock \"{name}\". Check that the version number is correct and that your index isn't out of date.")
sys.exit(1)
elif not result.ok:
print_error_message(f"Failed to download \"{name}\": \"{result.reason}\"")
sys.exit(1)
status.update("Pulling tarball...")
tar_file_data = requests.get(result.json()["tarball_url"])
tar_file_data.raise_for_status()
console.log(f"[d][:white_check_mark:] Downloaded tarball for {name}.[/]")
tar_file_io = io.BytesIO(tar_file_data.content)
status.update("Extracting...")
with tarfile.open(fileobj=tar_file_io, mode="r:gz") as tar:
# extract all in the root dir
members = []
for member in tar.getmembers():
if '/' in member.name and member.name != "/":
member.name = member.name.split("/", 1)[1]
if member.name:
members.append(member)
tar.extractall(path=temp_dir, members=members, filter="data")
console.log(f"[d][:white_check_mark:] Extracted tarball for {name}.[/]")
status.update(f"Installing [b]{name}[/]...") status.update(f"Installing [b]{name}[/]...")
rock_file = os.path.join(temp_dir, "rock.json") rock_file = os.path.join(temp_dir, "rock.json")
@@ -85,13 +117,13 @@ def install(args):
# this feels really fragile but who caresssss.... # this feels really fragile but who caresssss....
lib_data_path = os.path.join(data_path, name) lib_data_path = os.path.join(data_path, name)
if not os.path.isdir(lib_data_path): if not os.path.isdir(lib_data_path):
subprocess.run(["mkdir", "-p", lib_data_path], check=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) os.makedirs(lib_data_path, exist_ok=True)
subprocess.run(["cp", os.path.join(temp_dir, "rock.json"), os.path.join(lib_data_path, "rock.json")], check=True) shutil.copy(os.path.join(temp_dir, "rock.json"), os.path.join(lib_data_path, "rock.json"))
docs_path = os.path.join(temp_dir, "docs/") docs_path = os.path.join(temp_dir, "docs/")
if os.path.isdir(docs_path): if os.path.isdir(docs_path):
subprocess.run(["cp", "-R", docs_path, os.path.join(lib_data_path, "docs/")], check=True) shutil.copytree(docs_path, os.path.join(lib_data_path, "docs/"))
console.log(f"[d][:white_check_mark:] Copied data for {name}.[/]") console.log(f"[d][:white_check_mark:] Copied data for {name}.[/]")

View File

@@ -1,5 +1,5 @@
from .console import console from .console import console
from .util import libs_dir from .util import installed_libs, data_dir
from rich.box import ROUNDED from rich.box import ROUNDED
from rich.table import Table from rich.table import Table
@@ -9,13 +9,17 @@ import os
def list_packages(args) -> None: def list_packages(args) -> None:
data_path = data_dir()
installed = installed_libs()
if len(installed) == 0:
console.print("No rocks are installed.")
return
packages_table = Table("Name", "Version", "Description", "Author", box=ROUNDED, header_style="bold blue", ) packages_table = Table("Name", "Version", "Description", "Author", box=ROUNDED, header_style="bold blue", )
data_dir = os.path.join(libs_dir(), "lib_data/") for name in installed:
libs = os.listdir(data_dir) lib_data_dir = os.path.join(data_path, name)
for name in libs:
lib_data_dir = os.path.join(data_dir, name)
rock_file = os.path.join(lib_data_dir, "rock.json") rock_file = os.path.join(lib_data_dir, "rock.json")
json_data = {} json_data = {}

View File

@@ -5,16 +5,14 @@ import os
from .install import install from .install import install
from .pull import pull from .pull import pull
from .list import list_packages from .list import list_packages
from .uninstall import uninstall
__VERSION__ = "1.0.1"
def main() -> int: def main() -> int:
# parse cli args # parse cli args
arg_parser = argparse.ArgumentParser( arg_parser = argparse.ArgumentParser(
prog="neb", prog="neb",
description="Nebula, the package manager for the Comet programming language.", description="Nebula, the package manager for the Comet programming language."
epilog="Version " + __VERSION__
) )
sub_parsers = arg_parser.add_subparsers(dest="cmd") sub_parsers = arg_parser.add_subparsers(dest="cmd")
@@ -28,6 +26,10 @@ def main() -> int:
# list command # list command
list_cmd = sub_parsers.add_parser(name="list", description="list installed rocks") list_cmd = sub_parsers.add_parser(name="list", description="list installed rocks")
# uninstall command
uninstall_cmd = sub_parsers.add_parser(name="uninstall", description="uninstall an installed rock(s)")
uninstall_cmd.add_argument("names", help="name of the rocks to uninstall", nargs="+")
args = arg_parser.parse_args() args = arg_parser.parse_args()
@@ -43,6 +45,8 @@ def main() -> int:
pull(args) pull(args)
case "list": case "list":
list_packages(args) list_packages(args)
case "uninstall":
uninstall(args)
# really feeling like a C programmer lmao # really feeling like a C programmer lmao
return 0 return 0

23
neb/src/uninstall.py Normal file
View File

@@ -0,0 +1,23 @@
from .util import installed_libs, libs_dir, data_dir
from .console import print_error_message, console
import sys
import shutil
import os
def uninstall(args):
installed = installed_libs()
libs_path = libs_dir()
for name in args.names:
if name not in installed:
print_error_message(f"No rock with the name \"{name}\" is installed.")
sys.exit(1)
actual_lib = os.path.join(libs_path, f"{name}.cometlib")
if os.path.isfile(actual_lib):
os.remove(actual_lib)
shutil.rmtree(os.path.join(data_dir(), name))
console.log(f"[b][:white_check_mark:] Uninstalled [green]{name}[/green]![/b]")

View File

@@ -47,6 +47,13 @@ def get_needed_headers() -> bool:
console.log("[b][:white_check_mark:] Comet headers are installed![/b]\n") console.log("[b][:white_check_mark:] Comet headers are installed![/b]\n")
return True return True
def data_dir() -> str:
return os.path.join(libs_dir(), "lib_data/")
def installed_libs() -> list:
libs = os.listdir(data_dir())
return libs
def update_package_index() -> dict: def update_package_index() -> dict:
with console.status("Downloading package index...", spinner="moon") as status: with console.status("Downloading package index...", spinner="moon") as status:

View File

@@ -1,12 +1,11 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
from neb.src.main import __VERSION__
with open("neb/README.md", "r") as f: with open("neb/README.md", "r") as f:
long_description = f.read() long_description = f.read()
setup( setup(
name="nebpkg", name="nebpkg",
version=__VERSION__, version="1.1.0",
description="Nebula, the package manager for the Comet programming language.", description="Nebula, the package manager for the Comet programming language.",
classifiers=[ classifiers=[
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",