Jobs: list / create / edit + attach to changelist
- Tools -> Jobs: browse/filter jobs, create/edit job spec - Pending changelist menu -> Attach job... (p4 fix) - Backend p4 jobs, fix, job -o/-i Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -1867,6 +1867,59 @@ async fn p4_latest_change(state: State<'_, AppState>, scope: String) -> Result<V
|
||||
Ok(v.into_iter().next().unwrap_or(Value::Null))
|
||||
}
|
||||
|
||||
/// List jobs on the server (defect/task tracking).
|
||||
#[tauri::command]
|
||||
async fn p4_jobs(state: State<'_, AppState>) -> Result<Vec<Value>, String> {
|
||||
let conn = current(&state)?;
|
||||
run_json(&conn, &["jobs", "-m", "300"])
|
||||
}
|
||||
|
||||
/// Link a job to a pending changelist (`p4 fix -c <change> <job>`).
|
||||
#[tauri::command]
|
||||
async fn p4_fix(state: State<'_, AppState>, job: String, change: String) -> Result<String, String> {
|
||||
let conn = current(&state)?;
|
||||
let job = job.trim();
|
||||
let change = change.trim();
|
||||
if job.is_empty() || change.is_empty() {
|
||||
return Err("Job and changelist are required".into());
|
||||
}
|
||||
run_text(&conn, &["fix", "-c", change, job])
|
||||
}
|
||||
|
||||
/// Get a job spec as editable text (unknown name → new job template).
|
||||
#[tauri::command]
|
||||
async fn p4_job_spec(state: State<'_, AppState>, job: String) -> Result<String, String> {
|
||||
let conn = current(&state)?;
|
||||
let j = job.trim();
|
||||
if j.is_empty() {
|
||||
run_text(&conn, &["job", "-o"]) // template for a new job
|
||||
} else {
|
||||
run_text(&conn, &["job", "-o", j])
|
||||
}
|
||||
}
|
||||
|
||||
/// Save a job spec (`p4 job -i`), creating it if new.
|
||||
#[tauri::command]
|
||||
async fn p4_job_save(state: State<'_, AppState>, spec: String) -> Result<String, String> {
|
||||
let conn = current(&state)?;
|
||||
let mut child = p4_cmd(&conn, false)
|
||||
.args(["job", "-i"])
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.map_err(|e| format!("Failed to start p4: {e}"))?;
|
||||
if let Some(si) = child.stdin.as_mut() {
|
||||
si.write_all(spec.as_bytes()).map_err(|e| e.to_string())?;
|
||||
}
|
||||
let out = child.wait_with_output().map_err(|e| e.to_string())?;
|
||||
if !out.status.success() {
|
||||
let err = decode(&out.stderr);
|
||||
return Err(if err.trim().is_empty() { decode(&out.stdout).trim().to_string() } else { err.trim().to_string() });
|
||||
}
|
||||
Ok(decode(&out.stdout).trim().to_string())
|
||||
}
|
||||
|
||||
/// List streams on the server.
|
||||
#[tauri::command]
|
||||
async fn p4_streams(state: State<'_, AppState>) -> Result<Vec<Value>, String> {
|
||||
@ -2156,6 +2209,10 @@ pub fn run() {
|
||||
p4_streams,
|
||||
p4_switch_stream,
|
||||
p4_stream_integ,
|
||||
p4_jobs,
|
||||
p4_fix,
|
||||
p4_job_spec,
|
||||
p4_job_save,
|
||||
p4_client_spec,
|
||||
p4_client_save,
|
||||
uasset_thumbnail,
|
||||
|
||||
Reference in New Issue
Block a user