Skip to content

Commit

Permalink
imp: global plugin system
Browse files Browse the repository at this point in the history
  • Loading branch information
keyboard-slayer committed Sep 21, 2024
1 parent 5b213d7 commit aa1f701
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 18 deletions.
1 change: 1 addition & 0 deletions cutekit/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __bool__(self):
ARGV0 = "cutekit"
PROJECT_CK_DIR = ".cutekit"
GLOBAL_CK_DIR = os.path.join(os.path.expanduser("~"), ".cutekit")
GLOBAL_PLUGIN_DIR = os.path.join(GLOBAL_CK_DIR, "plugins")
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")
Expand Down
95 changes: 77 additions & 18 deletions cutekit/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import os
import sys

from . import cli, shell, model, const, vt100
from . import cli, model, const, vt100, shell
from pathlib import Path

import importlib.util as importlib

Expand Down Expand Up @@ -31,24 +32,21 @@ def loadAll():
_logger.info("Loading plugins...")

project = model.Project.topmost()
if project is None:
_logger.info("Not in project, skipping plugin loading")
return
paths = list(
map(lambda e: os.path.join(const.EXTERN_DIR, e), project.extern.keys())
) + ["."]

for dirname in paths:
pluginDir = os.path.join(project.dirname(), dirname, const.META_DIR, "plugins")
pluginDir = os.path.normpath(pluginDir)
initFile = os.path.join(pluginDir, "__init__.py")

if os.path.isfile(initFile):
load(initFile)
paths = list(Path(const.GLOBAL_PLUGIN_DIR).glob("*/"))

if project:
paths += list(
map(
lambda e: Path(project.dirname()) / e / const.META_DIR / "plugins",
project.extern.keys(),
)
) + [Path(project.dirname()) / const.META_DIR / "plugins"]

for path in paths:
if (path / "__init__.py").exists():
load(str(path / "__init__.py"))
else:
for files in shell.readdir(pluginDir):
if files.endswith(".py"):
load(os.path.join(pluginDir, files))
map(lambda p: load(str(p)), path.glob("*.py"))


class PluginsArgs:
Expand All @@ -59,3 +57,64 @@ def setup(args: PluginsArgs):
if args.safemod:
return
loadAll()


@cli.command("P", "plugins", "Manage plugins")
def _():
pass


class PluginsInstallArgs:
url: str = cli.arg(None, "url", "Git url of the plugin")
acknowledge: bool = cli.arg(
None, "acknowledge-risk", "Acknowledge the risk of installing a plugin"
)


@cli.command("i", "plugins/install", "Install a plugin")
def _(args: PluginsInstallArgs):
project = model.Project.topmost()

header = """Please read the following information carefully before proceeding:
- Plugins are not sandboxed and can execute arbitrary code
- Only install plugins from trusted sources
- Cutekit is unable to verify the integrity, security, and safety of plugins
Proceed with caution and at your own risk.
Do you want to continue? [y/N] """

if not args.url and not project:
raise RuntimeError("No plugin source was specified")

choice = input(header)

if choice.lower() == "y":
if args.url:
shell.cloneDir(
args.url,
"meta/plugins",
os.path.join(const.GLOBAL_PLUGIN_DIR, args.url.split("/")[-1]),
)
elif project:
shell.cpTree(
str(Path(project.dirname()) / "meta" / "plugins"),
os.path.join(const.GLOBAL_PLUGIN_DIR, project.name),
)

if (
Path(const.GLOBAL_PLUGIN_DIR) / args.url.split("/")[-1] / "requirements.txt"
).exists():
shell.exec(
sys.executable,
"-m",
"pip",
"install",
"-r",
str(
Path(const.GLOBAL_PLUGIN_DIR)
/ args.url.split("/")[-1]
/ "requirements.txt"
),
)
else:
raise RuntimeError("Plugin installation aborted")

0 comments on commit aa1f701

Please sign in to comment.