docs: add script and make target to auto-generate project structure - #26
Conversation
📝 WalkthroughWalkthroughAdds generated repository structure documentation and a script-backed ChangesRepository tooling
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
CONTRIBUTING.md (1)
47-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the generated structure document as the source of truth.
This adds another manually maintained repository map while
docs/PROJECT_STRUCTURE.mdis generated. Link to that document, or explicitly keep this as a small static overview to avoid future drift.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@CONTRIBUTING.md` at line 47, Update the repository navigation section in CONTRIBUTING.md to link to docs/PROJECT_STRUCTURE.md as the authoritative generated structure document, and remove or clearly limit any duplicated manually maintained map so it does not drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/PROJECT_STRUCTURE.md`:
- Around line 1055-1113: Regenerate the checked-in project structure artifact
with make structure so the scripts/ listing includes
scripts/update_structure.sh. Commit the generated documentation output without
manually editing unrelated entries.
In `@Makefile`:
- Around line 36-41: Update the manifest-generation printf invocation in the
Makefile to pass the format string as `%s\n` rather than `\%s\n`, preserving the
existing JSON arguments and output path so each manifest line is emitted without
a leading backslash.
- Around line 34-36: The install recipe has malformed GNU Make line
continuations because whitespace follows the trailing backslashes, separating
the shell commands. In the install target around the `fi`, `VER`, `TS`, and
`printf` commands, remove all characters after each continuation backslash so
the backslash is the final character on the line and the complete manifest
command remains one shell invocation.
- Around line 10-11: Fix the TARGET_DIR assignment by separating the Make shell
function name from its command with whitespace, while preserving the existing
CARGO metadata pipeline and target fallback so MAKO_BIN resolves from the actual
target directory.
In `@scripts/update_structure.sh`:
- Around line 16-20: Make the tree and fallback branches in
scripts/update_structure.sh use the same explicit repository file-selection
policy, ensuring both produce identical file sets. Then regenerate
docs/PROJECT_STRUCTURE.md using the updated script so the checked-in structure
reflects that policy and includes scripts/update_structure.sh.
- Around line 4-25: The update_structure.sh script must fail when directory
creation, file writes, tree, or git ls-files fails instead of always reporting
success. Add strict shell options including set -euo pipefail, and preferably
generate the output in a temporary file and rename it to OUTPUT_FILE only after
all generation steps succeed.
---
Nitpick comments:
In `@CONTRIBUTING.md`:
- Line 47: Update the repository navigation section in CONTRIBUTING.md to link
to docs/PROJECT_STRUCTURE.md as the authoritative generated structure document,
and remove or clearly limit any duplicated manually maintained map so it does
not drift.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 53c0a274-9cb1-4de2-85eb-4daa4cae137f
📒 Files selected for processing (4)
CONTRIBUTING.mdMakefiledocs/PROJECT_STRUCTURE.mdscripts/update_structure.sh
| scripts/adaptive-opt-cycle.sh | ||
| scripts/anneal-cycle.sh | ||
| scripts/api-backend-smoke.sh | ||
| scripts/bench-compile.py | ||
| scripts/bench-gate.sh | ||
| scripts/bench-http.sh | ||
| scripts/bench-vs-go-rust.sh | ||
| scripts/bench-vs-go.sh | ||
| scripts/bootstrap-native-toolchain.sh | ||
| scripts/ci-postgres.sh | ||
| scripts/ci-redis.sh | ||
| scripts/claims-gate.sh | ||
| scripts/cross-target-seed.sh | ||
| scripts/deploy-site.sh | ||
| scripts/file-io-regression.sh | ||
| scripts/fill-release-packaging.sh | ||
| scripts/grpc-unary-smoke.sh | ||
| scripts/h2-server-smoke.sh | ||
| scripts/h3-server-smoke.sh | ||
| scripts/http-lib-smoke.sh | ||
| scripts/http-long-run-soak.sh | ||
| scripts/http-server-smoke.sh | ||
| scripts/http_ka_client.py | ||
| scripts/https-server-smoke.sh | ||
| scripts/install-linux.sh | ||
| scripts/install-release.sh | ||
| scripts/install-smoke.sh | ||
| scripts/install.ps1 | ||
| scripts/install.sh | ||
| scripts/llvm-backend-test.sh | ||
| scripts/long-run-soak.sh | ||
| scripts/memory-safety-gate.sh | ||
| scripts/native-bench-baselines.json | ||
| scripts/native-bench-gate.sh | ||
| scripts/native-compiler-test.sh | ||
| scripts/package-deb.sh | ||
| scripts/package-linux-native.sh | ||
| scripts/package-macos-notarize-notes.md | ||
| scripts/package-msi-notes.md | ||
| scripts/package-msi-seed.sh | ||
| scripts/package-notarize-seed.sh | ||
| scripts/package-release.ps1 | ||
| scripts/package-release.sh | ||
| scripts/package-rpm.sh | ||
| scripts/parse_bench_ns.py | ||
| scripts/pgo-build.sh | ||
| scripts/publish-homebrew-tap-seed.sh | ||
| scripts/publish-winget-seed.sh | ||
| scripts/selfhost-gate.sh | ||
| scripts/stdlib-gate.sh | ||
| scripts/uninstall.ps1 | ||
| scripts/uninstall.sh | ||
| scripts/validate-matrix.sh | ||
| scripts/verify-target-artifact.sh | ||
| scripts/wasi-ci-build.sh | ||
| scripts/wasi-verify.sh | ||
| scripts/ws_client.py | ||
| scripts/ws_ping_client.py | ||
| src/ast/mod.rs |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Regenerate the checked-in structure document.
The scripts/ section omits scripts/update_structure.sh, so this generated artifact is already out of sync with the repository. Re-run make structure after the generator is tracked and commit the updated output.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/PROJECT_STRUCTURE.md` around lines 1055 - 1113, Regenerate the
checked-in project structure artifact with make structure so the scripts/
listing includes scripts/update_structure.sh. Commit the generated documentation
output without manually editing unrelated entries.
| TARGET_DIR ?= $(shell$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c 'import json,sys; print(json.load(sys.stdin)["target_directory"])' 2>/dev/null || echo target) | ||
| MAKO_BIN := $(TARGET_DIR)/release/mako |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
expected="$(cargo metadata --format-version 1 --no-deps 2>/dev/null | python3 -c 'import json,sys; print(json.load(sys.stdin)["target_directory"])')"
actual="$(make -pn 2>/dev/null | awk -F ' = ' '$1 == "TARGET_DIR" { print $2; exit }')"
test "$actual" = "$expected"Repository: loreste/mako
Length of output: 872
🏁 Script executed:
#!/bin/bash
set -u
echo "== Makefile excerpt =="
sed -n '1,25p' Makefile 2>/dev/null || true
echo
echo "== make DEBUG/prerequisite info for TARGET_DIR/MAKO_BIN (no recipes) =="
make -p -n 2>/dev/null | awk '
BEGIN { show=0 }
/(^|\s)TARGET_DIR (?:ORIGIN\s*=|:(?:=|:=|\?=|=)) / { show=1; print; next }
/(^|\s)MAKO_BIN (?:ORIGIN\s*=|:(?:=|:=|\?=|=)) / { show=1; print; next }
/^Target Directory:/ { print; exit }
show && /^[A-Za-z0-9_.%-]+=/ { print }
show && /^/ { print }
'
echo
echo "== Python shell expression behavior =="
python3 - <<'PY'
expected="$(cargo metadata --format-version 1 --no-deps 2>/dev/null | python3 -c 'import json,sys; print(json.load(sys.stdin)["target_directory"])')"
actual="$(make -p -n 2>/dev/null | awk -F ' = ' '$1 == "TARGET_DIR" { print $2; exit }')"
print("expected=", repr(expected))
print("actual=", repr(actual))
print("equal=", actual == expected)
try:
print("bash_eval=", repr(eval('$(shell$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'') 2>/dev/null || echo target', {'CARGO': 'cargo'})))
except Exception as e:
print("bash_eval_error=", repr(e))
PY
echo
echo "== local shell expansion probe without Make =="
bash -c 'CARGO=cargo; set -u; echo "$(shell$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'')"' || true
echo
echo "== local shell expansion probe with whitespace after shell =="
bash -c 'CARGO=cargo; set -u; echo "$(shell $(CARGO) metadata --format-version 1 --无-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'')"' || trueRepository: loreste/mako
Length of output: 3134
🏁 Script executed:
#!/bin/bash
set -u
echo "== Make output from current Makefile =="
make -p MAKO_BIN TARGET_DIR 2>/dev/null | awk '
/^TARGET_DIR (ORIGIN\s*=)?[=:]/ || /^MAKO_BIN (ORIGIN\s*=)?[=:]/ || /^.PHONY/ || /^Makefile path/ || /^Make version/ { print }
'
echo
echo "== Local Make-like expansion probe =="
python3 - <<'PY'
from pathlib import Path
text = Path("Makefile").read_text()
lines = text.splitlines()
for i, line in enumerate(lines, 1):
if "CARGO ?=" in line or "TARGET_DIR ?=" in line or "MAKO_BIN :=" in line:
print(f"{i}: {line}")
PY
echo
echo "== Bash expansion with missing command for comparison =="
env -i TERM="${TERM:-dumb}" bash -c 'set -u; CARGO=cargo; echo "$(shell$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'') 2>/dev/null || echo target"' 2>&1 || true
echo
echo "== Bash expansion with known cargo metadata succeeds =="
env -i TERM="${TERM:-dumb}" bash -c 'set -u; CARGO=cargo; echo "$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'')"' 2>&1 || trueRepository: loreste/mako
Length of output: 1555
🏁 Script executed:
#!/bin/bash
set -u
echo "== Local Makefile expansion via GNU make print-variable =="
make -s print-% --print-targets=TARGET_DIR 2>&1 || true
make TARGET_DIR -s --no-print-directory 2>&1 || true
make -s print-MAKO_BIN 2>&1 || true
echo
echo "== Local Shell expansion for malformed $(shell$(CARGO)...) =="
bash -c '
CARGO=cargo
set -u
out="$(shell$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'' 2>/dev/null || echo target)"
printf "TARGET_DIR=<%s>:<%s>\n" "${out}"
' 2>&1 || trueRepository: loreste/mako
Length of output: 512
🏁 Script executed:
#!/bin/bash
set -u
echo "== Local Makefile expansion via GNU make print-variable with GNU make from standard environment =="
make -s print-% 2>/dev/null || true
make TARGET_DIR -s --no-print-directory 2>/dev/null || true
make -s print-MAKO_BIN 2>/dev/null || true
echo
echo "== Local Shell expansion for malformed $(shell$(CARGO)...) =="
env -i PATH="$PATH" TERM="${TERM:-dumb}" bash -c '
CARGO=cargo
set -u
out="$(shell$(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'' 2>/dev/null || echo target)"
printf "TARGET_DIR=<%s>:<%s>\n" "${out}"
' 2>&1 || true
echo
echo "== Local Shell expansion for corrected $(shell $(CARGO)...) =="
env -i PATH="$PATH" TERM="${TERM:-dumb}" bash -c '
CARGO=cargo
set -u
out="$(shell $(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c '\''import json,sys; print(json.load(sys.stdin)["target_directory"])'\'' 2>/dev/null || echo target)"
printf "TARGET_DIR=<%s>:<%s>\n" "${out}"
' 2>&1 || trueRepository: loreste/mako
Length of output: 624
🏁 Script executed:
#!/bin/bash
set -u
if ! command -v make >/dev/null 2>&1; then
printf 'ERROR: make is not available in this environment\n'
exit 1
fi
echo "== Makefile lines =="
sed -n '8,12p' Makefile
echo
echo "== GNU make variable expansion =="
make -s TARGET_DIR -O --no-print-directory 2>&1 || true
make -s MAKO_BIN -O --no-print-directory 2>&1 || true
echo
echo "== Makefile parser report =="
make -p TARGET_DIR MAKO_BIN --no-print-directory 2>/dev/null | awk '
/^TARGET_DIR / || /^MAKO_BIN / || /^Makefile path/ || /^Make version/ { print }
'Repository: loreste/mako
Length of output: 199
🌐 Web query:
GNU make Function invocation syntax $(function arguments) whitespace after function name $(shell command)
💡 Result:
In GNU make, the syntax for a function invocation is
Citations:
- 1: http://odysseus.fi.muni.cz/pub/gnu/old-gnu/Manuals/make/html_chapter/make_8.html
- 2: https://www.cse.unr.edu/~sushil/class/cs202/help/man/make/make_73.html
- 3: https://docs.w3cub.com/gnu_make/syntax-of-functions
- 4: http://odysseus.fi.muni.cz/pub/gnu/old-gnu/Manuals/make-3.80/html_chapter/make%5F8.html
- 5: https://tool.oschina.net/uploads/apidocs/make-manual/Shell-Function.html
- 6: https://runebook.dev/en/docs/gnu_make/syntax-of-functions
Fix the malformed $(shell ...) invocation.
Make function arguments must be delimited from the function name, so add whitespace after shell: $(shell $(CARGO) metadata --format-version 1 --no-deps 2>/dev/null | python3 -c ...). As written, this is not parsed as Make’s shell function and causes MAKO_BIN to expand from the fallback target.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Makefile` around lines 10 - 11, Fix the TARGET_DIR assignment by separating
the Make shell function name from its command with whitespace, while preserving
the existing CARGO metadata pipeline and target fallback so MAKO_BIN resolves
from the actual target directory.
| rm -rf "$(SHARE_DIR)/std"; mkdir -p "$(SHARE_DIR)/std"; cp -R std/. "$(SHARE_DIR)/std/"; \ fi @VER=$$("$(BIN_DIR)/mako" version 2>/dev/null || true); \ | ||
| HOST=$$(uname -s 2>/dev/null)-$$(uname -m 2>/dev/null); \ | ||
| TS=$$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date); \ | ||
| printf '%s\n' \ | ||
| '{' \ | ||
| ' "schema": "mako.install.v1",' \ | ||
| " \"version\": \"$$VER\"," \ | ||
| TS=$$(date -u +\%Y-\%m-\%dT\%H:\%M:\%SZ 2>/dev/null \vert{}\vert{} date); \ printf '\%s\n' \ '{' \ ' "schema": "mako.install.v1",' \ " \"version\": \"$$VER\"," \ |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
make -n install | sed -n '/rm -rf.*std/,/install-manifest.json/p' | cat -vetRepository: loreste/mako
Length of output: 188
🏁 Script executed:
#!/bin/bash
set -u
if ! command -v make >/dev/null 2>&1; then
echo "make not available"
fi
sed -n '20,45p' Makefile | cat -vet
printf '\n--- parse Makefile recipe continuation check ---\n'
python3 - <<'PY'
from pathlib import Path
p = Path("Makefile")
text = p.read_text()
lines = text.splitlines()
for i, line in enumerate(lines, 1):
if 'TS=$$(date -u +\\%Y' in line or '`@VER`=$$' in line or 'cp -R std/.' in line:
before = ''
if 1 <= i-1 <= len(lines):
before = repr(lines[i-1])
print(f"line {i}: {line!r} (ends_backslash={line.endswith(chr(92))}) prev={before}")
PYRepository: loreste/mako
Length of output: 2388
🏁 Script executed:
#!/bin/bash
set -u
python3 - <<'PY'
from pathlib import Path
p = Path("/tmp/makefile-probe.txt")
# Only preserve the Makefile recipe lines of interest as literal bytes.
p.write_text(bytes([
ord('\t'), ord('@'), ord('i'), ord('f'), ord(' '), ord('['), ord(' '), ord('d'), ord(' '),
ord('s'), ord('t'), ord('d'), ord(']'), ord(';'), ord(' '), ord('\\ ')
ord('d') # duplicate 'd' from original snippet, but this is intentionally wrong so continuation fails
]) , "utf-8"))
PY
# Show the exact line endings and continuation characters for the affected Makefile lines.
python3 - <<'PY'
from pathlib import Path
p = Path("Makefile")
text = p.read_text()
for index, line in enumerate(text.splitlines(keepends=True), 1):
if 33 <= index <= 38:
print(f"--- line {index} ---")
print(repr(line))
PYRepository: loreste/mako
Length of output: 935
🌐 Web query:
GNU Make recipe continuation backslash whitespace after backslash behavior
💡 Result:
In GNU Make, a backslash () is used to split a long logical line in a recipe into multiple physical lines. It is critical that the backslash is the very last character on the line, immediately followed by the newline [1][2]. If you place any whitespace—such as spaces or tabs—after the backslash on the same line, GNU Make will not recognize the backslash as a line continuation character [3]. Instead, the backslash and the subsequent whitespace will be treated as part of the command line itself and passed directly to the shell [1][3]. This often results in unexpected behavior, such as a "command not found" error or syntax errors, because the shell receives the trailing backslash as a literal character in the command [3]. Key behavior regarding recipe line splitting: - Preservation: Unlike how backslash/newline pairs are treated elsewhere in a makefile, GNU Make does not remove the backslash and newline characters in a recipe [1][2]. They are preserved and passed to the shell [1][2]. - Shell Interpretation: Because the backslash and newline are passed to the shell, the actual behavior depends on how your chosen shell (e.g., /bin/sh or /bin/bash) interprets them [1][2]. - Recipe Prefix: When a recipe is split, if the first character of the next physical line is the recipe prefix character (a tab by default), GNU Make removes that prefix character before passing the line to the shell [1][2]. No additional whitespace is added by GNU Make during this process [1][2].
Citations:
- 1: https://www.uucp.hu/mirror/www.gnu.org/software/make/manual/html_node/Splitting-Recipe-Lines.html
- 2: https://tack.ch/gnu/make-3.82/make_37.html
- 3: https://runebook.dev/en/docs/gnu_make/splitting-recipe-lines
🌐 Web query:
GNU Make manual recipe continuation whitespace after backslash literal backslash space shell
💡 Result:
In GNU Make, a backslash immediately followed by a newline is used to split a single logical recipe line into multiple physical lines in the makefile [1][2]. Crucially, in the context of recipe lines (the commands executed by the shell), the backslash/newline pair is not removed by make [1][2]. Instead, both the backslash and the newline characters are preserved and passed directly to the shell [1][2]. Consequently, whether whitespace (such as a space) is permitted after the backslash depends entirely on how your shell interprets that sequence [1][2]. If you place a space after the backslash and before the newline: 1. The backslash is no longer immediately followed by the newline. 2. The sequence is not recognized by GNU Make as a line continuation directive for the recipe [1][2]. 3. The shell will receive the space, the backslash, and the newline as part of the command line, which will likely result in a syntax error or unintended behavior depending on the shell [1][2]. For splitting recipe lines, you must place the backslash at the very end of the line, immediately before the newline character [1][2]. If the first character of the next physical line is the recipe prefix character (a tab by default), GNU Make will remove only that tab character; it does not add any whitespace to the recipe [1][2]. If you need to include a newline in a quoted string passed to the shell, it is often safer to store the command in a GNU Make variable, where standard makefile line-continuation rules apply and backslash/newline sequences are stripped [1][2].
Citations:
- 1: https://getdocs.org/Make/docs/latest/Splitting-Recipe-Lines
- 2: https://www.uucp.hu/mirror/www.gnu.org/software/make/manual/html_node/Splitting-Recipe-Lines.html
🌐 Web query:
Make 4.4.1 split-recipes backslash line continuation Makefile lines "The backslash must be the last character"
💡 Result:
In GNU Make (including version 4.4.1), you can split long lines in your Makefile for better readability by using the backslash (\) character [1][2][3][4]. To use this feature correctly, the backslash must be the last character on the physical line before the newline character [1][5][6]. Key points regarding this behavior: - Requirement: The backslash must immediately precede the newline [1][5]. If there are any characters (including spaces or tabs) after the backslash on that same line, it will not act as a line continuation and will instead be treated as part of the line content. - Non-recipe lines: Outside of recipes, GNU Make converts the backslash-newline sequence into a single space character [2][3]. - Recipe lines: Inside recipes, the backslash-newline sequence is preserved and passed to the shell [1][5]. How the shell interprets this sequence depends on the specific shell being used (typically /bin/sh) [1][5]. In most cases, the shell treats the backslash-newline as a line continuation, allowing the command to span multiple lines [5][6]. - Readability: While GNU Make does not impose a limit on the length of a line, using backslashes to break up long commands or complex variable definitions is a standard and widely accepted practice to improve makefile maintainability [2][3][7].
Citations:
- 1: http://gnu.ist.utl.pt/software/make/manual/html_node/Splitting-Lines.html
- 2: https://getdocs.org/Make/docs/latest/Splitting-Lines
- 3: https://www.manpagez.com/info/make/make-4.0/make_14.php
- 4: https://www.manpagez.com/info/make/make-4.4.1/Rule_Syntax.php
- 5: https://www.chiark.greenend.org.uk/doc/make-doc/make.html/Recipes.html
- 6: https://web.mit.edu/gnu/doc/html/make_5.html
- 7: https://stackoverflow.com/questions/52800902/makefile-line-break-continuation-character-usage-generally-acceptable-o
🌐 Web query:
site:gnu.org/software/make/manual/html_node/Recipe-In-Preamble.html "\"When you use a backslash-newline\" recipe lines"
💡 Result:
In GNU make, a backslash-newline in a recipe line is not removed; both characters are preserved and passed to the shell. If the next line starts with the recipe prefix (a tab by default), that one character is removed, and no whitespace is added. (gnu.org)
Citations:
Fix the malformed GNU Make continuations before running make install.
Lines 34 and 36 leave whitespace after recipe \ continuations, so the fi/@VER=... and TS=.../printf boundaries are not kept on one Make command line. GNU Make passes the continuation newline and tab literally to the shell, so the manifest command is received with fi, @VER=..., and printf on separate lines and fails before writing install-manifest.json.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Makefile` around lines 34 - 36, The install recipe has malformed GNU Make
line continuations because whitespace follows the trailing backslashes,
separating the shell commands. In the install target around the `fi`, `VER`,
`TS`, and `printf` commands, remove all characters after each continuation
backslash so the backslash is the final character on the line and the complete
manifest command remains one shell invocation.
| TS=$$(date -u +\%Y-\%m-\%dT\%H:\%M:\%SZ 2>/dev/null \vert{}\vert{} date); \ printf '\%s\n' \ '{' \ ' "schema": "mako.install.v1",' \ " \"version\": \"$$VER\"," \ | ||
| " \"prefix\": \"$(PREFIX)\"," \ | ||
| " \"host\": \"$$HOST\"," \ | ||
| " \"installedAt\": \"$$TS\"," \ | ||
| " \"host\": \"$$HOST\"," \ " \"installedAt\": \"$$TS\"," \ | ||
| " \"runtime\": \"$(RUNTIME_DST)\"," \ | ||
| " \"std\": \"$(SHARE_DIR)/std\"" \ | ||
| '}' > "$(SHARE_DIR)/install-manifest.json" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
tmp="$(mktemp)"
printf '\%s\n' '{' ' "schema": "mako.install.v1",' '}' > "$tmp"
python3 -m json.tool "$tmp"Repository: loreste/mako
Length of output: 192
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- Makefile relevant section ---\n'
sed -n '30,50p' Makefile | cat -n
printf '\n--- behavioral probes ---\n'
tmp="$(mktemp)"
printf '%s\n' '{' '{"a":1}' > "$tmp"
printf -- 'single printf output:\n'
sed -n '1,5p' "$tmp"
printf '\nprintf \"\\%%s\\n\":\n'
printf '\%s\n' '{' ' "schema": "mako.install.v1",' '}' > "$tmp"
sed -n '1,5p' "$tmp"
python3 -m json.tool "$tmp" || true
printf '\nprintf \"%%%%s\\n\":\n'
printf '%s\n' '{' ' "schema": "mako.install.v1",' '}' > "$tmp"
sed -n '1,5p' "$tmp"
printf '\nmanifold printf behavior check:\n'
for line in 'printf '\''\%s\n'\'' '\''{'\''' 'printf '\''%s\n'\'' '\''{'\'''; do
tmp="$(mktemp)"
(eval "$line" 'a' 'b') > "$tmp"
printf '%s ->' "$line"
sed -n '1p' "$tmp" | od -c | tr '\n' ' '
printf '\n'
doneRepository: loreste/mako
Length of output: 241
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- Makefile relevant section ---'
sed -n '30,50p' Makefile | cat -n
printf '%s\n' ''
printf '%s\n' '--- behavioral probes ---'
tmp="$(mktemp)"
printf '%s\n' '{' '{"a":1}' > "$tmp"
printf 'single printf output:\n'
sed -n '1,5p' "$tmp"
printf '%s\n' ''
printf 'printf with literal backslash format:\n'
printf '\%s\n' '{' ' "schema": "mako.install.v1",' '}' > "$tmp"
sed -n '1,5p' "$tmp"
python3 -m json.tool "$tmp" || true
printf '%s\n' ''
printf 'printf with escaped backslash format:\n'
printf '%s\n' '{' ' "schema": "mako.install.v1",' '}' > "$tmp"
sed -n '1,5p' "$tmp"
printf '%s\n' ''
printf 'printf with escaped backslash format plus newline, if supported:\n'
printf '%s\n' '{' ' "schema": "mako.install.v1",' '}' > "$tmp"
sed -n '1,5p' "$tmp"Repository: loreste/mako
Length of output: 1731
Emit the manifest with printf '%s\n'.
The literal \%s\n is passed to printf, which emits each JSON line with a leading \, producing invalid JSON.
Proposed fix
- printf '\%s\n' \
+ printf '%s\n' \📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| TS=$$(date -u +\%Y-\%m-\%dT\%H:\%M:\%SZ 2>/dev/null \vert{}\vert{} date); \ printf '\%s\n' \ '{' \ ' "schema": "mako.install.v1",' \ " \"version\": \"$$VER\"," \ | |
| " \"prefix\": \"$(PREFIX)\"," \ | |
| " \"host\": \"$$HOST\"," \ | |
| " \"installedAt\": \"$$TS\"," \ | |
| " \"host\": \"$$HOST\"," \ " \"installedAt\": \"$$TS\"," \ | |
| " \"runtime\": \"$(RUNTIME_DST)\"," \ | |
| " \"std\": \"$(SHARE_DIR)/std\"" \ | |
| '}' > "$(SHARE_DIR)/install-manifest.json" | |
| TS=$$(date -u +\%Y-\%m-\%dT\%H:\%M:\%SZ 2>/dev/null \vert{}\vert{} date); \ | |
| printf '%s\n' \ | |
| '{' \ | |
| ' "schema": "mako.install.v1",' \ | |
| " \"version\": \"$$VER\"," \ | |
| " \"prefix\": \"$(PREFIX)\"," \ | |
| " \"host\": \"$$HOST\"," \ | |
| " \"installedAt\": \"$$TS\"," \ | |
| " \"runtime\": \"$(RUNTIME_DST)\"," \ | |
| " \"std\": \"$(SHARE_DIR)/std\"" \ | |
| '}' > "$(SHARE_DIR)/install-manifest.json" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Makefile` around lines 36 - 41, Update the manifest-generation printf
invocation in the Makefile to pass the format string as `%s\n` rather than
`\%s\n`, preserving the existing JSON arguments and output path so each manifest
line is emitted without a leading backslash.
| OUTPUT_FILE="docs/PROJECT_STRUCTURE.md" | ||
|
|
||
| # Asegurar que exista el directorio docs/ | ||
| mkdir -p docs | ||
|
|
||
| echo "# Mako Repository Structure" > "$OUTPUT_FILE" | ||
| echo "" >> "$OUTPUT_FILE" | ||
| echo "This file is automatically generated by \`make structure\` (\`./scripts/update_structure.sh\`). Do not edit directly." >> "$OUTPUT_FILE" | ||
| echo "" >> "$OUTPUT_FILE" | ||
| echo '```text' >> "$OUTPUT_FILE" | ||
|
|
||
| # Genera el árbol ignorando binarios, cachés y carpetas de compilación | ||
| if command -v tree &> /dev/null; then | ||
| tree -I 'target|.git|.mko|out|*.dSYM|node_modules' --noreport >> "$OUTPUT_FILE" | ||
| else | ||
| # Si no tiene 'tree', usa git ls-files | ||
| git ls-files >> "$OUTPUT_FILE" | ||
| fi | ||
|
|
||
| echo '```' >> "$OUTPUT_FILE" | ||
|
|
||
| echo "✅ Estructura generada correctamente en $OUTPUT_FILE" No newline at end of file |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Fail instead of reporting success after generation errors.
Without set -e, failures from mkdir, tree, git ls-files, or file writes are ignored, and line 25 still reports success. Add set -euo pipefail; preferably write to a temporary file and rename it only after successful generation.
🧰 Tools
🪛 Shellcheck (0.11.0)
[style] 10-10: Consider using { cmd1; cmd2; } >> file instead of individual redirects.
(SC2129)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/update_structure.sh` around lines 4 - 25, The update_structure.sh
script must fail when directory creation, file writes, tree, or git ls-files
fails instead of always reporting success. Add strict shell options including
set -euo pipefail, and preferably generate the output in a temporary file and
rename it to OUTPUT_FILE only after all generation steps succeed.
| if command -v tree &> /dev/null; then | ||
| tree -I 'target|.git|.mko|out|*.dSYM|node_modules' --noreport >> "$OUTPUT_FILE" | ||
| else | ||
| # Si no tiene 'tree', usa git ls-files | ||
| git ls-files >> "$OUTPUT_FILE" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Make structure generation deterministic across the working tree and checked-in output.
The generator’s two discovery paths describe different file sets, and the checked-in document demonstrates the consequence by omitting the new generator.
scripts/update_structure.sh#L16-L20: choose one explicit repository file-selection policy for both branches.docs/PROJECT_STRUCTURE.md#L1055-L1113: regenerate the document after applying that policy soscripts/update_structure.shappears.
📍 Affects 2 files
scripts/update_structure.sh#L16-L20(this comment)docs/PROJECT_STRUCTURE.md#L1055-L1113
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/update_structure.sh` around lines 16 - 20, Make the tree and fallback
branches in scripts/update_structure.sh use the same explicit repository
file-selection policy, ensuring both produce identical file sets. Then
regenerate docs/PROJECT_STRUCTURE.md using the updated script so the checked-in
structure reflects that policy and includes scripts/update_structure.sh.
|
Thanks for the contribution. The
Could you fix these three issues? The docs and script additions look good — just need the Makefile to not break existing installs. |
Adds scripts/update_structure.sh and a make structure target to automatically scan and update docs/PROJECT_STRUCTURE.md without requiring manual maintenance.
Summary by CodeRabbit
Documentation
New Features