Commit Graph
4 Commits
Author SHA1 Message Date
Dario LipicarandClaude Opus 5 efaa390484 docs: the widened Qt consumer surface (#84)
* test(doctests): `lm` publishes the LIDL contract vocabulary, not Qt names

A universal module's `getMethods()` comes from the cdylib backend's
`lidlInterfaceJson()` (logos-plugin-qt's glue forwards
`logos_module_get_methods` verbatim), and that now answers in the LIDL
contract spelling. `lm methods`, `lm events` and `logoscore module-info`
print those strings straight through, so every listing in Part 1 changed:

    qlonglong add(qlonglong a, qlonglong b)   ->  int add(int a, int b)
    QString libVersion()                      ->  tstr libVersion()
    void versionReady(QString version)        ->  void versionReady(tstr version)

Six `expect_contains` in tutorial-wrapping-c-library.test.yaml were pinned
to the Qt spellings and now fail.

HOW THIS WAS ALMOST MISSED, because the trap will recur. The hand-pinned
`outputs/tutorial-wrapping-c-library.md` already showed `int add(int a, int b)`
and `add(int,int)` — a stale snapshot from an earlier era that happened to
read as "already LIDL, nothing to do". CI runs the ASSERTIONS in
`tests/*.test.yaml`; it never diffs the outputs tree. Clearing a file by
reading `outputs/` proves nothing.

Every replacement string is derived mechanically rather than by hand: the
tutorial's own `src/calc_module_impl.h` + `metadata.json` were run through
`logos-cpp-generator --from-header --backend cdylib`, the emitted
`lidlInterfaceJson()` was parsed back into JSON, and that JSON was rendered
through logos-module's own printer (`cmd/main.cpp`) and logoscore's
(`src/client/output.cpp`). The displayed blocks in BOTH trees now compare
byte-identical to that render.

Two accuracy fixes fall out of doing that, both pre-existing drift in the
blocks being rewritten:

  * the derived identity methods `name()` / `version()` DO appear in every
    listing (nothing filters `derived` on the read side) and were missing
    from the shown output;
  * the `module-info` block said `libVersion() -> QString` and
    `versionReady(version: QString)`.

The C++-type table gains a column. "On the wire (Qt)" conflated two
different questions; it is now "LIDL contract type" — what the module
publishes, what Step 5 prints, what a Rust or Nim binding sees — and "A Qt
consumer sees", which is only the C++/Qt caller's spelling.

Also here, same cause:
  * tutorial-composing-modules and tutorial-interface-dependencies had the
    same "shows up as QString ... the wire types the generated glue exposes"
    prose. Their assertions are name-only, so they did not fail — but they
    described the listing wrongly. `LogosMap` publishes as `{tstr: any}`,
    verified by generating calc_aggregator's glue.
  * logos-developer-guide.md's `lm methods --json` example was a
    handwritten-Qt listing (`initLogos(LogosAPI*)`) presented as the general
    case. It now shows both publishers and says which is which: a universal
    module publishes its contract, a handwritten Qt plugin publishes what its
    QMetaObject says.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(guide): the plugin path needs the module's contract, not just its plugin

`logos-cpp-generator <plugin> [--module-only]` is documented here as a way to
generate a module's consumer wrapper, and the examples pass only the plugin.
That is now a trap for any module built with `interface: "universal"` or
`"cdylib"`: its published `getMethods()` answers in the LIDL contract
vocabulary — the same change d963871 pinned in the `lm` listings — while the
wrapper emitter reads Qt type names and falls back to QVariant / LogosMap for
anything else. The wrapper would compile and have lost every type.

The generator now takes the METHODS from the `.lidl` contract named by
`--events-from` (the flag keeps its name; the file always was the whole
contract), and REFUSES a LIDL-spelled listing when no contract was given rather
than emitting the untyped wrapper. Nix builds already pass the flag —
buildHeaders.nix finds `<module>/share/logos/<name>.lidl` — so only hand-run
invocations, which is what this section documents, had to change.

Both examples gain the flag, a second example shows the handcrafted-Qt case
that legitimately omits it, and the synopsis in the CLI reference lists it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 13:32:32 +02:00
Dario Gabriel LipicarandClaude Opus 4.8 dbce6ad7ca tutorial-v4 release
Update artifacts for tutorial-v4. Regenerate outputs/ against the 0.2.0
release tags: every {release} reference (logos-basecamp, logos-logoscore-cli,
logos-module-builder, logos-package-manager, logos-module) now resolves to
0.2.0 in both the generated .md tutorials and the example module flake.nix
files.

- Add the missing {release} placeholder to the advanced flake.nix examples in
  tutorial-wrapping-c-library and tutorial-interface-dependencies so they pin
  consistently.
- run.sh: clean now also removes the .logoscore persistence dirs; --release
  examples updated from tutorial-vN to 0.2.0 (repos carry semver tags;
  logos-tutorial carries the tutorial-vN tag).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 00:39:59 -03:00
Dario Lipicar 1a4fa6fc20 doctest: make the bad-bind step outcome-agnostic (#69)
* doctest: make the bad-bind step outcome-agnostic

Asserting status:error relied on the inner call to a missing module
blocking long enough to time out the outer RPC. With faster failure
detection the plain-int typed wrapper returns the type's default and the
outer call reports ok — both surfaces are legitimate, and which one wins
is a platform/timing race (consistently the fast path on Linux since the
transport extraction, still the slow path on macOS). Assert on the
stable part and teach the real contract: bad binds fail at call time;
methods that need caller-visible errors should return result.

* doctest(qml-ui): gate the Modules click on a wait_for

Right after the calculator round-trip the shell is still settling; on a
busy CI runner the Modules entry can take longer than the click action's
retry budget to materialize (flipped red on both platforms in one run,
green the previous hour, identical pins). Same pattern the spec already
uses for the post-launch wait.

* doctest(qml-ui): open Settings before clicking Modules

The Modules entry lives in the Settings left rail; clicking it cold
relied on incidental tree state (passed or failed depending on whether
the entry happened to be materialized). Mirror the basecamp doctests'
proven sequence: click Settings, wait for the view, then click Modules.

* tutorial: demonstrate the CallError out-param on bound interface calls

Generated typed wrappers now take an optional trailing
logos::CallError* — sumVia checks it and returns -1 when the inner call
fails (err.code == "object_unavailable" for a missing module), so the
bad-bind lesson no longer depends on which way the failure-timing race
falls. The doctest assert stays tolerant of the slow-transport
outer-timeout surface.
2026-06-12 23:59:40 -03:00
Dario LipicarandClaude Opus 4.7 c9f47391e5 feat: dependency interfaces — executable tutorial + guide (#64)
* feat: dependency interfaces tutorial (executable)

Add tests/tutorial-interface-dependencies.test.yaml — an executable
logos-doctest tutorial that builds calc_via_interface: a module declaring a
`calculator` interface and binding it to calc_module at runtime. Covers typed
sync/async/event calls, the no-validation rule, and the cross-repo interface
form. Registered in run.sh and CI (run + generate). Documents
interface_dependencies + bind_<interface> in the developer guide.

Depends on logos-cpp-sdk#74, logos-module-builder#108, logos-plugin-qt#8 —
the published flakes must carry these before the tutorial runs green in CI
(same release gating as the Composing Modules tutorial).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* address review: self-valid interface header + accurate CI step

- Interface calculator.h includes logos_module_context.h so the logos_events
  token is defined (valid C++ standalone); prose updated accordingly.
- CI step name/comment now reflect the third tutorial leaf
  (tutorial-interface-dependencies), not just the UI chain + Composing Modules.
(Copilot review, PR #64.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* rerun

* rerun

* fix(tutorial): correct the no-validation negative test

Binding to a module that isn't loaded does NOT return a silent default — the
inner remote call fails and propagates, so `logoscore call ... sumVia
no_such_module` exits non-zero with RPC_FAILED. The step asserted "result":0
and let the non-zero exit fail the doctest step. Reframe it accurately: a bad
bind surfaces as an ordinary RPC failure (not a crash); absorb the exit with
`|| true`, capture stderr, and assert `"status":"error"`. Fix the prose and the
recap row to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 22:19:30 -03:00