From 59d890f5e501ae722f4c95ef87efa63a0a1ca24f Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Wed, 3 Jun 2026 22:32:52 +0530 Subject: [PATCH] refactor: rename hook to postcreate --- README.md | 8 ++++---- crates/core/src/config.rs | 36 ++++++++++++++++++------------------ crates/core/src/hook.rs | 8 ++++---- crates/core/src/lib.rs | 4 ++-- crates/core/src/tests.rs | 14 +++++++------- specs.md | 6 +++--- 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index feed7f2..a5e678a 100644 --- a/README.md +++ b/README.md @@ -62,19 +62,19 @@ On btrfs, exact copies use writable subvolume snapshots and filtered copies use When the workspace is a Git repository, the new workspace has detached `HEAD` and retains index and working-tree state. -If the source contains `.rift.toml`, `rift create` runs configured postclone hooks after the workspace is copied, registered, and prepared. Use `--no-hooks` to skip them. +If the source contains `.rift.toml`, `rift create` runs configured postcreate hooks after the workspace is created, registered, and prepared. Use `--no-hooks` to skip them. ```toml version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = "pnpm install --frozen-lockfile" -[[hooks.postclone]] +[[hooks.postcreate]] run = "pnpm run codegen" ``` -Postclone commands run in the new workspace root. If a hook fails, the workspace remains registered and `rift create` exits with an error. +Postcreate commands run in the new workspace root. If a hook fails, the workspace remains registered and `rift create` exits with an error. ### List And Ancestors diff --git a/crates/core/src/config.rs b/crates/core/src/config.rs index fdd41a9..9c8e761 100644 --- a/crates/core/src/config.rs +++ b/crates/core/src/config.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; #[derive(Debug, Default)] pub(crate) struct Config { - postclone: Vec, + postcreate: Vec, } impl Config { @@ -17,17 +17,17 @@ impl Config { parse(&path, &fs::read_to_string(&path)?) } - pub(crate) fn postclone(&self) -> &[Postclone] { - &self.postclone + pub(crate) fn postcreate(&self) -> &[Postcreate] { + &self.postcreate } } #[derive(Clone, Debug)] -pub(crate) struct Postclone { +pub(crate) struct Postcreate { run: String, } -impl Postclone { +impl Postcreate { pub(crate) fn run(&self) -> &str { &self.run } @@ -45,12 +45,12 @@ struct RawConfig { #[serde(deny_unknown_fields)] struct RawHooks { #[serde(default)] - postclone: Vec, + postcreate: Vec, } #[derive(Deserialize)] #[serde(deny_unknown_fields)] -struct RawPostclone { +struct RawPostcreate { run: String, } @@ -64,18 +64,18 @@ fn parse(path: &Path, contents: &str) -> Result { )); } raw.hooks - .postclone + .postcreate .into_iter() .map(|step| { let run = step.run.trim().to_owned(); if run.is_empty() { - Err(invalid_config(path, "postclone run cannot be empty")) + Err(invalid_config(path, "postcreate run cannot be empty")) } else { - Ok(Postclone { run }) + Ok(Postcreate { run }) } }) .collect::>>() - .map(|postclone| Config { postclone }) + .map(|postcreate| Config { postcreate }) } fn invalid_config(path: &Path, message: impl Into) -> Error { @@ -90,16 +90,16 @@ mod tests { use super::*; #[test] - fn parses_ordered_postclone_steps() { + fn parses_ordered_postcreate_steps() { let config = parse( Path::new(".rift.toml"), r#" version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo one" -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo two" "#, ) @@ -107,9 +107,9 @@ run = "echo two" assert_eq!( config - .postclone() + .postcreate() .iter() - .map(Postclone::run) + .map(Postcreate::run) .collect::>(), vec!["echo one", "echo two"] ); @@ -123,7 +123,7 @@ run = "echo two" r#" version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = " " "#, ), @@ -139,7 +139,7 @@ run = " " r#" version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo ok" shell = "sh" "#, diff --git a/crates/core/src/hook.rs b/crates/core/src/hook.rs index 89e2715..3284e17 100644 --- a/crates/core/src/hook.rs +++ b/crates/core/src/hook.rs @@ -1,11 +1,11 @@ -use crate::config::Postclone; +use crate::config::Postcreate; use crate::id::RiftId; use crate::{Error, Result}; use std::path::Path; use std::process::Command; -pub(crate) fn run_postclone( - steps: &[Postclone], +pub(crate) fn run_postcreate( + steps: &[Postcreate], source: &Path, destination: &Path, id: &RiftId, @@ -13,7 +13,7 @@ pub(crate) fn run_postclone( ) -> Result<()> { steps .iter() - .map(Postclone::run) + .map(Postcreate::run) .try_for_each(|command| run_step(command, source, destination, id, parent_id)) } diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 9fa0f0a..e024b73 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -59,7 +59,7 @@ pub enum Error { InsideSource(PathBuf), #[error("invalid rift config at {path}: {message}")] InvalidConfig { path: PathBuf, message: String }, - #[error("postclone hook failed at {path}: `{command}` {message}")] + #[error("postcreate hook failed at {path}: `{command}` {message}")] HookFailed { path: PathBuf, command: String, @@ -250,7 +250,7 @@ impl Manager { let _ = self.strategy.remove_directory(&destination); } result?; - hook::run_postclone(config.postclone(), &from, &destination, &id, &source.id)?; + hook::run_postcreate(config.postcreate(), &from, &destination, &id, &source.id)?; Ok(destination) } diff --git a/crates/core/src/tests.rs b/crates/core/src/tests.rs index 0303e95..6eee307 100644 --- a/crates/core/src/tests.rs +++ b/crates/core/src/tests.rs @@ -186,7 +186,7 @@ fn create_copy_all_preserves_regenerable_artifacts() { } #[test] -fn create_runs_postclone_hooks_in_destination_order() { +fn create_runs_postcreate_hooks_in_destination_order() { let temp = TempDir::new().unwrap(); let source = source(&temp); fs::write( @@ -194,10 +194,10 @@ fn create_runs_postclone_hooks_in_destination_order() { r#" version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo first >> hook.log" -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo second >> hook.log" "#, ) @@ -212,7 +212,7 @@ run = "echo second >> hook.log" } #[test] -fn postclone_failure_leaves_registered_workspace() { +fn postcreate_failure_leaves_registered_workspace() { let temp = TempDir::new().unwrap(); let source = source(&temp); fs::write( @@ -220,13 +220,13 @@ fn postclone_failure_leaves_registered_workspace() { r#" version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo before >> hook.log" -[[hooks.postclone]] +[[hooks.postcreate]] run = "exit 7" -[[hooks.postclone]] +[[hooks.postcreate]] run = "echo after >> hook.log" "#, ) diff --git a/specs.md b/specs.md index dd104ee..1e39395 100644 --- a/specs.md +++ b/specs.md @@ -46,7 +46,7 @@ Default behavior: - Copy the workspace while excluding known heavyweight regenerable dependency, build, and cache artifacts. - Preserve manifests, lockfiles, dirty files, staged files, untracked files, and ignored files that are not part of the built-in excluded artifact set. - `copyAll` opts into exact copying, including dependency and build artifacts. -- `hooks` defaults to true and runs `.rift.toml` postclone hooks after copy, Git preparation, and registry insertion. `hooks: false` skips config loading and hook execution. +- `hooks` defaults to true and runs `.rift.toml` postcreate hooks after workspace creation, Git preparation, and registry insertion. `hooks: false` skips config loading and hook execution. - Detach `HEAD` in the new workspace. - Return the path of the new workspace. @@ -57,11 +57,11 @@ Default excluded artifacts are matched at any depth and include `node_modules`, ```toml version = 1 -[[hooks.postclone]] +[[hooks.postcreate]] run = "pnpm install --frozen-lockfile" ``` -Postclone hooks run sequentially in the destination workspace with inherited stdio and environment plus `RIFT_SOURCE`, `RIFT_DESTINATION`, `RIFT_ID`, and `RIFT_PARENT_ID`. The first failing command stops later hooks. The created workspace remains registered and on disk, and the create operation reports a hook failure with the destination path. +Postcreate hooks run sequentially in the destination workspace with inherited stdio and environment plus `RIFT_SOURCE`, `RIFT_DESTINATION`, `RIFT_ID`, and `RIFT_PARENT_ID`. The first failing command stops later hooks. The created workspace remains registered and on disk, and the create operation reports a hook failure with the destination path. On btrfs, `from` must already be a subvolume. If it is an ordinary directory, fail and instruct the user to run `rift init` first. On other reflink-capable Linux filesystems, clone the directory tree with native per-file reflinks.