diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml
index bdaab28..77e9483 100644
--- a/.github/workflows/python-publish.yml
+++ b/.github/workflows/python-publish.yml
@@ -17,7 +17,6 @@ permissions:
jobs:
deploy:
-
runs-on: ubuntu-latest
steps:
diff --git a/README.md b/README.md
index d0f02e4..975b4e2 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,39 @@
-# osdk
-
-The operating system development kit
+
+
+
+
+
+
+CuteKit
+
+ The Cute build system and package manager
+
+
+
+
## 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`
diff --git a/cutekit/__init__.py b/cutekit/__init__.py
new file mode 100644
index 0000000..124251a
--- /dev/null
+++ b/cutekit/__init__.py
@@ -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
\ No newline at end of file
diff --git a/osdk/__main__.py b/cutekit/__main__.py
similarity index 100%
rename from osdk/__main__.py
rename to cutekit/__main__.py
diff --git a/osdk/args.py b/cutekit/args.py
similarity index 100%
rename from osdk/args.py
rename to cutekit/args.py
diff --git a/osdk/builder.py b/cutekit/builder.py
similarity index 89%
rename from osdk/builder.py
rename to cutekit/builder.py
index 2e4bc7b..f505ec0 100644
--- a/osdk/builder.py
+++ b/cutekit/builder.py
@@ -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())
diff --git a/osdk/cmds.py b/cutekit/cmds.py
similarity index 70%
rename from osdk/cmds.py
rename to cutekit/cmds.py
index d6b2c25..6662374 100644
--- a/osdk/cmds.py
+++ b/cutekit/cmds.py
@@ -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} [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}")
diff --git a/cutekit/compat.py b/cutekit/compat.py
new file mode 100644
index 0000000..8da16ce
--- /dev/null
+++ b/cutekit/compat.py
@@ -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}")
diff --git a/cutekit/const.py b/cutekit/const.py
new file mode 100644
index 0000000..879cd42
--- /dev/null
+++ b/cutekit/const.py
@@ -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")
diff --git a/osdk/context.py b/cutekit/context.py
similarity index 96%
rename from osdk/context.py
rename to cutekit/context.py
index 9fe67dc..c9fd5de 100644
--- a/osdk/context.py
+++ b/cutekit/context.py
@@ -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)
diff --git a/osdk/graph.py b/cutekit/graph.py
similarity index 97%
rename from osdk/graph.py
rename to cutekit/graph.py
index 4759a9a..ab4d65e 100644
--- a/osdk/graph.py
+++ b/cutekit/graph.py
@@ -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):
diff --git a/osdk/jexpr.py b/cutekit/jexpr.py
similarity index 82%
rename from osdk/jexpr.py
rename to cutekit/jexpr.py
index 7e0e6c0..ab3d7d8 100644
--- a/osdk/jexpr.py
+++ b/cutekit/jexpr.py
@@ -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)
diff --git a/osdk/mixins.py b/cutekit/mixins.py
similarity index 97%
rename from osdk/mixins.py
rename to cutekit/mixins.py
index b996ac9..ed7ed54 100644
--- a/osdk/mixins.py
+++ b/cutekit/mixins.py
@@ -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]
diff --git a/osdk/model.py b/cutekit/model.py
similarity index 89%
rename from osdk/model.py
rename to cutekit/model.py
index 0ab153e..b8ec441 100644
--- a/osdk/model.py
+++ b/cutekit/model.py
@@ -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
diff --git a/osdk/ninja.py b/cutekit/ninja.py
similarity index 99%
rename from osdk/ninja.py
rename to cutekit/ninja.py
index 6148f82..a24698c 100644
--- a/osdk/ninja.py
+++ b/cutekit/ninja.py
@@ -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:
diff --git a/osdk/plugins.py b/cutekit/plugins.py
similarity index 64%
rename from osdk/plugins.py
rename to cutekit/plugins.py
index 0e8e9b7..dff9fb1 100644
--- a/osdk/plugins.py
+++ b/cutekit/plugins.py
@@ -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}")
diff --git a/cutekit/project.py b/cutekit/project.py
new file mode 100644
index 0000000..979fb7b
--- /dev/null
+++ b/cutekit/project.py
@@ -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)
\ No newline at end of file
diff --git a/osdk/rules.py b/cutekit/rules.py
similarity index 100%
rename from osdk/rules.py
rename to cutekit/rules.py
diff --git a/osdk/shell.py b/cutekit/shell.py
similarity index 92%
rename from osdk/shell.py
rename to cutekit/shell.py
index 5efb615..012e49b 100644
--- a/osdk/shell.py
+++ b/cutekit/shell.py
@@ -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]
diff --git a/osdk/utils.py b/cutekit/utils.py
similarity index 100%
rename from osdk/utils.py
rename to cutekit/utils.py
diff --git a/osdk/vt100.py b/cutekit/vt100.py
similarity index 100%
rename from osdk/vt100.py
rename to cutekit/vt100.py
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000..b103240
Binary files /dev/null and b/logo.png differ
diff --git a/osdk/__init__.py b/osdk/__init__.py
deleted file mode 100644
index 71f8363..0000000
--- a/osdk/__init__.py
+++ /dev/null
@@ -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
diff --git a/osdk/const.py b/osdk/const.py
deleted file mode 100644
index 1211fec..0000000
--- a/osdk/const.py
+++ /dev/null
@@ -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"
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 474aa62..50e48af 100644
--- a/setup.py
+++ b/setup.py
@@ -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",