docs(rules): require run-wsl-sh for CRLF .sh scripts
Cursor Write on Windows often saves CRLF; bare wsl -e bash script.sh then fails with No such file. Canon is run-wsl-sh.sh (strip CR).
This commit is contained in:
@@ -11,12 +11,15 @@ alwaysApply: true
|
|||||||
|
|
||||||
| Симптом | Причина | Как правильно |
|
| Симптом | Причина | Как правильно |
|
||||||
|---------|---------|---------------|
|
|---------|---------|---------------|
|
||||||
| `unexpected EOF`, `ParserError`, пустой curl | PS ломает `"`, `$`, heredoc, `&&` | Файл `.sh` → `wsl -e bash /mnt/c/.../script.sh` |
|
| `bash: /mnt/c/.../.tmp-*.sh: No such file or directory` при том что `ls` файл видит | **CRLF** от Cursor Write: shebang = `bash\r` | **Всегда** `wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/.../script.sh` (или `sed -i 's/\r$//' && bash`). **Не** голый `wsl -e bash /mnt/c/.../script.sh` |
|
||||||
|
| `unexpected EOF`, `ParserError`, пустой curl | PS ломает `"`, `$`, heredoc, `&&` | Файл `.sh` → `run-wsl-sh.sh` |
|
||||||
| `bash: syntax error near '('` | `grep -E ^(...)` в PS; **`fix(ci):` / `(…)` в `wsl -lc` one-liner** | Только внутри `.sh`; commit → `-F` файл (см. ниже) |
|
| `bash: syntax error near '('` | `grep -E ^(...)` в PS; **`fix(ci):` / `(…)` в `wsl -lc` one-liner** | Только внутри `.sh`; commit → `-F` файл (см. ниже) |
|
||||||
| `{{.Names}}: command not found` | `docker --format "{{…}}"` в PS | Формат в `.sh` или простой `docker ps` |
|
| `{{.Names}}: command not found` | `docker --format "{{…}}"` в PS | Формат в `.sh` или простой `docker ps` |
|
||||||
| `&&` is not valid | PowerShell не bash | Отдельные команды или `.sh` |
|
| `&&` is not valid | PowerShell не bash | Отдельные команды или `.sh` |
|
||||||
|
|
||||||
**Запрещено в PS:** `wsl -e bash -lc "…\"…"`, `curl -d "{\"x\":…}"`, heredoc commit, `npm`/`rebar3`.
|
**Запрещено в PS:** голый `wsl -e bash /mnt/c/.../.tmp-*.sh` (без `run-wsl-sh.sh`), `wsl -e bash -lc "…\"…"`, `curl -d "{\"x\":…}"`, heredoc commit, `npm`/`rebar3`.
|
||||||
|
|
||||||
|
Канон запуска скриптов: см. `shell-wsl-not-powershell.mdc` § CRLF.
|
||||||
|
|
||||||
## 2. Git
|
## 2. Git
|
||||||
|
|
||||||
@@ -43,7 +46,7 @@ git add path/to/file
|
|||||||
GIT_EDITOR=true git commit -F .tmp-commit-msg.txt
|
GIT_EDITOR=true git commit -F .tmp-commit-msg.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
Запуск из PS: `wsl -e bash /mnt/c/.../EventHubBack/.tmp-commit.sh` — **без** `-lc` и **без** `-m "fix(ci): …"`.
|
Запуск из PS: `wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/.../EventHubBack/.tmp-commit.sh` — **без** голого `wsl -e bash …/.tmp-commit.sh`, **без** `-lc` и **без** `-m "fix(ci): …"`.
|
||||||
|
|
||||||
## 3. Docker dev (Swarm локально)
|
## 3. Docker dev (Swarm локально)
|
||||||
|
|
||||||
|
|||||||
@@ -11,20 +11,53 @@ PowerShell в Cursor **ломает** кавычки, `$`, JSON, heredoc и вл
|
|||||||
## Правило
|
## Правило
|
||||||
1. **Нельзя** гонять сложные one-liner’ы в PowerShell (npm, curl+JSON, python -c, git commit heredoc, вложенный bash с кавычками).
|
1. **Нельзя** гонять сложные one-liner’ы в PowerShell (npm, curl+JSON, python -c, git commit heredoc, вложенный bash с кавычками).
|
||||||
2. **Можно** в PowerShell только простые вещи: `cd`, `git status`, `ls`, одиночный `wsl …` без вложенных кавычек в аргументе.
|
2. **Можно** в PowerShell только простые вещи: `cd`, `git status`, `ls`, одиночный `wsl …` без вложенных кавычек в аргументе.
|
||||||
3. Рабочий способ — **WSL bash** или **файл `.sh` + `wsl -e bash /path/to/script.sh`**.
|
3. Рабочий способ — **WSL bash** или **файл `.sh` + launcher** (см. ниже).
|
||||||
|
|
||||||
|
## CRLF / «No such file or directory» (обязательно)
|
||||||
|
|
||||||
|
Cursor `Write` на Windows часто сохраняет `.sh` с **CRLF**. Тогда:
|
||||||
|
|
||||||
|
```text
|
||||||
|
wsl -e bash /mnt/c/.../EventHubFront/.tmp-run.sh
|
||||||
|
# bash: .../.tmp-run.sh: No such file or directory
|
||||||
|
```
|
||||||
|
|
||||||
|
Файл **есть** (`ls` его видит) — ломается shebang (`#!/usr/bin/env bash\r`). Это **не** «файл не записался».
|
||||||
|
|
||||||
|
### Канон запуска любого `.sh` с `/mnt/c/...`
|
||||||
|
|
||||||
|
**Всегда** через хелпер (снимает `\r`, потом `bash`):
|
||||||
|
|
||||||
|
```text
|
||||||
|
wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubFront/.tmp-run.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Запрещено** после `Write` голый:
|
||||||
|
|
||||||
|
```text
|
||||||
|
wsl -e bash /mnt/c/.../repo/.tmp-something.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Альтернатива без хелпера (тот же смысл):
|
||||||
|
|
||||||
|
```text
|
||||||
|
wsl -e bash -lc 'sed -i "s/\r$//" /mnt/c/.../script.sh && bash /mnt/c/.../script.sh'
|
||||||
|
```
|
||||||
|
|
||||||
|
Предпочтительно класть долгоживущие скрипты в `/mnt/c/Users/alexc/.cursor/eventhub/` и тоже гонять через `run-wsl-sh.sh`.
|
||||||
|
|
||||||
## Канон (копируй)
|
## Канон (копируй)
|
||||||
|
|
||||||
### Вариант A — скрипт (предпочтительно)
|
### Вариант A — скрипт (предпочтительно)
|
||||||
1. Запиши команды в файл, например `EventHubBack/.tmp-run.sh` или `~/.cursor/eventhub/….sh` (LF, `#!/usr/bin/env bash`).
|
1. Запиши команды в файл, например `EventHubBack/.tmp-run.sh` или `~/.cursor/eventhub/….sh` (`#!/usr/bin/env bash`).
|
||||||
2. Запусти **без** вложенных кавычек в PowerShell:
|
2. Запусти **только** так (из PowerShell, без вложенных кавычек):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
wsl -e bash /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubBack/.tmp-run.sh
|
wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubBack/.tmp-run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Вариант B — один простой WSL вызов
|
### Вариант B — один простой WSL вызов
|
||||||
Только если внутри **одинарные** кавычки bash и нет `"`/`$` конфликтов с PS:
|
Только если внутри **одинарные** кавычки bash и нет `"`/`$` конфликтов с PS (и **нет** нового `.sh` с диска C):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
wsl -e bash -lc 'cd /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubFront && npm run lint'
|
wsl -e bash -lc 'cd /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubFront && npm run lint'
|
||||||
@@ -34,6 +67,7 @@ wsl -e bash -lc 'cd /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubFront && np
|
|||||||
|
|
||||||
### Запрещено
|
### Запрещено
|
||||||
```text
|
```text
|
||||||
|
wsl -e bash /mnt/c/.../.tmp-run.sh # без run-wsl-sh / sed — CRLF → No such file
|
||||||
wsl -e bash -lc ".... python -c \"import...\" ...." # ломается
|
wsl -e bash -lc ".... python -c \"import...\" ...." # ломается
|
||||||
curl ... -d "{\"email\":\"$x\"}" # в PS ломается
|
curl ... -d "{\"email\":\"$x\"}" # в PS ломается
|
||||||
git commit -m "$(cat <<'EOF' ...)" # в PS не так
|
git commit -m "$(cat <<'EOF' ...)" # в PS не так
|
||||||
@@ -44,7 +78,7 @@ npm / npx / node из Windows # сломан
|
|||||||
|
|
||||||
### Git commit — канон (subject с `( )`, `#`, `$`)
|
### Git commit — канон (subject с `( )`, `#`, `$`)
|
||||||
|
|
||||||
1. Текст коммита — в файл репо, напр. `.tmp-commit-msg.txt` (LF, без heredoc из PS).
|
1. Текст коммита — в файл репо, напр. `.tmp-commit-msg.txt` (без heredoc из PS).
|
||||||
2. Скрипт `.tmp-commit.sh`:
|
2. Скрипт `.tmp-commit.sh`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -55,7 +89,11 @@ git add path1 path2
|
|||||||
GIT_EDITOR=true git commit -F .tmp-commit-msg.txt
|
GIT_EDITOR=true git commit -F .tmp-commit-msg.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Из PowerShell только: `wsl -e bash /mnt/c/.../EventHubBack/.tmp-commit.sh`
|
3. Из PowerShell:
|
||||||
|
|
||||||
|
```text
|
||||||
|
wsl -e bash /mnt/c/Users/alexc/.cursor/eventhub/run-wsl-sh.sh /mnt/c/Users/alexc/IdeaProjects/eventHub/EventHubBack/.tmp-commit.sh
|
||||||
|
```
|
||||||
|
|
||||||
**Не** передавать сообщение аргументом в `git-commit.sh` / `-m` через `wsl -lc` — скобки в `fix(ci):` парсятся как subshell.
|
**Не** передавать сообщение аргументом в `git-commit.sh` / `-m` через `wsl -lc` — скобки в `fix(ci):` парсятся как subshell.
|
||||||
|
|
||||||
@@ -63,11 +101,11 @@ GIT_EDITOR=true git commit -F .tmp-commit-msg.txt
|
|||||||
|
|
||||||
| Задача | Как |
|
| Задача | Как |
|
||||||
|-----|-----|
|
|-----|-----|
|
||||||
| Front lint/build/e2e | `wsl -e bash` + `cd …/EventHubFront && npm …` |
|
| Front lint/build/e2e | `.sh` + `run-wsl-sh.sh` или `-lc` с PATH-fix + `npm …` |
|
||||||
| Front перед push main | сначала `npm run test:e2e:ift` в WSL, потом `~/.cursor/eventhub/git-push-main.sh` |
|
| Front перед push main | сначала `npm run test:e2e:ift` в WSL, потом `git-push-main.sh` |
|
||||||
| Back rebar/eunit | `source scripts/wsl-dev-env.sh` в WSL |
|
| Back rebar/eunit | `source scripts/wsl-dev-env.sh` в WSL |
|
||||||
| Git commit/push | **commit:** `.tmp-commit-msg.txt` + `git commit -F` в `.sh`; **push:** `bash /mnt/c/Users/alexc/.cursor/eventhub/git-push.sh …` |
|
| Git commit/push | **commit:** `.tmp-commit-msg.txt` + `git commit -F` в `.sh` через `run-wsl-sh.sh`; **push:** `bash /mnt/c/Users/alexc/.cursor/eventhub/git-push.sh …` |
|
||||||
| JSON/API/python | скрипт `.sh` или `.py` на диске, запуск из WSL |
|
| JSON/API/python | скрипт `.sh`/`.py` + `run-wsl-sh.sh` |
|
||||||
|
|
||||||
## Git push (обязательно)
|
## Git push (обязательно)
|
||||||
|
|
||||||
@@ -89,4 +127,4 @@ Credential store в WSL уже настроен (`credential.helper=store` + `gi
|
|||||||
3. Только потом push через `git-push-main.sh`. **Не пушить**, если lint/build/IFT красные.
|
3. Только потом push через `git-push-main.sh`. **Не пушить**, если lint/build/IFT красные.
|
||||||
|
|
||||||
## Частые сбои (подробнее)
|
## Частые сбои (подробнее)
|
||||||
См. **`agent-pitfalls.mdc`**: git `-F` вместо heredoc, `&&` в PS, docker dev scale, `git clean` vs `.cursor/`.
|
См. **`agent-pitfalls.mdc`**: CRLF/`run-wsl-sh.sh`, git `-F`, `&&` в PS, docker dev scale, `git clean` vs `.cursor/`.
|
||||||
|
|||||||
Reference in New Issue
Block a user