go-dev 0.4.2 → 0.6.0
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.
- package/LICENSE +20 -20
- package/README.md +254 -230
- package/bin/go-dev +18 -14
- package/package.json +1 -1
- package/src/cli-args.js +83 -0
- package/src/config.js +143 -122
- package/src/dependency-resolver.js +103 -101
- package/src/index.js +9 -4
- package/src/logger.js +47 -0
- package/src/orchestrator.js +180 -171
- package/src/prefix-lines.js +19 -19
- package/src/process-manager.js +358 -306
- package/src/service-colors.js +58 -0
- package/src/services/base.js +63 -51
- package/src/services/cmd.js +250 -148
- package/src/services/docker.js +194 -197
- package/src/services/ready-check.js +134 -0
- package/src/terminal-formatting/apply-formatting-codes.js +223 -223
- package/src/terminal-formatting/constants.js +150 -150
- package/src/terminal-formatting/detect-last-formatting.js +10 -10
- package/src/terminal-formatting/extract-formatting-codes.js +26 -26
- package/test/go-dev.yml +84 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Giuliano Collacchioni
|
|
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
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Giuliano Collacchioni
|
|
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
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,231 +1,255 @@
|
|
|
1
|
-
# `go-dev`
|
|
2
|
-
|
|
3
|
-
A simple and robust orchestrator for streamlining local development environments in monorepos.
|
|
4
|
-
|
|
5
|
-
**`npx go-dev <preset>` – Go develop!**
|
|
6
|
-
|
|
7
|
-
## 🚀 Introduction
|
|
8
|
-
|
|
9
|
-
In complex monorepos, starting your development environment can be a chore. You might need to spin up Docker containers, run multiple Node.js (or other language) development servers, handle pre-builds, and manage inter-service dependencies. `go-dev` simplifies this by allowing you to define your entire local development stack in a single YAML configuration file.
|
|
10
|
-
|
|
11
|
-
`go-dev` acts as a central command to bring up your `api`, `frontend`, `database`, and any other microservices, ensuring they start in the correct order, with the right modes, and provide clear, prefixed logs.
|
|
12
|
-
|
|
13
|
-
## ✨ Features
|
|
14
|
-
|
|
15
|
-
* **Unified Configuration:** Define all your services, their modes (e.g., `dev`, `docker`, `serve`), and dependencies in a single `go-dev.yml` file.
|
|
16
|
-
* **Service Types:**
|
|
17
|
-
* **`cmd` services:** Run any command-line process (e.g., `npm run dev`, `rollup -w`, `python app.py`). Supports `preCommands` for setup tasks like builds. Commands can be defined in multiple flexible ways to run single or multiple processes in parallel for a service.
|
|
18
|
-
* **`docker` services:** Manage Docker containers via `docker compose`. Automatically checks container status and performs health checks.
|
|
19
|
-
* **Mode-Aware Dependencies:** Services can depend on other services running in specific modes (e.g., your `api` dev mode might depend on `frontend` in `serve` mode).
|
|
20
|
-
* **Preset-Driven Startup:** Define different "presets" (e.g., `api`, `frontend`, `all`) to easily spin up specific combinations of services tailored to your current development focus.
|
|
21
|
-
* **Automatic Dependency Resolution:** `go-dev` builds an intelligent execution graph, starting services in the correct topological order.
|
|
22
|
-
* **Centralized Logging:** Prefixes logs from each service, making it easy to follow activity from multiple concurrent processes.
|
|
23
|
-
* **Automatic Process Exit:** The `go-dev` process will automatically exit when all primary services (those directly listed in the chosen preset) exit cleanly (with a success code of `0`).
|
|
24
|
-
* **Precise Docker Cleanup:** `go-dev` intelligently tracks which Docker Compose services it **actively started** (i.e., those that were not already running). During cleanup, it will only stop these specific services, leaving any pre-existing containers untouched.
|
|
25
|
-
* **Robust Cleanup:** Handles graceful shutdown of all started processes and Docker services on exit (e.g., via `Ctrl+C` or automatic exit).
|
|
26
|
-
|
|
27
|
-
## 🤔 Why `go-dev`?
|
|
28
|
-
|
|
29
|
-
While tools like `concurrently` manage parallel processes and `docker compose` handles containers, `go-dev` fills a crucial gap by:
|
|
30
|
-
|
|
31
|
-
* **Integrating `cmd` and `docker` services seamlessly:** It bridges the world of host-based processes and containerized applications under one roof.
|
|
32
|
-
* **Providing intelligent mode-aware dependency resolution:** It understands that "frontend" might mean a different set of commands (and dependencies) when you're actively developing the frontend vs. when it's just a dependency for API development.
|
|
33
|
-
* **Offering a single, declarative interface for your entire dev stack:** No more remembering multiple `npm` scripts or `docker compose` commands.
|
|
34
|
-
|
|
35
|
-
## 📦 Installation
|
|
36
|
-
|
|
37
|
-
`go-dev` is distributed via npm and designed to be used with `npx`.
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# Install it as a devDependency in your monorepo's root
|
|
41
|
-
npm install --save-dev go-dev
|
|
42
|
-
# or
|
|
43
|
-
yarn add --dev go-dev
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## 🚀 Usage
|
|
47
|
-
|
|
48
|
-
Once installed, simply run `go-dev` with the name of the preset you want to start:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
npx go-dev <preset_name> [
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
* `<preset_name>`: The name of the preset defined in your `go-dev.yml` (e.g., `api`, `frontend`, `all`).
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
**Passing Arguments to Service Commands:**
|
|
58
|
-
|
|
59
|
-
To pass additional arguments from the command line to a specific service command, use a keyword flag followed by the target and its arguments.
|
|
60
|
-
|
|
61
|
-
By default, the keyword flag is `--args-for`. This can be customized in your `go-dev.yml` using the `serviceArgsKeyword` option (e.g., `serviceArgsKeyword: pass-to`).
|
|
62
|
-
|
|
63
|
-
The target for arguments is specified as `<service_name>[:<command_index>]`:
|
|
64
|
-
|
|
65
|
-
Specify the target for arguments as `<service_name>:<command_index>` (e.g., `api:0`, `frontend:1`). The `command_index` is 0-based and refers to the position of the command within a service's `commands` array. If the `:<command_index>` part is omitted (e.g., just `<service_name>`), arguments are passed to the **first command (index `0`)** defined for that service.
|
|
66
|
-
|
|
67
|
-
You can combine multiple keyword flag blocks for different services or specific commands.
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
npx go-dev <preset_name> [--<serviceArgsKeyword> <service_name>[:<command_index>] [args...] ] [...]
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**How Arguments are Applied to `cmd` Service Commands:**
|
|
74
|
-
|
|
75
|
-
When arguments are passed to a `cmd` type service command, `go-dev` processes them in a special way:
|
|
76
|
-
|
|
77
|
-
1. **Placeholder Substitution:**
|
|
78
|
-
* The command array (e.g., `[npx, tsx, ./src/$arg.ts]`) is scanned for the special placeholder `$arg`.
|
|
79
|
-
* Each occurrence of `$arg` is replaced, in order, by an argument from the `[args...]` provided on the command line.
|
|
80
|
-
* Example: A command `[npx, tsx, ./src/$arg.ts]` with extra arguments `[index, -w]` will become `[npx, tsx, ./src/index.ts, -w]`.
|
|
81
|
-
|
|
82
|
-
2. **Escaped Placeholders:**
|
|
83
|
-
* If you need a literal `$arg` in your command that should *not* be substituted, escape it with a backslash: `\$arg`.
|
|
84
|
-
* Example: A command `[echo, \$arg]` with no extra arguments will result in `[echo, $arg]`.
|
|
85
|
-
|
|
86
|
-
3. **Remaining Arguments:**
|
|
87
|
-
* Any arguments from `[args...]` that were *not* used to substitute an `$arg` placeholder will be **appended** to the end of the command array.
|
|
88
|
-
* Example: A command `[echo, $arg, fixed]` with extra arguments `[first, second, third]` will become `[echo, first, fixed, second, third]`. Here, `first` replaces `$arg`, and `second`, `third` are appended.
|
|
89
|
-
|
|
90
|
-
**Full Example:**
|
|
91
|
-
|
|
92
|
-
Consider an `api` service with two parallel commands: `api:0` (main server, using `$arg`) and `api:1` (TypeScript compiler watch).
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
npx go-dev all \
|
|
96
|
-
--args-for api:0 main-entrypoint --host 0.0.0.0 --port 8081 \
|
|
97
|
-
--args-for api:1 --pretty --diagnostics \
|
|
98
|
-
--args-for frontend --log-level verbose
|
|
99
|
-
```
|
|
100
|
-
*In the example above, `--args-for frontend` is equivalent to `--args-for frontend:0`.*
|
|
101
|
-
|
|
102
|
-
Press `Ctrl+C` at any time to gracefully shut down all running services. `go-dev` will also automatically exit once all primary services (those directly listed in your chosen preset) have completed their execution cleanly.
|
|
103
|
-
|
|
104
|
-
## ⚙️ Configuration (`go-dev.yml`)
|
|
105
|
-
|
|
106
|
-
Create a configuration file in your project's root.
|
|
107
|
-
|
|
108
|
-
By default, `go-dev` automatically detects its configuration file. It looks for files named `go-dev` (or `.go-dev` for a hidden file), optionally including `.config` before the `.yml` or `.yaml` extension. It will search for these files in the directory where you run `npx go-dev`.
|
|
109
|
-
|
|
110
|
-
Common examples include: `go-dev.yml`, `.go-dev.yml`, and `go-dev.config.yaml`.
|
|
111
|
-
|
|
112
|
-
```yaml
|
|
113
|
-
# go-dev.yml
|
|
114
|
-
|
|
115
|
-
# Customize the keyword used to pass arguments to service commands from the CLI.
|
|
116
|
-
# Change this if 'args-for' conflicts with a command your services use.
|
|
117
|
-
serviceArgsKeyword: args-for # Default value
|
|
118
|
-
|
|
119
|
-
# Define your individual services here
|
|
120
|
-
services:
|
|
121
|
-
# Example: A Docker-based PostgreSQL database
|
|
122
|
-
postgres:
|
|
123
|
-
type: docker # This service runs inside Docker
|
|
124
|
-
service: postgres # Name of the service in your docker-compose.yml
|
|
125
|
-
composeFile: infrastructure/docker-compose.yml # Path to the docker-compose file
|
|
126
|
-
healthCheck: true # Enable health checks for this Docker service
|
|
127
|
-
|
|
128
|
-
# Example: Your API service, which can run in 'dev' (cmd) or 'docker' mode
|
|
129
|
-
api:
|
|
130
|
-
type: hybrid # This service has multiple modes
|
|
131
|
-
defaultMode: dev # Default mode if not specified by a preset or dependency
|
|
132
|
-
# Note: The name of the modes is totally arbitrary
|
|
133
|
-
modes:
|
|
134
|
-
# API in active development mode (runs directly on host)
|
|
135
|
-
dev:
|
|
136
|
-
type: cmd # This mode runs a command-line process
|
|
137
|
-
# The 'commands' property can be specified in three ways:
|
|
138
|
-
# 1. As a simple array of strings (for a single command without extra options)
|
|
139
|
-
# commands: [npx, rollup, -c, -w]
|
|
140
|
-
# 2. As a single command object (for one command with options like 'directory' or 'restartOnError')
|
|
141
|
-
# commands:
|
|
142
|
-
# command: [npx, rollup, -c, -w]
|
|
143
|
-
# directory: ./api
|
|
144
|
-
# restartOnError: true # Default is true for 'cmd' services
|
|
145
|
-
# 3. As an array of command objects (for multiple parallel commands)
|
|
146
|
-
commands:
|
|
147
|
-
- command: [npx, rollup, -c, -w] # The primary command for development (index 0)
|
|
148
|
-
directory: ./api # Directory to run the command from
|
|
149
|
-
# restartOnError: true # (Optional, defaults to true)
|
|
150
|
-
# Example of a second parallel command for API (index 1)
|
|
151
|
-
# - command: [npx, tsc, --watch]
|
|
152
|
-
# directory: ./api
|
|
153
|
-
dependencies: # What this mode depends on
|
|
154
|
-
- postgres # API dev needs PostgreSQL (will use postgres's default docker mode)
|
|
155
|
-
- { service: frontend, mode: serve } # API dev needs frontend running in its 'serve' mode
|
|
156
|
-
|
|
157
|
-
# API running as a Docker container (e.g., for frontend-only dev)
|
|
158
|
-
docker:
|
|
159
|
-
type: docker
|
|
160
|
-
service: api
|
|
161
|
-
composeFile: infrastructure/docker-compose.yml
|
|
162
|
-
healthCheck: true
|
|
163
|
-
dependencies:
|
|
164
|
-
- postgres # Docker API also needs PostgreSQL
|
|
165
|
-
|
|
166
|
-
# Example: Your Frontend service, which can run in 'dev' (cmd) or 'serve' (cmd) mode
|
|
167
|
-
frontend:
|
|
168
|
-
type: hybrid
|
|
169
|
-
defaultMode: dev
|
|
170
|
-
modes:
|
|
171
|
-
# Frontend in active development (watch mode)
|
|
172
|
-
dev:
|
|
173
|
-
type: cmd
|
|
174
|
-
commands:
|
|
175
|
-
command: [npx, rollup, -c, -w]
|
|
176
|
-
directory: ./frontend
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
1
|
+
# `go-dev`
|
|
2
|
+
|
|
3
|
+
A simple and robust orchestrator for streamlining local development environments in monorepos.
|
|
4
|
+
|
|
5
|
+
**`npx go-dev <preset>` – Go develop!**
|
|
6
|
+
|
|
7
|
+
## 🚀 Introduction
|
|
8
|
+
|
|
9
|
+
In complex monorepos, starting your development environment can be a chore. You might need to spin up Docker containers, run multiple Node.js (or other language) development servers, handle pre-builds, and manage inter-service dependencies. `go-dev` simplifies this by allowing you to define your entire local development stack in a single YAML configuration file.
|
|
10
|
+
|
|
11
|
+
`go-dev` acts as a central command to bring up your `api`, `frontend`, `database`, and any other microservices, ensuring they start in the correct order, with the right modes, and provide clear, prefixed logs.
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
* **Unified Configuration:** Define all your services, their modes (e.g., `dev`, `docker`, `serve`), and dependencies in a single `go-dev.yml` file.
|
|
16
|
+
* **Service Types:**
|
|
17
|
+
* **`cmd` services:** Run any command-line process (e.g., `npm run dev`, `rollup -w`, `python app.py`). Supports `preCommands` for setup tasks like builds, and `readyWhen` to hold back dependents until the service is actually usable (log match, file, or open port). Commands can be defined in multiple flexible ways to run single or multiple processes in parallel for a service.
|
|
18
|
+
* **`docker` services:** Manage Docker containers via `docker compose`. Automatically checks container status and performs health checks.
|
|
19
|
+
* **Mode-Aware Dependencies:** Services can depend on other services running in specific modes (e.g., your `api` dev mode might depend on `frontend` in `serve` mode).
|
|
20
|
+
* **Preset-Driven Startup:** Define different "presets" (e.g., `api`, `frontend`, `all`) to easily spin up specific combinations of services tailored to your current development focus.
|
|
21
|
+
* **Automatic Dependency Resolution:** `go-dev` builds an intelligent execution graph, starting services in the correct topological order.
|
|
22
|
+
* **Centralized Logging:** Prefixes logs from each service, making it easy to follow activity from multiple concurrent processes.
|
|
23
|
+
* **Automatic Process Exit:** The `go-dev` process will automatically exit when all primary services (those directly listed in the chosen preset) exit cleanly (with a success code of `0`).
|
|
24
|
+
* **Precise Docker Cleanup:** `go-dev` intelligently tracks which Docker Compose services it **actively started** (i.e., those that were not already running). During cleanup, it will only stop these specific services, leaving any pre-existing containers untouched.
|
|
25
|
+
* **Robust Cleanup:** Handles graceful shutdown of all started processes and Docker services on exit (e.g., via `Ctrl+C` or automatic exit).
|
|
26
|
+
|
|
27
|
+
## 🤔 Why `go-dev`?
|
|
28
|
+
|
|
29
|
+
While tools like `concurrently` manage parallel processes and `docker compose` handles containers, `go-dev` fills a crucial gap by:
|
|
30
|
+
|
|
31
|
+
* **Integrating `cmd` and `docker` services seamlessly:** It bridges the world of host-based processes and containerized applications under one roof.
|
|
32
|
+
* **Providing intelligent mode-aware dependency resolution:** It understands that "frontend" might mean a different set of commands (and dependencies) when you're actively developing the frontend vs. when it's just a dependency for API development.
|
|
33
|
+
* **Offering a single, declarative interface for your entire dev stack:** No more remembering multiple `npm` scripts or `docker compose` commands.
|
|
34
|
+
|
|
35
|
+
## 📦 Installation
|
|
36
|
+
|
|
37
|
+
`go-dev` is distributed via npm and designed to be used with `npx`.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Install it as a devDependency in your monorepo's root
|
|
41
|
+
npm install --save-dev go-dev
|
|
42
|
+
# or
|
|
43
|
+
yarn add --dev go-dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 🚀 Usage
|
|
47
|
+
|
|
48
|
+
Once installed, simply run `go-dev` with the name of the preset you want to start:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx go-dev <preset_name> [-c|--config <path>]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
* `<preset_name>`: The name of the preset defined in your `go-dev.yml` (e.g., `api`, `frontend`, `all`).
|
|
55
|
+
* `-c <path>` / `--config <path>` (also `-c=<path>` / `--config=<path>`): (Optional) Path to your `go-dev.yml` file. When omitted, `go-dev` auto-discovers a config file in the current directory (see the **Configuration** section below for the lookup order). The flag must appear before any `--args-for` block.
|
|
56
|
+
|
|
57
|
+
**Passing Arguments to Service Commands:**
|
|
58
|
+
|
|
59
|
+
To pass additional arguments from the command line to a specific service command, use a keyword flag followed by the target and its arguments.
|
|
60
|
+
|
|
61
|
+
By default, the keyword flag is `--args-for`. This can be customized in your `go-dev.yml` using the `serviceArgsKeyword` option (e.g., `serviceArgsKeyword: pass-to`).
|
|
62
|
+
|
|
63
|
+
The target for arguments is specified as `<service_name>[:<command_index>]`:
|
|
64
|
+
|
|
65
|
+
Specify the target for arguments as `<service_name>:<command_index>` (e.g., `api:0`, `frontend:1`). The `command_index` is 0-based and refers to the position of the command within a service's `commands` array. If the `:<command_index>` part is omitted (e.g., just `<service_name>`), arguments are passed to the **first command (index `0`)** defined for that service.
|
|
66
|
+
|
|
67
|
+
You can combine multiple keyword flag blocks for different services or specific commands.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx go-dev <preset_name> [--<serviceArgsKeyword> <service_name>[:<command_index>] [args...] ] [...]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**How Arguments are Applied to `cmd` Service Commands:**
|
|
74
|
+
|
|
75
|
+
When arguments are passed to a `cmd` type service command, `go-dev` processes them in a special way:
|
|
76
|
+
|
|
77
|
+
1. **Placeholder Substitution:**
|
|
78
|
+
* The command array (e.g., `[npx, tsx, ./src/$arg.ts]`) is scanned for the special placeholder `$arg`.
|
|
79
|
+
* Each occurrence of `$arg` is replaced, in order, by an argument from the `[args...]` provided on the command line.
|
|
80
|
+
* Example: A command `[npx, tsx, ./src/$arg.ts]` with extra arguments `[index, -w]` will become `[npx, tsx, ./src/index.ts, -w]`.
|
|
81
|
+
|
|
82
|
+
2. **Escaped Placeholders:**
|
|
83
|
+
* If you need a literal `$arg` in your command that should *not* be substituted, escape it with a backslash: `\$arg`.
|
|
84
|
+
* Example: A command `[echo, \$arg]` with no extra arguments will result in `[echo, $arg]`.
|
|
85
|
+
|
|
86
|
+
3. **Remaining Arguments:**
|
|
87
|
+
* Any arguments from `[args...]` that were *not* used to substitute an `$arg` placeholder will be **appended** to the end of the command array.
|
|
88
|
+
* Example: A command `[echo, $arg, fixed]` with extra arguments `[first, second, third]` will become `[echo, first, fixed, second, third]`. Here, `first` replaces `$arg`, and `second`, `third` are appended.
|
|
89
|
+
|
|
90
|
+
**Full Example:**
|
|
91
|
+
|
|
92
|
+
Consider an `api` service with two parallel commands: `api:0` (main server, using `$arg`) and `api:1` (TypeScript compiler watch).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx go-dev all \
|
|
96
|
+
--args-for api:0 main-entrypoint --host 0.0.0.0 --port 8081 \
|
|
97
|
+
--args-for api:1 --pretty --diagnostics \
|
|
98
|
+
--args-for frontend --log-level verbose
|
|
99
|
+
```
|
|
100
|
+
*In the example above, `--args-for frontend` is equivalent to `--args-for frontend:0`.*
|
|
101
|
+
|
|
102
|
+
Press `Ctrl+C` at any time to gracefully shut down all running services. `go-dev` will also automatically exit once all primary services (those directly listed in your chosen preset) have completed their execution cleanly.
|
|
103
|
+
|
|
104
|
+
## ⚙️ Configuration (`go-dev.yml`)
|
|
105
|
+
|
|
106
|
+
Create a configuration file in your project's root.
|
|
107
|
+
|
|
108
|
+
By default, `go-dev` automatically detects its configuration file. It looks for files named `go-dev` (or `.go-dev` for a hidden file), optionally including `.config` before the `.yml` or `.yaml` extension. It will search for these files in the directory where you run `npx go-dev`.
|
|
109
|
+
|
|
110
|
+
Common examples include: `go-dev.yml`, `.go-dev.yml`, and `go-dev.config.yaml`.
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
# go-dev.yml
|
|
114
|
+
|
|
115
|
+
# Customize the keyword used to pass arguments to service commands from the CLI.
|
|
116
|
+
# Change this if 'args-for' conflicts with a command your services use.
|
|
117
|
+
serviceArgsKeyword: args-for # Default value
|
|
118
|
+
|
|
119
|
+
# Define your individual services here
|
|
120
|
+
services:
|
|
121
|
+
# Example: A Docker-based PostgreSQL database
|
|
122
|
+
postgres:
|
|
123
|
+
type: docker # This service runs inside Docker
|
|
124
|
+
service: postgres # Name of the service in your docker-compose.yml
|
|
125
|
+
composeFile: infrastructure/docker-compose.yml # Path to the docker-compose file
|
|
126
|
+
healthCheck: true # Enable health checks for this Docker service
|
|
127
|
+
|
|
128
|
+
# Example: Your API service, which can run in 'dev' (cmd) or 'docker' mode
|
|
129
|
+
api:
|
|
130
|
+
type: hybrid # This service has multiple modes
|
|
131
|
+
defaultMode: dev # Default mode if not specified by a preset or dependency
|
|
132
|
+
# Note: The name of the modes is totally arbitrary
|
|
133
|
+
modes:
|
|
134
|
+
# API in active development mode (runs directly on host)
|
|
135
|
+
dev:
|
|
136
|
+
type: cmd # This mode runs a command-line process
|
|
137
|
+
# The 'commands' property can be specified in three ways:
|
|
138
|
+
# 1. As a simple array of strings (for a single command without extra options)
|
|
139
|
+
# commands: [npx, rollup, -c, -w]
|
|
140
|
+
# 2. As a single command object (for one command with options like 'directory' or 'restartOnError')
|
|
141
|
+
# commands:
|
|
142
|
+
# command: [npx, rollup, -c, -w]
|
|
143
|
+
# directory: ./api
|
|
144
|
+
# restartOnError: true # Default is true for 'cmd' services
|
|
145
|
+
# 3. As an array of command objects (for multiple parallel commands)
|
|
146
|
+
commands:
|
|
147
|
+
- command: [npx, rollup, -c, -w] # The primary command for development (index 0)
|
|
148
|
+
directory: ./api # Directory to run the command from
|
|
149
|
+
# restartOnError: true # (Optional, defaults to true)
|
|
150
|
+
# Example of a second parallel command for API (index 1)
|
|
151
|
+
# - command: [npx, tsc, --watch]
|
|
152
|
+
# directory: ./api
|
|
153
|
+
dependencies: # What this mode depends on
|
|
154
|
+
- postgres # API dev needs PostgreSQL (will use postgres's default docker mode)
|
|
155
|
+
- { service: frontend, mode: serve } # API dev needs frontend running in its 'serve' mode
|
|
156
|
+
|
|
157
|
+
# API running as a Docker container (e.g., for frontend-only dev)
|
|
158
|
+
docker:
|
|
159
|
+
type: docker
|
|
160
|
+
service: api
|
|
161
|
+
composeFile: infrastructure/docker-compose.yml
|
|
162
|
+
healthCheck: true
|
|
163
|
+
dependencies:
|
|
164
|
+
- postgres # Docker API also needs PostgreSQL
|
|
165
|
+
|
|
166
|
+
# Example: Your Frontend service, which can run in 'dev' (cmd) or 'serve' (cmd) mode
|
|
167
|
+
frontend:
|
|
168
|
+
type: hybrid
|
|
169
|
+
defaultMode: dev
|
|
170
|
+
modes:
|
|
171
|
+
# Frontend in active development (watch mode)
|
|
172
|
+
dev:
|
|
173
|
+
type: cmd
|
|
174
|
+
commands:
|
|
175
|
+
command: [npx, rollup, -c, -w]
|
|
176
|
+
directory: ./frontend
|
|
177
|
+
# 'readyWhen' holds back dependents until this (long-running) service is
|
|
178
|
+
# actually usable, instead of resolving as soon as the process spawns.
|
|
179
|
+
# This is the watch-mode counterpart of docker's 'healthCheck': prefer it
|
|
180
|
+
# over building shared artifacts again as a preCommand of every consumer.
|
|
181
|
+
# Provide at least one condition (multiple are combined with AND):
|
|
182
|
+
# logMatch: "<regex>" — ready when a line on stdout/stderr matches
|
|
183
|
+
# file: ./dist/index.js — ready when the path exists on disk
|
|
184
|
+
# port: 5173 — ready when a TCP connection succeeds
|
|
185
|
+
# Optional: host (default 127.0.0.1), timeoutMs (60000), pollIntervalMs (500).
|
|
186
|
+
readyWhen:
|
|
187
|
+
logMatch: "created .* in" # rollup's "created dist/... in 1.2s"
|
|
188
|
+
dependencies:
|
|
189
|
+
# Frontend dev needs API (will use api's default docker mode for this preset)
|
|
190
|
+
# Note: No direct circular dependency between dev modes.
|
|
191
|
+
# Dev modes often assume peers will eventually be ready.
|
|
192
|
+
- { service: api, mode: docker }
|
|
193
|
+
|
|
194
|
+
# Frontend serving its built assets (e.g., when API depends on it)
|
|
195
|
+
serve:
|
|
196
|
+
type: cmd
|
|
197
|
+
# 'preCommands' run and complete BEFORE the main command starts.
|
|
198
|
+
# Each entry can be one of:
|
|
199
|
+
# 1. An array of strings — a literal command, run synchronously.
|
|
200
|
+
# - [npm, --prefix, frontend, run, build]
|
|
201
|
+
# 2. An object — a literal command with options.
|
|
202
|
+
# - { command: [npm, run, build], directory: ./frontend }
|
|
203
|
+
# 3. An object referencing another service+mode — runs that service to
|
|
204
|
+
# completion (its own preCommands recurse; parallel commands run in
|
|
205
|
+
# parallel and are all awaited). The target must be a `cmd`-type
|
|
206
|
+
# mode. If multiple services reference the same `service:mode`
|
|
207
|
+
# within a single `go-dev` invocation, it runs only ONCE and other
|
|
208
|
+
# referrers await the same result.
|
|
209
|
+
# - { service: main, mode: build }
|
|
210
|
+
preCommands:
|
|
211
|
+
- [npm, --prefix, frontend, run, build]
|
|
212
|
+
commands:
|
|
213
|
+
command: [node, ./localserver.mjs] # Then start the local server
|
|
214
|
+
directory: ./frontend
|
|
215
|
+
dependencies:
|
|
216
|
+
- api # Frontend serve needs API (will use api's default dev mode for this preset)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# Define different development presets (combinations of services and their modes)
|
|
220
|
+
presets:
|
|
221
|
+
# Preset: "api" development focus
|
|
222
|
+
# Starts API in dev mode, pulling in its dependencies (postgres, frontend:serve)
|
|
223
|
+
api:
|
|
224
|
+
services: [api] # Only explicitly list top-level services you want to run
|
|
225
|
+
modes:
|
|
226
|
+
# no explicit modes needed here, as defaultMode and dependency requests handle it
|
|
227
|
+
# api: dev # (already default)
|
|
228
|
+
# frontend: serve # (requested by api:dev)
|
|
229
|
+
# postgres: dev # (pulled by dependencies)
|
|
230
|
+
|
|
231
|
+
# Preset: "frontend" development focus
|
|
232
|
+
# Starts Frontend in dev mode, pulling in its dependencies (api:docker, postgres)
|
|
233
|
+
frontend:
|
|
234
|
+
services: [frontend]
|
|
235
|
+
modes:
|
|
236
|
+
# frontend: dev # (already default)
|
|
237
|
+
# api: docker # (requested by frontend:dev)
|
|
238
|
+
# postgres: dev # (pulled by dependencies)
|
|
239
|
+
|
|
240
|
+
# Preset: "all" development (both API and Frontend in dev mode concurrently)
|
|
241
|
+
all:
|
|
242
|
+
services: [api, frontend] # Explicitly list both as top-level focus
|
|
243
|
+
modes:
|
|
244
|
+
# api: dev # (already default)
|
|
245
|
+
# frontend: dev # (already default)
|
|
246
|
+
# No need to specify modes if they match the defaultMode
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## 🤝 Contributing
|
|
250
|
+
|
|
251
|
+
Contributions are welcome! Feel free to open issues or submit pull requests.
|
|
252
|
+
|
|
253
|
+
## 📄 License
|
|
254
|
+
|
|
231
255
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
package/bin/go-dev
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const Orchestrator = require('../src/orchestrator');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const Orchestrator = require('../src/orchestrator');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const { parseCliArgs } = require('../src/cli-args');
|
|
7
|
+
|
|
8
|
+
const { presetName, configPath, logLevel, remaining } = parseCliArgs(process.argv.slice(2));
|
|
9
|
+
|
|
10
|
+
if (!presetName) {
|
|
11
|
+
console.error('Error: Please specify a preset to run. Usage: go-dev <preset_name> [-c|--config <path>] [-l|--log-level <level>] [--args-for ...]');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
process.argv = [process.argv[0], process.argv[1], presetName, ...remaining];
|
|
16
|
+
|
|
17
|
+
const orchestrator = new Orchestrator(configPath, { logLevel });
|
|
18
|
+
|
|
15
19
|
orchestrator.start(presetName);
|