dx-cli 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.
- dx_cli-0.1.0/LICENSE +21 -0
- dx_cli-0.1.0/PKG-INFO +145 -0
- dx_cli-0.1.0/README.md +120 -0
- dx_cli-0.1.0/dx/__init__.py +3 -0
- dx_cli-0.1.0/dx/__main__.py +5 -0
- dx_cli-0.1.0/dx/cli.py +141 -0
- dx_cli-0.1.0/dx/commands.py +752 -0
- dx_cli-0.1.0/dx/compose.py +501 -0
- dx_cli-0.1.0/dx/doctor.py +642 -0
- dx_cli-0.1.0/dx/generate.py +968 -0
- dx_cli-0.1.0/dx/output.py +77 -0
- dx_cli-0.1.0/dx/ports.py +471 -0
- dx_cli-0.1.0/dx/py.typed +0 -0
- dx_cli-0.1.0/dx_cli.egg-info/PKG-INFO +145 -0
- dx_cli-0.1.0/dx_cli.egg-info/SOURCES.txt +18 -0
- dx_cli-0.1.0/dx_cli.egg-info/dependency_links.txt +1 -0
- dx_cli-0.1.0/dx_cli.egg-info/entry_points.txt +2 -0
- dx_cli-0.1.0/dx_cli.egg-info/top_level.txt +1 -0
- dx_cli-0.1.0/pyproject.toml +39 -0
- dx_cli-0.1.0/setup.cfg +4 -0
dx_cli-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Lepton Software
|
|
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.
|
dx_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dx-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Developer experience CLI for Docker Compose monorepos — service scaffolding, port management, and project health checks
|
|
5
|
+
Author-email: Lepton Software <dev@lepton.software>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/LeptonSoftware/smart-market-platform
|
|
8
|
+
Project-URL: Repository, https://github.com/LeptonSoftware/smart-market-platform
|
|
9
|
+
Keywords: docker,compose,devtools,cli,monorepo,microservices
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Classifier: Topic :: System :: Systems Administration
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# dx — Developer Experience CLI
|
|
27
|
+
|
|
28
|
+
A zero-dependency CLI for managing Docker Compose monorepos. Handles service lifecycle, port management, code generation, and project health checks.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
pip install dx-cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or install from source:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pip install -e dev-cli/
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
dx up # Start all services
|
|
46
|
+
dx dev # Start with hot-reload
|
|
47
|
+
dx down # Stop everything
|
|
48
|
+
dx ps # Show running containers
|
|
49
|
+
dx logs service-data # Stream logs
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Commands
|
|
53
|
+
|
|
54
|
+
### Docker Lifecycle
|
|
55
|
+
|
|
56
|
+
| Command | Description |
|
|
57
|
+
|---------|-------------|
|
|
58
|
+
| `dx up [targets...]` | Start services (prod mode) |
|
|
59
|
+
| `dx dev [targets...]` | Start services (dev mode + hot-reload) |
|
|
60
|
+
| `dx down [targets...]` | Stop and remove containers |
|
|
61
|
+
| `dx restart [targets...]` | Restart containers |
|
|
62
|
+
| `dx reset [targets...]` | Stop + wipe volumes |
|
|
63
|
+
| `dx ps` | Show running containers |
|
|
64
|
+
| `dx logs [targets...]` | Stream container logs |
|
|
65
|
+
| `dx pull [targets...]` | Pull images |
|
|
66
|
+
| `dx reload <service>` | Recompile Java service for DevTools restart |
|
|
67
|
+
|
|
68
|
+
### Build / Test / Lint
|
|
69
|
+
|
|
70
|
+
| Command | Description |
|
|
71
|
+
|---------|-------------|
|
|
72
|
+
| `dx build [targets...]` | Build services (`all`, `common`, or names) |
|
|
73
|
+
| `dx test [targets...]` | Run tests (`all` or service names) |
|
|
74
|
+
| `dx lint [targets...]` | Run linters (`all`, `frontend`, `python`) |
|
|
75
|
+
|
|
76
|
+
### Service Scaffolding
|
|
77
|
+
|
|
78
|
+
| Command | Description |
|
|
79
|
+
|---------|-------------|
|
|
80
|
+
| `dx generate python <name>` | Scaffold a new Python/FastAPI service |
|
|
81
|
+
| `dx generate java <name>` | Scaffold a new Java/Spring Boot service |
|
|
82
|
+
|
|
83
|
+
Generated services include Dockerfiles, compose entries, health checks, config, and agent guides.
|
|
84
|
+
|
|
85
|
+
### Port Management
|
|
86
|
+
|
|
87
|
+
| Command | Description |
|
|
88
|
+
|---------|-------------|
|
|
89
|
+
| `dx ports` | Show port assignments |
|
|
90
|
+
| `dx ports pin <svc> <port>` | Pin a service to a specific port |
|
|
91
|
+
| `dx ports reset [service]` | Clear port reservations |
|
|
92
|
+
|
|
93
|
+
Ports are auto-allocated for all services (infra, services, apps) and persisted in `.dx/ports.json`.
|
|
94
|
+
|
|
95
|
+
### Project Health
|
|
96
|
+
|
|
97
|
+
| Command | Description |
|
|
98
|
+
|---------|-------------|
|
|
99
|
+
| `dx doctor` | Check project structure, Dockerfiles, and conventions |
|
|
100
|
+
| `dx doctor --fix` | Auto-fix issues in compose files and Dockerfiles |
|
|
101
|
+
|
|
102
|
+
Checks include:
|
|
103
|
+
- Compose service naming conventions
|
|
104
|
+
- Required files per service type (Dockerfile, pom.xml, pyproject.toml)
|
|
105
|
+
- Java Dockerfile module sync with pom.xml
|
|
106
|
+
- Hardcoded ports (auto-fixable)
|
|
107
|
+
- Missing Dockerfile references
|
|
108
|
+
|
|
109
|
+
### Proxy & DNS
|
|
110
|
+
|
|
111
|
+
| Command | Description |
|
|
112
|
+
|---------|-------------|
|
|
113
|
+
| `dx proxy start` | Start reverse proxy on `:7355` |
|
|
114
|
+
| `dx proxy stop` | Stop reverse proxy |
|
|
115
|
+
| `dx hosts setup` | Add `*.dx.localhost` DNS entries |
|
|
116
|
+
|
|
117
|
+
Access services at `http://<service>.dx.localhost:7355`.
|
|
118
|
+
|
|
119
|
+
## Target Resolution
|
|
120
|
+
|
|
121
|
+
Targets can be:
|
|
122
|
+
- **Group names**: `infra`, `services`, `apps`
|
|
123
|
+
- **Service names**: `service-data`, `infra-postgres`
|
|
124
|
+
- **Shorthand**: `data`, `ai`, `frontend`
|
|
125
|
+
- **Glob patterns**: `service-d*`, `app-*-ui`
|
|
126
|
+
|
|
127
|
+
## Compose File Convention
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
docker-compose.infra.yml # Infrastructure (prefix: infra-*)
|
|
131
|
+
docker-compose.services.yml # Backend services (prefix: service-*)
|
|
132
|
+
docker-compose.apps.yml # Frontend apps (prefix: app-*)
|
|
133
|
+
docker-compose.dev.services.yml # Dev overlay for services
|
|
134
|
+
docker-compose.dev.apps.yml # Dev overlay for apps
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Requirements
|
|
138
|
+
|
|
139
|
+
- Python 3.11+
|
|
140
|
+
- Docker with Compose v2
|
|
141
|
+
- No Python dependencies (zero-dependency CLI)
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT
|
dx_cli-0.1.0/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# dx — Developer Experience CLI
|
|
2
|
+
|
|
3
|
+
A zero-dependency CLI for managing Docker Compose monorepos. Handles service lifecycle, port management, code generation, and project health checks.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pip install dx-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or install from source:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install -e dev-cli/
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
dx up # Start all services
|
|
21
|
+
dx dev # Start with hot-reload
|
|
22
|
+
dx down # Stop everything
|
|
23
|
+
dx ps # Show running containers
|
|
24
|
+
dx logs service-data # Stream logs
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
### Docker Lifecycle
|
|
30
|
+
|
|
31
|
+
| Command | Description |
|
|
32
|
+
|---------|-------------|
|
|
33
|
+
| `dx up [targets...]` | Start services (prod mode) |
|
|
34
|
+
| `dx dev [targets...]` | Start services (dev mode + hot-reload) |
|
|
35
|
+
| `dx down [targets...]` | Stop and remove containers |
|
|
36
|
+
| `dx restart [targets...]` | Restart containers |
|
|
37
|
+
| `dx reset [targets...]` | Stop + wipe volumes |
|
|
38
|
+
| `dx ps` | Show running containers |
|
|
39
|
+
| `dx logs [targets...]` | Stream container logs |
|
|
40
|
+
| `dx pull [targets...]` | Pull images |
|
|
41
|
+
| `dx reload <service>` | Recompile Java service for DevTools restart |
|
|
42
|
+
|
|
43
|
+
### Build / Test / Lint
|
|
44
|
+
|
|
45
|
+
| Command | Description |
|
|
46
|
+
|---------|-------------|
|
|
47
|
+
| `dx build [targets...]` | Build services (`all`, `common`, or names) |
|
|
48
|
+
| `dx test [targets...]` | Run tests (`all` or service names) |
|
|
49
|
+
| `dx lint [targets...]` | Run linters (`all`, `frontend`, `python`) |
|
|
50
|
+
|
|
51
|
+
### Service Scaffolding
|
|
52
|
+
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---------|-------------|
|
|
55
|
+
| `dx generate python <name>` | Scaffold a new Python/FastAPI service |
|
|
56
|
+
| `dx generate java <name>` | Scaffold a new Java/Spring Boot service |
|
|
57
|
+
|
|
58
|
+
Generated services include Dockerfiles, compose entries, health checks, config, and agent guides.
|
|
59
|
+
|
|
60
|
+
### Port Management
|
|
61
|
+
|
|
62
|
+
| Command | Description |
|
|
63
|
+
|---------|-------------|
|
|
64
|
+
| `dx ports` | Show port assignments |
|
|
65
|
+
| `dx ports pin <svc> <port>` | Pin a service to a specific port |
|
|
66
|
+
| `dx ports reset [service]` | Clear port reservations |
|
|
67
|
+
|
|
68
|
+
Ports are auto-allocated for all services (infra, services, apps) and persisted in `.dx/ports.json`.
|
|
69
|
+
|
|
70
|
+
### Project Health
|
|
71
|
+
|
|
72
|
+
| Command | Description |
|
|
73
|
+
|---------|-------------|
|
|
74
|
+
| `dx doctor` | Check project structure, Dockerfiles, and conventions |
|
|
75
|
+
| `dx doctor --fix` | Auto-fix issues in compose files and Dockerfiles |
|
|
76
|
+
|
|
77
|
+
Checks include:
|
|
78
|
+
- Compose service naming conventions
|
|
79
|
+
- Required files per service type (Dockerfile, pom.xml, pyproject.toml)
|
|
80
|
+
- Java Dockerfile module sync with pom.xml
|
|
81
|
+
- Hardcoded ports (auto-fixable)
|
|
82
|
+
- Missing Dockerfile references
|
|
83
|
+
|
|
84
|
+
### Proxy & DNS
|
|
85
|
+
|
|
86
|
+
| Command | Description |
|
|
87
|
+
|---------|-------------|
|
|
88
|
+
| `dx proxy start` | Start reverse proxy on `:7355` |
|
|
89
|
+
| `dx proxy stop` | Stop reverse proxy |
|
|
90
|
+
| `dx hosts setup` | Add `*.dx.localhost` DNS entries |
|
|
91
|
+
|
|
92
|
+
Access services at `http://<service>.dx.localhost:7355`.
|
|
93
|
+
|
|
94
|
+
## Target Resolution
|
|
95
|
+
|
|
96
|
+
Targets can be:
|
|
97
|
+
- **Group names**: `infra`, `services`, `apps`
|
|
98
|
+
- **Service names**: `service-data`, `infra-postgres`
|
|
99
|
+
- **Shorthand**: `data`, `ai`, `frontend`
|
|
100
|
+
- **Glob patterns**: `service-d*`, `app-*-ui`
|
|
101
|
+
|
|
102
|
+
## Compose File Convention
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
docker-compose.infra.yml # Infrastructure (prefix: infra-*)
|
|
106
|
+
docker-compose.services.yml # Backend services (prefix: service-*)
|
|
107
|
+
docker-compose.apps.yml # Frontend apps (prefix: app-*)
|
|
108
|
+
docker-compose.dev.services.yml # Dev overlay for services
|
|
109
|
+
docker-compose.dev.apps.yml # Dev overlay for apps
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Requirements
|
|
113
|
+
|
|
114
|
+
- Python 3.11+
|
|
115
|
+
- Docker with Compose v2
|
|
116
|
+
- No Python dependencies (zero-dependency CLI)
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT
|
dx_cli-0.1.0/dx/cli.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""CLI entry point — argument parsing and command dispatch."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from dx import __version__
|
|
11
|
+
from dx.compose import ComposeCatalog
|
|
12
|
+
from dx.output import error
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _find_repo_root() -> Path:
|
|
16
|
+
"""Walk up from CWD to find the repo root (contains docker-compose.infra.yml)."""
|
|
17
|
+
# Check env var first (set by wrapper or user)
|
|
18
|
+
env_root = os.environ.get("DX_REPO_ROOT")
|
|
19
|
+
if env_root:
|
|
20
|
+
return Path(env_root)
|
|
21
|
+
|
|
22
|
+
path = Path.cwd()
|
|
23
|
+
while path != path.parent:
|
|
24
|
+
if (path / "docker-compose.infra.yml").exists():
|
|
25
|
+
return path
|
|
26
|
+
path = path.parent
|
|
27
|
+
|
|
28
|
+
# Fallback: assume CWD is repo root
|
|
29
|
+
return Path.cwd()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
USAGE = """\
|
|
33
|
+
dx — developer experience CLI for Docker Compose projects
|
|
34
|
+
|
|
35
|
+
Usage: dx <command> [targets...]
|
|
36
|
+
|
|
37
|
+
Docker lifecycle:
|
|
38
|
+
up [targets...] Start services (prod mode)
|
|
39
|
+
dev [targets...] Start services (dev mode + hot-reload)
|
|
40
|
+
down [targets...] Stop and remove containers
|
|
41
|
+
restart [targets...] Restart containers
|
|
42
|
+
reset [targets...] Stop + wipe volumes
|
|
43
|
+
ps Show running containers
|
|
44
|
+
logs [targets...] Stream container logs
|
|
45
|
+
pull [targets...] Pull images
|
|
46
|
+
reload <service> Recompile Java service for DevTools restart
|
|
47
|
+
|
|
48
|
+
Build / Test / Lint:
|
|
49
|
+
build [targets...] Build services ("all", "common", or names)
|
|
50
|
+
test [targets...] Run tests ("all" or service names)
|
|
51
|
+
lint [targets...] Run linters ("all", "frontend", "python")
|
|
52
|
+
|
|
53
|
+
Port management:
|
|
54
|
+
ports Show port assignments
|
|
55
|
+
ports pin <svc> <port> Pin a service to a specific port
|
|
56
|
+
ports reset [service] Clear port reservations
|
|
57
|
+
|
|
58
|
+
Proxy:
|
|
59
|
+
proxy start Start reverse proxy daemon on :7355
|
|
60
|
+
proxy stop Stop reverse proxy
|
|
61
|
+
hosts Show DNS resolution status
|
|
62
|
+
hosts setup Add *.dx.localhost entries (/etc/hosts)
|
|
63
|
+
hosts remove Remove all dx DNS entries
|
|
64
|
+
|
|
65
|
+
Dev utilities:
|
|
66
|
+
vite start|stop|logs Manage vite dev server as a daemon
|
|
67
|
+
|
|
68
|
+
Scaffolding:
|
|
69
|
+
generate python <name> Scaffold a new Python/FastAPI service
|
|
70
|
+
generate java <name> Scaffold a new Java/Spring Boot service
|
|
71
|
+
|
|
72
|
+
Project health:
|
|
73
|
+
doctor Check project structure, Dockerfiles, and conventions
|
|
74
|
+
doctor --fix Auto-fix issues in compose files and Dockerfiles
|
|
75
|
+
|
|
76
|
+
Setup:
|
|
77
|
+
init Initialize ClickStack/HyperDX
|
|
78
|
+
validate Run harness validation
|
|
79
|
+
list [group] List services by group
|
|
80
|
+
|
|
81
|
+
Targets can be group names (infra, services, apps), service names,
|
|
82
|
+
glob patterns (service-d*), or shorthand (data, frontend, ai).
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def main(argv: list[str] | None = None) -> None:
|
|
87
|
+
args = argv if argv is not None else sys.argv[1:]
|
|
88
|
+
|
|
89
|
+
if not args or args[0] in ("-h", "--help", "help"):
|
|
90
|
+
print(USAGE.strip())
|
|
91
|
+
sys.exit(0)
|
|
92
|
+
|
|
93
|
+
if args[0] in ("-V", "--version"):
|
|
94
|
+
print(f"dx {__version__}")
|
|
95
|
+
sys.exit(0)
|
|
96
|
+
|
|
97
|
+
command = args[0]
|
|
98
|
+
rest = args[1:]
|
|
99
|
+
|
|
100
|
+
root = _find_repo_root()
|
|
101
|
+
catalog = ComposeCatalog(root)
|
|
102
|
+
|
|
103
|
+
from dx import commands as cmd
|
|
104
|
+
|
|
105
|
+
from dx.doctor import cmd_doctor
|
|
106
|
+
from dx.generate import cmd_generate
|
|
107
|
+
|
|
108
|
+
dispatch = {
|
|
109
|
+
"up": lambda: cmd.cmd_up(catalog, rest),
|
|
110
|
+
"dev": lambda: cmd.cmd_dev(catalog, rest),
|
|
111
|
+
"down": lambda: cmd.cmd_down(catalog, rest),
|
|
112
|
+
"restart": lambda: cmd.cmd_restart(catalog, rest),
|
|
113
|
+
"reset": lambda: cmd.cmd_reset(catalog, rest),
|
|
114
|
+
"ps": lambda: cmd.cmd_ps(catalog),
|
|
115
|
+
"logs": lambda: cmd.cmd_logs(catalog, rest),
|
|
116
|
+
"pull": lambda: cmd.cmd_pull(catalog, rest),
|
|
117
|
+
"reload": lambda: cmd.cmd_reload(catalog, rest),
|
|
118
|
+
"build": lambda: cmd.cmd_build(catalog, rest),
|
|
119
|
+
"test": lambda: cmd.cmd_test(catalog, rest),
|
|
120
|
+
"lint": lambda: cmd.cmd_lint(catalog, rest),
|
|
121
|
+
"init": lambda: cmd.cmd_init(catalog),
|
|
122
|
+
"validate": lambda: cmd.cmd_validate(catalog),
|
|
123
|
+
"list": lambda: cmd.cmd_list(catalog, rest),
|
|
124
|
+
"ports": lambda: cmd.cmd_ports(catalog, rest),
|
|
125
|
+
"proxy": lambda: cmd.cmd_proxy(catalog, rest),
|
|
126
|
+
"hosts": lambda: cmd.cmd_hosts(catalog, rest),
|
|
127
|
+
"vite": lambda: cmd.cmd_vite(catalog, rest[0] if rest else ""),
|
|
128
|
+
"doctor": lambda: cmd_doctor(catalog, fix="--fix" in rest),
|
|
129
|
+
"generate": lambda: cmd_generate(catalog, rest),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
handler = dispatch.get(command)
|
|
133
|
+
if not handler:
|
|
134
|
+
error(f"Unknown command: {command}")
|
|
135
|
+
print(f"\nRun 'dx help' for usage.", file=sys.stderr)
|
|
136
|
+
sys.exit(1)
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
handler()
|
|
140
|
+
except KeyboardInterrupt:
|
|
141
|
+
sys.exit(130)
|