Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/commands/open/hook_ctx.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use anyhow::Result;
use worktree_io::{
config::Config,
hooks::HookContext,
hooks::{run_hook, HookContext},
issue::IssueRef,
opener,
repo_hooks::{combined_script, RepoConfig},
};

Expand Down Expand Up @@ -69,3 +71,30 @@ pub(super) fn build_hook_context(issue: &IssueRef, worktree_path: &std::path::Pa
worktree_path: worktree_path.to_string_lossy().into_owned(),
}
}

pub(super) fn launch_editor(
workspace: &std::path::Path,
cmd: Option<&str>,
post_hook: Option<&str>,
background: bool,
ctx: &HookContext,
) -> Result<()> {
match (cmd, post_hook) {
(Some(c), Some(s)) => {
let rendered = ctx.render(s);
if !opener::open_with_hook(workspace, c, &rendered, background)? {
eprintln!("Running post:open hook…");
run_hook(s, ctx)?;
}
}
(Some(c), None) => {
opener::open_editor_or_terminal(workspace, c, background)?;
}
(None, Some(s)) => {
eprintln!("Running post:open hook…");
run_hook(s, ctx)?;
}
(None, None) => {}
}
Ok(())
}
43 changes: 21 additions & 22 deletions src/commands/open/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ use worktree_io::{
config::Config,
hooks::run_hook,
issue::{DeepLinkOptions, IssueRef},
opener,
repo_hooks_scaffold::scaffold_if_missing,
ttl::{self, WorkspaceRegistry},
workspace::Workspace,
};

use hook_ctx::{build_hook_context, effective_hooks};
use hook_ctx::{build_hook_context, effective_hooks, launch_editor};

pub fn cmd_open(issue_ref: Option<&str>, force_editor: bool, no_hooks: bool) -> Result<()> {
pub fn cmd_open(
issue_ref: Option<&str>,
force_editor: bool,
no_hooks: bool,
headless: bool,
) -> Result<()> {
let (issue, deep_link_opts) = match issue_ref {
Some(r) => IssueRef::parse_with_options(r)?,
None => (IssueRef::from_current_repo()?, DeepLinkOptions::default()),
Expand Down Expand Up @@ -63,6 +67,13 @@ pub fn cmd_open(issue_ref: Option<&str>, force_editor: bool, no_hooks: bool) ->
run_hook(script, &hook_ctx)?;
}

if headless {
if let Some(script) = &effective_post {
eprintln!("Running post:open hook…");
run_hook(script, &hook_ctx)?;
}
return Ok(());
}
let editor_cmd: Option<String> = if let Some(editor_name) = deep_link_opts.editor {
Some(editor::resolve_editor_command(&editor_name))
} else if force_editor || config.open.editor {
Expand All @@ -73,25 +84,13 @@ pub fn cmd_open(issue_ref: Option<&str>, force_editor: bool, no_hooks: bool) ->
} else {
None
};

match (editor_cmd.as_deref(), effective_post.as_deref()) {
(Some(cmd), Some(script)) => {
let rendered = hook_ctx.render(script);
if !opener::open_with_hook(&workspace.path, cmd, &rendered, config.editor.background)? {
eprintln!("Running post:open hook…");
run_hook(script, &hook_ctx)?;
}
}
(Some(cmd), None) => {
opener::open_editor_or_terminal(&workspace.path, cmd, config.editor.background)?;
}
(None, Some(script)) => {
eprintln!("Running post:open hook…");
run_hook(script, &hook_ctx)?;
}
(None, None) => {}
}

launch_editor(
&workspace.path,
editor_cmd.as_deref(),
effective_post.as_deref(),
config.editor.background,
&hook_ctx,
)?;
Ok(())
}

Expand Down
9 changes: 5 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#![allow(missing_docs)] // binary crate; public API lives in the library
use anyhow::Result;
use clap::{Parser, Subcommand};

mod commands;
use commands::config::{cmd_config, ConfigAction};
use commands::list::cmd_list;
Expand All @@ -12,7 +11,6 @@ use commands::prune::cmd_prune;
use commands::restore::cmd_restore;
use commands::scheme::{cmd_scheme, SchemeAction};
use commands::setup::cmd_setup;

#[derive(Parser)]
#[command(
name = "worktree",
Expand All @@ -23,7 +21,6 @@ struct Cli {
#[command(subcommand)]
command: Commands,
}

#[derive(Subcommand)]
enum Commands {
/// Parse an issue reference, create a worktree, and open it
Expand All @@ -37,6 +34,9 @@ enum Commands {
/// Skip pre/post-open hooks
#[arg(long)]
no_hooks: bool,
/// Skip opening editor/terminal (hooks still run); useful for programmatic invocation
#[arg(long)]
headless: bool,
},
/// Open multiple repos as a unified workspace under ~/workspaces/<name>/
#[command(name = "open-multi")]
Expand Down Expand Up @@ -85,7 +85,8 @@ fn main() -> Result<()> {
issue_ref,
editor,
no_hooks,
} => cmd_open(issue_ref.as_deref(), editor, no_hooks)?,
headless,
} => cmd_open(issue_ref.as_deref(), editor, no_hooks, headless)?,
Commands::OpenMulti { refs, no_hooks } => cmd_open_multi(&refs, no_hooks)?,
Commands::Config { action } => cmd_config(action)?,
Commands::List { json } => cmd_list(json)?,
Expand Down
Loading