invoke-tasklib 0.0.3a0__tar.gz → 0.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: invoke-tasklib
3
- Version: 0.0.3a0
3
+ Version: 0.0.7
4
4
  Summary: Reusable Invoke tasks shared across Python projects.
5
5
  Project-URL: Homepage, https://github.com/durandtibo/invoke-tasklib
6
6
  Project-URL: Repository, https://github.com/durandtibo/invoke-tasklib
@@ -128,7 +128,7 @@ tasklib:
128
128
 
129
129
  ```shell
130
130
  invoke --list
131
- invoke format.check-python lint.check-lint
131
+ invoke format.check-python lint.check-python
132
132
  invoke test.unit
133
133
  ```
134
134
 
@@ -152,8 +152,9 @@ Tasks are grouped into namespaces, one per module. Each task either
152
152
  | `format` | `format.fix-docstrings` | Format docstrings with docformatter | ✅ |
153
153
  | `format` | `format.check-shell` | Check shell scripts with shellcheck | ❌ |
154
154
  | `format` | `format.fix-shell` | Format shell scripts with shfmt | ✅ |
155
- | `lint` | `lint.check-lint` | Check linting with ruff | ❌ |
156
- | `lint` | `lint.fix` | Fix auto-fixable linting issues with ruff | ✅ |
155
+ | `lint` | `lint.check-python` | Check linting with ruff | ❌ |
156
+ | `lint` | `lint.fix-python` | Fix auto-fixable linting issues with ruff | ✅ |
157
+ | `imports` | `imports.check-cycles` | Check for cyclic import dependencies | ❌ |
157
158
  | `types` | `types.check` | Check type hints with pyright | ❌ |
158
159
  | `test` | `test.doctest` | Run doctests on source code and markdown files | ❌ |
159
160
  | `test` | `test.doctest-src` | Run doctests on source code | ❌ |
@@ -100,7 +100,7 @@ tasklib:
100
100
 
101
101
  ```shell
102
102
  invoke --list
103
- invoke format.check-python lint.check-lint
103
+ invoke format.check-python lint.check-python
104
104
  invoke test.unit
105
105
  ```
106
106
 
@@ -124,8 +124,9 @@ Tasks are grouped into namespaces, one per module. Each task either
124
124
  | `format` | `format.fix-docstrings` | Format docstrings with docformatter | ✅ |
125
125
  | `format` | `format.check-shell` | Check shell scripts with shellcheck | ❌ |
126
126
  | `format` | `format.fix-shell` | Format shell scripts with shfmt | ✅ |
127
- | `lint` | `lint.check-lint` | Check linting with ruff | ❌ |
128
- | `lint` | `lint.fix` | Fix auto-fixable linting issues with ruff | ✅ |
127
+ | `lint` | `lint.check-python` | Check linting with ruff | ❌ |
128
+ | `lint` | `lint.fix-python` | Fix auto-fixable linting issues with ruff | ✅ |
129
+ | `imports` | `imports.check-cycles` | Check for cyclic import dependencies | ❌ |
129
130
  | `types` | `types.check` | Check type hints with pyright | ❌ |
130
131
  | `test` | `test.doctest` | Run doctests on source code and markdown files | ❌ |
131
132
  | `test` | `test.doctest-src` | Run doctests on source code | ❌ |
@@ -28,6 +28,7 @@ from invoke_tasklib import (
28
28
  doc,
29
29
  env,
30
30
  format, # noqa: A004
31
+ imports,
31
32
  lint,
32
33
  release,
33
34
  security,
@@ -40,6 +41,7 @@ __all__ = [
40
41
  "doc",
41
42
  "env",
42
43
  "format",
44
+ "imports",
43
45
  "lint",
44
46
  "ns",
45
47
  "release",
@@ -51,6 +53,7 @@ __all__ = [
51
53
  ns: Collection = Collection()
52
54
  ns.add_collection(Collection.from_module(format), name="format")
53
55
  ns.add_collection(Collection.from_module(lint), name="lint")
56
+ ns.add_collection(Collection.from_module(imports), name="imports")
54
57
  ns.add_collection(Collection.from_module(types), name="types")
55
58
  ns.add_collection(Collection.from_module(test), name="test")
56
59
  ns.add_collection(Collection.from_module(env), name="env")
@@ -0,0 +1,47 @@
1
+ r"""Import-graph tasks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import shlex
7
+ from typing import TYPE_CHECKING
8
+
9
+ from invoke.tasks import task
10
+
11
+ from invoke_tasklib.config import get_config
12
+
13
+ if TYPE_CHECKING:
14
+ from invoke.context import Context
15
+
16
+ logger: logging.Logger = logging.getLogger(__name__)
17
+
18
+
19
+ @task
20
+ def check_cycles(c: Context) -> None:
21
+ r"""Check for cyclic import dependencies by importing each subpackage
22
+ in isolation.
23
+
24
+ Subpackages are discovered dynamically instead of relying on a hand-
25
+ maintained list, so newly added subpackages are automatically
26
+ covered.
27
+ """
28
+ cfg = get_config(c)
29
+ name = cfg["package"]["name"]
30
+ logger.info(f"🔍 Discovering subpackages of {name}...")
31
+ discover_script = (
32
+ "import importlib, pkgutil, sys\n"
33
+ "name = sys.argv[1]\n"
34
+ "package = importlib.import_module(name)\n"
35
+ "names = [name] + sorted(\n"
36
+ " n for _, n, ispkg in pkgutil.walk_packages(package.__path__, prefix=f'{name}.')\n"
37
+ " if ispkg\n"
38
+ ")\n"
39
+ "print('\\n'.join(names))\n"
40
+ )
41
+ discover = c.run(f"python -c {shlex.quote(discover_script)} {name}", hide=True)
42
+ modules = [line for line in discover.stdout.splitlines() if line]
43
+ logger.info(f"🔍 Checking {len(modules)} module(s) for cyclic imports...")
44
+ for module in modules:
45
+ logger.info(f"🔍 Checking: {module}")
46
+ c.run(f"python -c {shlex.quote(f'import {module}')}", pty=True)
47
+ logger.info(f"✅ All {len(modules)} module(s) imported without cyclic dependency errors")
@@ -14,7 +14,7 @@ logger: logging.Logger = logging.getLogger(__name__)
14
14
 
15
15
 
16
16
  @task
17
- def check_lint(c: Context) -> None:
17
+ def check_python(c: Context) -> None:
18
18
  r"""Check code linting with ruff."""
19
19
  logger.info("🔍 Checking code linting with ruff...")
20
20
  c.run("ruff check --output-format=github .", pty=True)
@@ -22,7 +22,7 @@ def check_lint(c: Context) -> None:
22
22
 
23
23
 
24
24
  @task
25
- def fix(c: Context) -> None:
25
+ def fix_python(c: Context) -> None:
26
26
  r"""Fix auto-fixable linting issues in place with ruff.
27
27
 
28
28
  Note:
@@ -10,7 +10,7 @@ only-include = ["src"]
10
10
 
11
11
  [project]
12
12
  name = "invoke-tasklib"
13
- version = "0.0.3a0"
13
+ version = "0.0.7"
14
14
  description = "Reusable Invoke tasks shared across Python projects."
15
15
  readme = "README.md"
16
16
  authors = [
File without changes