0
# Triggers and Automation
1
2
Configure commands to execute automatically when files change, with pattern matching and batching support. Triggers enable automated workflows based on file system changes.
3
4
## Capabilities
5
6
### Create Trigger
7
8
Set up a trigger that executes a command when files matching specified patterns change.
9
10
```bash { .api }
11
watchman -- trigger <path> <trigger-name> [patterns...] -- <command> [args...]
12
```
13
14
**JSON Protocol:**
15
```json
16
["trigger", "/absolute/path", "trigger-name", "pattern1", "pattern2", "--", "command", "arg1", "arg2"]
17
```
18
19
**Parameters:**
20
- `path`: Absolute path to watched directory (required)
21
- `trigger-name`: Unique name for this trigger (required)
22
- `patterns`: Filename patterns to match (optional)
23
- `command`: Command to execute (required)
24
- `args`: Command arguments (optional)
25
26
**Response:**
27
```json
28
{
29
"version": "2.0",
30
"triggerid": "unique-trigger-id"
31
}
32
```
33
34
The `--` separator is required when using the CLI to distinguish patterns from the command and its arguments.
35
36
**Example:**
37
```bash
38
# Trigger on JavaScript file changes
39
watchman -- trigger ~/project jsfiles '*.js' -- echo "JS file changed"
40
41
# Trigger with complex command
42
watchman -- trigger ~/project build '*.c' '*.h' -- make clean && make
43
44
# Trigger on any file change
45
watchman -- trigger ~/project notify -- notify-send "Files changed"
46
```
47
48
### List Triggers
49
50
Return all triggers registered for a watched directory.
51
52
```bash { .api }
53
watchman trigger-list <path>
54
```
55
56
**JSON Protocol:**
57
```json
58
["trigger-list", "/absolute/path"]
59
```
60
61
**Parameters:**
62
- `path`: Absolute path to watched directory (required)
63
64
**Response:**
65
```json
66
{
67
"version": "2.0",
68
"triggers": [
69
{
70
"name": "jsfiles",
71
"command": ["echo", "JS file changed"],
72
"expression": ["suffix", "js"],
73
"append_files": true
74
}
75
]
76
}
77
```
78
79
**Example:**
80
```bash
81
$ watchman trigger-list ~/project
82
{
83
"version": "2.0",
84
"triggers": [
85
{
86
"name": "build",
87
"command": ["make"],
88
"expression": ["anyof", ["suffix", "c"], ["suffix", "h"]]
89
}
90
]
91
}
92
```
93
94
### Delete Trigger
95
96
Remove a named trigger from a watched directory.
97
98
```bash { .api }
99
watchman trigger-del <path> <trigger-name>
100
```
101
102
**JSON Protocol:**
103
```json
104
["trigger-del", "/absolute/path", "trigger-name"]
105
```
106
107
**Parameters:**
108
- `path`: Absolute path to watched directory (required)
109
- `trigger-name`: Name of trigger to delete (required)
110
111
**Response:**
112
```json
113
{
114
"version": "2.0",
115
"deleted": true,
116
"trigger": "trigger-name"
117
}
118
```
119
120
**Example:**
121
```bash
122
# Delete a specific trigger
123
watchman trigger-del ~/project jsfiles
124
```
125
126
## Trigger Execution Behavior
127
128
### File System Settling
129
- Watchman waits for the filesystem to settle before executing triggers
130
- Default settle time is 20 milliseconds (configurable with `-s` option)
131
- Batches multiple file changes into a single trigger execution
132
133
### Command Execution
134
- Triggers execute in the watched directory (using `chdir`)
135
- Changed files are passed as command-line arguments
136
- Standard input receives JSON array of file information
137
- Only one instance of a trigger runs at a time per watch
138
139
### File Information Format
140
Standard input receives JSON with file details:
141
```json
142
[
143
{
144
"name": "src/main.js",
145
"exists": true,
146
"size": 1024,
147
"mode": 33188,
148
"mtime": 1234567890,
149
"new": false
150
}
151
]
152
```
153
154
### Command Line Length Limits
155
- Watchman respects system `ARG_MAX` limits
156
- If command line would be too long, excess files are truncated
157
- Use JSON input stream for processing large file lists
158
159
**Example reading JSON input:**
160
```bash
161
# Shell script that processes JSON input
162
#!/bin/bash
163
while read -r line; do
164
echo "Changed files: $line" | jq '.[] | .name'
165
done
166
```
167
168
## Advanced Trigger Configuration
169
170
### Pattern Matching
171
Triggers support the same pattern syntax as queries:
172
173
```bash
174
# Glob patterns
175
watchman -- trigger ~/project css '*.css' '*.scss' -- sass-compile
176
177
# Regex patterns
178
watchman -- trigger ~/project tests -p '\.test\.(js|ts)$' -- npm test
179
180
# Exclusion patterns
181
watchman -- trigger ~/project build '*.js' '! node_modules' -- webpack
182
```
183
184
### Trigger State Persistence
185
- Triggers are saved in the Watchman state file
186
- Automatically restored when Watchman restarts
187
- Use `--no-save-state` to disable persistence
188
189
### Environment Variables
190
Watchman provides environment variables to triggered commands:
191
- `WATCHMAN_ROOT`: The watched root path
192
- `WATCHMAN_SOCK`: Path to Watchman socket
193
- `WATCHMAN_TRIGGER`: Name of the trigger being executed
194
195
## Usage Examples
196
197
### Build System Integration
198
199
```bash
200
# Auto-compile on source changes
201
watchman -- trigger ~/project compile '*.c' '*.h' -- make
202
203
# Run tests when test files change
204
watchman -- trigger ~/project test '*.test.js' -- npm test
205
206
# Restart server on code changes
207
watchman -- trigger ~/project restart '*.js' '*.json' -- ./restart-server.sh
208
```
209
210
### Development Workflow
211
212
```bash
213
# Live reload for web development
214
watchman -- trigger ~/web static '*.html' '*.css' '*.js' -- browser-reload
215
216
# Generate documentation
217
watchman -- trigger ~/project docs '*.md' -- generate-docs
218
219
# Lint on file save
220
watchman -- trigger ~/project lint '*.js' -- eslint
221
```
222
223
### Custom Processing Script
224
225
```bash
226
#!/bin/bash
227
# process-changes.sh - Advanced trigger script
228
229
# Read JSON from stdin
230
changes=$(cat)
231
232
# Extract file names
233
files=$(echo "$changes" | jq -r '.[] | .name')
234
235
echo "Processing changes:"
236
for file in $files; do
237
echo " - $file"
238
239
# Custom processing based on file type
240
case "$file" in
241
*.js)
242
echo " Running JavaScript checks..."
243
eslint "$file"
244
;;
245
*.css)
246
echo " Processing CSS..."
247
autoprefixer "$file"
248
;;
249
*)
250
echo " No special processing"
251
;;
252
esac
253
done
254
```
255
256
Register the script as a trigger:
257
```bash
258
watchman -- trigger ~/project process '*.js' '*.css' -- ./process-changes.sh
259
```
260
261
## Error Handling and Debugging
262
263
### Trigger Execution Failures
264
- Failed commands don't prevent other triggers from running
265
- Check Watchman logs for execution errors
266
- Use `-f` flag to run Watchman in foreground for debugging
267
268
### Debugging Tips
269
- Use `watchman trigger-list` to verify trigger configuration
270
- Test commands manually before setting up triggers
271
- Check file permissions for trigger commands
272
- Monitor system resources if triggers execute frequently
273
274
### Common Issues
275
- **Command not found**: Ensure commands are in PATH or use absolute paths
276
- **Permission denied**: Verify execute permissions on trigger commands
277
- **Infinite loops**: Avoid triggers that modify files they watch
278
- **Resource exhaustion**: Limit trigger frequency for resource-intensive commands