repopy 0.2.0__tar.gz → 0.3.1__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.
- {repopy-0.2.0/src/repopy.egg-info → repopy-0.3.1}/PKG-INFO +43 -25
- {repopy-0.2.0 → repopy-0.3.1}/README.md +42 -24
- {repopy-0.2.0 → repopy-0.3.1}/pyproject.toml +10 -1
- repopy-0.3.1/src/repopy/__main__.py +50 -0
- repopy-0.3.1/src/repopy/cli.py +115 -0
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy/dependencies.py +5 -4
- repopy-0.3.1/src/repopy/file_system.py +200 -0
- repopy-0.3.1/src/repopy/git_engine.py +91 -0
- repopy-0.3.1/src/repopy/orchestrators.py +166 -0
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy/os_detector.py +14 -10
- repopy-0.3.1/src/repopy/prompts.py +146 -0
- repopy-0.3.1/src/repopy/py.typed +0 -0
- repopy-0.3.1/src/repopy/templates.py +60 -0
- repopy-0.3.1/src/repopy/validators.py +48 -0
- {repopy-0.2.0 → repopy-0.3.1/src/repopy.egg-info}/PKG-INFO +43 -25
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy.egg-info/SOURCES.txt +9 -0
- repopy-0.3.1/tests/test_cli.py +64 -0
- repopy-0.3.1/tests/test_dependencies.py +27 -0
- repopy-0.3.1/tests/test_file_system.py +356 -0
- repopy-0.3.1/tests/test_git_engine.py +173 -0
- repopy-0.3.1/tests/test_main.py +156 -0
- repopy-0.3.1/tests/test_orchestrators.py +413 -0
- repopy-0.3.1/tests/test_os_detector.py +43 -0
- repopy-0.3.1/tests/test_prompts.py +207 -0
- repopy-0.3.1/tests/test_templates.py +40 -0
- repopy-0.3.1/tests/test_validators.py +62 -0
- repopy-0.2.0/src/repopy/__main__.py +0 -45
- repopy-0.2.0/src/repopy/cli.py +0 -99
- repopy-0.2.0/src/repopy/file_system.py +0 -128
- repopy-0.2.0/src/repopy/git_engine.py +0 -102
- repopy-0.2.0/src/repopy/orchestrators.py +0 -160
- repopy-0.2.0/src/repopy/prompts.py +0 -109
- repopy-0.2.0/src/repopy/templates.py +0 -47
- repopy-0.2.0/src/repopy/validators.py +0 -53
- repopy-0.2.0/tests/test_prompts.py +0 -45
- repopy-0.2.0/tests/test_validators.py +0 -41
- {repopy-0.2.0 → repopy-0.3.1}/LICENSE +0 -0
- {repopy-0.2.0 → repopy-0.3.1}/setup.cfg +0 -0
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy/__init__.py +0 -0
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy.egg-info/dependency_links.txt +0 -0
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy.egg-info/entry_points.txt +0 -0
- {repopy-0.2.0 → repopy-0.3.1}/src/repopy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repopy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: A modular CLI workspace initializer and cloning automation tool.
|
|
5
5
|
Author-email: Janitha Manatunga <janithamanatunga@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -28,25 +28,29 @@ Dynamic: license-file
|
|
|
28
28
|
A modular, cross-platform Python CLI workspace manager and developer tooling suite designed to automate reproducible local scaffolding, virtual environment creation, and remote repository synchronization.
|
|
29
29
|
|
|
30
30
|

|
|
31
|
+
[](https://opensource.org/license/mit)
|
|
32
|
+
[](https://pypi.org)
|
|
33
|
+
|
|
31
34
|
[](https://github.com/manatunga/repopy/actions/workflows/tests.yml)
|
|
32
|
-
[](https://codecov.io/github/manatunga/repopy)
|
|
36
|
+
[](https://mypy-lang.org)
|
|
37
|
+
[](#)
|
|
34
38
|
|
|
35
39
|
---
|
|
36
40
|
|
|
37
41
|
## 🌟 Key Features
|
|
38
42
|
|
|
39
|
-
- **Lifecycle Project Scaffolding (`repopy init`)**:
|
|
43
|
+
- **Lifecycle Project Scaffolding (`repopy init`)**: Provisions clean directory structures, dedicated virtual environments, automated `.gitignore` templates, and PEP 621 `pyproject.toml` or `requirements.txt` configs.
|
|
40
44
|
|
|
41
|
-
- **Remote Cloning (`repopy clone`)**: Clones remote Git repositories
|
|
45
|
+
- **Smart Remote Cloning (`repopy clone`)**: Clones remote Git repositories, creates isolated `.venv` environments, previews declared dependencies, and installs them interactively or via flags.
|
|
42
46
|
|
|
43
47
|
- **Upstream Linking (`repopy link`)**: Instantly connects an unlinked local workspace to a remote Git upstream, staging files, executing initial commits, and pushing to the default branch in one step.
|
|
44
48
|
|
|
45
|
-
- **Architectural Themes**:
|
|
49
|
+
- **Architectural Themes**: Built-in layout presets (`minimal`, `web_api`, `cli_package`, `data_science`) tailored to modern packaging standards.
|
|
46
50
|
|
|
47
|
-
- **Transactional Cleanups**: Employs defensive rollback mechanisms (`shutil.rmtree`) to purge
|
|
51
|
+
- **Transactional Cleanups**: Employs defensive rollback mechanisms (`shutil.rmtree`) to safely purge half-baked directories if setup fails midway.
|
|
48
52
|
|
|
49
|
-
- **
|
|
53
|
+
- **Isolated & Tested**: Fully decoupled architecture backed by comprehensive unit and mock test suites.
|
|
50
54
|
|
|
51
55
|
---
|
|
52
56
|
|
|
@@ -55,11 +59,11 @@ A modular, cross-platform Python CLI workspace manager and developer tooling sui
|
|
|
55
59
|
`repopy` is organized into single-responsibility layers:
|
|
56
60
|
- **Presentation & Routing (`cli.py`, `prompts.py`, `__main__.py`)**: Evaluates native terminal arguments via `argparse`, orchestrates interactive prompt flows, and handles OS interrupts gracefully.
|
|
57
61
|
|
|
58
|
-
- **Supervision (`orchestrators.py`)**: Broker layer executing lifecycle validation checks, branch sequencing, and command handoffs.
|
|
62
|
+
- **Supervision (`orchestrators.py`)**: Broker layer executing lifecycle validation checks, branch sequencing, rollback triggers and command handoffs.
|
|
59
63
|
|
|
60
|
-
- **Low-Level Engines (`file_system.py`, `git_engine.py`)**: Decoupled engines handling transactional directory allocations, venv isolation, and direct subprocess execution.
|
|
64
|
+
- **Low-Level Engines (`file_system.py`, `git_engine.py`)**: Decoupled engines handling transactional directory allocations, venv isolation, dependency installation and direct subprocess execution.
|
|
61
65
|
|
|
62
|
-
- **Validation & Translation (`validators.py`, `dependencies.py`, `os_detector.py`)**: Sanitizes paths,
|
|
66
|
+
- **Validation & Translation (`validators.py`, `dependencies.py`, `os_detector.py`)**: Sanitizes names and paths, validates Git URLs, verifies host binaries (`python`, `git`), and resolves cross-platform paths.
|
|
63
67
|
|
|
64
68
|
---
|
|
65
69
|
|
|
@@ -100,15 +104,25 @@ repopy init my-cli -t cli_package --link <git-url>
|
|
|
100
104
|
- `minimal`: Bare directory setup with `requirements.txt`.
|
|
101
105
|
- `web_api`: Layered service layout prepared for modern frameworks.
|
|
102
106
|
- `cli_package`: Modular structure configured with PEP 621 compliant `pyproject.toml`.
|
|
103
|
-
- `data_science`: Notebooks, data
|
|
104
|
-
|
|
107
|
+
- `data_science`: Notebooks, data directories (raw, processed), and pipeline layout.
|
|
108
|
+
|
|
105
109
|
<br>
|
|
106
110
|
|
|
107
111
|
### 2. Clone a Remote Project (`repopy clone`)
|
|
108
|
-
Fetch a remote repository
|
|
112
|
+
Fetch a remote repository, provision a virtual environment, and manage dependencies:
|
|
109
113
|
|
|
110
114
|
```bash
|
|
111
|
-
|
|
115
|
+
# Interactive mode (previews requirements.txt and prompts for installation)
|
|
116
|
+
repopy clone <git-url>
|
|
117
|
+
|
|
118
|
+
# Custom directory name
|
|
119
|
+
repopy clone <git-url> -n custom-folder-name
|
|
120
|
+
|
|
121
|
+
# Auto-install dependencies without prompting
|
|
122
|
+
repopy clone <git-url> -i
|
|
123
|
+
|
|
124
|
+
# Fetch and provision environment only (skip dependency installation)
|
|
125
|
+
repopy clone <git-url> --no-install
|
|
112
126
|
```
|
|
113
127
|
|
|
114
128
|
<br>
|
|
@@ -117,7 +131,11 @@ repopy clone <git-url> -n [custom-project-name]
|
|
|
117
131
|
Run inside an existing workspace to push tracking history to an upstream origin:
|
|
118
132
|
|
|
119
133
|
```bash
|
|
120
|
-
|
|
134
|
+
# Link with default initial commit message
|
|
135
|
+
repopy link <git-url>
|
|
136
|
+
|
|
137
|
+
# Link with custom commit message
|
|
138
|
+
repopy link <git-url> -m "feat: initial project structure"
|
|
121
139
|
```
|
|
122
140
|
|
|
123
141
|
---
|
|
@@ -130,8 +148,6 @@ Run the test suite using `pytest`:
|
|
|
130
148
|
pytest -v
|
|
131
149
|
```
|
|
132
150
|
|
|
133
|
-
All contributions and pull requests are validated through our GitHub Actions workflow matrix (`.github/workflows/tests.yml`), running integration and validation tests across supported Python versions.
|
|
134
|
-
|
|
135
151
|
---
|
|
136
152
|
|
|
137
153
|
## 🗂️ Project Structure
|
|
@@ -155,7 +171,16 @@ repopy/
|
|
|
155
171
|
│ ├── templates.py # Static asset definitions & manifests
|
|
156
172
|
│ └── validators.py # Input sanitation & regex filters
|
|
157
173
|
├── tests/
|
|
174
|
+
| ├── __init__.py
|
|
175
|
+
│ ├── test_cli.py # CLI argument parser & flag exclusivity tests
|
|
176
|
+
│ ├── test_dependencies.py # Binary detection & absence verification tests
|
|
177
|
+
│ ├── test_file_system.py # Workspace scaffolding & requirements parsing tests
|
|
178
|
+
│ ├── test_git_engine.py # Subprocess Git mocking & exit code tests
|
|
179
|
+
│ ├── test_main.py # CLI dispatching & interrupt lifecycle tests
|
|
180
|
+
│ ├── test_orchestrators.py # Pipeline logic, prompts, and rollback tests
|
|
181
|
+
│ ├── test_os_detector.py # Cross-platform path resolution tests
|
|
158
182
|
│ ├── test_prompts.py # Input loop & default manifest tests
|
|
183
|
+
│ ├── test_templates.py # PEP 621 generator & asset template tests
|
|
159
184
|
│ └── test_validators.py # Path and schema validation tests
|
|
160
185
|
├── pyproject.toml # PEP 621 packaging configuration
|
|
161
186
|
├── LICENSE # MIT License
|
|
@@ -167,10 +192,3 @@ repopy/
|
|
|
167
192
|
## 📄 License
|
|
168
193
|
|
|
169
194
|
Distributed under the MIT License. See `LICENSE` for details.
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## Key Review Notes
|
|
174
|
-
|
|
175
|
-
* Verify the GitHub Actions workflow file path (`.github/workflows/tests.yml`) matches your actual workflow file name so the build badge renders correctly.
|
|
176
|
-
* In the `repopy init` theme section, verify that the theme descriptions match what you have mapped out in `templates.py`.
|
|
@@ -3,25 +3,29 @@
|
|
|
3
3
|
A modular, cross-platform Python CLI workspace manager and developer tooling suite designed to automate reproducible local scaffolding, virtual environment creation, and remote repository synchronization.
|
|
4
4
|
|
|
5
5
|

|
|
6
|
+
[](https://opensource.org/license/mit)
|
|
7
|
+
[](https://pypi.org)
|
|
8
|
+
|
|
6
9
|
[](https://github.com/manatunga/repopy/actions/workflows/tests.yml)
|
|
7
|
-
[](https://codecov.io/github/manatunga/repopy)
|
|
11
|
+
[](https://mypy-lang.org)
|
|
12
|
+
[](#)
|
|
9
13
|
|
|
10
14
|
---
|
|
11
15
|
|
|
12
16
|
## 🌟 Key Features
|
|
13
17
|
|
|
14
|
-
- **Lifecycle Project Scaffolding (`repopy init`)**:
|
|
18
|
+
- **Lifecycle Project Scaffolding (`repopy init`)**: Provisions clean directory structures, dedicated virtual environments, automated `.gitignore` templates, and PEP 621 `pyproject.toml` or `requirements.txt` configs.
|
|
15
19
|
|
|
16
|
-
- **Remote Cloning (`repopy clone`)**: Clones remote Git repositories
|
|
20
|
+
- **Smart Remote Cloning (`repopy clone`)**: Clones remote Git repositories, creates isolated `.venv` environments, previews declared dependencies, and installs them interactively or via flags.
|
|
17
21
|
|
|
18
22
|
- **Upstream Linking (`repopy link`)**: Instantly connects an unlinked local workspace to a remote Git upstream, staging files, executing initial commits, and pushing to the default branch in one step.
|
|
19
23
|
|
|
20
|
-
- **Architectural Themes**:
|
|
24
|
+
- **Architectural Themes**: Built-in layout presets (`minimal`, `web_api`, `cli_package`, `data_science`) tailored to modern packaging standards.
|
|
21
25
|
|
|
22
|
-
- **Transactional Cleanups**: Employs defensive rollback mechanisms (`shutil.rmtree`) to purge
|
|
26
|
+
- **Transactional Cleanups**: Employs defensive rollback mechanisms (`shutil.rmtree`) to safely purge half-baked directories if setup fails midway.
|
|
23
27
|
|
|
24
|
-
- **
|
|
28
|
+
- **Isolated & Tested**: Fully decoupled architecture backed by comprehensive unit and mock test suites.
|
|
25
29
|
|
|
26
30
|
---
|
|
27
31
|
|
|
@@ -30,11 +34,11 @@ A modular, cross-platform Python CLI workspace manager and developer tooling sui
|
|
|
30
34
|
`repopy` is organized into single-responsibility layers:
|
|
31
35
|
- **Presentation & Routing (`cli.py`, `prompts.py`, `__main__.py`)**: Evaluates native terminal arguments via `argparse`, orchestrates interactive prompt flows, and handles OS interrupts gracefully.
|
|
32
36
|
|
|
33
|
-
- **Supervision (`orchestrators.py`)**: Broker layer executing lifecycle validation checks, branch sequencing, and command handoffs.
|
|
37
|
+
- **Supervision (`orchestrators.py`)**: Broker layer executing lifecycle validation checks, branch sequencing, rollback triggers and command handoffs.
|
|
34
38
|
|
|
35
|
-
- **Low-Level Engines (`file_system.py`, `git_engine.py`)**: Decoupled engines handling transactional directory allocations, venv isolation, and direct subprocess execution.
|
|
39
|
+
- **Low-Level Engines (`file_system.py`, `git_engine.py`)**: Decoupled engines handling transactional directory allocations, venv isolation, dependency installation and direct subprocess execution.
|
|
36
40
|
|
|
37
|
-
- **Validation & Translation (`validators.py`, `dependencies.py`, `os_detector.py`)**: Sanitizes paths,
|
|
41
|
+
- **Validation & Translation (`validators.py`, `dependencies.py`, `os_detector.py`)**: Sanitizes names and paths, validates Git URLs, verifies host binaries (`python`, `git`), and resolves cross-platform paths.
|
|
38
42
|
|
|
39
43
|
---
|
|
40
44
|
|
|
@@ -75,15 +79,25 @@ repopy init my-cli -t cli_package --link <git-url>
|
|
|
75
79
|
- `minimal`: Bare directory setup with `requirements.txt`.
|
|
76
80
|
- `web_api`: Layered service layout prepared for modern frameworks.
|
|
77
81
|
- `cli_package`: Modular structure configured with PEP 621 compliant `pyproject.toml`.
|
|
78
|
-
- `data_science`: Notebooks, data
|
|
79
|
-
|
|
82
|
+
- `data_science`: Notebooks, data directories (raw, processed), and pipeline layout.
|
|
83
|
+
|
|
80
84
|
<br>
|
|
81
85
|
|
|
82
86
|
### 2. Clone a Remote Project (`repopy clone`)
|
|
83
|
-
Fetch a remote repository
|
|
87
|
+
Fetch a remote repository, provision a virtual environment, and manage dependencies:
|
|
84
88
|
|
|
85
89
|
```bash
|
|
86
|
-
|
|
90
|
+
# Interactive mode (previews requirements.txt and prompts for installation)
|
|
91
|
+
repopy clone <git-url>
|
|
92
|
+
|
|
93
|
+
# Custom directory name
|
|
94
|
+
repopy clone <git-url> -n custom-folder-name
|
|
95
|
+
|
|
96
|
+
# Auto-install dependencies without prompting
|
|
97
|
+
repopy clone <git-url> -i
|
|
98
|
+
|
|
99
|
+
# Fetch and provision environment only (skip dependency installation)
|
|
100
|
+
repopy clone <git-url> --no-install
|
|
87
101
|
```
|
|
88
102
|
|
|
89
103
|
<br>
|
|
@@ -92,7 +106,11 @@ repopy clone <git-url> -n [custom-project-name]
|
|
|
92
106
|
Run inside an existing workspace to push tracking history to an upstream origin:
|
|
93
107
|
|
|
94
108
|
```bash
|
|
95
|
-
|
|
109
|
+
# Link with default initial commit message
|
|
110
|
+
repopy link <git-url>
|
|
111
|
+
|
|
112
|
+
# Link with custom commit message
|
|
113
|
+
repopy link <git-url> -m "feat: initial project structure"
|
|
96
114
|
```
|
|
97
115
|
|
|
98
116
|
---
|
|
@@ -105,8 +123,6 @@ Run the test suite using `pytest`:
|
|
|
105
123
|
pytest -v
|
|
106
124
|
```
|
|
107
125
|
|
|
108
|
-
All contributions and pull requests are validated through our GitHub Actions workflow matrix (`.github/workflows/tests.yml`), running integration and validation tests across supported Python versions.
|
|
109
|
-
|
|
110
126
|
---
|
|
111
127
|
|
|
112
128
|
## 🗂️ Project Structure
|
|
@@ -130,7 +146,16 @@ repopy/
|
|
|
130
146
|
│ ├── templates.py # Static asset definitions & manifests
|
|
131
147
|
│ └── validators.py # Input sanitation & regex filters
|
|
132
148
|
├── tests/
|
|
149
|
+
| ├── __init__.py
|
|
150
|
+
│ ├── test_cli.py # CLI argument parser & flag exclusivity tests
|
|
151
|
+
│ ├── test_dependencies.py # Binary detection & absence verification tests
|
|
152
|
+
│ ├── test_file_system.py # Workspace scaffolding & requirements parsing tests
|
|
153
|
+
│ ├── test_git_engine.py # Subprocess Git mocking & exit code tests
|
|
154
|
+
│ ├── test_main.py # CLI dispatching & interrupt lifecycle tests
|
|
155
|
+
│ ├── test_orchestrators.py # Pipeline logic, prompts, and rollback tests
|
|
156
|
+
│ ├── test_os_detector.py # Cross-platform path resolution tests
|
|
133
157
|
│ ├── test_prompts.py # Input loop & default manifest tests
|
|
158
|
+
│ ├── test_templates.py # PEP 621 generator & asset template tests
|
|
134
159
|
│ └── test_validators.py # Path and schema validation tests
|
|
135
160
|
├── pyproject.toml # PEP 621 packaging configuration
|
|
136
161
|
├── LICENSE # MIT License
|
|
@@ -142,10 +167,3 @@ repopy/
|
|
|
142
167
|
## 📄 License
|
|
143
168
|
|
|
144
169
|
Distributed under the MIT License. See `LICENSE` for details.
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Key Review Notes
|
|
149
|
-
|
|
150
|
-
* Verify the GitHub Actions workflow file path (`.github/workflows/tests.yml`) matches your actual workflow file name so the build badge renders correctly.
|
|
151
|
-
* In the `repopy init` theme section, verify that the theme descriptions match what you have mapped out in `templates.py`.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "repopy"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "A modular CLI workspace initializer and cloning automation tool."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -35,3 +35,12 @@ Repository = "https://github.com/manatunga/repopy"
|
|
|
35
35
|
|
|
36
36
|
[project.scripts]
|
|
37
37
|
repopy = "repopy.__main__:main"
|
|
38
|
+
|
|
39
|
+
[tool.coverage.report]
|
|
40
|
+
exclude_lines = [
|
|
41
|
+
"pragma: no cover",
|
|
42
|
+
"if __name__ == .__main__.:",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
repopy = ["py.typed"]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main entrypoint of repopy. Brings together the argument parser and
|
|
3
|
+
the orchestrators together under a main function.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from repopy.cli import parse_arguments
|
|
9
|
+
from repopy.orchestrators import CloneInitializer, LinkInitializer, LocalInitializer
|
|
10
|
+
from repopy.prompts import capture_project_manifests
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> None:
|
|
14
|
+
try:
|
|
15
|
+
args = parse_arguments()
|
|
16
|
+
|
|
17
|
+
if args.command == "init":
|
|
18
|
+
print("⌛ Working on it...\n")
|
|
19
|
+
manifest = capture_project_manifests(args)
|
|
20
|
+
local_initializer = LocalInitializer(manifest)
|
|
21
|
+
success = local_initializer.run()
|
|
22
|
+
|
|
23
|
+
if success and args.link:
|
|
24
|
+
print("⌛ Initiating automated repository link shortcut...")
|
|
25
|
+
link_initializer = LinkInitializer(args.link, args.message)
|
|
26
|
+
link_initializer.run()
|
|
27
|
+
|
|
28
|
+
elif args.command == "clone":
|
|
29
|
+
print("⌛ Working on it...\n")
|
|
30
|
+
clone_initializer = CloneInitializer(
|
|
31
|
+
args.repo_url, args.name, args.install, args.no_install
|
|
32
|
+
)
|
|
33
|
+
clone_initializer.run()
|
|
34
|
+
|
|
35
|
+
elif args.command == "link":
|
|
36
|
+
print("⌛ Working on it...\n")
|
|
37
|
+
link_initializer = LinkInitializer(args.repo_url, args.message)
|
|
38
|
+
link_initializer.run()
|
|
39
|
+
|
|
40
|
+
else:
|
|
41
|
+
print("Usage: repopy [init | clone | link] --help")
|
|
42
|
+
print("⚠️ Error: Please specify a subcommand")
|
|
43
|
+
|
|
44
|
+
except KeyboardInterrupt:
|
|
45
|
+
print("\n ✖️ Workspace operation cancelled by user.")
|
|
46
|
+
sys.exit(1)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
main()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parser layer. Imports Python's built-in argparse module
|
|
3
|
+
to identify user intent and any extra information passed.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def parse_arguments() -> argparse.Namespace:
|
|
10
|
+
parser = argparse.ArgumentParser(
|
|
11
|
+
description="repopy: A modular project scaffolder and workflow manager for Python."
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
15
|
+
|
|
16
|
+
# ---------------------------------------------------------------------------------
|
|
17
|
+
# `repopy init` subcommand
|
|
18
|
+
# ---------------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
init_parser = subparsers.add_parser(
|
|
21
|
+
"init",
|
|
22
|
+
help="Initializes a standardized Python development workspace in a new directory",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# Optional argument to add a project_name
|
|
26
|
+
init_parser.add_argument(
|
|
27
|
+
"project_name", nargs="?", help="Name of the target project folder to create"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Project theme shortcut flag (-t / --theme)
|
|
31
|
+
init_parser.add_argument(
|
|
32
|
+
"-t",
|
|
33
|
+
"--theme",
|
|
34
|
+
choices=["minimal", "web_api", "cli_package", "data_science"],
|
|
35
|
+
help="Pre-select an architectural theme layout",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Skip flag (-s / --skip) to bypass input prompts completely
|
|
39
|
+
init_parser.add_argument(
|
|
40
|
+
"-s",
|
|
41
|
+
"--skip",
|
|
42
|
+
action="store_true",
|
|
43
|
+
help="Skip interactive loops and generate workspace using default values",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Link flag (-l / --link) to pass an existing remote URL during creation
|
|
47
|
+
init_parser.add_argument(
|
|
48
|
+
"-l",
|
|
49
|
+
"--link",
|
|
50
|
+
metavar="GIT_URL",
|
|
51
|
+
help="Automatically link and push the new local repo to this remote Git URL",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Custom commit message shortcut allowed directly during init orchestration
|
|
55
|
+
init_parser.add_argument(
|
|
56
|
+
"-m",
|
|
57
|
+
"--message",
|
|
58
|
+
help="Custom commit message to use for the initial repository push",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# ---------------------------------------------------------------------------------
|
|
62
|
+
# `repopy clone` subcommand
|
|
63
|
+
# ---------------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
clone_parser = subparsers.add_parser(
|
|
66
|
+
"clone", help="Clones a remote Git repository to the local machine"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Positional argument to add remote Git URL
|
|
70
|
+
clone_parser.add_argument(
|
|
71
|
+
"repo_url", help="Repository URL from Github to clone locally"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Name flag (-n / --name) to pass an optional name for the to-be-cloned repository
|
|
75
|
+
clone_parser.add_argument("-n", "--name", help="Name of the project folder")
|
|
76
|
+
|
|
77
|
+
# Mutually exclusive commands regarding installing dependencies:
|
|
78
|
+
# install flag (-i / --install) for installing dependencies, bypassing prompt
|
|
79
|
+
# download-only flag (-d / --download-only) for only fetching dependencies without installing, bypassing prompt
|
|
80
|
+
deps_group = clone_parser.add_mutually_exclusive_group()
|
|
81
|
+
deps_group.add_argument(
|
|
82
|
+
"-i",
|
|
83
|
+
"--install",
|
|
84
|
+
action="store_true",
|
|
85
|
+
help="Automatically install dependencies without confirmation",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
deps_group.add_argument(
|
|
89
|
+
"--no-install",
|
|
90
|
+
action="store_true",
|
|
91
|
+
help="Skip dependency installation completely (fetch-only safe mode)",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------------
|
|
95
|
+
# `repopy link` subcommand
|
|
96
|
+
# ---------------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
link_parser = subparsers.add_parser(
|
|
99
|
+
"link",
|
|
100
|
+
help="Stage, commit and link current local repository to a remote Git URL",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Positional argument to add a dedicated existing remote Git URL for the local repository
|
|
104
|
+
link_parser.add_argument(
|
|
105
|
+
"repo_url",
|
|
106
|
+
help="Target remote Git repository URL (e.g., git@github.com:user/repo.git)",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
link_parser.add_argument(
|
|
110
|
+
"-m",
|
|
111
|
+
"--message",
|
|
112
|
+
help="Custom commit message to use instead of the default repopy message",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return parser.parse_args()
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
2
|
Layer for Dependency-checking. Contains functions to check whether
|
|
3
3
|
expected dependencies (such as python and git) are installed.
|
|
4
|
-
|
|
4
|
+
"""
|
|
5
5
|
|
|
6
6
|
import shutil
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
def has_python() -> bool:
|
|
9
|
-
return bool(shutil.which(
|
|
10
|
+
return bool(shutil.which("python") or shutil.which("python3"))
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def has_git() -> bool:
|
|
13
|
-
return bool(shutil.which(
|
|
14
|
+
return bool(shutil.which("git"))
|