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)
## Changelog
### 1.1.0
- Switched from getting the latest commit of packages to getting the latest release
- Added the `uninstall` subcommand
### 1.0.1
- Fix long description hopefully

View File

@@ -3,11 +3,14 @@ from .util import libs_dir, comet_dir, get_package_index
import tempfile
import subprocess
import requests
import os
import sys
import json
import shutil
import glob
import io
import tarfile
def install(args):
@@ -38,12 +41,41 @@ def install(args):
status.update(f"Downloading [b]{name}[/]...", spinner="moon")
with tempfile.TemporaryDirectory() as 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()}\"")
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)
console.log(f"[d][:white_check_mark:] Downloaded {name}.[/]")
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}[/]...")
rock_file = os.path.join(temp_dir, "rock.json")
@@ -85,13 +117,13 @@ def install(args):
# this feels really fragile but who caresssss....
lib_data_path = os.path.join(data_path, name)
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/")
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}.[/]")

View File

@@ -1,5 +1,5 @@
from .console import console
from .util import libs_dir
from .util import installed_libs, data_dir
from rich.box import ROUNDED
from rich.table import Table
@@ -9,13 +9,17 @@ import os
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", )
data_dir = os.path.join(libs_dir(), "lib_data/")
libs = os.listdir(data_dir)
for name in libs:
lib_data_dir = os.path.join(data_dir, name)
for name in installed:
lib_data_dir = os.path.join(data_path, name)
rock_file = os.path.join(lib_data_dir, "rock.json")
json_data = {}

View File

@@ -5,16 +5,14 @@ import os
from .install import install
from .pull import pull
from .list import list_packages
__VERSION__ = "1.0.1"
from .uninstall import uninstall
def main() -> int:
# parse cli args
arg_parser = argparse.ArgumentParser(
prog="neb",
description="Nebula, the package manager for the Comet programming language.",
epilog="Version " + __VERSION__
description="Nebula, the package manager for the Comet programming language."
)
sub_parsers = arg_parser.add_subparsers(dest="cmd")
@@ -29,6 +27,10 @@ def main() -> int:
# list command
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()
# do different things based on args
@@ -43,6 +45,8 @@ def main() -> int:
pull(args)
case "list":
list_packages(args)
case "uninstall":
uninstall(args)
# really feeling like a C programmer lmao
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

@@ -48,6 +48,13 @@ def get_needed_headers() -> bool:
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:
with console.status("Downloading package index...", spinner="moon") as status:
package_data = requests.get("https://chookspace.com/Comet/Nebula/raw/branch/main/package_index.json")

View File

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