devctl 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.
- devctl-1.0.0/LICENSE +21 -0
- devctl-1.0.0/PKG-INFO +127 -0
- devctl-1.0.0/README.md +86 -0
- devctl-1.0.0/devctl/__init__.py +3 -0
- devctl-1.0.0/devctl/commands/__init__.py +3 -0
- devctl-1.0.0/devctl/commands/add.py +166 -0
- devctl-1.0.0/devctl/commands/deploy.py +61 -0
- devctl-1.0.0/devctl/commands/docker.py +65 -0
- devctl-1.0.0/devctl/commands/init.py +193 -0
- devctl-1.0.0/devctl/commands/run.py +67 -0
- devctl-1.0.0/devctl/generators/__init__.py +3 -0
- devctl-1.0.0/devctl/generators/angular.py +112 -0
- devctl-1.0.0/devctl/generators/django.py +61 -0
- devctl-1.0.0/devctl/generators/docker_scaffold.py +656 -0
- devctl-1.0.0/devctl/generators/fastapi.py +67 -0
- devctl-1.0.0/devctl/generators/go_fiber.py +61 -0
- devctl-1.0.0/devctl/generators/nestjs.py +49 -0
- devctl-1.0.0/devctl/generators/nextjs.py +53 -0
- devctl-1.0.0/devctl/generators/nodejs.py +109 -0
- devctl-1.0.0/devctl/generators/react.py +43 -0
- devctl-1.0.0/devctl/generators/scaffold_angular.py +163 -0
- devctl-1.0.0/devctl/generators/scaffold_django.py +79 -0
- devctl-1.0.0/devctl/generators/scaffold_fastapi.py +83 -0
- devctl-1.0.0/devctl/generators/scaffold_go.py +67 -0
- devctl-1.0.0/devctl/generators/scaffold_nestjs.py +52 -0
- devctl-1.0.0/devctl/generators/scaffold_nextjs.py +73 -0
- devctl-1.0.0/devctl/generators/scaffold_nodejs.py +81 -0
- devctl-1.0.0/devctl/generators/scaffold_react.py +80 -0
- devctl-1.0.0/devctl/generators/scaffold_spring.py +166 -0
- devctl-1.0.0/devctl/generators/scaffold_svelte.py +73 -0
- devctl-1.0.0/devctl/generators/scaffold_vue.py +111 -0
- devctl-1.0.0/devctl/generators/spring.py +221 -0
- devctl-1.0.0/devctl/generators/svelte.py +52 -0
- devctl-1.0.0/devctl/generators/vue.py +105 -0
- devctl-1.0.0/devctl/main.py +45 -0
- devctl-1.0.0/devctl/orchestrator/__init__.py +3 -0
- devctl-1.0.0/devctl/orchestrator/config_builder.py +64 -0
- devctl-1.0.0/devctl/orchestrator/runner.py +219 -0
- devctl-1.0.0/devctl/orchestrator/scanner.py +155 -0
- devctl-1.0.0/devctl/templates/angular/config/environment.development.ts.j2 +4 -0
- devctl-1.0.0/devctl/templates/angular/config/environment.ts.j2 +5 -0
- devctl-1.0.0/devctl/templates/angular/config/proxy.conf.json.j2 +8 -0
- devctl-1.0.0/devctl/templates/angular/feature/models/request.model.ts.j2 +5 -0
- devctl-1.0.0/devctl/templates/angular/feature/models/response.model.ts.j2 +6 -0
- devctl-1.0.0/devctl/templates/angular/feature/pages/form/form.component.html.j2 +21 -0
- devctl-1.0.0/devctl/templates/angular/feature/pages/form/form.component.scss.j2 +0 -0
- devctl-1.0.0/devctl/templates/angular/feature/pages/form/form.component.ts.j2 +63 -0
- devctl-1.0.0/devctl/templates/angular/feature/pages/list/list.component.html.j2 +28 -0
- devctl-1.0.0/devctl/templates/angular/feature/pages/list/list.component.scss.j2 +0 -0
- devctl-1.0.0/devctl/templates/angular/feature/pages/list/list.component.ts.j2 +34 -0
- devctl-1.0.0/devctl/templates/angular/feature/routes.ts.j2 +9 -0
- devctl-1.0.0/devctl/templates/angular/feature/services/service.ts.j2 +34 -0
- devctl-1.0.0/devctl/templates/docker/deploy.yml.j2 +37 -0
- devctl-1.0.0/devctl/templates/docker/django/Dockerfile.j2 +21 -0
- devctl-1.0.0/devctl/templates/docker/fastapi/Dockerfile.j2 +15 -0
- devctl-1.0.0/devctl/templates/docker/frontend/Dockerfile.j2 +31 -0
- devctl-1.0.0/devctl/templates/docker/go/Dockerfile.j2 +24 -0
- devctl-1.0.0/devctl/templates/docker/nestjs/Dockerfile.j2 +26 -0
- devctl-1.0.0/devctl/templates/docker/nextjs/Dockerfile.j2 +43 -0
- devctl-1.0.0/devctl/templates/docker/nodejs/Dockerfile.j2 +24 -0
- devctl-1.0.0/devctl/templates/docker/spring/Dockerfile.j2 +24 -0
- devctl-1.0.0/devctl/templates/docker/svelte/Dockerfile.j2 +24 -0
- devctl-1.0.0/devctl/templates/proxy.conf.json.j2 +0 -0
- devctl-1.0.0/devctl/templates/spring/Controller.java.j2 +50 -0
- devctl-1.0.0/devctl/templates/spring/Entity.java.j2 +22 -0
- devctl-1.0.0/devctl/templates/spring/Repository.java.j2 +9 -0
- devctl-1.0.0/devctl/templates/spring/Service.java.j2 +20 -0
- devctl-1.0.0/devctl/templates/spring/ServiceImpl.java.j2 +62 -0
- devctl-1.0.0/devctl/templates/spring/application.properties.j2 +19 -0
- devctl-1.0.0/devctl/templates/spring/config/ApplicationConfig.java.j2 +46 -0
- devctl-1.0.0/devctl/templates/spring/config/JwtAuthenticationFilter.java.j2 +54 -0
- devctl-1.0.0/devctl/templates/spring/config/JwtService.java.j2 +68 -0
- devctl-1.0.0/devctl/templates/spring/config/SecurityConfig.java.j2 +42 -0
- devctl-1.0.0/devctl/templates/spring/docker-compose.yml.j2 +29 -0
- devctl-1.0.0/devctl/templates/spring/dto/Request.java.j2 +20 -0
- devctl-1.0.0/devctl/templates/spring/dto/Response.java.j2 +22 -0
- devctl-1.0.0/devctl/templates/spring/mapper/Mapper.java.j2 +30 -0
- devctl-1.0.0/devctl/templates/vue/config/App.vue.j2 +35 -0
- devctl-1.0.0/devctl/templates/vue/config/main.ts.j2 +9 -0
- devctl-1.0.0/devctl/templates/vue/config/router.ts.j2 +18 -0
- devctl-1.0.0/devctl/templates/vue/config/vite.config.ts.j2 +16 -0
- devctl-1.0.0/devctl/templates/vue/feature/Form.vue.j2 +162 -0
- devctl-1.0.0/devctl/templates/vue/feature/List.vue.j2 +155 -0
- devctl-1.0.0/devctl/templates/vue/feature/models.ts.j2 +12 -0
- devctl-1.0.0/devctl/templates/vue/feature/routes.ts.j2 +19 -0
- devctl-1.0.0/devctl/templates/vue/feature/service.ts.j2 +44 -0
- devctl-1.0.0/devctl/utils/__init__.py +3 -0
- devctl-1.0.0/devctl/utils/dependencies.py +36 -0
- devctl-1.0.0/devctl/utils/env_loader.py +57 -0
- devctl-1.0.0/devctl.egg-info/PKG-INFO +127 -0
- devctl-1.0.0/devctl.egg-info/SOURCES.txt +115 -0
- devctl-1.0.0/devctl.egg-info/dependency_links.txt +1 -0
- devctl-1.0.0/devctl.egg-info/entry_points.txt +2 -0
- devctl-1.0.0/devctl.egg-info/requires.txt +5 -0
- devctl-1.0.0/devctl.egg-info/top_level.txt +1 -0
- devctl-1.0.0/pyproject.toml +37 -0
- devctl-1.0.0/setup.cfg +4 -0
- devctl-1.0.0/test/test_add.py +35 -0
- devctl-1.0.0/test/test_commands.py +81 -0
- devctl-1.0.0/test/test_deploy.py +72 -0
- devctl-1.0.0/test/test_django.py +43 -0
- devctl-1.0.0/test/test_docker_scaffold.py +136 -0
- devctl-1.0.0/test/test_env_loader.py +49 -0
- devctl-1.0.0/test/test_fastapi.py +41 -0
- devctl-1.0.0/test/test_go.py +40 -0
- devctl-1.0.0/test/test_init.py +33 -0
- devctl-1.0.0/test/test_main.py +19 -0
- devctl-1.0.0/test/test_mongodb.py +39 -0
- devctl-1.0.0/test/test_nestjs.py +46 -0
- devctl-1.0.0/test/test_nextjs.py +40 -0
- devctl-1.0.0/test/test_nodejs.py +40 -0
- devctl-1.0.0/test/test_pom_patcher.py +52 -0
- devctl-1.0.0/test/test_react.py +44 -0
- devctl-1.0.0/test/test_runner.py +105 -0
- devctl-1.0.0/test/test_scanner.py +59 -0
- devctl-1.0.0/test/test_svelte.py +40 -0
- devctl-1.0.0/test/test_utils.py +21 -0
devctl-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Youssef Fellah
|
|
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.
|
devctl-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devctl
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Local development orchestrator for Spring Boot, Angular, and Vue.js
|
|
5
|
+
Author: Youssef Fellah
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Youssef Fellah
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Classifier: Programming Language :: Python :: 3
|
|
29
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
+
Classifier: Operating System :: OS Independent
|
|
31
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
32
|
+
Requires-Python: >=3.9
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: typer>=0.12.3
|
|
36
|
+
Requires-Dist: requests>=2.31.0
|
|
37
|
+
Requires-Dist: jinja2>=3.1.3
|
|
38
|
+
Requires-Dist: rich>=13.7.0
|
|
39
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# devctl
|
|
43
|
+
|
|
44
|
+
`devctl` is a professional command-line interface (CLI) designed to automate and
|
|
45
|
+
orchestrate the development lifecycle for modern full-stack architectures. It
|
|
46
|
+
provides a unified workflow for managing backends (Spring Boot, NestJS, Go,
|
|
47
|
+
FastAPI), frontends (Angular, Vue, React, NextJS, Svelte), and their
|
|
48
|
+
containerization.
|
|
49
|
+
|
|
50
|
+
## Core Features
|
|
51
|
+
|
|
52
|
+
- **Multi-Stack Orchestration**: Launch databases, multiple microservices, and
|
|
53
|
+
frontend dev servers with a single command. Includes real-time, prefixed log
|
|
54
|
+
streaming.
|
|
55
|
+
- **Full-Stack Scaffolding**: Generate consistent business resources
|
|
56
|
+
(Entities, DTOs, Controllers, Services) across both backend and frontend
|
|
57
|
+
layers simultaneously.
|
|
58
|
+
- **Instant Infrastructure**: Automatically generate optimized, multi-stage
|
|
59
|
+
`Dockerfiles` and global `docker-compose-prod.yml` configurations by scanning
|
|
60
|
+
your project tree.
|
|
61
|
+
- **Security by Default**: Inject standardized JWT authentication and security
|
|
62
|
+
configurations into new projects.
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
You can install `devctl` locally for development:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/yss-ef/devctl.git
|
|
70
|
+
cd devctl
|
|
71
|
+
pip install -e .
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Quick Start
|
|
75
|
+
|
|
76
|
+
### 1. Initialize a Full-Stack Project
|
|
77
|
+
|
|
78
|
+
Create a new backend and frontend in seconds:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
mkdir my-app && cd my-app
|
|
82
|
+
devctl init spring api --db postgres
|
|
83
|
+
devctl init angular front
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 2. Add a Business Resource
|
|
87
|
+
|
|
88
|
+
Generate a complete vertical slice of your application:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
devctl add resource Product -f "name:string,price:double,quantity:int"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 3. Run the Environment
|
|
95
|
+
|
|
96
|
+
Launch everything in parallel with automatic database startup:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
devctl run
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Supported Stacks
|
|
103
|
+
|
|
104
|
+
| Type | Frameworks / Technologies |
|
|
105
|
+
| :--- | :--- |
|
|
106
|
+
| **Backends** | Spring Boot, NestJS, Express (NodeJS), FastAPI, Django, Go (Fiber) |
|
|
107
|
+
| **Frontends** | Angular, Vue.js, ReactJS, NextJS, Svelte |
|
|
108
|
+
| **Databases** | PostgreSQL, MySQL, MongoDB |
|
|
109
|
+
|
|
110
|
+
## Documentation
|
|
111
|
+
|
|
112
|
+
For a detailed reference of all available commands and their options, see the
|
|
113
|
+
[Commands Reference](COMMANDS.md).
|
|
114
|
+
|
|
115
|
+
## Contributing
|
|
116
|
+
|
|
117
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for
|
|
118
|
+
development setup and code quality guidelines.
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
123
|
+
for details.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
Authored by Youssef Fellah.
|
|
127
|
+
Professional Development Orchestrator.
|
devctl-1.0.0/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# devctl
|
|
2
|
+
|
|
3
|
+
`devctl` is a professional command-line interface (CLI) designed to automate and
|
|
4
|
+
orchestrate the development lifecycle for modern full-stack architectures. It
|
|
5
|
+
provides a unified workflow for managing backends (Spring Boot, NestJS, Go,
|
|
6
|
+
FastAPI), frontends (Angular, Vue, React, NextJS, Svelte), and their
|
|
7
|
+
containerization.
|
|
8
|
+
|
|
9
|
+
## Core Features
|
|
10
|
+
|
|
11
|
+
- **Multi-Stack Orchestration**: Launch databases, multiple microservices, and
|
|
12
|
+
frontend dev servers with a single command. Includes real-time, prefixed log
|
|
13
|
+
streaming.
|
|
14
|
+
- **Full-Stack Scaffolding**: Generate consistent business resources
|
|
15
|
+
(Entities, DTOs, Controllers, Services) across both backend and frontend
|
|
16
|
+
layers simultaneously.
|
|
17
|
+
- **Instant Infrastructure**: Automatically generate optimized, multi-stage
|
|
18
|
+
`Dockerfiles` and global `docker-compose-prod.yml` configurations by scanning
|
|
19
|
+
your project tree.
|
|
20
|
+
- **Security by Default**: Inject standardized JWT authentication and security
|
|
21
|
+
configurations into new projects.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
You can install `devctl` locally for development:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/yss-ef/devctl.git
|
|
29
|
+
cd devctl
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### 1. Initialize a Full-Stack Project
|
|
36
|
+
|
|
37
|
+
Create a new backend and frontend in seconds:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
mkdir my-app && cd my-app
|
|
41
|
+
devctl init spring api --db postgres
|
|
42
|
+
devctl init angular front
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. Add a Business Resource
|
|
46
|
+
|
|
47
|
+
Generate a complete vertical slice of your application:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
devctl add resource Product -f "name:string,price:double,quantity:int"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Run the Environment
|
|
54
|
+
|
|
55
|
+
Launch everything in parallel with automatic database startup:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
devctl run
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Supported Stacks
|
|
62
|
+
|
|
63
|
+
| Type | Frameworks / Technologies |
|
|
64
|
+
| :--- | :--- |
|
|
65
|
+
| **Backends** | Spring Boot, NestJS, Express (NodeJS), FastAPI, Django, Go (Fiber) |
|
|
66
|
+
| **Frontends** | Angular, Vue.js, ReactJS, NextJS, Svelte |
|
|
67
|
+
| **Databases** | PostgreSQL, MySQL, MongoDB |
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
For a detailed reference of all available commands and their options, see the
|
|
72
|
+
[Commands Reference](COMMANDS.md).
|
|
73
|
+
|
|
74
|
+
## Contributing
|
|
75
|
+
|
|
76
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for
|
|
77
|
+
development setup and code quality guidelines.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
82
|
+
for details.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
Authored by Youssef Fellah.
|
|
86
|
+
Professional Development Orchestrator.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI command group for adding new resources to existing projects.
|
|
3
|
+
Supports Spring Boot, Angular, Vue.js, NestJS, NodeJS, React, NextJS, FastAPI,
|
|
4
|
+
Django, Svelte, and Go scaffolding.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from devctl.generators.scaffold_angular import generate_angular_resource
|
|
12
|
+
from devctl.generators.scaffold_django import generate_django_resource
|
|
13
|
+
from devctl.generators.scaffold_fastapi import generate_fastapi_resource
|
|
14
|
+
from devctl.generators.scaffold_go import generate_go_resource
|
|
15
|
+
from devctl.generators.scaffold_nestjs import generate_nest_resource
|
|
16
|
+
from devctl.generators.scaffold_nextjs import generate_nextjs_resource
|
|
17
|
+
from devctl.generators.scaffold_nodejs import generate_nodejs_resource
|
|
18
|
+
from devctl.generators.scaffold_react import generate_react_resource
|
|
19
|
+
from devctl.generators.scaffold_spring import generate_spring_resource
|
|
20
|
+
from devctl.generators.scaffold_svelte import generate_svelte_resource
|
|
21
|
+
from devctl.generators.scaffold_vue import generate_vue_resource
|
|
22
|
+
from devctl.orchestrator.scanner import detect_environment
|
|
23
|
+
from devctl.utils.dependencies import check_tool
|
|
24
|
+
|
|
25
|
+
app = typer.Typer(help="Adds resources to the current project (Scaffolding).")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@app.command()
|
|
29
|
+
def resource(
|
|
30
|
+
name: str = typer.Argument(..., help="The name of the resource (e.g., Client, Product)"),
|
|
31
|
+
fields: str = typer.Option(
|
|
32
|
+
"", "--fields", "-f", help="Fields in the format 'name:type, age:int'"
|
|
33
|
+
),
|
|
34
|
+
):
|
|
35
|
+
"""
|
|
36
|
+
Scans the current folder and generates a suitable business architecture.
|
|
37
|
+
"""
|
|
38
|
+
typer.secho("Analyzing current context...", fg=typer.colors.CYAN)
|
|
39
|
+
env_state = detect_environment(".")
|
|
40
|
+
|
|
41
|
+
original_dir = os.getcwd()
|
|
42
|
+
project_detected = False
|
|
43
|
+
|
|
44
|
+
# Check for Spring Boot project
|
|
45
|
+
if env_state["has_spring"]:
|
|
46
|
+
check_tool("java", "generating Spring Boot resources")
|
|
47
|
+
project_detected = True
|
|
48
|
+
typer.secho(
|
|
49
|
+
"Spring Boot project detected. Launching Java generator...", fg=typer.colors.GREEN
|
|
50
|
+
)
|
|
51
|
+
os.chdir(env_state["spring_path"])
|
|
52
|
+
try:
|
|
53
|
+
generate_spring_resource(name, fields)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
typer.secho(f"Error: Spring generation failed: {e}", fg=typer.colors.RED)
|
|
56
|
+
finally:
|
|
57
|
+
os.chdir(original_dir)
|
|
58
|
+
|
|
59
|
+
# Check for Angular project
|
|
60
|
+
if env_state["has_angular"]:
|
|
61
|
+
check_tool("npm", "generating Angular resources")
|
|
62
|
+
project_detected = True
|
|
63
|
+
typer.secho(
|
|
64
|
+
"Angular project detected. Launching TypeScript generator...", fg=typer.colors.CYAN
|
|
65
|
+
)
|
|
66
|
+
try:
|
|
67
|
+
generate_angular_resource(name, fields, root_path=".")
|
|
68
|
+
except Exception as e:
|
|
69
|
+
typer.secho(f"Error: Angular generation failed: {e}", fg=typer.colors.RED)
|
|
70
|
+
|
|
71
|
+
# Check for Vue.js project
|
|
72
|
+
if env_state.get("has_vue"):
|
|
73
|
+
check_tool("npm", "generating Vue.js resources")
|
|
74
|
+
project_detected = True
|
|
75
|
+
typer.secho("Vue.js project detected. Launching Vue generator...", fg=typer.colors.GREEN)
|
|
76
|
+
try:
|
|
77
|
+
generate_vue_resource(name, fields, root_path=".")
|
|
78
|
+
except Exception as e:
|
|
79
|
+
typer.secho(f"Error: Vue generation failed: {e}", fg=typer.colors.RED)
|
|
80
|
+
|
|
81
|
+
# Check for NestJS project
|
|
82
|
+
if env_state.get("has_nest"):
|
|
83
|
+
project_detected = True
|
|
84
|
+
typer.secho("NestJS project detected. Launching Nest generator...", fg=typer.colors.CYAN)
|
|
85
|
+
try:
|
|
86
|
+
generate_nest_resource(name, fields, root_path=".")
|
|
87
|
+
except Exception as e:
|
|
88
|
+
typer.secho(f"Error: Nest generation failed: {e}", fg=typer.colors.RED)
|
|
89
|
+
|
|
90
|
+
# Check for React project
|
|
91
|
+
if env_state.get("has_react"):
|
|
92
|
+
project_detected = True
|
|
93
|
+
typer.secho("React project detected. Launching React generator...", fg=typer.colors.BLUE)
|
|
94
|
+
try:
|
|
95
|
+
generate_react_resource(name, fields, root_path=".")
|
|
96
|
+
except Exception as e:
|
|
97
|
+
typer.secho(f"Error: React generation failed: {e}", fg=typer.colors.RED)
|
|
98
|
+
|
|
99
|
+
# Check for NextJS project
|
|
100
|
+
if env_state.get("has_nextjs"):
|
|
101
|
+
project_detected = True
|
|
102
|
+
typer.secho(
|
|
103
|
+
"NextJS project detected. Launching NextJS generator...", fg=typer.colors.YELLOW
|
|
104
|
+
)
|
|
105
|
+
try:
|
|
106
|
+
generate_nextjs_resource(name, fields, root_path=".")
|
|
107
|
+
except Exception as e:
|
|
108
|
+
typer.secho(f"Error: NextJS generation failed: {e}", fg=typer.colors.RED)
|
|
109
|
+
|
|
110
|
+
# Check for FastAPI project
|
|
111
|
+
if env_state.get("has_fastapi"):
|
|
112
|
+
project_detected = True
|
|
113
|
+
typer.secho(
|
|
114
|
+
"FastAPI project detected. Launching FastAPI generator...", fg=typer.colors.CYAN
|
|
115
|
+
)
|
|
116
|
+
try:
|
|
117
|
+
generate_fastapi_resource(name, fields, root_path=".")
|
|
118
|
+
except Exception as e:
|
|
119
|
+
typer.secho(f"Error: FastAPI generation failed: {e}", fg=typer.colors.RED)
|
|
120
|
+
|
|
121
|
+
# Check for Django project
|
|
122
|
+
if env_state.get("has_django"):
|
|
123
|
+
project_detected = True
|
|
124
|
+
typer.secho("Django project detected. Launching Django generator...", fg=typer.colors.GREEN)
|
|
125
|
+
try:
|
|
126
|
+
generate_django_resource(name, fields, root_path=".")
|
|
127
|
+
except Exception as e:
|
|
128
|
+
typer.secho(f"Error: Django generation failed: {e}", fg=typer.colors.RED)
|
|
129
|
+
|
|
130
|
+
# Check for Svelte project
|
|
131
|
+
if env_state.get("has_svelte"):
|
|
132
|
+
project_detected = True
|
|
133
|
+
typer.secho("Svelte project detected. Launching Svelte generator...", fg=typer.colors.RED)
|
|
134
|
+
try:
|
|
135
|
+
generate_svelte_resource(name, fields, root_path=".")
|
|
136
|
+
except Exception as e:
|
|
137
|
+
typer.secho(f"Error: Svelte generation failed: {e}", fg=typer.colors.RED)
|
|
138
|
+
|
|
139
|
+
# Check for Go project
|
|
140
|
+
if env_state.get("has_go"):
|
|
141
|
+
project_detected = True
|
|
142
|
+
typer.secho("Go project detected. Launching Go generator...", fg=typer.colors.CYAN)
|
|
143
|
+
try:
|
|
144
|
+
generate_go_resource(name, fields, root_path=".")
|
|
145
|
+
except Exception as e:
|
|
146
|
+
typer.secho(f"Error: Go generation failed: {e}", fg=typer.colors.RED)
|
|
147
|
+
|
|
148
|
+
# Check for NodeJS project
|
|
149
|
+
if os.path.exists("package.json") and not project_detected:
|
|
150
|
+
# Heuristic for generic nodejs project if not already caught by others
|
|
151
|
+
project_detected = True
|
|
152
|
+
typer.secho("NodeJS project detected. Launching NodeJS generator...", fg=typer.colors.GREEN)
|
|
153
|
+
try:
|
|
154
|
+
generate_nodejs_resource(name, fields, root_path=".")
|
|
155
|
+
except Exception as e:
|
|
156
|
+
typer.secho(f"Error: NodeJS generation failed: {e}", fg=typer.colors.RED)
|
|
157
|
+
|
|
158
|
+
# Error message only if NO project detected
|
|
159
|
+
if not project_detected:
|
|
160
|
+
typer.secho(
|
|
161
|
+
"Error: Unable to determine project type. "
|
|
162
|
+
"Please run from within a supported project directory "
|
|
163
|
+
"(Spring, Angular, React, NextJS, FastAPI, Django, Svelte, Go, or Vue.js).",
|
|
164
|
+
fg=typer.colors.RED,
|
|
165
|
+
)
|
|
166
|
+
raise typer.Exit(code=1)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from devctl.generators.docker_scaffold import (
|
|
6
|
+
DockerScaffoldError,
|
|
7
|
+
scaffold_docker_assets,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
app = typer.Typer(help="Deployment and orchestration commands.")
|
|
11
|
+
|
|
12
|
+
PATH_ARGUMENT = typer.Argument(
|
|
13
|
+
Path("."),
|
|
14
|
+
help="Repository or project directory to scan for services.",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
FORCE_OPTION = typer.Option(
|
|
18
|
+
False,
|
|
19
|
+
"--force",
|
|
20
|
+
help="Overwrite generated Docker files that already exist.",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
@app.command()
|
|
24
|
+
def deploy(
|
|
25
|
+
path: Path = PATH_ARGUMENT,
|
|
26
|
+
force: bool = FORCE_OPTION,
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Generate a global docker-compose-prod.yml by scanning subdirectories.
|
|
30
|
+
"""
|
|
31
|
+
typer.secho(f"Preparing deployment for {path.resolve()}...", fg=typer.colors.CYAN, bold=True)
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
result = scaffold_docker_assets(
|
|
35
|
+
path,
|
|
36
|
+
force=force,
|
|
37
|
+
)
|
|
38
|
+
except DockerScaffoldError as exc:
|
|
39
|
+
typer.secho(f"Error: {exc}", fg=typer.colors.RED)
|
|
40
|
+
raise typer.Exit(code=1) from exc
|
|
41
|
+
|
|
42
|
+
typer.secho(
|
|
43
|
+
f"Deployment scaffolding complete for {result.root_path}",
|
|
44
|
+
fg=typer.colors.CYAN,
|
|
45
|
+
bold=True,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
typer.echo("\nDetected services:")
|
|
49
|
+
for service in result.services:
|
|
50
|
+
typer.echo(f" - {service.kind}: {service.service_name} ({service.relative_context})")
|
|
51
|
+
|
|
52
|
+
typer.echo("\nFiles:")
|
|
53
|
+
for operation in result.operations:
|
|
54
|
+
if "docker-compose-prod.yml" in str(operation.path):
|
|
55
|
+
relative_path = operation.path.relative_to(result.root_path)
|
|
56
|
+
typer.echo(f" - {operation.action}: {relative_path}")
|
|
57
|
+
|
|
58
|
+
typer.secho(
|
|
59
|
+
f"\nSummary: {result.created_count} created, {result.skipped_count} skipped.",
|
|
60
|
+
fg=typer.colors.GREEN,
|
|
61
|
+
)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI command group for Docker-related operations.
|
|
3
|
+
Includes scaffolding Dockerfiles for detected services.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
from devctl.generators.docker_scaffold import (
|
|
11
|
+
DockerScaffoldError,
|
|
12
|
+
scaffold_docker_assets,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
PATH_ARGUMENT = typer.Argument(
|
|
16
|
+
Path("."),
|
|
17
|
+
help="Repository or project directory to scan for Dockerizable services.",
|
|
18
|
+
)
|
|
19
|
+
FORCE_OPTION = typer.Option(
|
|
20
|
+
False,
|
|
21
|
+
"--force",
|
|
22
|
+
help="Overwrite generated Docker files that already exist.",
|
|
23
|
+
)
|
|
24
|
+
DRY_RUN_OPTION = typer.Option(
|
|
25
|
+
False,
|
|
26
|
+
"--dry-run",
|
|
27
|
+
help="Show what would be generated without writing files.",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def dockerize(
|
|
32
|
+
path: Path = PATH_ARGUMENT,
|
|
33
|
+
force: bool = FORCE_OPTION,
|
|
34
|
+
dry_run: bool = DRY_RUN_OPTION,
|
|
35
|
+
):
|
|
36
|
+
"""
|
|
37
|
+
Scaffold Dockerfiles for Spring Boot, Angular, and Vue/Vite projects.
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
result = scaffold_docker_assets(
|
|
41
|
+
path,
|
|
42
|
+
force=force,
|
|
43
|
+
dry_run=dry_run,
|
|
44
|
+
)
|
|
45
|
+
except DockerScaffoldError as exc:
|
|
46
|
+
typer.secho(f"Error: {exc}", fg=typer.colors.RED)
|
|
47
|
+
raise typer.Exit(code=1) from exc
|
|
48
|
+
|
|
49
|
+
mode = "Dry run" if dry_run else "Docker scaffolding"
|
|
50
|
+
typer.secho(f"{mode} complete for {result.root_path}", fg=typer.colors.CYAN, bold=True)
|
|
51
|
+
|
|
52
|
+
typer.echo("\nDetected services:")
|
|
53
|
+
for service in result.services:
|
|
54
|
+
typer.echo(f" - {service.kind}: {service.service_name} ({service.relative_context})")
|
|
55
|
+
|
|
56
|
+
typer.echo("\nFiles:")
|
|
57
|
+
for operation in result.operations:
|
|
58
|
+
relative_path = operation.path.relative_to(result.root_path)
|
|
59
|
+
typer.echo(f" - {operation.action}: {relative_path}")
|
|
60
|
+
|
|
61
|
+
typer.secho(
|
|
62
|
+
f"\nSummary: {result.created_count} created, "
|
|
63
|
+
f"{result.skipped_count} skipped, {result.planned_count} planned.",
|
|
64
|
+
fg=typer.colors.GREEN,
|
|
65
|
+
)
|