pni501 0.1.0__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.
- pni501-0.1.0/PKG-INFO +106 -0
- pni501-0.1.0/README.md +93 -0
- pni501-0.1.0/pyproject.toml +108 -0
- pni501-0.1.0/src/pni/__init__.py +25 -0
- pni501-0.1.0/src/pni/cli.py +48 -0
- pni501-0.1.0/src/pni/py.typed +0 -0
pni501-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: pni501
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Project Nemesis Index (PNI) - Evaluate software development project health and generate reports.
|
|
5
|
+
Author: Yuichi Ito
|
|
6
|
+
Author-email: Yuichi Ito <yuichi@yuichi.com>
|
|
7
|
+
License: Apache-2.0
|
|
8
|
+
Requires-Dist: typer>=0.12.0
|
|
9
|
+
Requires-Dist: rich>=13.0.0
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Project-URL: Repository, https://github.com/yuichi110/pni501
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# pni501 (Project Nemesis Index)
|
|
15
|
+
|
|
16
|
+
**Project Nemesis Index (PNI)** evaluates software development project health and generates diagnostic reports to help engineering teams identify risks, maintain architectural integrity, and improve delivery velocity.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
Software projects naturally accumulate friction—technical debt, uneven test coverage, stagnant dependencies, architectural drift, and workflow bottlenecks. **PNI (Project Nemesis Index)** analyzes software repositories to produce quantifiable health scores and actionable reports.
|
|
23
|
+
|
|
24
|
+
- **Package Name (PyPI)**: `pni501`
|
|
25
|
+
- **Import Module**: `pni`
|
|
26
|
+
- **CLI Command**: `pni501`
|
|
27
|
+
- **Developer Management Tool**: `./pcli`
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
Install via `pip`:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install pni501
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or using `uv`:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv add pni501
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Quickstart
|
|
48
|
+
|
|
49
|
+
Verify the installation:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pni501 version
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Display CLI options and help:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pni501 --help
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Development
|
|
64
|
+
|
|
65
|
+
This project is managed with `uv` and uses `./pcli` (`tools/pcli`) for development workflows.
|
|
66
|
+
|
|
67
|
+
### 1. Shell Setup
|
|
68
|
+
|
|
69
|
+
Run `./pcli` to inspect available toolsets or source it to enable dynamic autocompletion:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
./pcli # Display available toolsets
|
|
73
|
+
source ./pcli # Register 'pcli' shell alias & autocompletion
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. Available Toolsets
|
|
77
|
+
|
|
78
|
+
| Toolset | Command | Description |
|
|
79
|
+
| :--- | :--- | :--- |
|
|
80
|
+
| **`code-check`** | `./pcli code-check all [--fix]` | Ruff linting & formatting, Ty static type checking |
|
|
81
|
+
| **`test`** | `./pcli test all [--cov]` | Run pytest unit tests with coverage |
|
|
82
|
+
| **`pypi`** | `./pcli pypi check-version` | Verify versions, inspect dependencies & publish |
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Code Quality
|
|
86
|
+
./pcli code-check lint [--fix]
|
|
87
|
+
./pcli code-check type
|
|
88
|
+
./pcli code-check lines
|
|
89
|
+
./pcli code-check all
|
|
90
|
+
|
|
91
|
+
# Testing
|
|
92
|
+
./pcli test all
|
|
93
|
+
./pcli test pni
|
|
94
|
+
./pcli test pcli
|
|
95
|
+
|
|
96
|
+
# PyPI Management
|
|
97
|
+
./pcli pypi check-version
|
|
98
|
+
./pcli pypi publish --test-pypi
|
|
99
|
+
./pcli pypi publish
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
This project is licensed under the Apache 2.0 License. See [LICENSE](LICENSE) for details.
|
pni501-0.1.0/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# pni501 (Project Nemesis Index)
|
|
2
|
+
|
|
3
|
+
**Project Nemesis Index (PNI)** evaluates software development project health and generates diagnostic reports to help engineering teams identify risks, maintain architectural integrity, and improve delivery velocity.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Software projects naturally accumulate friction—technical debt, uneven test coverage, stagnant dependencies, architectural drift, and workflow bottlenecks. **PNI (Project Nemesis Index)** analyzes software repositories to produce quantifiable health scores and actionable reports.
|
|
10
|
+
|
|
11
|
+
- **Package Name (PyPI)**: `pni501`
|
|
12
|
+
- **Import Module**: `pni`
|
|
13
|
+
- **CLI Command**: `pni501`
|
|
14
|
+
- **Developer Management Tool**: `./pcli`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install via `pip`:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install pni501
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or using `uv`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uv add pni501
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
Verify the installation:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pni501 version
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Display CLI options and help:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pni501 --help
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Development
|
|
51
|
+
|
|
52
|
+
This project is managed with `uv` and uses `./pcli` (`tools/pcli`) for development workflows.
|
|
53
|
+
|
|
54
|
+
### 1. Shell Setup
|
|
55
|
+
|
|
56
|
+
Run `./pcli` to inspect available toolsets or source it to enable dynamic autocompletion:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
./pcli # Display available toolsets
|
|
60
|
+
source ./pcli # Register 'pcli' shell alias & autocompletion
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Available Toolsets
|
|
64
|
+
|
|
65
|
+
| Toolset | Command | Description |
|
|
66
|
+
| :--- | :--- | :--- |
|
|
67
|
+
| **`code-check`** | `./pcli code-check all [--fix]` | Ruff linting & formatting, Ty static type checking |
|
|
68
|
+
| **`test`** | `./pcli test all [--cov]` | Run pytest unit tests with coverage |
|
|
69
|
+
| **`pypi`** | `./pcli pypi check-version` | Verify versions, inspect dependencies & publish |
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Code Quality
|
|
73
|
+
./pcli code-check lint [--fix]
|
|
74
|
+
./pcli code-check type
|
|
75
|
+
./pcli code-check lines
|
|
76
|
+
./pcli code-check all
|
|
77
|
+
|
|
78
|
+
# Testing
|
|
79
|
+
./pcli test all
|
|
80
|
+
./pcli test pni
|
|
81
|
+
./pcli test pcli
|
|
82
|
+
|
|
83
|
+
# PyPI Management
|
|
84
|
+
./pcli pypi check-version
|
|
85
|
+
./pcli pypi publish --test-pypi
|
|
86
|
+
./pcli pypi publish
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
This project is licensed under the Apache 2.0 License. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv-build<0.12"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pni501"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Project Nemesis Index (PNI) - Evaluate software development project health and generate reports."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [{name = "Yuichi Ito", email = "yuichi@yuichi.com"}]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"typer>=0.12.0",
|
|
15
|
+
"rich>=13.0.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Repository = "https://github.com/yuichi110/pni501"
|
|
20
|
+
|
|
21
|
+
[project.scripts]
|
|
22
|
+
pni501 = "pni.cli:main"
|
|
23
|
+
|
|
24
|
+
[tool.uv.build-backend]
|
|
25
|
+
module-name = "pni"
|
|
26
|
+
|
|
27
|
+
[dependency-groups]
|
|
28
|
+
dev = [
|
|
29
|
+
"ruff>=0.9.0",
|
|
30
|
+
"pytest>=8.3.0",
|
|
31
|
+
"pytest-cov>=6.0.0",
|
|
32
|
+
"tomlkit>=0.14.0",
|
|
33
|
+
"ty>=0.0.35",
|
|
34
|
+
"typer>=0.12.0",
|
|
35
|
+
"rich>=13.0.0",
|
|
36
|
+
"pytest-xdist>=3.8.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
preview = false
|
|
41
|
+
fix = true
|
|
42
|
+
unsafe-fixes = false
|
|
43
|
+
line-length = 120
|
|
44
|
+
|
|
45
|
+
[tool.ruff.lint]
|
|
46
|
+
select = [
|
|
47
|
+
"C90", # mccabe
|
|
48
|
+
"F", # Pyflakes
|
|
49
|
+
"D", # pydocstyle
|
|
50
|
+
"E", # Pycodestyle Error
|
|
51
|
+
"I", # isort
|
|
52
|
+
"N", # pep8-naming (N)
|
|
53
|
+
"W", # Pycodestyle Warning
|
|
54
|
+
"ANN", # flake8-annotations (ANN)
|
|
55
|
+
"CPY", # flake8-copyright
|
|
56
|
+
"S", # flake8-bandit
|
|
57
|
+
"PL" # Pylint
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
ignore = [
|
|
61
|
+
"D203", # 1 blank line required before class docstring
|
|
62
|
+
"D212", # Multi-line docstring summary should start at the first line
|
|
63
|
+
"D415", # First line should end with a period, question mark, or exclamation point
|
|
64
|
+
"F401", # imported but unused
|
|
65
|
+
"PLC0414", # Import alias does not rename original package
|
|
66
|
+
"PLC1901", # compare-to-empty-string
|
|
67
|
+
"PLR0904", # Too many public methods
|
|
68
|
+
"PLR0912", # Too many branches
|
|
69
|
+
"PLR0913", # Too many arguments in function definition
|
|
70
|
+
"PLR0914", # Too many local variables
|
|
71
|
+
"PLR0915", # Too many statements
|
|
72
|
+
"PLR0917", # Too many positional arguments
|
|
73
|
+
"PLR2004", # Magic value used in comparison
|
|
74
|
+
"PLW2901" # Outer variable overwritten by inner target
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
[tool.ruff.lint.per-file-ignores]
|
|
78
|
+
"tools/**.py" = [
|
|
79
|
+
"ANN", # flake8-annotations
|
|
80
|
+
"S101", # Use of assert detected
|
|
81
|
+
"S310", # Audit URL open for permitted schemes
|
|
82
|
+
"S404", # Subprocess module usage
|
|
83
|
+
"S603", # Subprocess call without shell=True
|
|
84
|
+
"S607", # Subprocess with partial executable path
|
|
85
|
+
"PLC2701", # Private name import from external module
|
|
86
|
+
"PLR6301", # Method could be a function/static method
|
|
87
|
+
]
|
|
88
|
+
"tests/**.py" = [
|
|
89
|
+
"F403", # undefined-local-with-import-star
|
|
90
|
+
"F405", # undefined-local-with-import-star-usage
|
|
91
|
+
"D100", # undocumented-public-module
|
|
92
|
+
"D101", # undocumented-public-class
|
|
93
|
+
"D102", # undocumented-public-method
|
|
94
|
+
"D103", # undocumented-public-function
|
|
95
|
+
"D104", # undocumented-public-package
|
|
96
|
+
"D107", # undocumented-public-init
|
|
97
|
+
"ANN", # flake8-annotations
|
|
98
|
+
"CPY", # flake8-copyright
|
|
99
|
+
"S101", # Use of assert detected
|
|
100
|
+
"PLC2701", # Private name import from external module (standard for unit tests)
|
|
101
|
+
"PLR6301" # Method could be a function/static method (standard for pytest classes)
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[tool.ruff.lint.pydocstyle]
|
|
105
|
+
convention = "google"
|
|
106
|
+
|
|
107
|
+
[tool.pytest.ini_options]
|
|
108
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Copyright (c) 2026 Yuichi Ito (yuichi@yuichi.com)
|
|
2
|
+
#
|
|
3
|
+
# This software is licensed under the Apache License, Version 2.0.
|
|
4
|
+
# For more information, please visit: https://github.com/yuichi110/pni501
|
|
5
|
+
#
|
|
6
|
+
# This software is provided "as is", without warranty of any kind,
|
|
7
|
+
# express or implied, including but not limited to the warranties of
|
|
8
|
+
# merchantability, fitness for a particular purpose and noninfringement.
|
|
9
|
+
|
|
10
|
+
"""Project Nemesis Index (PNI) - Evaluate software development project health and generate reports."""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Final
|
|
15
|
+
|
|
16
|
+
LIB_NAME: Final[str] = "pni501"
|
|
17
|
+
LIB_VERSION: Final[str] = "0.1.0"
|
|
18
|
+
|
|
19
|
+
__version__: Final[str] = LIB_VERSION
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"LIB_NAME",
|
|
23
|
+
"LIB_VERSION",
|
|
24
|
+
"__version__",
|
|
25
|
+
]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2026 Yuichi Ito (yuichi@yuichi.com)
|
|
2
|
+
#
|
|
3
|
+
# This software is licensed under the Apache License, Version 2.0.
|
|
4
|
+
# For more information, please visit: https://github.com/yuichi110/pni501
|
|
5
|
+
#
|
|
6
|
+
# This software is provided "as is", without warranty of any kind,
|
|
7
|
+
# express or implied, including but not limited to the warranties of
|
|
8
|
+
# merchantability, fitness for a particular purpose and noninfringement.
|
|
9
|
+
|
|
10
|
+
"""Command line interface for Project Nemesis Index (pni501)."""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import typer
|
|
15
|
+
from rich.console import Console
|
|
16
|
+
|
|
17
|
+
from pni import LIB_NAME, LIB_VERSION
|
|
18
|
+
|
|
19
|
+
app = typer.Typer(
|
|
20
|
+
name="pni501",
|
|
21
|
+
help="Project Nemesis Index (PNI) - Evaluate software development project health and generate reports.",
|
|
22
|
+
)
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.command()
|
|
27
|
+
def version() -> None:
|
|
28
|
+
"""Show pni501 version."""
|
|
29
|
+
console.print(f"[bold cyan]{LIB_NAME}[/bold cyan] version [bold green]{LIB_VERSION}[/bold green]")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@app.callback(invoke_without_command=True)
|
|
33
|
+
def callback(ctx: typer.Context) -> None:
|
|
34
|
+
"""PNI 501 entrypoint callback."""
|
|
35
|
+
if ctx.invoked_subcommand is None:
|
|
36
|
+
console.print("[bold cyan]Project Nemesis Index (PNI)[/bold cyan]")
|
|
37
|
+
console.print(f"{LIB_NAME} version [bold green]{LIB_VERSION}[/bold green]\n")
|
|
38
|
+
console.print("Evaluate software development project health and generate reports.")
|
|
39
|
+
console.print("Run [bold]pni501 --help[/bold] for available commands.")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def main() -> None:
|
|
43
|
+
"""Execute pni501 CLI."""
|
|
44
|
+
app()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
main()
|
|
File without changes
|