Skip to content

Commit d8e05a7

Browse files
authored
feat(cli): ship the binary from the published crate (#217)
`cargo install rustmotion` could not work. The README documents it, and the crate's own description calls it "a CLI tool", but the published crate carried only a `[lib]`: the `rustmotion` binary was declared in `rustmotion-cli`, which is `publish = false`. Installing it gave a library and no command. The binary now lives in `crates/rustmotion` and `rustmotion-cli` is gone. The studio subcommand could not come along, and not for want of trying: an optional dependency does not help, because `rustmotion-studio` depends on `rustmotion`, so cargo rejects the cycle before compiling anything. No capability is lost — `rustmotion-studio` already declares its own binary of that name, so the studio is launched directly instead of through a subcommand. Moving the CLI exposed a second defect, latent while the crate was unpublished and the same class as the themes bug fixed in #216: `build.rs` walked `.claude/skills/rustmotion/` and `skills.rs` embedded `CLAUDE.md`, both outside the package directory. `cargo package` archives only what lives under the crate, so the tarball did not compile — the verify step failed on a missing SKILL.md. Both now live inside the crate, with symlinks at their old paths so Claude Code still finds them. One copy, not two: this repository already learned in #165 what a duplicated skill list costs when it drifts, and the test that caught that drift is what still guards it. The install destination is unchanged. `build.rs` embeds the path the file will be written to rather than the path it came from, and running the built binary in an empty directory writes 59 files to `.claude/skills/rustmotion/` as before.
1 parent ac39010 commit d8e05a7

94 files changed

Lines changed: 332 additions & 357 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/rustmotion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../crates/rustmotion/skills

.github/workflows/publish.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ jobs:
6262
# pouvait donc jamais reussir, et la release 0.6.0 s'est arretee la — apres
6363
# avoir publie rustmotion-core, definitivement.
6464
#
65-
# studio et cli portent `publish = false` : cargo les saute tout seul.
65+
# rustmotion-studio porte `publish = false` : cargo la saute tout seul.
6666
- name: Publish all crates
6767
run: cargo publish --workspace --token ${{ secrets.CARGO_REGISTRY_TOKEN }}

CLAUDE.md

Lines changed: 0 additions & 230 deletions
This file was deleted.

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
crates/rustmotion/CLAUDE.md

Cargo.lock

Lines changed: 5 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ members = [
44
"crates/rustmotion-core",
55
"crates/rustmotion-components",
66
"crates/rustmotion",
7-
"crates/rustmotion-cli",
87
"crates/rustmotion-studio",
98
"crates/rustmotion-html",
109
]
1110

12-
# Les six crates avancent ensemble. La version se change ici, et nulle part
11+
# Les cinq crates avancent ensemble. La version se change ici, et nulle part
1312
# ailleurs : elle était auparavant répétée dix fois — une par manifeste, plus une
1413
# par dépendance interne — et une seule oubliée fait échouer la publication après
1514
# que les précédentes soient parties, ce qui ne se rattrape pas.

crates/rustmotion-cli/Cargo.toml

Lines changed: 0 additions & 27 deletions
This file was deleted.

crates/rustmotion-components/src/intrinsic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub struct TextIntrinsic {
116116
impl TextIntrinsic {
117117
/// M1: `white-space: nowrap|pre` disables wrapping — the geometry
118118
/// validator's `unwrappable_text_overflow`/`ContentOverflowsBox` checks
119-
/// (crates/rustmotion-cli/src/commands/geometry.rs) already branch on
119+
/// (crates/rustmotion/src/cli/commands/geometry.rs) already branch on
120120
/// exactly this pair of variants and re-measure via this same
121121
/// `TextIntrinsic`, so the wrap decision here must match theirs exactly
122122
/// or the validator's assumption about what the renderer produces is
@@ -164,7 +164,7 @@ impl TextIntrinsic {
164164
// No *real* `LengthContext` (real viewport, real parent width) is
165165
// reachable here without changing this constructor's signature —
166166
// its only callers are `box_builder.rs` and
167-
// `rustmotion-cli/src/commands/geometry.rs`, both outside this
167+
// `rustmotion/src/cli/commands/geometry.rs`, both outside this
168168
// workstream's scope (box_builder.rs is a sibling's live file this
169169
// wave; the geometry validator re-measures via this exact type and
170170
// must keep agreeing with it byte-for-byte, so changing what it

crates/rustmotion-components/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ pub struct ChildComponent {
319319
/// `style` property — `CssStyle` is `deny_unknown_fields` and belongs to
320320
/// no one this wave. Defaults to `false`: no existing scenario changes
321321
/// behaviour. Exempts only `viewport_overflow` and `animated_text_overflow`
322-
/// (see `crates/rustmotion-cli/src/commands/geometry.rs`); it does NOT
322+
/// (see `crates/rustmotion/src/cli/commands/geometry.rs`); it does NOT
323323
/// exempt `content_overflows_box` — content larger than its own box stays
324324
/// a reported defect regardless of `bleed`. Applies to this component
325325
/// only: a bled container does not suppress checks on its children, since

crates/rustmotion-core/src/css/style.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ use super::units::{Length, LengthContext, LengthPercentage, ParsedLength};
1313
// shape either way — a css-local mirror would only duplicate the struct.
1414
use crate::schema::{deserialize_animation_effects, AnimationEffect, GradientBorder, InnerShadow};
1515

16-
// ─── Legibility floor (relocated from `rustmotion-cli/src/commands/
16+
// ─── Legibility floor (relocated from `rustmotion/src/cli/commands/
1717
// geometry.rs`'s `check_legibility`, issue #110/#102 — moved here, not
1818
// duplicated, so `text-autofit` below can shrink down to the exact same
19-
// calibrated threshold instead of inventing a second one; `rustmotion-cli`
19+
// calibrated threshold instead of inventing a second one; `rustmotion`
2020
// depends on `rustmotion-core`, never the other way around, so the shared
2121
// value has to live on this side of that boundary) ─────────────────────────
2222
//
@@ -124,7 +124,7 @@ pub struct CssStyle {
124124
/// instead of overflowing it. This is what lets an author declare "this
125125
/// text must fit here" and closes `ContentOverflowsBox` as a possible
126126
/// validator failure for that node — see `apply_fixes`
127-
/// (`rustmotion-cli/src/commands/validate.rs`)'s comment on why it
127+
/// (`rustmotion/src/cli/commands/validate.rs`)'s comment on why it
128128
/// deliberately refuses to auto-fix that violation today: growing the
129129
/// box, shrinking the font, and shortening the copy are all legitimate
130130
/// fixes, and picking one was never this tool's call to make silently.
@@ -163,7 +163,7 @@ pub struct CssStyle {
163163
///
164164
/// **The floor.** Never shrinks below [`TEXT_AUTOFIT_MIN_FONT_PX`] — the
165165
/// same calibrated legibility ratio `check_legibility`
166-
/// (`rustmotion-cli/src/commands/geometry.rs`) already enforces, not a
166+
/// (`rustmotion/src/cli/commands/geometry.rs`) already enforces, not a
167167
/// new threshold. If the content still doesn't fit at the floor, the
168168
/// floor size is used anyway (illegible-but-smallest beats an even
169169
/// larger overflow) and the geometry validator's `ContentOverflowsBox`

0 commit comments

Comments
 (0)