planpilot 1.0.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.
- planpilot-1.0.0/LICENSE +21 -0
- planpilot-1.0.0/PKG-INFO +199 -0
- planpilot-1.0.0/README.md +175 -0
- planpilot-1.0.0/pyproject.toml +119 -0
- planpilot-1.0.0/src/planpilot/__init__.py +4 -0
- planpilot-1.0.0/src/planpilot/__main__.py +8 -0
- planpilot-1.0.0/src/planpilot/cli.py +196 -0
- planpilot-1.0.0/src/planpilot/config.py +41 -0
- planpilot-1.0.0/src/planpilot/exceptions.py +45 -0
- planpilot-1.0.0/src/planpilot/models/__init__.py +45 -0
- planpilot-1.0.0/src/planpilot/models/enums.py +13 -0
- planpilot-1.0.0/src/planpilot/models/plan.py +98 -0
- planpilot-1.0.0/src/planpilot/models/project.py +137 -0
- planpilot-1.0.0/src/planpilot/models/sync.py +38 -0
- planpilot-1.0.0/src/planpilot/plan/__init__.py +7 -0
- planpilot-1.0.0/src/planpilot/plan/hasher.py +22 -0
- planpilot-1.0.0/src/planpilot/plan/loader.py +41 -0
- planpilot-1.0.0/src/planpilot/plan/validator.py +70 -0
- planpilot-1.0.0/src/planpilot/providers/__init__.py +8 -0
- planpilot-1.0.0/src/planpilot/providers/base.py +202 -0
- planpilot-1.0.0/src/planpilot/providers/github/__init__.py +5 -0
- planpilot-1.0.0/src/planpilot/providers/github/client.py +115 -0
- planpilot-1.0.0/src/planpilot/providers/github/mapper.py +168 -0
- planpilot-1.0.0/src/planpilot/providers/github/provider.py +541 -0
- planpilot-1.0.0/src/planpilot/providers/github/queries.py +127 -0
- planpilot-1.0.0/src/planpilot/rendering/__init__.py +10 -0
- planpilot-1.0.0/src/planpilot/rendering/base.py +95 -0
- planpilot-1.0.0/src/planpilot/rendering/components.py +60 -0
- planpilot-1.0.0/src/planpilot/rendering/markdown.py +120 -0
- planpilot-1.0.0/src/planpilot/slice.py +75 -0
- planpilot-1.0.0/src/planpilot/sync/__init__.py +5 -0
- planpilot-1.0.0/src/planpilot/sync/engine.py +460 -0
- planpilot-1.0.0/src/planpilot/sync/relations.py +54 -0
planpilot-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 aryeko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
planpilot-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: planpilot
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: github,projects,roadmap,sync,issues
|
|
8
|
+
Author: aryeko
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Requires-Dist: pydantic (>=2.12.5,<3.0.0)
|
|
20
|
+
Project-URL: Homepage, https://github.com/aryeko/planpilot
|
|
21
|
+
Project-URL: Repository, https://github.com/aryeko/planpilot
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# planpilot
|
|
25
|
+
|
|
26
|
+
[](https://github.com/aryeko/planpilot/actions/workflows/ci.yml)
|
|
27
|
+
[](https://codecov.io/gh/aryeko/planpilot)
|
|
28
|
+
[](https://pypi.org/project/planpilot/)
|
|
29
|
+
[](https://pypi.org/project/planpilot/)
|
|
30
|
+
[](LICENSE)
|
|
31
|
+
|
|
32
|
+
Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2.
|
|
33
|
+
|
|
34
|
+
## What it does
|
|
35
|
+
|
|
36
|
+
**planpilot** takes structured plan files and turns them into a fully linked project board:
|
|
37
|
+
|
|
38
|
+
```mermaid
|
|
39
|
+
flowchart LR
|
|
40
|
+
A["roadmap.md"] --> B["epics.json\nstories.json\ntasks.json"]
|
|
41
|
+
B -->|planpilot| C["GitHub Issues\n+ Projects v2"]
|
|
42
|
+
C --> D["Epic / Story / Task\nissue types"]
|
|
43
|
+
C --> E["Sub-issue\nhierarchy"]
|
|
44
|
+
C --> F["Blocked-by\ndependencies"]
|
|
45
|
+
C --> G["Project fields\nstatus, priority,\niteration, size"]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- **One-way sync**: local plan files -> GitHub
|
|
49
|
+
- **Idempotent**: safe to rerun -- updates existing issues via markers
|
|
50
|
+
- **Dry-run first**: preview all changes before applying
|
|
51
|
+
- **Multi-epic**: slice large plans and sync each epic sequentially
|
|
52
|
+
- **Provider-agnostic**: adapter pattern supports GitHub today, with Jira/Linear planned
|
|
53
|
+
- **Async-first**: built on asyncio for fast, concurrent sync operations
|
|
54
|
+
|
|
55
|
+
## Architecture
|
|
56
|
+
|
|
57
|
+
planpilot follows SOLID principles with a modular, provider-agnostic design:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
src/planpilot/
|
|
61
|
+
├── models/ # Pydantic domain models (Plan, Epic, Story, Task, …)
|
|
62
|
+
├── plan/ # Plan loading, validation, and hashing
|
|
63
|
+
├── providers/ # Provider adapter pattern (ABC + implementations)
|
|
64
|
+
│ └── github/ # GitHub adapter (gh CLI)
|
|
65
|
+
├── rendering/ # Issue body rendering (Protocol + Markdown impl)
|
|
66
|
+
├── sync/ # Sync engine orchestrator + relation logic
|
|
67
|
+
├── config.py # SyncConfig (pydantic)
|
|
68
|
+
├── exceptions.py # Custom exception hierarchy
|
|
69
|
+
├── cli.py # CLI entry point
|
|
70
|
+
└── slice.py # Multi-epic plan slicing
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The sync engine depends only on abstract interfaces (`Provider` ABC and `BodyRenderer` Protocol), making it easy to add new providers (Jira, Linear) without touching the core sync logic.
|
|
74
|
+
|
|
75
|
+
See [docs/architecture.md](docs/architecture.md) for the full architecture guide.
|
|
76
|
+
|
|
77
|
+
## Requirements
|
|
78
|
+
|
|
79
|
+
- Python 3.11+
|
|
80
|
+
- [`gh` CLI](https://cli.github.com/) installed and authenticated
|
|
81
|
+
- GitHub token scopes: `repo`, `project`
|
|
82
|
+
|
|
83
|
+
## Installation
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install planpilot
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Or with Poetry:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
poetry add planpilot
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Quickstart
|
|
96
|
+
|
|
97
|
+
### 1. Dry-run (preview changes)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
planpilot \
|
|
101
|
+
--repo your-org/your-repo \
|
|
102
|
+
--project-url https://github.com/orgs/your-org/projects/1 \
|
|
103
|
+
--epics-path .plans/epics.json \
|
|
104
|
+
--stories-path .plans/stories.json \
|
|
105
|
+
--tasks-path .plans/tasks.json \
|
|
106
|
+
--sync-path .plans/github-sync-map.json \
|
|
107
|
+
--dry-run
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 2. Apply changes
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
planpilot \
|
|
114
|
+
--repo your-org/your-repo \
|
|
115
|
+
--project-url https://github.com/orgs/your-org/projects/1 \
|
|
116
|
+
--epics-path .plans/epics.json \
|
|
117
|
+
--stories-path .plans/stories.json \
|
|
118
|
+
--tasks-path .plans/tasks.json \
|
|
119
|
+
--sync-path .plans/github-sync-map.json \
|
|
120
|
+
--apply
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 3. Multi-epic plans
|
|
124
|
+
|
|
125
|
+
The sync tool expects one epic per run. For multi-epic plans, slice first:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
planpilot-slice \
|
|
129
|
+
--epics-path .plans/epics.json \
|
|
130
|
+
--stories-path .plans/stories.json \
|
|
131
|
+
--tasks-path .plans/tasks.json \
|
|
132
|
+
--out-dir .plans/tmp
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Then sync each epic:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
for f in .plans/tmp/epics.*.json; do
|
|
139
|
+
id=$(basename "$f" .json | sed 's/epics\.//')
|
|
140
|
+
planpilot \
|
|
141
|
+
--repo your-org/your-repo \
|
|
142
|
+
--project-url https://github.com/orgs/your-org/projects/1 \
|
|
143
|
+
--epics-path ".plans/tmp/epics.${id}.json" \
|
|
144
|
+
--stories-path ".plans/tmp/stories.${id}.json" \
|
|
145
|
+
--tasks-path ".plans/tmp/tasks.${id}.json" \
|
|
146
|
+
--sync-path ".plans/github-sync-map.${id}.json" \
|
|
147
|
+
--apply
|
|
148
|
+
done
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Optional flags
|
|
152
|
+
|
|
153
|
+
| Flag | Default | Description |
|
|
154
|
+
|------|---------|-------------|
|
|
155
|
+
| `--label` | `codex` | Label applied to created issues |
|
|
156
|
+
| `--status` | `Backlog` | Project status field value |
|
|
157
|
+
| `--priority` | `P1` | Project priority field value |
|
|
158
|
+
| `--iteration` | `active` | Iteration title, `active`, or `none` |
|
|
159
|
+
| `--size-field` | `Size` | Project size field name |
|
|
160
|
+
| `--no-size-from-tshirt` | off | Disable t-shirt size mapping |
|
|
161
|
+
| `--verbose` | off | Enable verbose logging |
|
|
162
|
+
|
|
163
|
+
Full CLI reference: [docs/cli-reference.md](docs/cli-reference.md)
|
|
164
|
+
|
|
165
|
+
## Plan file schemas
|
|
166
|
+
|
|
167
|
+
See [docs/schemas.md](docs/schemas.md) for the expected structure of `epics.json`, `stories.json`, and `tasks.json`, with full examples.
|
|
168
|
+
|
|
169
|
+
A complete working example is in the [examples/](examples/) directory, including sample rendered issue bodies and a sync-map output.
|
|
170
|
+
|
|
171
|
+
## Documentation
|
|
172
|
+
|
|
173
|
+
- [How It Works](docs/how-it-works.md) -- sync pipeline, idempotency, what gets created
|
|
174
|
+
- [CLI Reference](docs/cli-reference.md) -- all flags and commands
|
|
175
|
+
- [Plan Schemas](docs/schemas.md) -- JSON format with examples and validation rules
|
|
176
|
+
- [Architecture](docs/architecture.md) -- module map, data flow, provider pattern, extension guide
|
|
177
|
+
- [Release Guide](RELEASE.md) -- automated versioning, publishing, and release pipeline
|
|
178
|
+
|
|
179
|
+
## Development
|
|
180
|
+
|
|
181
|
+
Development tasks use [poethepoet](https://github.com/nat-n/poethepoet):
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
poe lint # ruff check
|
|
185
|
+
poe format # ruff format
|
|
186
|
+
poe test # pytest -v
|
|
187
|
+
poe coverage # pytest + HTML coverage report
|
|
188
|
+
poe typecheck # mypy
|
|
189
|
+
poe check # lint + format-check + tests (all-in-one)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Contributing
|
|
193
|
+
|
|
194
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and development instructions.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
[MIT](LICENSE)
|
|
199
|
+
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# planpilot
|
|
2
|
+
|
|
3
|
+
[](https://github.com/aryeko/planpilot/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/aryeko/planpilot)
|
|
5
|
+
[](https://pypi.org/project/planpilot/)
|
|
6
|
+
[](https://pypi.org/project/planpilot/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2.
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
|
|
13
|
+
**planpilot** takes structured plan files and turns them into a fully linked project board:
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
flowchart LR
|
|
17
|
+
A["roadmap.md"] --> B["epics.json\nstories.json\ntasks.json"]
|
|
18
|
+
B -->|planpilot| C["GitHub Issues\n+ Projects v2"]
|
|
19
|
+
C --> D["Epic / Story / Task\nissue types"]
|
|
20
|
+
C --> E["Sub-issue\nhierarchy"]
|
|
21
|
+
C --> F["Blocked-by\ndependencies"]
|
|
22
|
+
C --> G["Project fields\nstatus, priority,\niteration, size"]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- **One-way sync**: local plan files -> GitHub
|
|
26
|
+
- **Idempotent**: safe to rerun -- updates existing issues via markers
|
|
27
|
+
- **Dry-run first**: preview all changes before applying
|
|
28
|
+
- **Multi-epic**: slice large plans and sync each epic sequentially
|
|
29
|
+
- **Provider-agnostic**: adapter pattern supports GitHub today, with Jira/Linear planned
|
|
30
|
+
- **Async-first**: built on asyncio for fast, concurrent sync operations
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
planpilot follows SOLID principles with a modular, provider-agnostic design:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
src/planpilot/
|
|
38
|
+
├── models/ # Pydantic domain models (Plan, Epic, Story, Task, …)
|
|
39
|
+
├── plan/ # Plan loading, validation, and hashing
|
|
40
|
+
├── providers/ # Provider adapter pattern (ABC + implementations)
|
|
41
|
+
│ └── github/ # GitHub adapter (gh CLI)
|
|
42
|
+
├── rendering/ # Issue body rendering (Protocol + Markdown impl)
|
|
43
|
+
├── sync/ # Sync engine orchestrator + relation logic
|
|
44
|
+
├── config.py # SyncConfig (pydantic)
|
|
45
|
+
├── exceptions.py # Custom exception hierarchy
|
|
46
|
+
├── cli.py # CLI entry point
|
|
47
|
+
└── slice.py # Multi-epic plan slicing
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The sync engine depends only on abstract interfaces (`Provider` ABC and `BodyRenderer` Protocol), making it easy to add new providers (Jira, Linear) without touching the core sync logic.
|
|
51
|
+
|
|
52
|
+
See [docs/architecture.md](docs/architecture.md) for the full architecture guide.
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
|
|
56
|
+
- Python 3.11+
|
|
57
|
+
- [`gh` CLI](https://cli.github.com/) installed and authenticated
|
|
58
|
+
- GitHub token scopes: `repo`, `project`
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install planpilot
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or with Poetry:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
poetry add planpilot
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Quickstart
|
|
73
|
+
|
|
74
|
+
### 1. Dry-run (preview changes)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
planpilot \
|
|
78
|
+
--repo your-org/your-repo \
|
|
79
|
+
--project-url https://github.com/orgs/your-org/projects/1 \
|
|
80
|
+
--epics-path .plans/epics.json \
|
|
81
|
+
--stories-path .plans/stories.json \
|
|
82
|
+
--tasks-path .plans/tasks.json \
|
|
83
|
+
--sync-path .plans/github-sync-map.json \
|
|
84
|
+
--dry-run
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 2. Apply changes
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
planpilot \
|
|
91
|
+
--repo your-org/your-repo \
|
|
92
|
+
--project-url https://github.com/orgs/your-org/projects/1 \
|
|
93
|
+
--epics-path .plans/epics.json \
|
|
94
|
+
--stories-path .plans/stories.json \
|
|
95
|
+
--tasks-path .plans/tasks.json \
|
|
96
|
+
--sync-path .plans/github-sync-map.json \
|
|
97
|
+
--apply
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3. Multi-epic plans
|
|
101
|
+
|
|
102
|
+
The sync tool expects one epic per run. For multi-epic plans, slice first:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
planpilot-slice \
|
|
106
|
+
--epics-path .plans/epics.json \
|
|
107
|
+
--stories-path .plans/stories.json \
|
|
108
|
+
--tasks-path .plans/tasks.json \
|
|
109
|
+
--out-dir .plans/tmp
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Then sync each epic:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
for f in .plans/tmp/epics.*.json; do
|
|
116
|
+
id=$(basename "$f" .json | sed 's/epics\.//')
|
|
117
|
+
planpilot \
|
|
118
|
+
--repo your-org/your-repo \
|
|
119
|
+
--project-url https://github.com/orgs/your-org/projects/1 \
|
|
120
|
+
--epics-path ".plans/tmp/epics.${id}.json" \
|
|
121
|
+
--stories-path ".plans/tmp/stories.${id}.json" \
|
|
122
|
+
--tasks-path ".plans/tmp/tasks.${id}.json" \
|
|
123
|
+
--sync-path ".plans/github-sync-map.${id}.json" \
|
|
124
|
+
--apply
|
|
125
|
+
done
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Optional flags
|
|
129
|
+
|
|
130
|
+
| Flag | Default | Description |
|
|
131
|
+
|------|---------|-------------|
|
|
132
|
+
| `--label` | `codex` | Label applied to created issues |
|
|
133
|
+
| `--status` | `Backlog` | Project status field value |
|
|
134
|
+
| `--priority` | `P1` | Project priority field value |
|
|
135
|
+
| `--iteration` | `active` | Iteration title, `active`, or `none` |
|
|
136
|
+
| `--size-field` | `Size` | Project size field name |
|
|
137
|
+
| `--no-size-from-tshirt` | off | Disable t-shirt size mapping |
|
|
138
|
+
| `--verbose` | off | Enable verbose logging |
|
|
139
|
+
|
|
140
|
+
Full CLI reference: [docs/cli-reference.md](docs/cli-reference.md)
|
|
141
|
+
|
|
142
|
+
## Plan file schemas
|
|
143
|
+
|
|
144
|
+
See [docs/schemas.md](docs/schemas.md) for the expected structure of `epics.json`, `stories.json`, and `tasks.json`, with full examples.
|
|
145
|
+
|
|
146
|
+
A complete working example is in the [examples/](examples/) directory, including sample rendered issue bodies and a sync-map output.
|
|
147
|
+
|
|
148
|
+
## Documentation
|
|
149
|
+
|
|
150
|
+
- [How It Works](docs/how-it-works.md) -- sync pipeline, idempotency, what gets created
|
|
151
|
+
- [CLI Reference](docs/cli-reference.md) -- all flags and commands
|
|
152
|
+
- [Plan Schemas](docs/schemas.md) -- JSON format with examples and validation rules
|
|
153
|
+
- [Architecture](docs/architecture.md) -- module map, data flow, provider pattern, extension guide
|
|
154
|
+
- [Release Guide](RELEASE.md) -- automated versioning, publishing, and release pipeline
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
Development tasks use [poethepoet](https://github.com/nat-n/poethepoet):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
poe lint # ruff check
|
|
162
|
+
poe format # ruff format
|
|
163
|
+
poe test # pytest -v
|
|
164
|
+
poe coverage # pytest + HTML coverage report
|
|
165
|
+
poe typecheck # mypy
|
|
166
|
+
poe check # lint + format-check + tests (all-in-one)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Contributing
|
|
170
|
+
|
|
171
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and development instructions.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "planpilot"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
authors = ["aryeko"]
|
|
8
|
+
homepage = "https://github.com/aryeko/planpilot"
|
|
9
|
+
repository = "https://github.com/aryeko/planpilot"
|
|
10
|
+
keywords = ["github", "projects", "roadmap", "sync", "issues"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Topic :: Software Development :: Build Tools",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Programming Language :: Python :: 3.14",
|
|
21
|
+
]
|
|
22
|
+
packages = [{include = "planpilot", from = "src"}]
|
|
23
|
+
|
|
24
|
+
[tool.poetry.scripts]
|
|
25
|
+
planpilot = "planpilot.cli:main"
|
|
26
|
+
planpilot-slice = "planpilot.slice:slice_cli"
|
|
27
|
+
|
|
28
|
+
[tool.poetry.dependencies]
|
|
29
|
+
python = ">=3.11"
|
|
30
|
+
pydantic = "^2.12.5"
|
|
31
|
+
|
|
32
|
+
[tool.poetry.group.dev.dependencies]
|
|
33
|
+
pytest = ">=7.0"
|
|
34
|
+
ruff = ">=0.4"
|
|
35
|
+
mypy = ">=1.0"
|
|
36
|
+
pytest-cov = "^7.0.0"
|
|
37
|
+
pytest-asyncio = "^1.3.0"
|
|
38
|
+
commitlint = ">=1.3"
|
|
39
|
+
poethepoet = "^0.40.0"
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["poetry-core"]
|
|
43
|
+
build-backend = "poetry.core.masonry.api"
|
|
44
|
+
|
|
45
|
+
[tool.poe.tasks]
|
|
46
|
+
lint = "ruff check ."
|
|
47
|
+
format = "ruff format ."
|
|
48
|
+
format-check = "ruff format --check ."
|
|
49
|
+
test = "pytest -v"
|
|
50
|
+
coverage = "pytest -v --cov-report=html:.coverage/html"
|
|
51
|
+
typecheck = "mypy src/planpilot"
|
|
52
|
+
check = ["lint", "format-check", "test"]
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
testpaths = ["tests"]
|
|
56
|
+
addopts = "--cov=planpilot --cov-report=term-missing --cov-report=xml:.coverage/coverage.xml"
|
|
57
|
+
asyncio_mode = "auto"
|
|
58
|
+
|
|
59
|
+
[tool.coverage.run]
|
|
60
|
+
source = ["planpilot"]
|
|
61
|
+
branch = true
|
|
62
|
+
data_file = ".coverage/coverage.db"
|
|
63
|
+
|
|
64
|
+
[tool.coverage.report]
|
|
65
|
+
show_missing = true
|
|
66
|
+
skip_empty = true
|
|
67
|
+
exclude_lines = [
|
|
68
|
+
"pragma: no cover",
|
|
69
|
+
"if __name__ == .__main__.",
|
|
70
|
+
"if TYPE_CHECKING:",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
[tool.ruff]
|
|
74
|
+
target-version = "py311"
|
|
75
|
+
line-length = 120
|
|
76
|
+
src = ["src", "tests"]
|
|
77
|
+
|
|
78
|
+
[tool.ruff.lint]
|
|
79
|
+
select = [
|
|
80
|
+
"E", # pycodestyle errors
|
|
81
|
+
"F", # pyflakes
|
|
82
|
+
"I", # isort
|
|
83
|
+
"UP", # pyupgrade
|
|
84
|
+
"B", # bugbear
|
|
85
|
+
"SIM", # simplify
|
|
86
|
+
"RUF", # ruff-specific
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
[tool.ruff.lint.isort]
|
|
90
|
+
known-first-party = ["planpilot"]
|
|
91
|
+
|
|
92
|
+
[tool.mypy]
|
|
93
|
+
python_version = "3.11"
|
|
94
|
+
warn_return_any = true
|
|
95
|
+
warn_unused_configs = true
|
|
96
|
+
disallow_untyped_defs = true
|
|
97
|
+
plugins = ["pydantic.mypy"]
|
|
98
|
+
|
|
99
|
+
[tool.semantic_release]
|
|
100
|
+
version_toml = ["pyproject.toml:tool.poetry.version"]
|
|
101
|
+
version_variables = ["src/planpilot/__init__.py:__version__"]
|
|
102
|
+
commit_parser = "conventional"
|
|
103
|
+
commit_message = "chore(release): {version}"
|
|
104
|
+
tag_format = "v{version}"
|
|
105
|
+
major_on_zero = true
|
|
106
|
+
allow_zero_version = true
|
|
107
|
+
|
|
108
|
+
[tool.semantic_release.commit_parser_options]
|
|
109
|
+
minor_tags = ["feat"]
|
|
110
|
+
patch_tags = ["fix", "perf"]
|
|
111
|
+
|
|
112
|
+
[tool.semantic_release.branches.main]
|
|
113
|
+
match = "main"
|
|
114
|
+
|
|
115
|
+
[tool.semantic_release.changelog]
|
|
116
|
+
mode = "update"
|
|
117
|
+
|
|
118
|
+
[tool.semantic_release.remote]
|
|
119
|
+
type = "github"
|