Skip to content

feat(source-set): add dependency-aware build order - #50

Open
korolevpavel wants to merge 4 commits into
alkoleft:masterfrom
korolevpavel:feat/issue-32-dependency-aware-build
Open

feat(source-set): add dependency-aware build order#50
korolevpavel wants to merge 4 commits into
alkoleft:masterfrom
korolevpavel:feat/issue-32-dependency-aware-build

Conversation

@korolevpavel

@korolevpavel korolevpavel commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Closes #32.

  • adds optional source-set dependsOn with fail-closed validation for unknown/self/duplicate/external dependencies, cycles, and configuration-root ambiguity;
  • resolves stable dependency-first order while preserving canonical/YAML order for unrelated source sets;
  • expands scoped builds to transitive dependency closures with diamond de-duplication across Designer, IBCMD, and EDT;
  • preserves legacy behavior when dependsOn is omitted and keeps test yaxunit build-before-run behavior.

Verification:

  • config validation: 48 passed; deep chain 10,000 nodes passed
  • source inventory, build, CLI build 21/21, CLI test 21/21
  • cargo check --tests; cargo fmt --all -- --check; git diff --check
  • independent final Rust review: no blocking findings.

Known baseline: pre-existing unused variable warning in tool_extension.rs and macOS path/timing failures in broad suite.

Summary by CodeRabbit

  • Новые возможности

    • Добавлена настройка зависимостей между source-set через dependsOn.
    • Сборка автоматически включает транзитивные зависимости и выполняет их в стабильном корректном порядке.
    • При выборе одного source-set собирается весь необходимый граф зависимостей.
    • При ошибке зависимого шага последующие шаги пропускаются с сохранением статуса в результате.
    • Тестовый запуск начинается только после успешной сборки графа зависимостей.
  • Документация

    • Обновлены руководство, схема конфигурации, примеры и архитектурные спецификации с описанием нового поведения и правил валидации.

- add optional dependsOn model and schema support
- reject invalid dependency graphs before platform launch
- validate deep chains with iterative traversal and memoized roots
- order full builds by stable dependency graph
- expand scoped builds to transitive source-set closure
- preserve legacy and backend build behavior
- verify scoped dependency order, change detection, and failure blocking
- preserve yaxunit build-first behavior and result compatibility
- document dependsOn workflow and architecture decision
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@korolevpavel, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c14c279-a062-4285-98ea-ccaf3ec9a8de

📥 Commits

Reviewing files that changed from the base of the PR and between 6b1a27e and 0b44492.

📒 Files selected for processing (1)
  • docs/DEEP_DIVE.md

Walkthrough

Добавлена декларативная связь source-set[].dependsOn: конфигурация валидируется, scoped-сборка расширяется транзитивными зависимостями, а source-set выполняются в стабильном топологическом порядке. Обновлены build/test-сценарии, схемы, документация и интеграционные тесты.

Changes

Зависимости source-set

Layer / File(s) Summary
Контракт и валидация зависимостей
src/config/model.rs, src/config/schema.rs, src/config/validate.rs, src/config/loader.rs, docs/CONFIGURATION.md, spec/decisions/*
Добавлено необязательное dependsOn; валидируются неизвестные, дублирующиеся, цикличные и неподдерживаемые зависимости, включая разрешение единственного configuration root.
Разрешение порядка сборки
src/use_cases/source_inventory.rs, src/use_cases/build_project.rs
Scoped selection расширяется транзитивным closure, а source-set упорядочиваются стабильной topological sort с сохранением canonical order для готовых узлов.
Интеграционная проверка
tests/cli_build.rs, tests/cli_test.rs
Проверены цепочка main → yaxunit → TESTS, инкрементальная сборка, блокировка dependent после ошибки и запуск тестов после успешного build graph.
Документация и тестовые конфигурации
ARCHITECTURE.md, docs/*, SKILL/*, examples/*, src/**/*
Обновлены архитектурные и пользовательские описания, схема, пример YAML и существующие тестовые конструкторы SourceSetConfig.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ConfigValidator
  participant SourceSetInventory
  participant BuildProject
  participant PlatformDSL
  participant TestRunner

  CLI->>ConfigValidator: загрузка v8project.yaml
  ConfigValidator-->>CLI: валидированный dependency graph
  CLI->>BuildProject: build или test с selection
  BuildProject->>SourceSetInventory: построение closure и порядка
  SourceSetInventory-->>BuildProject: main -> yaxunit -> TESTS
  BuildProject->>PlatformDSL: последовательная сборка
  PlatformDSL-->>BuildProject: результат build steps
  BuildProject->>TestRunner: запуск после успешного графа
Loading

Suggested reviewers: alkoleft

Poem

Я, кролик, прыгаю по DAG,
Веду зависимости в верный шаг.
Сначала main, затем TESTS,
Ошибка — дальше прыгать нельзя.
Но skip сохранён в следах,
И сборка танцует в топологических снах.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.20% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Заголовок точно отражает основное изменение: зависимый порядок сборки для source-set.
Linked Issues check ✅ Passed Изменения покрывают dependsOn, валидацию зависимостей, топологическую сортировку и scoped build closure, как требуется в linked issue #32.
Out of Scope Changes check ✅ Passed Существенных изменений вне заявленной темы нет; документация, схема и тесты поддерживают тот же dependency-aware контракт.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
tests/cli_build.rs (3)

31-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Дублирование форматной строки скрипта.

write_recording_build_script повторяет тело write_build_script (строки 15–29) целиком, отличаясь одной строкой записи в лог. При изменении поведения фейкового 1cv8 придётся править два места.

♻️ Вариант объединения helper'ов
-fn write_recording_build_script(path: &Path, calls_log: &Path, fail_pattern: Option<&str>) {
-    let pattern_branch = fail_pattern
-        .map(|pattern| {
-            format!(
-                "if printf '%s' \"$args\" | grep -F -q -- '{}'; then exit 17; fi",
-                pattern
-            )
-        })
-        .unwrap_or_default();
-    let body = format!(
-        "args=\"$*\"\nout=\"\"\nprev=\"\"\nfor arg in \"$@\"; do\n  if [ \"$prev\" = \"/Out\" ]; then out=\"$arg\"; fi\n  prev=\"$arg\"\ndone\nprintf '%s\\n' \"$args\" >> '{}'\nif [ -n \"$out\" ]; then printf 'designer log for %s\\n' \"$args\" > \"$out\"; fi\n{}\nexit 0",
-        calls_log.display(),
-        pattern_branch
-    );
-    write_script(path, &body);
-}
+fn write_recording_build_script(path: &Path, calls_log: &Path, fail_pattern: Option<&str>) {
+    write_build_script_with_log(path, Some(calls_log), fail_pattern);
+}

write_build_script при этом становится write_build_script_with_log(path, None, fail_pattern), а строка записи в лог добавляется в тело только при Some(calls_log).

🤖 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 `@tests/cli_build.rs` around lines 31 - 46, Устраните дублирование между
write_recording_build_script и write_build_script: выделите общее формирование
тела в write_build_script_with_log, принимающий опциональный calls_log и
fail_pattern. Добавляйте строку записи аргументов только при Some(calls_log), а
существующий write_build_script переведите на этот helper с None, сохранив
текущее поведение обоих сценариев.

702-715: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Общий корень: нет общего helper'а для разбора лога вызовов /UpdateDBCfg. Правило «строка с -Extension <name> относится к расширению, иначе к конфигурации» скопировано в три места; при изменении формата аргументов придётся править все.

  • tests/cli_build.rs#L702-L715: заменить inline-блок вызовом общего helper'а (например update_db_cfg_order) из tests/support/mod.rs.
  • tests/cli_build.rs#L771-L784: заменить второй inline-блок тем же helper'ом.
  • tests/cli_test.rs#L479-L494: использовать тот же helper, вынеся ветвь RunUnitTests= → enterprise в параметр или отдельную обёртку.
🤖 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 `@tests/cli_build.rs` around lines 702 - 715, Extract the duplicated
/UpdateDBCfg call-log parsing into a shared helper in tests/support/mod.rs, such
as update_db_cfg_order, preserving the rule that -Extension <name> maps to that
extension and other calls map to main. Replace both inline parsing blocks in
tests/cli_build.rs at lines 702-715 and 771-784 with the helper, and update
tests/cli_test.rs at lines 479-494 to use it while supporting the RunUnitTests=
→ enterprise distinction through a parameter or dedicated wrapper.

800-804: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Магический код выхода и хрупкий шаблон фейла.

Some(4) без пояснения затрудняет чтение — стоит сослаться на константу/enum кода ошибки, как это сделано в src/domain/test.rs. Кроме того, fail_pattern требует, чтобы /UpdateDBCfg и -Extension yaxunit шли строго подряд в $*; любое добавление аргумента между ними тихо изменит сценарий теста (сборка перестанет падать). Рассмотрите два отдельных grep по подстрокам вместо одной склеенной.

Также setup_dependency_project уже записывает скрипт, а строки 800–804 сразу его перезаписывают — можно параметризовать helper fail_pattern.

Also applies to: 819-820

🤖 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 `@tests/cli_build.rs` around lines 800 - 804, Update the build-script test
setup around setup_dependency_project and write_recording_build_script to accept
fail_pattern as a helper parameter instead of writing the script again at the
call sites. Replace the magic exit status Some(4) with the existing named
error-code constant or enum used by the test domain. Make fail_pattern validate
/UpdateDBCfg and -Extension yaxunit independently so inserted arguments do not
alter the intended failure scenario.
tests/cli_test.rs (1)

171-178: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Таймаут зашит в helper и дублирует аргумент setup_project.

execution_timeout_seconds: 5 жёстко прописан, хотя тот же 5 передаётся в setup_project (строка 432). При правке одного значения второе тихо разойдётся. Стоит принять таймаут параметром.

♻️ Предлагаемая правка
-fn write_dependency_test_config(path: &Path, work_path: &Path, install_dir: &Path) {
+fn write_dependency_test_config(
+    path: &Path,
+    work_path: &Path,
+    install_dir: &Path,
+    timeout_seconds: u64,
+) {
     let config = format!(
-        "workPath: '{}'\n...\n  execution_timeout_seconds: 5\n...",
+        "workPath: '{}'\n...\n  execution_timeout_seconds: {}\n...",
         work_path.display(),
+        timeout_seconds,
         install_dir.display(),
     );
🤖 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 `@tests/cli_test.rs` around lines 171 - 178, Update
write_dependency_test_config to accept an execution-timeout parameter and
interpolate it into the generated configuration instead of hardcoding 5. Pass
the existing timeout value from setup_project at its call site, keeping the
configuration and setup argument synchronized.
🤖 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/DEEP_DIVE.md`:
- Around line 66-68: Уточните описание поведения после сбоя зависимости в
разделе документации: замените утверждение, что выполнение останавливается для
всех оставшихся selected nodes, на правило, согласно которому пропускаются
только узлы, зависящие от failed node, а независимые source-set продолжают
выполняться в стабильном порядке.

---

Nitpick comments:
In `@tests/cli_build.rs`:
- Around line 31-46: Устраните дублирование между write_recording_build_script и
write_build_script: выделите общее формирование тела в
write_build_script_with_log, принимающий опциональный calls_log и fail_pattern.
Добавляйте строку записи аргументов только при Some(calls_log), а существующий
write_build_script переведите на этот helper с None, сохранив текущее поведение
обоих сценариев.
- Around line 702-715: Extract the duplicated /UpdateDBCfg call-log parsing into
a shared helper in tests/support/mod.rs, such as update_db_cfg_order, preserving
the rule that -Extension <name> maps to that extension and other calls map to
main. Replace both inline parsing blocks in tests/cli_build.rs at lines 702-715
and 771-784 with the helper, and update tests/cli_test.rs at lines 479-494 to
use it while supporting the RunUnitTests= → enterprise distinction through a
parameter or dedicated wrapper.
- Around line 800-804: Update the build-script test setup around
setup_dependency_project and write_recording_build_script to accept fail_pattern
as a helper parameter instead of writing the script again at the call sites.
Replace the magic exit status Some(4) with the existing named error-code
constant or enum used by the test domain. Make fail_pattern validate
/UpdateDBCfg and -Extension yaxunit independently so inserted arguments do not
alter the intended failure scenario.

In `@tests/cli_test.rs`:
- Around line 171-178: Update write_dependency_test_config to accept an
execution-timeout parameter and interpolate it into the generated configuration
instead of hardcoding 5. Pass the existing timeout value from setup_project at
its call site, keeping the configuration and setup argument synchronized.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1432398b-9f4c-4d2e-aa8d-66587d70ee9e

📥 Commits

Reviewing files that changed from the base of the PR and between d612e2d and 6b1a27e.

📒 Files selected for processing (39)
  • ARCHITECTURE.md
  • SKILL/SKILL.md
  • SKILL/references/command-selection.md
  • SKILL/references/config-and-backends.md
  • SKILL/references/project-workflows.md
  • SKILL/references/testing.md
  • docs/CAPABILITIES.md
  • docs/CONFIGURATION.md
  • docs/DEEP_DIVE.md
  • docs/schemas/v8project.schema.json
  • examples/v8project.yaml
  • spec/architecture/invariants.md
  • spec/decisions/0023-zavisimosti-source-set-i-stabilnyy-poryadok-build.md
  • spec/decisions/README.md
  • src/change_detection/source_sets.rs
  • src/cli/execute.rs
  • src/config/loader.rs
  • src/config/model.rs
  • src/config/schema.rs
  • src/config/validate.rs
  • src/mcp/port.rs
  • src/mcp/server.rs
  • src/mcp/service.rs
  • src/platform/edt.rs
  • src/use_cases/artifacts.rs
  • src/use_cases/build_project.rs
  • src/use_cases/check_syntax.rs
  • src/use_cases/configure_extensions.rs
  • src/use_cases/dump_config.rs
  • src/use_cases/extension_identity.rs
  • src/use_cases/external_artifacts.rs
  • src/use_cases/init_project.rs
  • src/use_cases/launch_app.rs
  • src/use_cases/run_tests.rs
  • src/use_cases/source_inventory.rs
  • src/use_cases/transport.rs
  • src/use_cases/workspace_lock.rs
  • tests/cli_build.rs
  • tests/cli_test.rs

Comment thread docs/DEEP_DIVE.md Outdated
Comment on lines +66 to +68
уже успешные ранние шаги. Failure dependency останавливает platform execution для всех оставшихся
selected nodes; они остаются в structured result как `skipped` с причиной
`aborted after previous failure`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Не останавливайте независимые source-set после сбоя зависимости.

Формулировка «для всех оставшихся selected nodes» противоречит контракту PR: после ошибки должны блокироваться зависимые узлы, но независимые source-set должны по-прежнему обрабатываться в стабильном порядке. Уточните документацию, например: «останавливается выполнение узлов, зависящих от failed node; независимые узлы продолжают выполняться».

Предлагаемая правка
-Failure dependency останавливает platform execution для всех оставшихся
-selected nodes; они остаются в structured result как `skipped` с причиной
+Failure dependency останавливает platform execution для узлов, зависящих от
+неуспешного узла; такие узлы остаются в structured result как `skipped` с причиной
 `aborted after previous failure`.
📝 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.

Suggested change
уже успешные ранние шаги. Failure dependency останавливает platform execution для всех оставшихся
selected nodes; они остаются в structured result как `skipped` с причиной
`aborted after previous failure`.
уже успешные ранние шаги. Failure dependency останавливает platform execution для узлов, зависящих от
неуспешного узла; такие узлы остаются в structured result как `skipped` с причиной
`aborted after previous failure`.
🤖 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/DEEP_DIVE.md` around lines 66 - 68, Уточните описание поведения после
сбоя зависимости в разделе документации: замените утверждение, что выполнение
останавливается для всех оставшихся selected nodes, на правило, согласно
которому пропускаются только узлы, зависящие от failed node, а независимые
source-set продолжают выполняться в стабильном порядке.

- Document that failed builds skip all remaining selected source sets\n- Preserve the actual sequential build contract for independent nodes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(source-set): добавить dependsOn и dependency-aware build для CFE → CFE

1 participant