use super::{OwnedEditAction, execute};
use crate::cmd;
use crate::config::Config;
use crate::diagnostic::{DiagnosticResult, Diagnostics};
use crate::model::{ClauseKind, RfcPhase, WorkItemStatus};
use crate::write::{BumpLevel, WriteOp};
use crate::{
FinalizeStatus, GetOutputFormat, ListOutputFormat, ListTarget, OutputFormat, RenderTarget,
ShowOutputFormat, TraceOutputFormat,
};
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Scope {
Global,
Collection {
target: ListTarget,
},
Artifact {
artifact: cmd::edit::ArtifactType,
id: String,
},
Target {
artifact: cmd::edit::ArtifactType,
id: String,
target: cmd::edit::engine::ResolvedTarget,
},
}
#[derive(Debug, Clone)]
pub enum BuiltinOp {
Init {
force: bool,
},
InitSkills {
force: bool,
format: crate::SkillFormat,
dir: Option<std::path::PathBuf>,
},
Check,
Status,
RenderGlobal {
target: RenderTarget,
dry_run: bool,
force: bool,
},
Migrate,
Verify {
guard_ids: Vec<String>,
work: Option<String>,
},
Search {
query: Vec<String>,
types: Vec<ListTarget>,
tags: Vec<String>,
limit: Option<usize>,
output: OutputFormat,
reindex: bool,
},
Describe {
context: bool,
},
Completions {
shell: clap_complete::Shell,
},
SelfUpdate {
check: bool,
},
#[cfg(feature = "tui")]
Tui,
ReleaseCut {
version: String,
date: Option<String>,
},
ReleaseUndo {
expected_version: String,
},
TagNew {
tag: String,
},
TagDelete {
tag: String,
},
TagList {
output: crate::OutputFormat,
},
LoopStart {
loop_id: Option<String>,
work_ids: Vec<String>,
},
LoopList {
filter: Option<String>,
limit: Option<usize>,
output: crate::OutputFormat,
},
LoopShow {
loop_id: String,
},
LoopResume {
loop_id: String,
},
LoopReplan {
loop_id: String,
},
LoopAdd {
loop_id: String,
field: String,
value: String,
},
LoopRemove {
loop_id: String,
field: String,
value: String,
},
LoopRun {
loop_id: String,
target_work_ids: Vec<String>,
},
ConformanceList {
filter: Option<String>,
limit: Option<usize>,
output: Option<ListOutputFormat>,
tags: Vec<String>,
},
ConformanceGet {
id: String,
field: Option<String>,
output: Option<GetOutputFormat>,
},
ConformanceShow {
id: String,
output: ShowOutputFormat,
history: bool,
},
ConformanceNew {
title: String,
path: String,
selector: String,
requirements: Vec<String>,
guards: Vec<String>,
id: Option<String>,
},
ConformanceEdit {
id: String,
path: String,
action: OwnedEditAction,
},
ConformanceDelete {
id: String,
force: bool,
},
ConformanceTrace {
target: Option<String>,
output: Option<TraceOutputFormat>,
},
}
impl BuiltinOp {
fn is_lock_free(&self) -> bool {
match self {
Self::Check { .. }
| Self::Status
| Self::Verify { .. }
| Self::Describe { .. }
| Self::Completions { .. }
| Self::SelfUpdate { .. }
| Self::TagList { .. }
| Self::LoopList { .. }
| Self::LoopShow { .. }
| Self::LoopResume { .. } => true,
Self::ConformanceList { .. }
| Self::ConformanceGet { .. }
| Self::ConformanceShow { .. }
| Self::ConformanceTrace { .. } => true,
Self::Search { .. } => true,
#[cfg(feature = "tui")]
Self::Tui => true,
_ => false,
}
}
}
#[derive(Debug, Clone)]
pub enum CreateOp {
Rfc {
title: String,
id: Option<String>,
},
Clause {
clause_id: String,
title: String,
section: String,
kind: ClauseKind,
},
Adr {
title: String,
},
Work {
title: String,
active: bool,
},
Guard {
title: String,
},
}
#[derive(Debug, Clone)]
pub enum EditOp {
Field { action: OwnedEditAction },
}
#[derive(Debug, Clone)]
pub enum LifecycleOp {
Bump {
level: Option<BumpLevel>,
summary: Option<String>,
changes: Vec<String>,
},
Finalize {
status: FinalizeStatus,
},
Advance {
phase: RfcPhase,
},
Deprecate {
force: bool,
},
Supersede {
by: String,
force: bool,
},
AcceptAdr {
force: bool,
},
RejectAdr,
MoveWork {
file_or_id: PathBuf,
status: WorkItemStatus,
},
}
#[derive(Debug, Clone)]
pub enum Op {
Builtin(BuiltinOp),
Create(CreateOp),
List {
filter: Option<String>,
limit: Option<usize>,
output: Option<ListOutputFormat>,
tags: Vec<String>,
},
Get {
output: Option<GetOutputFormat>,
},
Show {
output: ShowOutputFormat,
history: bool,
},
Edit(EditOp),
Lifecycle(LifecycleOp),
Delete {
force: bool,
},
RenderArtifact {
dry_run: bool,
},
}
impl Op {
fn is_lock_free(&self) -> bool {
match self {
Self::Builtin(builtin) => builtin.is_lock_free(),
Self::Get { .. } | Self::List { .. } | Self::Show { .. } => true,
_ => false,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LockDisposition {
None,
GovRootExclusive,
}
#[derive(Debug, Clone)]
pub struct CommandPlan {
pub scope: Scope,
pub op: Op,
}
impl CommandPlan {
pub(crate) fn new(scope: Scope, op: Op) -> Self {
Self { scope, op }
}
pub fn lock_disposition(&self) -> LockDisposition {
if self.op.is_lock_free() {
LockDisposition::None
} else {
LockDisposition::GovRootExclusive
}
}
pub fn execute(&self, config: &Config, op: WriteOp) -> DiagnosticResult<Diagnostics> {
execute::execute_plan(self, config, op)
}
}