diff --git a/requirements.txt b/requirements.txt index e3f8726..662428e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,8 @@ gitpython==3.1.14 # via mk (setup.cfg) importlib-metadata==3.10.0 # via mk (setup.cfg) +pluggy==0.13.1 + # via mk (setup.cfg) pygments==2.8.1 # via # mk (setup.cfg) diff --git a/setup.cfg b/setup.cfg index 9f8a42b..b21aadf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,6 +43,7 @@ install_requires = click-help-colors colorama # for Windows importlib-metadata + pluggy pygments pyyaml rich >= 9.0 @@ -55,6 +56,11 @@ where = src [options.entry_points] console_scripts = mk=mk.__main__:cli +mk_tools = + tox=mk.tools.tox:ToxTool + npm=mk.tools.npm:NpmTool + pre-commit=mk.tools.pre_commit:PreCommitTool + make=mk.tools.make:MakeTool [flake8] max-complexity = 22 diff --git a/src/mk/runner.py b/src/mk/runner.py index c0ec109..f838fe9 100644 --- a/src/mk/runner.py +++ b/src/mk/runner.py @@ -4,10 +4,11 @@ from pathlib import Path from typing import List +import pluggy from git import Repo from git.exc import GitError -from mk.tools import Action, Tool +from mk.tools import Action class Runner: @@ -21,7 +22,11 @@ def __init__(self) -> None: self.root = Path(self.repo.working_dir) self.actions: List[Action] = [] - for c in Tool: + self.pm = pluggy.PluginManager("mk_tools") + self.pm.load_setuptools_entrypoints("mk_tools") + for _, cls_name in self.pm.list_name_plugin(): + # for c in Tool: + c = cls_name() if c.is_present(self.root): logging.info("Detected %s !", c) self.actions.extend(c.actions()) diff --git a/src/mk/tools/__init__.py b/src/mk/tools/__init__.py index 2858ddd..b5fc364 100644 --- a/src/mk/tools/__init__.py +++ b/src/mk/tools/__init__.py @@ -1,6 +1,3 @@ -import os -import subprocess -from configparser import ConfigParser from typing import Any, List, Optional @@ -69,64 +66,3 @@ def __repr__(self): def __rich__(self): return f"[magenta]{self.name}[/]" - - -class PreCommitTool(Tool): - name = "pre-commit" - - def run(self, action: Optional[str] = None): - subprocess.run(["pre-commit", "run", "-a"], check=True) - - def is_present(self, path: str) -> bool: - if os.path.isfile(os.path.join(path, ".pre-commit-config.yaml")): - return True - return False - - def actions(self) -> List[Action]: - return [Action(name="lint", tool=self)] - - -class ToxTool(Tool): - name = "tox" - - def is_present(self, path: str) -> bool: - if os.path.isfile(os.path.join(path, "tox.ini")): - return True - return False - - def actions(self) -> List[Action]: - # -a is not supported by tox4! - actions: List[Action] = [] - cp = ConfigParser() - tox_cfg = subprocess.check_output(["tox", "--showconfig"], universal_newlines=True) - cp.read_string(tox_cfg) - for section in cp.sections(): - if section.startswith("testenv:"): - _, env_name = section.split(":") - # we ignore hidden envs like implicit .pkg: - if not env_name.startswith("."): - actions.append( - Action( - name=env_name, - tool=self, - description=cp[section]["description"], - args=[env_name], - ) - ) - - return actions - - def run(self, action: Optional[str] = None) -> None: - if not action: - cmd = ["tox"] - else: - cmd = ["tox", "-e", action] - subprocess.run(cmd, check=True) - - -class MakeTool(Tool): - name = "make" - - -class NpmTool(Tool): - name = "npm" diff --git a/src/mk/tools/make.py b/src/mk/tools/make.py new file mode 100644 index 0000000..1622b0d --- /dev/null +++ b/src/mk/tools/make.py @@ -0,0 +1,5 @@ +from mk.tools import Tool + + +class MakeTool(Tool): + name = "make" diff --git a/src/mk/tools/npm.py b/src/mk/tools/npm.py new file mode 100644 index 0000000..1cb01a9 --- /dev/null +++ b/src/mk/tools/npm.py @@ -0,0 +1,5 @@ +from mk.tools import Tool + + +class NpmTool(Tool): + name = "npm" diff --git a/src/mk/tools/pre_commit.py b/src/mk/tools/pre_commit.py new file mode 100644 index 0000000..2d425c5 --- /dev/null +++ b/src/mk/tools/pre_commit.py @@ -0,0 +1,20 @@ +import os +import subprocess +from typing import List, Optional + +from mk.tools import Action, Tool + + +class PreCommitTool(Tool): + name = "pre-commit" + + def run(self, action: Optional[str] = None): + subprocess.run(["pre-commit", "run", "-a"], check=True) + + def is_present(self, path: str) -> bool: + if os.path.isfile(os.path.join(path, ".pre-commit-config.yaml")): + return True + return False + + def actions(self) -> List[Action]: + return [Action(name="lint", tool=self)] diff --git a/src/mk/tools/tox.py b/src/mk/tools/tox.py new file mode 100644 index 0000000..b484bc4 --- /dev/null +++ b/src/mk/tools/tox.py @@ -0,0 +1,44 @@ +import os +import subprocess +from configparser import ConfigParser +from typing import List, Optional + +from mk.tools import Action, Tool + + +class ToxTool(Tool): + name = "tox" + + def is_present(self, path: str) -> bool: + if os.path.isfile(os.path.join(path, "tox.ini")): + return True + return False + + def actions(self) -> List[Action]: + # -a is not supported by tox4! + actions: List[Action] = [] + cp = ConfigParser() + tox_cfg = subprocess.check_output(["tox", "--showconfig"], universal_newlines=True) + cp.read_string(tox_cfg) + for section in cp.sections(): + if section.startswith("testenv:"): + _, env_name = section.split(":") + # we ignore hidden envs like implicit .pkg: + if not env_name.startswith("."): + actions.append( + Action( + name=env_name, + tool=self, + description=cp[section]["description"], + args=[env_name], + ) + ) + + return actions + + def run(self, action: Optional[str] = None) -> None: + if not action: + cmd = ["tox"] + else: + cmd = ["tox", "-e", action] + subprocess.run(cmd, check=True) diff --git a/test-requirements.txt b/test-requirements.txt index e166704..32d5c15 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -34,7 +34,9 @@ more-itertools==8.7.0 packaging==20.9 # via pytest pluggy==0.13.1 - # via pytest + # via + # mk (setup.cfg) + # pytest py==1.10.0 # via pytest pygments==2.8.1