Skip to content
Open
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
6 changes: 6 additions & 0 deletions cli/assets/hooks/post-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#!/bin/sh
set -eu

remote_url="$(git remote get-url origin 2>/dev/null || true)"

if [ -n "$remote_url" ]; then
exec sce hooks post-commit --vcs git --remote-url "$remote_url" "$@"
fi

exec sce hooks post-commit --vcs git "$@"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE agent_traces
ADD COLUMN remote_url TEXT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE INDEX IF NOT EXISTS idx_agent_traces_remote_url
ON agent_traces (remote_url);
3 changes: 3 additions & 0 deletions cli/src/cli_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ pub enum HooksSubcommand {
PostCommit {
#[arg(long = "vcs")]
vcs: Option<String>,

#[arg(long = "remote-url")]
remote_url: Option<String>,
},

#[command(about = "Run post-rewrite hook (reads pairs from STDIN)")]
Expand Down
26 changes: 25 additions & 1 deletion cli/src/services/agent_trace_db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ const CREATE_DIFF_TRACES_TIME_MS_ID_INDEX_MIGRATION: &str =
const CREATE_AGENT_TRACES_AGENT_TRACE_ID_INDEX_MIGRATION: &str = include_str!(
"../../../migrations/agent-trace/005_create_agent_traces_agent_trace_id_index.sql"
);
const ADD_AGENT_TRACES_REMOTE_URL_MIGRATION: &str =
include_str!("../../../migrations/agent-trace/006_add_agent_traces_vcs_remote_url.sql");
const CREATE_AGENT_TRACES_REMOTE_URL_INDEX_MIGRATION: &str = include_str!(
"../../../migrations/agent-trace/007_create_agent_traces_vcs_remote_url_index.sql"
);

const AGENT_TRACE_MIGRATIONS: &[(&str, &str)] = &[
("001_create_diff_traces", CREATE_DIFF_TRACES_MIGRATION),
Expand All @@ -39,6 +44,14 @@ const AGENT_TRACE_MIGRATIONS: &[(&str, &str)] = &[
"005_create_agent_traces_agent_trace_id_index",
CREATE_AGENT_TRACES_AGENT_TRACE_ID_INDEX_MIGRATION,
),
(
"006_add_agent_traces_remote_url",
ADD_AGENT_TRACES_REMOTE_URL_MIGRATION,
),
(
"007_create_agent_traces_remote_url_index",
CREATE_AGENT_TRACES_REMOTE_URL_INDEX_MIGRATION,
),
];

/// Parameterized SQL for inserting a captured diff trace payload.
Expand Down Expand Up @@ -66,7 +79,7 @@ pub const INSERT_POST_COMMIT_PATCH_INTERSECTION_SQL: &str =

/// Parameterized SQL for inserting a built agent trace payload.
pub const INSERT_AGENT_TRACE_SQL: &str =
"INSERT INTO agent_traces (commit_id, commit_time_ms, trace_json, agent_trace_id, url) VALUES (?1, ?2, ?3, ?4, ?5)";
"INSERT INTO agent_traces (commit_id, commit_time_ms, trace_json, agent_trace_id, url, remote_url) VALUES (?1, ?2, ?3, ?4, ?5, ?6)";

/// Agent trace database configuration.
pub struct AgentTraceDbSpec;
Expand Down Expand Up @@ -168,6 +181,7 @@ pub struct AgentTraceInsert<'a> {
pub trace_json: &'a str,
pub agent_trace_id: &'a str,
pub url: &'a str,
pub remote_url: &'a str,
}

impl AgentTraceDb {
Expand Down Expand Up @@ -241,6 +255,7 @@ fn insert_agent_trace_with<M: DbSpec>(db: &TursoDb<M>, input: AgentTraceInsert<'
input.trace_json,
input.agent_trace_id,
input.url,
input.remote_url,
),
)
}
Expand Down Expand Up @@ -537,6 +552,11 @@ mod tests {
"index",
"idx_agent_traces_agent_trace_id"
));
assert!(sqlite_object_exists(
&db,
"index",
"idx_agent_traces_remote_url"
));
assert_eq!(
applied_migration_ids(&db),
vec![
Expand All @@ -545,6 +565,8 @@ mod tests {
"003_create_agent_traces",
"004_create_diff_traces_time_ms_id_index",
"005_create_agent_traces_agent_trace_id_index",
"006_add_agent_traces_remote_url",
"007_create_agent_traces_remote_url_index",
]
);

Expand All @@ -556,6 +578,7 @@ mod tests {
trace_json: r#"{"id":"trace-1"}"#,
agent_trace_id: "trace-1",
url: "sce.crocoder.dev/trace/trace-1",
remote_url: "https://github.com/test/repo",
},
);
assert!(duplicate_insert.is_ok());
Expand All @@ -568,6 +591,7 @@ mod tests {
trace_json: r#"{"id":"trace-1"}"#,
agent_trace_id: "trace-1",
url: "sce.crocoder.dev/trace/trace-1",
remote_url: "https://github.com/test/repo",
},
);
assert!(duplicate_insert.is_err());
Expand Down
39 changes: 30 additions & 9 deletions cli/src/services/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ const MAX_TRACE_FILE_CREATE_ATTEMPTS: u64 = 1_000_000;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum HookSubcommand {
PreCommit,
CommitMsg { message_file: PathBuf },
PostCommit { vcs_type: Option<AgentTraceVcsType> },
PostRewrite { rewrite_method: String },
CommitMsg {
message_file: PathBuf,
},
PostCommit {
vcs_type: Option<AgentTraceVcsType>,
remote_url: Option<String>,
},
PostRewrite {
rewrite_method: String,
},
DiffTrace,
}

Expand Down Expand Up @@ -85,9 +92,10 @@ fn run_hooks_subcommand_in_repo(
HookSubcommand::CommitMsg { message_file } => {
run_commit_msg_subcommand_with_trace(repository_root, subcommand, message_file)
}
HookSubcommand::PostCommit { vcs_type } => {
run_post_commit_subcommand_with_trace(repository_root, *vcs_type)
}
HookSubcommand::PostCommit {
vcs_type,
remote_url,
} => run_post_commit_subcommand_with_trace(repository_root, *vcs_type, remote_url.clone()),
HookSubcommand::PostRewrite { rewrite_method } => {
run_post_rewrite_subcommand_with_trace(repository_root, subcommand, rewrite_method)
}
Expand Down Expand Up @@ -486,10 +494,12 @@ fn run_commit_msg_subcommand_with_trace(
fn run_post_commit_subcommand(
repository_root: &Path,
vcs_type: Option<AgentTraceVcsType>,
remote_url: &str,
) -> Result<String> {
run_post_commit_subcommand_with(
repository_root,
vcs_type,
remote_url,
run_post_commit_intersection_flow,
run_post_commit_agent_trace_flow,
)
Expand All @@ -498,6 +508,7 @@ fn run_post_commit_subcommand(
fn run_post_commit_subcommand_with<F, B>(
repository_root: &Path,
vcs_type: Option<AgentTraceVcsType>,
remote_url: &str,
run_intersection_flow: F,
run_agent_trace_flow: B,
) -> Result<String>
Expand All @@ -507,10 +518,11 @@ where
&Path,
&PostCommitIntersectionFlowResult,
Option<AgentTraceVcsType>,
&str,
) -> Result<AgentTrace>,
{
let result = run_intersection_flow(repository_root)?;
let _agent_trace = run_agent_trace_flow(repository_root, &result, vcs_type)?;
let _agent_trace = run_agent_trace_flow(repository_root, &result, vcs_type, remote_url)?;

Ok(format!(
"post-commit hook processed intersection: commit={}, intersection_files={}",
Expand All @@ -523,12 +535,14 @@ fn run_post_commit_agent_trace_flow(
_repository_root: &Path,
flow_result: &PostCommitIntersectionFlowResult,
vcs_type: Option<AgentTraceVcsType>,
remote_url: &str,
) -> Result<AgentTrace> {
let db = AgentTraceDb::new().context("Failed to open Agent Trace DB for post-commit trace.")?;

run_post_commit_agent_trace_flow_with(
flow_result,
vcs_type,
remote_url,
|trace_value| {
validate_agent_trace_value(trace_value)
.map_err(|error| anyhow!(error.to_string()))
Expand All @@ -548,6 +562,7 @@ fn run_post_commit_agent_trace_flow(
fn run_post_commit_agent_trace_flow_with<V, I>(
flow_result: &PostCommitIntersectionFlowResult,
vcs_type: Option<AgentTraceVcsType>,
remote_url: &str,
validate_agent_trace: V,
persist_agent_trace: I,
) -> Result<AgentTrace>
Expand Down Expand Up @@ -597,6 +612,7 @@ where
trace_json: &serialized,
agent_trace_id: &agent_trace.id,
url: &constructed_url,
remote_url,
};
persist_agent_trace(insert_input)?;

Expand Down Expand Up @@ -700,10 +716,15 @@ fn current_unix_time_ms() -> Result<i64> {
fn run_post_commit_subcommand_with_trace(
repository_root: &Path,
vcs_type: Option<AgentTraceVcsType>,
remote_url: Option<String>,
) -> Result<String> {
let subcommand = HookSubcommand::PostCommit { vcs_type };
let remote_url_value = remote_url.clone().unwrap_or_default();
let subcommand = HookSubcommand::PostCommit {
vcs_type,
remote_url,
};
let input = build_hook_trace_input_for_post_commit(repository_root);
let outcome = run_post_commit_subcommand(repository_root, vcs_type);
let outcome = run_post_commit_subcommand(repository_root, vcs_type, &remote_url_value);

let _ = persist_hook_trace(repository_root, &subcommand, &input, &outcome);

Expand Down
16 changes: 14 additions & 2 deletions cli/src/services/parse/command_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,17 @@ fn convert_hooks_subcommand(
subcommand: services::hooks::HookSubcommand::CommitMsg { message_file },
}))
}
cli_schema::HooksSubcommand::PostCommit { vcs } => {
cli_schema::HooksSubcommand::PostCommit { vcs, remote_url } => {
let vcs_type = parse_optional_hook_vcs_type(vcs.as_deref())
.map_err(ClassifiedError::validation)?;
let remote_url =
parse_optional_hook_remote_url(remote_url).map_err(ClassifiedError::validation)?;

Ok(Box::new(services::hooks::command::HooksCommand {
subcommand: services::hooks::HookSubcommand::PostCommit { vcs_type },
subcommand: services::hooks::HookSubcommand::PostCommit {
vcs_type,
remote_url: Some(remote_url),
},
}))
}
cli_schema::HooksSubcommand::PostRewrite { rewrite_method } => {
Expand Down Expand Up @@ -424,3 +429,10 @@ fn parse_optional_hook_vcs_type(
)),
}
}

fn parse_optional_hook_remote_url(remote_url: Option<String>) -> Result<String, String> {
match remote_url {
Some(url) if !url.trim().is_empty() => Ok(url),
_ => Err("Missing required option '--remote-url' for 'sce hooks post-commit'.".to_string()),
}
}
Loading