feat(lang): rename schedule keyword from extends to modifies
Changed the schedule composition keyword from "extends" to "modifies" to better reflect the semantic meaning of schedule inheritance. When a schedule modifies another, it inherits base blocks and can override them by name or add new blocks. This is a breaking change for all existing Storybook files that use schedule composition. The migration is a simple find-and-replace: schedule X extends Y → schedule X modifies Y Changes include: - Grammar: Updated tree-sitter grammar and lexer token - Parser: Updated lalrpop parser and AST field names - Documentation: Updated all reference docs, tutorials, and specs - Examples: Updated baker-family example schedules - Tests: Updated all test cases and corpus files - Testing: Added type system keywords to prop_tests exclusion list - Tooling: Added xtask for workspace cleanup - Version: Bumped to v0.3.1 (skipping v0.3.0) - Spec: Created SBIR v0.3.1 spec documenting the change BREAKING CHANGE: The "extends" keyword for schedules has been replaced with "modifies". Update all schedule declarations.
This commit is contained in:
8
xtask/Cargo.toml
Normal file
8
xtask/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
142
xtask/src/main.rs
Normal file
142
xtask/src/main.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
use std::{
|
||||
env,
|
||||
path::PathBuf,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
use anyhow::{
|
||||
Context,
|
||||
Result,
|
||||
};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let task = env::args().nth(1);
|
||||
match task.as_deref() {
|
||||
| Some("clean") => clean()?,
|
||||
| Some(task) => {
|
||||
eprintln!("Unknown task: {}", task);
|
||||
print_help();
|
||||
std::process::exit(1);
|
||||
},
|
||||
| None => {
|
||||
print_help();
|
||||
std::process::exit(1);
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_help() {
|
||||
eprintln!(
|
||||
r#"
|
||||
Tasks:
|
||||
clean Clean all build artifacts across all projects
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
fn clean() -> Result<()> {
|
||||
let root = project_root();
|
||||
|
||||
println!("🧹 Cleaning Storybook workspace...\n");
|
||||
|
||||
// Clean Rust projects
|
||||
println!(" Cleaning Rust artifacts...");
|
||||
run_command(&["cargo", "clean"], &root)?;
|
||||
|
||||
// Clean tree-sitter-storybook
|
||||
let tree_sitter_dir = root.join("tree-sitter-storybook");
|
||||
if tree_sitter_dir.exists() {
|
||||
println!(" Cleaning tree-sitter-storybook...");
|
||||
|
||||
// Remove node_modules
|
||||
let node_modules = tree_sitter_dir.join("node_modules");
|
||||
if node_modules.exists() {
|
||||
println!(" Removing node_modules/");
|
||||
std::fs::remove_dir_all(&node_modules)
|
||||
.context("Failed to remove tree-sitter-storybook/node_modules")?;
|
||||
}
|
||||
|
||||
// Remove target directory
|
||||
let target = tree_sitter_dir.join("target");
|
||||
if target.exists() {
|
||||
println!(" Removing target/");
|
||||
std::fs::remove_dir_all(&target)
|
||||
.context("Failed to remove tree-sitter-storybook/target")?;
|
||||
}
|
||||
|
||||
// Remove Cargo.lock
|
||||
let cargo_lock = tree_sitter_dir.join("Cargo.lock");
|
||||
if cargo_lock.exists() {
|
||||
println!(" Removing Cargo.lock");
|
||||
std::fs::remove_file(&cargo_lock)
|
||||
.context("Failed to remove tree-sitter-storybook/Cargo.lock")?;
|
||||
}
|
||||
|
||||
// Remove build artifacts
|
||||
let build_dir = tree_sitter_dir.join("build");
|
||||
if build_dir.exists() {
|
||||
println!(" Removing build/");
|
||||
std::fs::remove_dir_all(&build_dir)
|
||||
.context("Failed to remove tree-sitter-storybook/build")?;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean zed-storybook
|
||||
let zed_dir = root.join("zed-storybook");
|
||||
if zed_dir.exists() {
|
||||
println!(" Cleaning zed-storybook...");
|
||||
|
||||
// Remove grammars directory (build artifact)
|
||||
let grammars = zed_dir.join("grammars");
|
||||
if grammars.exists() {
|
||||
println!(" Removing grammars/");
|
||||
std::fs::remove_dir_all(&grammars)
|
||||
.context("Failed to remove zed-storybook/grammars")?;
|
||||
}
|
||||
|
||||
// Remove extension.wasm
|
||||
let wasm = zed_dir.join("extension.wasm");
|
||||
if wasm.exists() {
|
||||
println!(" Removing extension.wasm");
|
||||
std::fs::remove_file(&wasm).context("Failed to remove zed-storybook/extension.wasm")?;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean mdbook artifacts
|
||||
let docs_dir = root.join("docs");
|
||||
if docs_dir.exists() {
|
||||
println!(" Cleaning mdbook artifacts...");
|
||||
|
||||
let book_dir = docs_dir.join("book");
|
||||
if book_dir.exists() {
|
||||
println!(" Removing docs/book/");
|
||||
std::fs::remove_dir_all(&book_dir).context("Failed to remove docs/book")?;
|
||||
}
|
||||
}
|
||||
|
||||
println!("\n✨ Clean complete!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_command(cmd: &[&str], cwd: &PathBuf) -> Result<()> {
|
||||
let mut command = Command::new(cmd[0]);
|
||||
command.args(&cmd[1..]).current_dir(cwd);
|
||||
|
||||
let status = command
|
||||
.status()
|
||||
.with_context(|| format!("Failed to run command: {:?}", cmd))?;
|
||||
|
||||
if !status.success() {
|
||||
anyhow::bail!("Command failed: {:?}", cmd);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn project_root() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf()
|
||||
}
|
||||
Reference in New Issue
Block a user