meta: Renamed osdk -> cutekit + improved logging + better error handling.

This commit is contained in:
Sleepy Monax 2023-05-28 11:28:52 +02:00
parent f03051df7e
commit 004a5f4518
25 changed files with 283 additions and 154 deletions

View file

@ -17,7 +17,6 @@ permissions:
jobs:
deploy:
runs-on: ubuntu-latest
steps:

View file

@ -1,30 +1,39 @@
# osdk
The operating system development kit
<br/>
<br/>
<br/>
<p align="center">
<img src="logo.png" width="200" height="200">
</p>
<h1 align="center">CuteKit</h1>
<p align="center">
The Cute build system and package manager
</p>
<br/>
<br/>
<br/>
## Table of contents
- [osdk](#osdk)
- [Table of contents](#table-of-contents)
- [Macros](#macros)
- [`@latest`](#latest)
- [`@uname`](#uname)
- [`@include`](#include)
- [`@join`](#join)
- [`@concat`](#concat)
- [`@exec`](#exec)
- [Manifest file format](#manifest-file-format)
- [`id`](#id)
- [`type`](#type)
- [`description`](#description)
- [`enabledIf`](#enabledif)
- [`requires`](#requires)
- [`provides`](#provides)
- [Target file format](#target-file-format)
- [`id`](#id-1)
- [`type`](#type-1)
- [`props`](#props)
- [`tools`](#tools)
- [Table of contents](#table-of-contents)
- [Macros](#macros)
- [`@latest`](#latest)
- [`@uname`](#uname)
- [`@include`](#include)
- [`@join`](#join)
- [`@concat`](#concat)
- [`@exec`](#exec)
- [Manifest file format](#manifest-file-format)
- [`id`](#id)
- [`type`](#type)
- [`description`](#description)
- [`enabledIf`](#enabledif)
- [`requires`](#requires)
- [`provides`](#provides)
- [Target file format](#target-file-format)
- [`id`](#id-1)
- [`type`](#type-1)
- [`props`](#props)
- [`tools`](#tools)
## Macros
@ -197,7 +206,7 @@ Exemple:
}
```
Theses values are exposed the translation unit as `__osdk_{prop}__`.
Theses values are exposed the translation unit as `__ck_{prop}__`.
### `tools`

50
cutekit/__init__.py Normal file
View file

@ -0,0 +1,50 @@
import sys
import os
import logging
from cutekit import const, project, vt100, plugins, cmds
from cutekit.args import parse
def setupLogger(verbose: bool):
if verbose:
logging.basicConfig(
level=logging.INFO,
format=f"{vt100.CYAN}%(asctime)s{vt100.RESET} {vt100.YELLOW}%(levelname)s{vt100.RESET} %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
else:
projectRoot = project.root()
logFile = const.GLOBAL_LOG_FILE
if projectRoot is not None:
logFile = os.path.join(projectRoot, const.PROJECT_LOG_FILE)
# create the directory if it doesn't exist
logDir = os.path.dirname(logFile)
if not os.path.isdir(logDir):
os.makedirs(logDir)
logging.basicConfig(
level=logging.INFO,
filename=logFile,
filemode="w",
format=f"%(asctime)s %(levelname)s %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
def main() -> int:
try:
a = parse(sys.argv[1:])
setupLogger(a.consumeOpt("verbose", False) == True)
plugins.loadAll()
cmds.exec(a)
print()
return 0
except RuntimeError as e:
logging.exception(e)
cmds.error(str(e))
cmds.usage()
print()
return 1
except KeyboardInterrupt:
print()
return 1

View file

@ -2,10 +2,10 @@ import os
import logging
from typing import TextIO
from osdk.model import Props
from osdk.ninja import Writer
from osdk.context import ComponentInstance, Context, contextFor
from osdk import shell, rules
from cutekit.model import Props
from cutekit.ninja import Writer
from cutekit.context import ComponentInstance, Context, contextFor
from cutekit import shell, rules
logger = logging.getLogger(__name__)
@ -54,7 +54,7 @@ def gen(out: TextIO, context: Context):
for obj in objects:
r = rules.byFileIn(obj[0])
if r is None:
raise Exception(f"Unknown rule for file {obj[0]}")
raise RuntimeError(f"Unknown rule for file {obj[0]}")
t = target.tools[r.id]
writer.build(obj[1], r.id, obj[0], order_only=t.files)
@ -73,10 +73,10 @@ def gen(out: TextIO, context: Context):
reqInstance = context.componentByName(req)
if reqInstance is None:
raise Exception(f"Component {req} not found")
raise RuntimeError(f"Component {req} not found")
if not reqInstance.isLib():
raise Exception(f"Component {req} is not a library")
raise RuntimeError(f"Component {req} is not a library")
libraries.append(reqInstance.outfile())
@ -105,10 +105,10 @@ def build(componentSpec: str, targetSpec: str, props: Props = {}) -> ComponentIn
instance = context.componentByName(componentSpec)
if instance is None:
raise Exception(f"Component {componentSpec} not found")
raise RuntimeError(f"Component {componentSpec} not found")
if not instance.enabled:
raise Exception(
raise RuntimeError(
f"Component {componentSpec} is disabled: {instance.disableReason}")
shell.exec(f"ninja", "-v", "-f", ninjaPath, instance.outfile())

View file

@ -3,17 +3,19 @@ import json
import logging
import tempfile
import requests
import sys
from typing import Callable, cast
from osdk import context, shell, const, vt100, builder, graph
from osdk.args import Args
from osdk.context import contextFor
from cutekit import context, shell, const, vt100, builder, graph, project
from cutekit.args import Args
from cutekit.context import contextFor
Callback = Callable[[Args], None]
logger = logging.getLogger(__name__)
class Cmd:
shortName: str | None
longName: str
@ -38,19 +40,21 @@ def append(cmd: Cmd):
def runCmd(args: Args):
project.chdir()
targetSpec = cast(str, args.consumeOpt(
"target", "host-" + shell.uname().machine))
componentSpec = args.consumeArg()
if componentSpec is None:
raise Exception("Component not specified")
raise RuntimeError("Component not specified")
component = builder.build(componentSpec, targetSpec)
os.environ["OSDK_TARGET"] = component.context.target.id
os.environ["OSDK_COMPONENT"] = component.id()
os.environ["OSDK_BUILDDIR"] = component.context.builddir()
os.environ["CK_TARGET"] = component.context.target.id
os.environ["CK_COMPONENT"] = component.id()
os.environ["CK_BUILDDIR"] = component.context.builddir()
shell.exec(component.outfile(), *args.args)
@ -59,6 +63,8 @@ cmds += [Cmd("r", "run", "Run the target", runCmd)]
def testCmd(args: Args):
project.chdir()
targetSpec = cast(str, args.consumeOpt(
"target", "host-" + shell.uname().machine))
builder.testAll(targetSpec)
@ -68,19 +74,21 @@ cmds += [Cmd("t", "test", "Run all test targets", testCmd)]
def debugCmd(args: Args):
project.chdir()
targetSpec = cast(str, args.consumeOpt(
"target", "host-" + shell.uname().machine))
componentSpec = args.consumeArg()
if componentSpec is None:
raise Exception("Component not specified")
raise RuntimeError("Component not specified")
component = builder.build(componentSpec, targetSpec)
os.environ["OSDK_TARGET"] = component.context.target.id
os.environ["OSDK_COMPONENT"] = component.id()
os.environ["OSDK_BUILDDIR"] = component.context.builddir()
os.environ["CK_TARGET"] = component.context.target.id
os.environ["CK_COMPONENT"] = component.id()
os.environ["CK_BUILDDIR"] = component.context.builddir()
shell.exec("lldb", "-o", "run", component.outfile(), *args.args)
@ -89,6 +97,8 @@ cmds += [Cmd("d", "debug", "Debug the target", debugCmd)]
def buildCmd(args: Args):
project.chdir()
targetSpec = cast(str, args.consumeOpt(
"target", "host-" + shell.uname().machine))
@ -104,6 +114,8 @@ cmds += [Cmd("b", "build", "Build the target", buildCmd)]
def listCmd(args: Args):
project.chdir()
components = context.loadAllComponents()
targets = context.loadAllTargets()
@ -129,6 +141,7 @@ cmds += [Cmd("l", "list", "List the targets", listCmd)]
def cleanCmd(args: Args):
project.chdir()
shell.rmrf(const.BUILD_DIR)
@ -136,7 +149,8 @@ cmds += [Cmd("c", "clean", "Clean the build directory", cleanCmd)]
def nukeCmd(args: Args):
shell.rmrf(const.OSDK_DIR)
project.chdir()
shell.rmrf(const.PROJECT_CK_DIR)
cmds += [Cmd("n", "nuke", "Clean the build directory and cache", nukeCmd)]
@ -148,7 +162,7 @@ def helpCmd(args: Args):
print()
vt100.title("Description")
print(" Operating System Development Kit.")
print(f" {const.DESCRIPTION}")
print()
vt100.title("Commands")
@ -161,19 +175,25 @@ def helpCmd(args: Args):
f" {vt100.GREEN}{cmd.shortName or ' '}{vt100.RESET} {cmd.longName} - {cmd.helpText} {pluginText}")
print()
vt100.title("Logging")
print(f" Logs are stored in:")
print(f" - {const.PROJECT_LOG_FILE}")
print(f" - {const.GLOBAL_LOG_FILE}")
cmds += [Cmd("h", "help", "Show this help message", helpCmd)]
def versionCmd(args: Args):
print(f"OSDK v{const.VERSION}\n")
print(f"CuteKit v{const.VERSION_STR}\n")
cmds += [Cmd("v", "version", "Show current version", versionCmd)]
def graphCmd(args: Args):
project.chdir()
targetSpec = cast(str, args.consumeOpt(
"target", "host-" + shell.uname().machine))
@ -191,10 +211,12 @@ cmds += [Cmd("g", "graph", "Show dependency graph", graphCmd)]
def installCmd(args: Args):
project = context.loadProject(".")
project.chdir()
for extSpec in project.extern:
ext = project.extern[extSpec]
pj = context.loadProject(".")
for extSpec in pj.extern:
ext = pj.extern[extSpec]
extPath = os.path.join(const.EXTERN_DIR, extSpec)
@ -212,41 +234,54 @@ cmds += [Cmd("i", "install", "Install all the external packages", installCmd)]
def initCmd(args: Args):
template = args.consumeArg()
if template is None:
template = "default"
repo = const.DEFAULT_REPO_TEMPLATES if not "repo" in args.opts else args.opts["repo"]
list = "list" in args.opts
if list:
logger.info("Fetching registry...")
r = requests.get(f'https://raw.githubusercontent.com/{repo}/main/registry.json')
r = requests.get(
f'https://raw.githubusercontent.com/{repo}/main/registry.json')
if r.status_code != 200:
logger.error('Failed to fetch registry')
exit(1)
print('\n'.join(f"* {entry['id']} - {entry['description']}" for entry in json.loads(r.text)))
print('\n'.join(
f"* {entry['id']} - {entry['description']}" for entry in json.loads(r.text)))
else:
with tempfile.TemporaryDirectory() as tmp:
shell.exec(*["git", "clone", "-n", "--depth=1", "--filter=tree:0", f"https://github.com/{repo}", os.path.join(tmp, "osdk-repo"), "-q"])
shell.exec(*["git", "-C", os.path.join(tmp, "osdk-repo"), "sparse-checkout", "set", "--no-cone", template, "-q"])
shell.exec(*["git", "-C", os.path.join(tmp, "osdk-repo"), "checkout", "-q"])
shell.mv(os.path.join(tmp, "osdk-repo", template), os.path.join(".", template))
shell.exec(*["git", "clone", "-n", "--depth=1",
"--filter=tree:0", f"https://github.com/{repo}", tmp, "-q"])
shell.exec(*["git", "-C", tmp, "sparse-checkout",
"set", "--no-cone", template, "-q"])
shell.exec(*["git", "-C", tmp, "checkout", "-q"])
shell.mv(os.path.join(tmp, template), os.path.join(".", template))
cmds += [Cmd("I", "init", "Start a new project", initCmd)]
cmds += [Cmd("I", "init", "Initialize a new project", initCmd)]
def usage():
print(f"Usage: {const.ARGV0} <command> [args...]")
def error(msg: str) -> None:
print(f"{vt100.RED}Error:{vt100.RESET} {msg}\n", file=sys.stderr)
def exec(args: Args):
cmd = args.consumeArg()
if cmd is None:
raise Exception("No command specified")
raise RuntimeError("No command specified")
for c in cmds:
if c.shortName == cmd or c.longName == cmd:
c.callback(args)
return
raise Exception(f"Unknown command {cmd}")
raise RuntimeError(f"Unknown command {cmd}")

33
cutekit/compat.py Normal file
View file

@ -0,0 +1,33 @@
from typing import Any
SUPPORTED_MANIFEST = [
"https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"https://schemas.cute.engineering/stable/cutekit.manifest.project.v1",
"https://schemas.cute.engineering/stable/cutekit.manifest.target.v1",
]
OSDK_MANIFEST_NOT_SUPPORTED = "OSDK manifests are not supported by CuteKit. Please use CuteKit manifest instead"
UNSUPORTED_MANIFEST = {
"https://schemas.cute.engineering/stable/osdk.manifest.component.v1": OSDK_MANIFEST_NOT_SUPPORTED,
"https://schemas.cute.engineering/stable/osdk.manifest.project.v1": OSDK_MANIFEST_NOT_SUPPORTED,
"https://schemas.cute.engineering/stable/osdk.manifest.target.v1": OSDK_MANIFEST_NOT_SUPPORTED,
"https://schemas.cute.engineering/latest/osdk.manifest.component": OSDK_MANIFEST_NOT_SUPPORTED,
"https://schemas.cute.engineering/latest/osdk.manifest.project": OSDK_MANIFEST_NOT_SUPPORTED,
"https://schemas.cute.engineering/latest/osdk.manifest.target": OSDK_MANIFEST_NOT_SUPPORTED,
}
def ensureSupportedManifest(manifest: Any, path: str):
if not "$schema" in manifest:
raise RuntimeError(f"Missing $schema in {path}")
if manifest["$schema"] in UNSUPORTED_MANIFEST:
raise RuntimeError(
f"Unsupported manifest schema {manifest['$schema']} in {path}: {UNSUPORTED_MANIFEST[manifest['$schema']]}")
if not manifest["$schema"] in SUPPORTED_MANIFEST:
raise RuntimeError(
f"Unsupported manifest schema {manifest['$schema']} in {path}")

19
cutekit/const.py Normal file
View file

@ -0,0 +1,19 @@
import os
import sys
VERSION = (0, 5, 0, "dev")
VERSION_STR = f"{VERSION[0]}.{VERSION[1]}.{VERSION[2]}{'-' + VERSION[3] if VERSION[3] else ''}"
MODULE_DIR = os.path.dirname(os.path.realpath(__file__))
ARGV0 = os.path.basename(sys.argv[0])
PROJECT_CK_DIR = ".cutekit"
GLOBAL_CK_DIR = os.path.join(os.path.expanduser("~"), ".cutekit")
BUILD_DIR = os.path.join(PROJECT_CK_DIR, "build")
CACHE_DIR = os.path.join(PROJECT_CK_DIR, "cache")
EXTERN_DIR = os.path.join(PROJECT_CK_DIR, "extern")
SRC_DIR = "src"
META_DIR = f"meta"
TARGETS_DIR = os.path.join(META_DIR, "targets")
DEFAULT_REPO_TEMPLATES = "cute-engineering/cutekit-templates"
DESCRIPTION = "A build system and package manager for low-level software development"
PROJECT_LOG_FILE = os.path.join(PROJECT_CK_DIR, "cutekit.log")
GLOBAL_LOG_FILE = os.path.join(os.path.expanduser("~"), ".cutekit", "cutekit.log")

View file

@ -4,8 +4,8 @@ from pathlib import Path
import os
import logging
from osdk.model import ProjectManifest, TargetManifest, ComponentManifest, Props, Type, Tool, Tools
from osdk import const, shell, jexpr, utils, rules, mixins
from cutekit.model import ProjectManifest, TargetManifest, ComponentManifest, Props, Type, Tool, Tools
from cutekit import const, shell, jexpr, utils, rules, mixins
logger = logging.getLogger(__name__)
@ -131,7 +131,7 @@ def loadTarget(id: str) -> TargetManifest:
try:
return next(filter(lambda t: t.id == id, loadAllTargets()))
except StopIteration:
raise Exception(f"Target '{id}' not found")
raise RuntimeError(f"Target '{id}' not found")
def loadAllComponents() -> list[ComponentManifest]:
@ -181,7 +181,7 @@ def resolveDeps(componentSpec: str, components: list[ComponentManifest], target:
return False, unresolvedReason, []
if resolved in stack:
raise Exception(f"Dependency loop: {stack} -> {resolved}")
raise RuntimeError(f"Dependency loop: {stack} -> {resolved}")
stack.append(resolved)

View file

@ -1,7 +1,7 @@
import os
from osdk.context import Context
from osdk import vt100
from cutekit.context import Context
from cutekit import vt100
def view(context: Context, scope: str | None = None, showExe: bool = True, showDisabled: bool = False):

View file

@ -1,7 +1,8 @@
from typing import Any, cast, Callable, Final
import json
import osdk.shell as shell
import cutekit.shell as shell
from cutekit.compat import ensureSupportedManifest
Json = Any
Builtin = Callable[..., Json]
@ -32,7 +33,7 @@ def eval(jexpr: Json) -> Json:
if funcName in BUILTINS:
return BUILTINS[funcName](*eval(jexpr[1:]))
raise Exception(f"Unknown macro {funcName}")
raise RuntimeError(f"Unknown macro {funcName}")
else:
return list(map(eval, jexpr))
else:
@ -44,8 +45,10 @@ def read(path: str) -> Json:
with open(path, "r") as f:
return json.load(f)
except:
raise Exception(f"Failed to read {path}")
raise RuntimeError(f"Failed to read {path}")
def evalRead(path: str) -> Json:
return eval(read(path))
data = read(path)
ensureSupportedManifest(data, path)
return eval(data)

View file

@ -1,5 +1,5 @@
from typing import Callable
from osdk.model import TargetManifest, Tools
from cutekit.model import TargetManifest, Tools
Mixin = Callable[[TargetManifest, Tools], Tools]

View file

@ -3,7 +3,7 @@ from enum import Enum
from typing import Any
import logging
from osdk.jexpr import Json
from cutekit.jexpr import Json
logger = logging.getLogger(__name__)
@ -27,18 +27,18 @@ class Manifest:
def __init__(self, json: Json = None, path: str = "", strict: bool = True, **kwargs: Any):
if json is not None:
if not "id" in json:
raise ValueError("Missing id")
raise RuntimeError("Missing id")
self.id = json["id"]
if not "type" in json and strict:
raise ValueError("Missing type")
raise RuntimeError("Missing type")
self.type = Type(json["type"])
self.path = path
elif strict:
raise ValueError("Missing json")
raise RuntimeError("Missing json")
for key in kwargs:
setattr(self, key, kwargs[key])
@ -67,16 +67,16 @@ class Extern:
def __init__(self, json: Json = None, strict: bool = True, **kwargs: Any):
if json is not None:
if not "git" in json and strict:
raise ValueError("Missing git")
raise RuntimeError("Missing git")
self.git = json["git"]
if not "tag" in json and strict:
raise ValueError("Missing tag")
raise RuntimeError("Missing tag")
self.tag = json["tag"]
elif strict:
raise ValueError("Missing json")
raise RuntimeError("Missing json")
for key in kwargs:
setattr(self, key, kwargs[key])
@ -101,14 +101,14 @@ class ProjectManifest(Manifest):
def __init__(self, json: Json = None, path: str = "", strict: bool = True, **kwargs: Any):
if json is not None:
if not "description" in json and strict:
raise ValueError("Missing description")
raise RuntimeError("Missing description")
self.description = json["description"]
self.extern = {k: Extern(v)
for k, v in json.get("extern", {}).items()}
elif strict:
raise ValueError("Missing json")
raise RuntimeError("Missing json")
super().__init__(json, path, strict, **kwargs)
@ -134,18 +134,18 @@ class Tool:
def __init__(self, json: Json = None, strict: bool = True, **kwargs: Any):
if json is not None:
if not "cmd" in json and strict:
raise ValueError("Missing cmd")
raise RuntimeError("Missing cmd")
self.cmd = json.get("cmd", self.cmd)
if not "args" in json and strict:
raise ValueError("Missing args")
raise RuntimeError("Missing args")
self.args = json.get("args", [])
self.files = json.get("files", [])
elif strict:
raise ValueError("Missing json")
raise RuntimeError("Missing json")
for key in kwargs:
setattr(self, key, kwargs[key])
@ -175,12 +175,12 @@ class TargetManifest(Manifest):
def __init__(self, json: Json = None, path: str = "", strict: bool = True, **kwargs: Any):
if json is not None:
if not "props" in json and strict:
raise ValueError("Missing props")
raise RuntimeError("Missing props")
self.props = json["props"]
if not "tools" in json and strict:
raise ValueError("Missing tools")
raise RuntimeError("Missing tools")
self.tools = {k: Tool(v) for k, v in json["tools"].items()}
@ -211,9 +211,9 @@ class TargetManifest(Manifest):
macrovalue = str(prop).lower().replace(" ", "_").replace("-", "_")
if isinstance(prop, bool):
if prop:
defines += [f"-D__osdk_{macroname}__"]
defines += [f"-D__ck_{macroname}__"]
else:
defines += [f"-D__osdk_{macroname}_{macrovalue}__"]
defines += [f"-D__ck_{macroname}_{macrovalue}__"]
return defines

View file

@ -25,7 +25,7 @@ use Python.
import textwrap
from typing import TextIO, Union
from osdk.utils import asList
from cutekit.utils import asList
def escapePath(word: str) -> str:

View file

@ -1,8 +1,9 @@
import os
import logging
from cutekit import shell, project
import importlib.util as importlib
from osdk.shell import readdir
logger = logging.getLogger(__name__)
@ -20,9 +21,17 @@ def load(path: str):
def loadAll():
logger.info("Loading plugins...")
for files in readdir(os.path.join("meta", "plugins")):
projectRoot = project.root()
if projectRoot is None:
logger.info("Not in project, skipping plugin loading")
return
pluginDir = os.path.join(projectRoot, "meta/plugins")
for files in shell.readdir(pluginDir):
if files.endswith(".py"):
plugin = load(os.path.join("meta", "plugins", files))
plugin = load(os.path.join(pluginDir, files))
if plugin:
print(f"Loaded plugin {plugin.name}")

17
cutekit/project.py Normal file
View file

@ -0,0 +1,17 @@
import os
def root() -> str | None:
cwd = os.getcwd()
while cwd != "/":
if os.path.isfile(os.path.join(cwd, "project.json")):
return cwd
cwd = os.path.dirname(cwd)
return None
def chdir() -> None:
projectRoot = root()
if projectRoot is None:
raise RuntimeError("No project.json found in this directory or any parent directory")
os.chdir(projectRoot)

View file

@ -10,7 +10,7 @@ import fnmatch
import platform
import logging
from osdk import const
from cutekit import const
logger = logging.getLogger(__name__)
@ -131,16 +131,16 @@ def exec(*args: str):
proc = subprocess.run(args)
except FileNotFoundError:
raise Exception(f"{args[0]}: Command not found")
raise RuntimeError(f"{args[0]}: Command not found")
except KeyboardInterrupt:
raise Exception(f"{args[0]}: Interrupted")
raise RuntimeError(f"{args[0]}: Interrupted")
if proc.returncode == -signal.SIGSEGV:
raise Exception(f"{args[0]}: Segmentation fault")
raise RuntimeError(f"{args[0]}: Segmentation fault")
if proc.returncode != 0:
raise Exception(
raise RuntimeError(
f"{args[0]}: Process exited with code {proc.returncode}")
return True
@ -152,13 +152,13 @@ def popen(*args: str) -> str:
try:
proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=sys.stderr)
except FileNotFoundError:
raise Exception(f"{args[0]}: Command not found")
raise RuntimeError(f"{args[0]}: Command not found")
if proc.returncode == -signal.SIGSEGV:
raise Exception(f"{args[0]}: Segmentation fault")
raise RuntimeError(f"{args[0]}: Segmentation fault")
if proc.returncode != 0:
raise Exception(
raise RuntimeError(
f"{args[0]}: Process exited with code {proc.returncode}")
return proc.stdout.decode('utf-8')
@ -221,7 +221,7 @@ def latest(cmd: str) -> str:
versions.append(f)
if len(versions) == 0:
raise Exception(f"{cmd} not found")
raise RuntimeError(f"{cmd} not found")
versions.sort()
chosen = versions[-1]

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -1,32 +0,0 @@
import sys
import logging
from os.path import isdir
from osdk import const, shell
from osdk.args import parse
from osdk.cmds import exec, usage
from osdk.plugins import loadAll
import osdk.vt100 as vt100
def main() -> int:
logging.basicConfig(
level=logging.INFO,
format=f"{vt100.CYAN}%(asctime)s{vt100.RESET} {vt100.YELLOW}%(levelname)s{vt100.RESET} %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
a = parse(sys.argv[1:])
try:
loadAll()
exec(a)
return 0
except Exception as e:
logging.error(f"{vt100.RED}{e}{vt100.RESET}")
print()
usage()
print()
raise e

View file

@ -1,14 +0,0 @@
import os
import sys
VERSION = "0.4.1"
MODULE_DIR = os.path.dirname(os.path.realpath(__file__))
ARGV0 = os.path.basename(sys.argv[0])
OSDK_DIR = ".osdk"
BUILD_DIR = os.path.join(OSDK_DIR, "build")
CACHE_DIR = os.path.join(OSDK_DIR, "cache")
EXTERN_DIR = os.path.join(OSDK_DIR, "extern")
SRC_DIR = "src"
META_DIR = f"meta"
TARGETS_DIR = os.path.join(META_DIR, "targets")
DEFAULT_REPO_TEMPLATES = "cute-engineering/osdk-template"

View file

@ -1,22 +1,23 @@
from setuptools import setup
from osdk.const import VERSION
from cutekit.const import VERSION_STR, DESCRIPTION
setup(
name="osdk",
version=VERSION,
name="cutekit",
version=VERSION_STR,
python_requires='>=3.10',
description="Operating System Development Kit",
description=DESCRIPTION,
author="Cute Engineering",
author_email="contact@cute.engineering",
url="https://cute.engineering/",
packages=["osdk"],
packages=["cutekit"],
install_requires=[
"requests",
"graphviz"
],
entry_points={
"console_scripts": [
"osdk = osdk:main",
"ck = cutekit:main",
"cutekit = cutekit:main",
],
},
license="MIT",