Skip to content

Commit

Permalink
0.4.0 (#141)
Browse files Browse the repository at this point in the history
* ⬆️ Upgrade python-slugify to ^0.8

* 💥 Use argx instead of pyparam

* ✅ Fix tests

* 🔖 0.4.0

* 👷 Add python3.11 to CI

* 👷 Remove python3.11 from CI
  • Loading branch information
pwwang authored Feb 20, 2023
1 parent 96c7b28 commit b5ed061
Show file tree
Hide file tree
Showing 17 changed files with 403 additions and 258 deletions.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
omit =
# need plugins to be installed to test
pipen/cli/plugins.py

[report]
exclude_lines =
if TYPE_CHECKING:
pragma: no cover
14 changes: 7 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ jobs:
if: "! contains(github.event.head_commit.message, 'wip')"
strategy:
matrix:
# dependencies install is too slow
# 3.11 is slow to install
python-version: [3.7, 3.8, 3.9, "3.10"]
# python-version: [3.7, 3.8, 3.9]
# python-version: [3.7, 3.8, 3.9, "3.10", "3.11"]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Python # Set Python version
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -31,7 +31,7 @@ jobs:
- name: Test with pytest
run: pytest tests/ --junitxml=junit/test-results-${{ matrix.python-version }}.xml
- name: Upload pytest test results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: pytest-results-${{ matrix.python-version }}
path: junit/test-results-${{ matrix.python-version }}.xml
Expand All @@ -52,9 +52,9 @@ jobs:
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Python # Set Python version
uses: actions/setup-python@v2
uses: actions/setup-python@v4
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ jobs:
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Python # Set Python version
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -39,7 +39,7 @@ jobs:
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: gh-pages
- name: Fix index.html
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Pipen().set_starts(P1).run()
[09/13/21 04:23:37] I main _ ____/__/ / _ ____/_ /___ _ /| /
[09/13/21 04:23:37] I main /_/ /___/ /_/ /_____/ /_/ |_/
[09/13/21 04:23:37] I main
[09/13/21 04:23:37] I main version: 0.3.10
[09/13/21 04:23:37] I main version: 0.4.0
[09/13/21 04:23:37] I main
[09/13/21 04:23:37] I main ╭══════════════════════════════ PIPEN-0 ════════════════════════════════╮
[09/13/21 04:23:37] I main ║ # procs = 2 ║
Expand Down
7 changes: 7 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Change Log

## 0.4.0

- ⬆️ Upgrade python-slugify to ^0.8
- ⬆️ Upgrade xqute to 0.1.4
- ⬆️ Upgrade varname to 0.11
- 💥 Use argx instead of pyparam

## 0.3.12

- ⬆️ Upgrade python-slugify to ^7
Expand Down
Binary file modified pipen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions pipen/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .cli._main import main


if __name__ == '__main__':
main()
27 changes: 16 additions & 11 deletions pipen/cli/_hooks.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
"""Provide Cli class"""
from __future__ import annotations

from abc import ABC, abstractmethod, abstractproperty
from typing import TYPE_CHECKING, Any, List, Mapping
from typing import TYPE_CHECKING

from simplug import Simplug

from ..defaults import CLI_ENTRY_GROUP

if TYPE_CHECKING: # pragma: no cover
from pyparam import Params
if TYPE_CHECKING:
from argx import ArgumentParser
from argparse import Namespace

cli_plugin = Simplug(CLI_ENTRY_GROUP)


class CLIPlugin(ABC):
"""The abc for cli plugin"""

def __init__(
self,
parser: ArgumentParser,
subparser: ArgumentParser,
) -> None:
self.parser = parser
self.subparser = subparser

@abstractproperty
def name(self) -> str:
"""The name/command of this plugin"""

@abstractproperty
def params(self) -> "Params":
"""Define parameters"""
def define_args(self, parser: ArgumentParser):
"""Define arguments for the command"""

@abstractmethod
def exec_command(self, args: Mapping[str, Any]) -> None:
def exec_command(self, args: Namespace) -> None:
"""Execute the command"""

def parse_args(self, args: List[str]) -> Mapping[str, Any]:
"""Parse the arguments"""
return self.params.parse(args)
57 changes: 14 additions & 43 deletions pipen/cli/_main.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"""CLI main entrance"""
import re
import sys
import importlib
from pathlib import Path
from typing import Iterable

from pyparam import Params
from rich import print
from argx import ArgumentParser

from ._hooks import cli_plugin
from ..version import __version__

params = Params(desc=f"CLI Tool for pipen v{__version__}")
parser = ArgumentParser(
prog="pipen",
description=f"CLI Tool for pipen v{__version__}",
)


def load_builtin_clis() -> None:
Expand All @@ -24,54 +24,25 @@ def load_builtin_clis() -> None:
cli_plugin.register(plg)


def _print_help(plugin_names: Iterable[str]) -> None:
"""Print help of pipen CLI"""
params.add_param(
params.help_keys,
desc="Print help information for the CLI tool.",
)
for name in plugin_names:
plugin = cli_plugin.get_plugin(name, raw=True)
params.add_command(
plugin.name,
re.sub(r"\s+", " ", plugin.__doc__.strip()),
force=True,
)
params.print_help()


def main() -> None:
"""Main function of pipen CLI"""
cli_plugin.load_entrypoints()
# builtin plugins have the highest priority
# so they are loaded later to override the entrypoints
load_builtin_clis()

args = sys.argv
plugin_names = sorted(
cli_plugin.get_enabled_plugin_names(),
key=lambda cmd: 999 if cmd == "help" else 0,
)
if len(args) == 1:
_print_help(plugin_names)

command = sys.argv[1]
help_keys = [
f"-{key}" if len(key) == 1 else f"--{key}" for key in params.help_keys
]
if command in help_keys:
_print_help(plugin_names)

plugins = {}
for name in plugin_names:
plg = cli_plugin.get_plugin(name, raw=True)
if plg.name != command:
continue
plg = plg()
parsed = plg.parse_args(sys.argv[2:])
plg.exec_command(parsed)
return
subparser = parser.add_command(
plg.name,
help=re.sub(r"\s+", " ", plg.__doc__.strip().split("\n\n")[0]),
)
plugins[name] = plg(parser, subparser)

print(
"[red][b]ERROR: [/b][/red]No such command: "
f"[green]{command}[/green]"
)
_print_help(plugin_names)
parsed = parser.parse_args()
plugins[parsed.COMMAND].exec_command(parsed)
56 changes: 18 additions & 38 deletions pipen/cli/help.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""Print help for commands"""
from typing import Any, Mapping

from rich import print
from pyparam import Params, POSITIONAL
from __future__ import annotations
from typing import TYPE_CHECKING

from ._hooks import CLIPlugin, cli_plugin

if TYPE_CHECKING:
from argx import ArgumentParser
from argparse import Namespace

__all__ = ("CLIHelpPlugin",)


Expand All @@ -14,41 +16,19 @@ class CLIHelpPlugin(CLIPlugin):

name = "help"

@property
def params(self) -> Params:
"""Define the params"""
pms = Params(
desc=self.__class__.__doc__,
help_on_void=False,
def __init__(self, parser: ArgumentParser, subparser: ArgumentParser):
super().__init__(parser, subparser)
subparser.add_argument(
"cmd",
nargs="?",
choices=cli_plugin.get_enabled_plugin_names(),
help="The command to show help for",
)
pms.add_param(
POSITIONAL,
default="",
desc="The command to show help for",
)
return pms

def exec_command(self, args: Mapping[str, Any]) -> None:
def exec_command(self, args: Namespace) -> None:
"""Run the command"""
command = args[POSITIONAL]
plugin_names = sorted(
cli_plugin.get_enabled_plugin_names(),
key=lambda cmd: 999 if cmd == "help" else 0,
)

plg = None
for name in plugin_names:
plg = cli_plugin.get_plugin(name, raw=True)
if command != plg.name:
continue

plg().params.print_help()

from ._main import _print_help

if command:
print(
"[red][b]ERROR: [/b][/red]No such command: "
f"[green]{command}[/green]"
)
_print_help(plugin_names)
if not args.cmd:
self.parser.parse_args(["--help"])
else:
self.parser.parse_args([args.cmd, "--help"])
34 changes: 19 additions & 15 deletions pipen/cli/plugins.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""List plugins"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Iterable, List, Tuple

from typing import Any, Iterable, List, Mapping, Tuple

from pyparam import Params
from rich import print

from ._hooks import CLIPlugin
Expand All @@ -13,6 +12,10 @@
)
from ..utils import load_entrypoints

if TYPE_CHECKING:
from argx import ArgumentParser
from argparse import Namespace


COMMAND = "plugins"
GROUPS = [
Expand Down Expand Up @@ -102,20 +105,21 @@ class CliPluginsPlugin(CLIPlugin):

name = "plugins"

@property
def params(self) -> Params:
"""Define the params"""
pms = Params(desc=self.__class__.__doc__, help_on_void=False)
pms.add_param(
"g,group",
default="",
desc="The name of the entry point group. "
"If not provided, show all plugins. "
f"Avaiable groups are: {' '.join(GROUPS)}",
def __init__(
self,
parser: ArgumentParser,
subparser: ArgumentParser,
) -> None:
super().__init__(parser, subparser)
subparser.add_argument(
"-g",
"--group",
choices=GROUPS + ["all"],
default="all",
help="The name of the entry point group. Show all if not provided",
)
return pms

def exec_command(self, args: Mapping[str, Any]) -> None:
def exec_command(self, args: Namespace) -> None:
"""Execute the command"""
from ..version import __version__
print("Pipen version:", __version__)
Expand Down
Loading

0 comments on commit b5ed061

Please sign in to comment.