diff --git a/install_local.sh b/install_local.sh new file mode 100755 index 0000000..9937ce8 --- /dev/null +++ b/install_local.sh @@ -0,0 +1,14 @@ +#!/bin/bash +VENV_DIR="venv" + +if [ -d "$VENV_DIR" ]; then + source "$VENV_DIR/bin/activate" +else + python3 -m venv venv + source "$VENV_DIR/bin/activate" +fi + +pip install --upgrade pip +pip install -r requirements.txt +python setup.py sdist || { echo "setup.py failed!"; exit 1; } +pip install . || { echo "pip install failed!"; exit 1; } \ No newline at end of file diff --git a/neb/README.md b/neb/README.md new file mode 100644 index 0000000..b9302ef --- /dev/null +++ b/neb/README.md @@ -0,0 +1,19 @@ +# Nebula Package Manager +Nebula is the CLI package manager for the Comet Programming Language. + +The source code for Comet can be found here: https://chookspace.com/Comet/Comet +Or for Nebula: https://chookspace.com/Comet/Nebula + +There is also Github mirror of Comet if you would prefer that: https://github.com/SpookyDervish/Comet + +## Usage +### Installing a Package +To install a package type: +``` +neb install packageName +``` +Or if you wish to install a particular version: +``` +neb install packageName@1.0.0 +``` +(replace the number with the version number of the package you want to install) diff --git a/neb/__init__.py b/neb/__init__.py new file mode 100644 index 0000000..152be6b --- /dev/null +++ b/neb/__init__.py @@ -0,0 +1 @@ +from .src.main import main \ No newline at end of file diff --git a/neb/src/__init__.py b/neb/src/__init__.py new file mode 100644 index 0000000..b668da9 --- /dev/null +++ b/neb/src/__init__.py @@ -0,0 +1 @@ +from .main import main \ No newline at end of file diff --git a/neb/src/console.py b/neb/src/console.py new file mode 100644 index 0000000..310e797 --- /dev/null +++ b/neb/src/console.py @@ -0,0 +1,7 @@ +from rich.console import Console + +console = Console() + + +def print_error_message(message: str) -> None: + console.print(f"[bold red]error:[/] {message}") \ No newline at end of file diff --git a/neb/src/install.py b/neb/src/install.py new file mode 100644 index 0000000..f436c71 --- /dev/null +++ b/neb/src/install.py @@ -0,0 +1,25 @@ +from .console import print_error_message +from .util import ensure_libs_env, comet_dir, get_package_index + +import os + + +def install(args): + ensure_libs_env() + + # install each package in given list + for name in args.names: + version = "latest" + + # get version number + name: str = name + if '@' in name: + version: str = (name.rsplit('@', 1)[-1]) + name = name.rpartition('@')[0] + + if version == "": + print_error_message("did not provide version") + return + + index = get_package_index() + print(index) \ No newline at end of file diff --git a/src/main.py b/neb/src/main.py similarity index 85% rename from src/main.py rename to neb/src/main.py index 92cbf7e..42a57a0 100644 --- a/src/main.py +++ b/neb/src/main.py @@ -1,5 +1,8 @@ import argparse import sys +import os + +from .install import install __VERSION__ = "1.0.0" @@ -20,10 +23,15 @@ def main() -> int: args = arg_parser.parse_args() + # do different things based on args if not args.cmd: arg_parser.print_help() return 0 + match args.cmd: + case "install": + install(args) + # really feeling like a C programmer lmao return 0 diff --git a/neb/src/util.py b/neb/src/util.py new file mode 100644 index 0000000..ad06e5b --- /dev/null +++ b/neb/src/util.py @@ -0,0 +1,98 @@ +import os +import sys +import subprocess +import tempfile +import requests +import json +from pathlib import Path +from .console import console, print_error_message +from rich.prompt import Confirm + + +def comet_dir() -> str: + comet_dir_path = Path.home() / ".comet" + comet_dir_path.mkdir(parents=True, exist_ok=True) + return str(comet_dir_path) + +def get_needed_headers() -> bool: + should_continue: bool = Confirm.ask("The headers needed to install Comet libs were not found. Install them? (answering no will cancel installation): ") + if not should_continue: + return False + + with console.status("Cloning git repo...") as status: + with tempfile.TemporaryDirectory() as temp_dir: + repo_url = "https://chookspace.com/Comet/Comet" + result = subprocess.run(["git", "clone", repo_url, temp_dir], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if result.returncode != 0: + print_error_message(f"failed to get the Comet repository: {result.stderr.decode()}") + + console.print("[d][:white_check_mark:] Cloned repo.[/]") + + os.chdir(temp_dir) + + status.update("Building Comet...") + result = subprocess.run(["make"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if result.returncode != 0: + print_error_message(f"failed to build Comet: {result.stderr.decode()}") + console.print("[d][:white_check_mark:] Built Comet.[/]") + + status.update("Installing...") + status.stop() + console.print("You will need to type your admin password: ") + result = subprocess.run(["sudo", "make", "install"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if result.returncode != 0: + print_error_message(f"failed to install: {result.stderr.decode()}") + + console.print("[d][:white_check_mark:] Installed headers.[/]") + console.print("[b][green]Comet headers are installed![/green] [:white_check_mark:][/b]\n") + +def get_package_index() -> dict: + if not os.path.isfile(os.path.join(comet_dir(), "package_index.json")): + package_data = requests.get("https://chookspace.com/Comet/Nebula/raw/branch/main/package_index.json") + if not package_data.ok: + print_error_message(f"Failed to download package index: {package_data.reason}") + sys.exit(1) + + return package_data.json() + + with open(os.path.join(comet_dir(), "package_index.json"), "r") as f: + package_data = json.load(f) + + return package_data + +def ensure_includes_exist() -> list[str]: + # create a test C file + with tempfile.NamedTemporaryFile(mode="w", suffix=".c", delete=False) as f: + + f.write(""" + #include + + int main() { + return 0; + } + """) + + temp_file_name = f.name + + + + result = subprocess.run( + ["gcc", temp_file_name, "-fsyntax-only"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + + if os.path.exists(temp_file_name): + os.remove(temp_file_name) + + if result.returncode != 0: + return get_needed_headers() + + return True + +def ensure_libs_env() -> None: + if not os.getenv("COMET_LIBS"): + os.environ["COMET_LIBS"] = "/usr/lib/comet" + + if not ensure_includes_exist(): + exit(0) \ No newline at end of file diff --git a/publish.sh b/publish.sh new file mode 100755 index 0000000..5f3ba8a --- /dev/null +++ b/publish.sh @@ -0,0 +1,15 @@ +#!/bin/bash +VENV_DIR="venv" + +if [ -d "$VENV_DIR" ]; then + source "$VENV_DIR/bin/activate" +else + python3 -m venv venv + source "$VENV_DIR/bin/activate" +fi + +pip install --upgrade pip +pip install -r requirements.txt +python setup.py || { echo "setup.py failed!"; exit 1; } + +twine check dist/* || { echo "twine check failed!"; exit 1; } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8d01bb9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +rich +setuptools +wheel +twine \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..3e812da --- /dev/null +++ b/setup.py @@ -0,0 +1,34 @@ +from setuptools import setup, find_packages + +with open("neb/README.md", "r") as f: + long_description = f.read() + +setup( + name="nebpkg", + version="1.0", + description="Nebula, the package manager for the Comet programming language.", + classifiers=[ + "Development Status :: 4 - Beta", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Natural Language :: English", + "Operating System :: POSIX", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development :: Compilers", + "Topic :: Software Development :: Libraries", + ], + author="Nathaniel Chandler", + license="GPLv3", + long_description=long_description, + packages=find_packages(), + install_requires=[ + "rich>=15.0.0", + "requests>=2.34.2" + ], + entry_points={ + "console_scripts": [ + "neb = neb:main" + ] + } +) \ No newline at end of file