use std::path::PathBuf;
use clap::{ArgAction, Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(
name = "ign",
version,
propagate_version = true,
about = "Operate Ignition 8.3+ gateways from the terminal"
)]
pub struct Cli {
#[arg(long, global = true, value_name = "NAME")]
pub profile: Option<String>,
#[arg(long, global = true, action = ArgAction::SetTrue)]
pub json: bool,
#[arg(long, global = true, action = ArgAction::SetTrue)]
pub compact: bool,
#[arg(long, short = 'y', global = true, action = ArgAction::SetTrue)]
pub yes: bool,
#[arg(long, short = 'v', global = true, action = ArgAction::Count)]
pub verbose: u8,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Debug, Subcommand)]
pub enum Commands {
Version,
#[command(arg_required_else_help = true)]
Completions {
#[arg(value_enum)]
shell: clap_complete::aot::Shell,
},
Status,
Modules {
#[arg(long)]
quarantined: bool,
},
Metrics {
#[arg(long)]
history: bool,
},
Sessions(SessionsArgs),
Connections {
#[arg(long, value_enum)]
r#type: Option<ConnectionType>,
},
Logs(LogsArgs),
Restart {
#[arg(long)]
wait: bool,
#[arg(long, value_name = "SECS")]
timeout: Option<u64>,
#[arg(long, value_name = "SECS")]
interval: Option<u64>,
},
#[command(arg_required_else_help = true)]
Wait(WaitArgs),
Doctor {
#[arg(long)]
check_write: bool,
#[arg(long, value_name = "NAME")]
webdev_route: Option<String>,
},
Adopt {
#[arg(long, value_name = "NAME")]
user: Option<String>,
#[arg(long, value_name = "NAME")]
key_name: Option<String>,
#[arg(long, value_name = "PATH")]
level: Option<String>,
#[arg(long = "write-level", value_name = "PATH")]
write_level: Vec<String>,
#[arg(long, conflicts_with_all = ["write_level", "restrict_write"])]
read_only: bool,
#[arg(long)]
restrict_write: bool,
#[arg(long, value_name = "NAME")]
project: Option<String>,
#[arg(long, requires = "project")]
testing: bool,
#[arg(long, value_name = "DIR")]
checkout: Option<String>,
#[arg(long, value_name = "FILE")]
bake: Option<String>,
},
#[command(arg_required_else_help = true)]
Session(SessionArgs),
#[command(arg_required_else_help = true)]
Project(ProjectArgs),
#[command(arg_required_else_help = true)]
Workspace(WorkspaceArgs),
#[command(arg_required_else_help = true)]
Deploy(DeployArgs),
Edit(EditArgs),
#[command(arg_required_else_help = true)]
Resource(ResourceArgs),
#[command(arg_required_else_help = true)]
Webdev(WebdevArgs),
#[command(arg_required_else_help = true)]
Tags(TagsArgs),
#[command(arg_required_else_help = true)]
Rig(RigArgs),
#[command(arg_required_else_help = true)]
Backup(BackupArgs),
#[command(arg_required_else_help = true)]
Eam(EamArgs),
#[command(arg_required_else_help = true)]
Script(ScriptArgs),
#[command(arg_required_else_help = true)]
Testing(TestingArgs),
#[command(arg_required_else_help = true)]
Jvm(JvmArgs),
Lint(LintArgs),
#[command(arg_required_else_help = true)]
E2e(E2eArgs),
#[command(arg_required_else_help = true)]
Api(ApiArgs),
#[command(arg_required_else_help = true)]
License(LicenseArgs),
#[command(arg_required_else_help = true)]
Redundancy(RedundancyArgs),
#[command(arg_required_else_help = true)]
Gan(GanArgs),
#[command(arg_required_else_help = true)]
Diagnostics(DiagnosticsArgs),
#[command(arg_required_else_help = true)]
Profile(ProfileArgs),
#[command(hide = true)]
Mcp(McpArgs),
#[command(hide = true)]
Lsp,
#[cfg(feature = "tui")]
Tui,
#[cfg(feature = "tui")]
#[command(alias = "itop")]
Top,
}
#[derive(Debug, clap::Args)]
pub struct McpArgs {
#[arg(value_parser = ["serve"], value_name = "SERVE")]
pub serve: String,
}
#[derive(Debug, clap::Args)]
pub struct WaitArgs {
#[command(subcommand)]
pub command: WaitCmd,
}
#[derive(Debug, Subcommand)]
pub enum WaitCmd {
Gateway {
#[arg(long, default_value_t = 2, value_name = "SECS")]
interval: u64,
#[arg(long, default_value_t = 120, value_name = "SECS")]
timeout: u64,
},
Restart {
#[arg(long, default_value_t = 2, value_name = "SECS")]
interval: u64,
#[arg(long, default_value_t = 300, value_name = "SECS")]
timeout: u64,
},
Module {
id: String,
#[arg(long, default_value_t = 2, value_name = "SECS")]
interval: u64,
#[arg(long, default_value_t = 120, value_name = "SECS")]
timeout: u64,
},
}
#[derive(Debug, clap::Args)]
pub struct ProjectArgs {
#[command(subcommand)]
pub command: ProjectCommand,
}
#[derive(Debug, Subcommand)]
pub enum ProjectCommand {
List,
New {
name: String,
#[arg(long, value_name = "TEXT")]
title: Option<String>,
#[arg(long, value_name = "TEXT")]
description: Option<String>,
#[arg(long, value_name = "NAME")]
parent: Option<String>,
#[arg(long)]
inheritable: bool,
#[arg(long)]
disabled: bool,
},
Copy {
src: String,
dst: String,
},
Rename {
old_name: String,
new_name: String,
},
#[command(group(
clap::ArgGroup::new("set_fields")
.required(true)
.multiple(true)
.args(&["title", "description", "parent", "set_enabled", "disabled", "inheritable"])
))]
Set {
name: String,
#[arg(long, value_name = "TEXT")]
title: Option<String>,
#[arg(long, value_name = "TEXT")]
description: Option<String>,
#[arg(long, value_name = "NAME")]
parent: Option<String>,
#[arg(long, conflicts_with = "disabled")]
set_enabled: bool,
#[arg(long)]
disabled: bool,
#[arg(long, value_name = "BOOL")]
inheritable: Option<bool>,
},
Delete {
name: String,
},
Export {
name: String,
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
#[arg(long)]
decode_scripts: bool,
},
Import {
name: String,
#[arg(long, value_name = "PATH")]
file: String,
#[arg(long, value_enum, default_value_t = CollisionPolicy::Abort)]
collision_policy: CollisionPolicy,
#[arg(long)]
encode_scripts: bool,
},
Diff {
profile_a: String,
profile_b: String,
#[arg(long, value_name = "NAME")]
project: String,
},
Sync {
profile_a: String,
profile_b: String,
#[arg(long, value_name = "NAME")]
project: String,
#[arg(long, value_name = "PATH")]
resource: Vec<String>,
#[arg(long)]
all_changed: bool,
#[arg(long)]
delete: bool,
},
}
#[derive(Debug, clap::Args)]
pub struct WorkspaceArgs {
#[command(subcommand)]
pub command: WorkspaceCommand,
}
#[derive(Debug, Subcommand)]
pub enum WorkspaceCommand {
Checkout {
project: String,
target: PathBuf,
#[arg(long)]
decode_scripts: bool,
},
Status {
#[arg(default_value = ".")]
path: PathBuf,
},
Push {
#[arg(default_value = ".")]
path: PathBuf,
#[arg(long)]
delete: bool,
},
}
#[derive(Debug, clap::Args)]
pub struct DeployArgs {
#[command(subcommand)]
pub command: DeployCommand,
}
#[derive(Debug, Subcommand)]
pub enum DeployCommand {
Render {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
#[arg(long, value_name = "DIR")]
out: Option<PathBuf>,
},
Plan {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
#[arg(long, value_name = "DIR")]
base: Option<PathBuf>,
#[arg(long)]
diff: bool,
},
Pull {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
},
Verify {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
#[arg(long, value_name = "NAME", default_value = "ign-cli")]
project: String,
#[arg(long, value_enum, value_name = "NODE", default_value = "master")]
node: VerifyNodeArg,
},
Apply {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
#[arg(long, value_name = "DIR")]
base: Option<PathBuf>,
#[arg(long, value_name = "NAME", default_value = "ign-cli")]
project: String,
#[arg(long, value_name = "HASH")]
plan_sha256: Option<String>,
#[arg(long)]
allow_destructive: bool,
#[arg(long, value_name = "REASON")]
allow_drift: Option<String>,
#[arg(long, value_name = "PROVIDER")]
allow_provider_wipe: Vec<String>,
#[arg(long, value_enum, value_name = "MODE", default_value = "fail")]
designers: DesignersArg,
#[arg(
long,
value_name = "SECS",
default_value_t = 600,
value_parser = clap::value_parser!(u64).range(1..=86400)
)]
designers_timeout: u64,
#[arg(long)]
skip_gwbk: bool,
#[arg(
long,
value_name = "SECS",
default_value_t = 300,
value_parser = clap::value_parser!(u64).range(1..=86400)
)]
backup_timeout: u64,
},
Rollback {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
#[arg(long, value_name = "ID")]
run: String,
#[arg(long)]
discard_live_changes: bool,
#[arg(long, value_enum, value_name = "MODE", default_value = "fail")]
designers: DesignersArg,
#[arg(
long,
value_name = "SECS",
default_value_t = 600,
value_parser = clap::value_parser!(u64).range(1..=86400)
)]
designers_timeout: u64,
#[arg(
long,
value_name = "SECS",
default_value_t = 300,
value_parser = clap::value_parser!(u64).range(1..=86400)
)]
backup_timeout: u64,
},
Projects {
#[arg(long, value_name = "ENV")]
env: String,
#[arg(long, value_name = "TAG", required_unless_present = "rollback_run")]
release: Option<String>,
#[arg(
long,
value_name = "RUN_ID",
conflicts_with_all = [
"release",
"artifact_sha256",
"tags_sha256",
"allow_downgrade",
"allow_first_change",
"allow_destructive",
]
)]
rollback_run: Option<String>,
#[arg(long, value_name = "DIR", default_value = ".")]
repo: PathBuf,
#[arg(long, value_name = "DIR")]
targets: Option<PathBuf>,
#[arg(long)]
check: bool,
#[arg(long, value_name = "HASH")]
artifact_sha256: Option<String>,
#[arg(long, value_name = "HASH")]
tags_sha256: Option<String>,
#[arg(long)]
allow_downgrade: bool,
#[arg(long, value_name = "REASON")]
allow_first_change: Option<String>,
#[arg(long)]
allow_destructive: bool,
#[arg(long, value_enum, value_name = "MODE", default_value = "fail")]
designers: DesignersArg,
#[arg(
long,
value_name = "SECS",
default_value_t = 600,
value_parser = clap::value_parser!(u64).range(1..=86400)
)]
designers_timeout: u64,
#[arg(
long,
value_name = "SECS",
default_value_t = ignition_core::deploy::pair::BACKUP_TIMEOUT_DEFAULT_S,
value_parser = clap::value_parser!(u64).range(1..=86400)
)]
backup_timeout: u64,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum VerifyNodeArg {
Master,
Backup,
Both,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum DesignersArg {
Fail,
Wait,
Proceed,
}
#[derive(Debug, clap::Args)]
pub struct EditArgs {
pub project: String,
pub resource_path: String,
}
#[derive(Debug, clap::Args)]
pub struct ResourceArgs {
#[command(subcommand)]
pub command: ResourceCommand,
}
#[derive(Debug, Subcommand)]
pub enum ResourceCommand {
List {
project: String,
#[arg(long, value_name = "PREFIX")]
prefix: Option<String>,
},
Get {
project: String,
path: String,
},
Put {
project: String,
path: String,
#[arg(long, value_name = "PATH")]
file: String,
},
Delete {
project: String,
path: String,
},
}
#[derive(Debug, clap::Args)]
pub struct WebdevArgs {
#[command(subcommand)]
pub command: WebdevCommand,
}
#[derive(Debug, Subcommand)]
pub enum WebdevCommand {
Deploy {
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
#[arg(long)]
with_script_exec: bool,
#[arg(long, requires = "with_script_exec")]
rotate_secret: bool,
#[arg(long)]
with_testing: bool,
#[arg(
long,
requires_all = ["tag_delete_repo", "tag_delete_user_source", "tag_delete_role"]
)]
with_tag_delete: bool,
#[arg(
long,
value_name = "PATH",
requires = "with_tag_delete",
action = clap::ArgAction::Append
)]
tag_delete_repo: Vec<std::path::PathBuf>,
#[arg(long, value_name = "NAME", requires = "with_tag_delete")]
tag_delete_user_source: Option<String>,
#[arg(long, value_name = "ROLE", requires = "with_tag_delete")]
tag_delete_role: Option<String>,
#[arg(long, requires = "with_tag_delete")]
rotate_tag_delete_secret: bool,
},
Status {
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, clap::Args)]
pub struct TagsArgs {
#[command(subcommand)]
pub command: TagsCommand,
}
#[derive(Debug, Subcommand)]
pub enum TagsCommand {
#[command(subcommand)]
Provider(TagsProviderCommand),
Browse {
path: Option<String>,
#[arg(long, value_name = "SUBSTR")]
filter: Option<String>,
#[arg(long)]
include_properties: bool,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
#[arg(long, value_name = "PATH", conflicts_with_all = ["path"])]
from_export: Option<PathBuf>,
},
Read {
#[arg(value_name = "PATH", required = true)]
paths: Vec<String>,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Write {
path: String,
#[arg(long, value_name = "V")]
value: String,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
#[command(subcommand)]
Config(TagsConfigCommand),
#[command(subcommand)]
Udt(TagsUdtCommand),
#[command(subcommand)]
Alarms(TagsAlarmsCommand),
#[command(subcommand)]
History(TagsHistoryCommand),
Export {
#[arg(value_name = "PATH", required = true)]
paths: Vec<String>,
#[arg(short = 'o', long, value_name = "FILE")]
output: Option<PathBuf>,
#[arg(long, value_enum, default_value_t = TransferFormat::Json, value_name = "FORMAT")]
format: TransferFormat,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Import {
#[arg(long, value_name = "FILE")]
file: PathBuf,
#[arg(long, value_name = "NAME")]
provider: String,
#[arg(long, value_enum, default_value_t = TransferFormat::Json, value_name = "FORMAT")]
format: TransferFormat,
#[arg(long, value_enum, default_value_t = CollisionPolicy::Abort)]
collision_policy: CollisionPolicy,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, clap::ValueEnum)]
pub enum TransferFormat {
#[default]
Json,
Xml,
Csv,
}
impl std::fmt::Display for TransferFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let label = match self {
Self::Json => "json",
Self::Xml => "xml",
Self::Csv => "csv",
};
f.write_str(label)
}
}
#[derive(Debug, Subcommand)]
pub enum TagsConfigCommand {
Get {
path: String,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Create {
path: String,
#[arg(long, value_name = "FILE")]
file: PathBuf,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Edit {
path: String,
#[arg(long, value_name = "FILE")]
file: PathBuf,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Delete {
#[arg(value_name = "PATH", required = true)]
paths: Vec<String>,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, Subcommand)]
pub enum TagsUdtCommand {
Types {
#[arg(long, default_value = "default", value_name = "NAME")]
provider: String,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Def {
name: String,
#[arg(long, default_value = "default", value_name = "NAME")]
provider: String,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, Subcommand)]
pub enum TagsProviderCommand {
List,
Create {
name: String,
},
Delete {
name: String,
},
}
#[derive(Debug, Subcommand)]
pub enum TagsAlarmsCommand {
Active {
#[arg(long, value_name = "SOURCE")]
source: Option<String>,
#[arg(long, value_name = "PRIORITY")]
priority: Option<String>,
#[arg(long, value_name = "STATE")]
state: Option<String>,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
History {
#[arg(long, value_name = "T")]
start: String,
#[arg(long, value_name = "T")]
end: String,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Ack {
#[arg(value_name = "ID", required = true)]
ids: Vec<String>,
#[arg(long, value_name = "NOTE")]
note: Option<String>,
#[arg(long, value_name = "NAME")]
username: String,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, Subcommand)]
pub enum TagsHistoryCommand {
Query {
#[arg(value_name = "PATH", required = true)]
paths: Vec<String>,
#[arg(long, value_name = "T")]
start: String,
#[arg(long, value_name = "T")]
end: String,
#[arg(long, value_name = "N")]
return_size: Option<i64>,
#[arg(long, value_name = "MODE")]
aggregation: Option<String>,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, clap::Args)]
pub struct RigArgs {
#[arg(long, value_name = "NAME")]
pub rig: Option<String>,
#[command(subcommand)]
pub command: RigCommand,
}
#[derive(Debug, Subcommand)]
pub enum RigCommand {
Up {
#[arg(long, default_value_t = 300, value_name = "SECS")]
timeout: u64,
#[arg(long, value_name = "ID@VERSION")]
with_module: Vec<String>,
#[arg(long, conflicts_with = "accept_upstream_change")]
refresh: bool,
#[arg(long, conflicts_with = "refresh")]
accept_upstream_change: bool,
},
Down,
Reset {
#[arg(long, default_value_t = 300, value_name = "SECS")]
timeout: u64,
#[arg(long, value_name = "ID@VERSION")]
with_module: Vec<String>,
#[arg(long, conflicts_with = "accept_upstream_change")]
refresh: bool,
#[arg(long, conflicts_with = "refresh")]
accept_upstream_change: bool,
},
Status,
Logs {
#[arg(long, default_value_t = 200, value_name = "N")]
tail: u32,
#[arg(short = 'f', long)]
follow: bool,
service: Option<String>,
},
Trial(TrialArgs),
Module(ModuleArgs),
Snapshot {
#[arg(short = 'o', long, value_name = "DIR")]
output: Option<PathBuf>,
},
Restore {
#[arg(long, value_name = "PATH")]
file: PathBuf,
#[arg(long, default_value_t = 300, value_name = "SECS")]
timeout: u64,
},
}
#[derive(Debug, clap::Args)]
pub struct TrialArgs {
#[command(subcommand)]
pub command: TrialCommand,
}
#[derive(Debug, Clone, Subcommand)]
pub enum TrialCommand {
Status,
Reset {
#[arg(long, value_name = "NAME")]
user: Option<String>,
},
}
#[derive(Debug, clap::Args)]
pub struct ModuleArgs {
#[command(subcommand)]
pub command: ModuleCommand,
}
#[derive(Debug, Clone, Subcommand)]
pub enum ModuleCommand {
Uninstall {
id: String,
},
}
#[derive(Debug, clap::Args)]
pub struct BackupArgs {
#[command(subcommand)]
pub command: BackupCommand,
}
#[derive(Debug, Subcommand)]
pub enum BackupCommand {
Download {
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
#[arg(long, value_enum, default_value_t = CliBackupType::Roaming)]
r#type: CliBackupType,
},
Restore {
file: PathBuf,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum CliBackupType {
Roaming,
All,
}
impl From<CliBackupType> for ignition_core::client::backup::BackupType {
fn from(value: CliBackupType) -> Self {
match value {
CliBackupType::Roaming => Self::Roaming,
CliBackupType::All => Self::All,
}
}
}
#[derive(Debug, clap::Args)]
pub struct EamArgs {
#[command(subcommand)]
pub command: EamCommand,
}
#[derive(Debug, Subcommand)]
pub enum EamCommand {
History {
#[arg(long, value_name = "N")]
limit: Option<u32>,
#[arg(long, value_name = "TEXT")]
search: Option<String>,
},
Tasks {
name: Option<String>,
},
#[command(subcommand)]
Task(EamTaskCommand),
}
#[derive(Debug, Subcommand)]
pub enum EamTaskCommand {
New {
name: String,
r#type: String,
#[arg(long, value_name = "NAME")]
target: Vec<String>,
#[arg(long, value_name = "K=V")]
setting: Vec<String>,
#[arg(long, value_name = "PATH", conflicts_with = "setting")]
definition: Option<PathBuf>,
#[arg(long, value_enum, default_value_t = ScheduleMode::OnDemand)]
schedule_mode: ScheduleMode,
},
Force {
name: String,
},
Suspend {
name: String,
},
Resume {
name: String,
},
Cancel {
name: String,
},
Modify {
name: String,
#[arg(long)]
enable: bool,
#[arg(long, conflicts_with = "enable")]
disable: bool,
#[arg(long, value_name = "MODE")]
schedule_mode: Option<String>,
#[arg(long, value_name = "K=V")]
setting: Vec<String>,
#[arg(long, value_name = "TEXT")]
description: Option<String>,
},
Delete {
name: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum ScheduleMode {
OnDemand,
Immediate,
Scheduled,
AtTime,
AtDelay,
}
impl ScheduleMode {
pub fn wire(self) -> &'static str {
match self {
Self::OnDemand => "OnDemand",
Self::Immediate => "Immediate",
Self::Scheduled => "Scheduled",
Self::AtTime => "AtTime",
Self::AtDelay => "AtDelay",
}
}
}
#[derive(Debug, clap::Args)]
pub struct ScriptArgs {
#[command(subcommand)]
pub command: ScriptCommand,
}
#[derive(Debug, clap::Args)]
pub struct TestingArgs {
#[command(subcommand)]
pub command: TestingCommand,
}
#[derive(Debug, clap::Args)]
pub struct E2eArgs {
#[command(subcommand)]
pub command: E2eCmd,
}
#[derive(Debug, Subcommand)]
pub enum E2eCmd {
Doctor {
#[arg(value_name = "DIR")]
dir: Option<PathBuf>,
#[arg(long, value_name = "NAME")]
project: Option<String>,
},
Init {
#[arg(value_name = "DIR")]
dir: Option<PathBuf>,
#[arg(long, value_name = "NAME")]
project: Option<String>,
#[arg(long, value_name = "NAME")]
run_project: Option<String>,
#[arg(long)]
browsers: bool,
},
}
#[derive(Debug, clap::Args)]
pub struct SessionArgs {
#[command(subcommand)]
pub command: SessionCmd,
}
#[derive(Debug, Subcommand)]
pub enum SessionCmd {
Login {
#[arg(long, value_name = "NAME")]
user: Option<String>,
},
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, clap::ValueEnum)]
pub enum TestingFormatArg {
#[default]
Json,
Junit,
Text,
}
impl From<TestingFormatArg> for ignition_core::actions::testing::TestingFormat {
fn from(value: TestingFormatArg) -> Self {
match value {
TestingFormatArg::Json => Self::Json,
TestingFormatArg::Junit => Self::Junit,
TestingFormatArg::Text => Self::Text,
}
}
}
#[derive(Debug, Subcommand)]
pub enum TestingCommand {
Run {
#[arg(long, value_name = "NAME", required = true)]
project: String,
#[arg(long, conflicts_with_all = ["module", "package"])]
discover: bool,
#[arg(long, value_name = "DOTTED", conflicts_with = "package")]
module: Option<String>,
#[arg(long, value_name = "PREFIX")]
package: Option<String>,
#[arg(long, value_name = "FORMAT", default_value = "json")]
format: TestingFormatArg,
},
}
#[derive(Debug, clap::Args)]
pub struct LintArgs {
#[arg(value_name = "PATH", required = true)]
pub paths: Vec<String>,
#[arg(long)]
pub strict: bool,
#[arg(last = true, value_name = "ARGS")]
pub passthrough: Vec<String>,
}
#[derive(Debug, Subcommand)]
pub enum ScriptCommand {
Run {
#[arg(long, value_name = "PY")]
code: Option<String>,
#[arg(long, value_name = "PATH")]
file: Option<String>,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, clap::Args)]
pub struct ApiArgs {
#[command(subcommand)]
pub command: ApiCommand,
}
#[derive(Debug, Subcommand)]
pub enum ApiCommand {
Call(ApiCallArgs),
}
#[derive(Debug, clap::Args)]
pub struct ApiCallArgs {
#[arg(long, value_name = "METHOD")]
pub method: String,
#[arg(long, value_name = "PATH")]
pub path: String,
#[arg(long, value_name = "TEXT")]
pub data: Option<String>,
#[arg(long, value_name = "NAME: VALUE")]
pub header: Vec<String>,
#[arg(long, value_name = "K=V")]
pub query: Vec<String>,
}
#[derive(Debug, clap::Args)]
pub struct LicenseArgs {
#[command(subcommand)]
pub command: LicenseCommand,
}
#[derive(Debug, Subcommand)]
pub enum LicenseCommand {
Status,
}
#[derive(Debug, clap::Args)]
pub struct RedundancyArgs {
#[command(subcommand)]
pub command: RedundancyCommand,
}
#[derive(Debug, Subcommand)]
pub enum RedundancyCommand {
Status {
#[arg(long, value_name = "PROFILE")]
peer: Option<String>,
},
}
#[derive(Debug, clap::Args)]
pub struct GanArgs {
#[command(subcommand)]
pub command: GanCommand,
}
#[derive(Debug, Subcommand)]
pub enum GanCommand {
Status,
}
#[derive(Debug, clap::Args)]
pub struct DiagnosticsArgs {
#[command(subcommand)]
pub command: DiagnosticsCommand,
}
#[derive(Debug, Subcommand)]
pub enum DiagnosticsCommand {
#[command(subcommand)]
Bundle(BundleCommand),
}
#[derive(Debug, Subcommand)]
pub enum BundleCommand {
Generate,
Status,
Download {
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
},
Wait {
#[arg(long, default_value_t = 2, value_name = "SECS")]
interval: u64,
#[arg(long, default_value_t = 300, value_name = "SECS")]
timeout: u64,
},
}
#[derive(Debug, clap::Args)]
pub struct JvmArgs {
#[command(subcommand)]
pub command: JvmCommand,
}
#[derive(Debug, Subcommand)]
pub enum JvmCommand {
Sample {
#[arg(long, value_name = "SECS")]
duration_secs: Option<u64>,
#[arg(long, value_name = "MS")]
interval_ms: Option<u64>,
#[arg(long, default_value_t = 25, value_name = "N")]
top: u64,
#[arg(long, value_name = "PATH")]
folded_out: Option<PathBuf>,
#[arg(long, action = ArgAction::SetTrue)]
follow: bool,
#[arg(long, action = ArgAction::SetTrue)]
i_accept_the_risk: bool,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
#[command(arg_required_else_help = true)]
Jfr(JvmJfrArgs),
}
#[derive(Debug, clap::Args)]
pub struct JvmJfrArgs {
#[command(subcommand)]
pub command: JvmJfrCommand,
}
#[derive(Debug, Subcommand)]
pub enum JvmJfrCommand {
Start {
#[arg(long, default_value_t = 60, value_name = "SECS")]
duration_secs: u64,
#[arg(long, value_enum, default_value_t = JfrSettingsArg::Default, value_name = "NAME")]
settings: JfrSettingsArg,
#[arg(long, action = ArgAction::SetTrue)]
i_accept_the_risk: bool,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Status {
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
Stop {
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
#[arg(long, default_value = "ign-cli", value_name = "NAME")]
project: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum JfrSettingsArg {
Default,
Profile,
}
#[derive(Debug, clap::Args)]
pub struct ProfileArgs {
#[command(subcommand)]
pub command: ProfileCmd,
}
#[derive(Debug, clap::Args)]
pub struct SessionsArgs {
#[arg(long, value_enum)]
pub r#type: Option<SessionType>,
#[command(subcommand)]
pub command: Option<SessionsCmd>,
}
#[derive(Debug, Subcommand)]
pub enum SessionsCmd {
Terminate {
#[arg(long, value_enum)]
r#type: SessionType,
#[arg(long)]
id: String,
#[arg(long)]
message: Option<String>,
},
}
#[derive(Debug, clap::Args)]
pub struct LogsArgs {
#[arg(long, value_name = "NAME")]
pub logger: Option<String>,
#[arg(long, value_enum, value_name = "LEVEL")]
pub min_level: Option<LogLevel>,
#[arg(
long,
value_name = "EPOCH_MS|Nms|Ns|Nmin|Nh",
value_parser = parse_since_arg
)]
pub since: Option<i64>,
#[arg(long, default_value_t = 200)]
pub limit: i64,
#[arg(short = 'f', long)]
pub follow: bool,
#[arg(long, default_value_t = 2, value_name = "SECS")]
pub interval: u64,
#[arg(long, value_name = "SECS")]
pub timeout: Option<u64>,
#[command(subcommand)]
pub command: Option<LogsCmd>,
}
#[derive(Debug, Subcommand)]
pub enum LogsCmd {
Download {
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
},
Loggers(LoggersArgs),
}
#[derive(Debug, clap::Args)]
pub struct LoggersArgs {
#[arg(long, value_name = "TEXT")]
pub search: Option<String>,
#[command(subcommand)]
pub command: Option<LoggersCmd>,
}
#[derive(Debug, Subcommand)]
pub enum LoggersCmd {
Set {
name: String,
#[arg(value_enum)]
level: LogLevel,
},
Reset,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum LogLevel {
Trace,
Debug,
Info,
Warn,
Error,
Fatal,
Off,
}
impl LogLevel {
pub fn wire(self) -> &'static str {
match self {
Self::Trace => "TRACE",
Self::Debug => "DEBUG",
Self::Info => "INFO",
Self::Warn => "WARN",
Self::Error => "ERROR",
Self::Fatal => "FATAL",
Self::Off => "OFF",
}
}
}
fn parse_since_arg(spec: &str) -> Result<i64, String> {
let now_ms = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("system clock is after the unix epoch")
.as_millis() as i64;
ignition_core::actions::logs::parse_since(spec, now_ms)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum SessionType {
Designer,
Perspective,
Vision,
}
impl From<SessionType> for ignition_core::actions::sessions::SessionType {
fn from(value: SessionType) -> Self {
match value {
SessionType::Designer => Self::Designer,
SessionType::Perspective => Self::Perspective,
SessionType::Vision => Self::Vision,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum ConnectionType {
Database,
Opc,
}
impl From<ConnectionType> for ignition_core::actions::connections::ConnectionType {
fn from(value: ConnectionType) -> Self {
match value {
ConnectionType::Database => Self::Database,
ConnectionType::Opc => Self::Opc,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum CollisionPolicy {
Abort,
Overwrite,
}
impl From<CollisionPolicy> for ignition_core::actions::projects::CollisionPolicy {
fn from(value: CollisionPolicy) -> Self {
match value {
CollisionPolicy::Abort => Self::Abort,
CollisionPolicy::Overwrite => Self::Overwrite,
}
}
}
#[derive(Debug, Subcommand)]
#[command(arg_required_else_help = true)]
pub enum ProfileCmd {
Add {
name: String,
url: String,
#[arg(long, value_name = "TEXT")]
label: Option<String>,
#[arg(long, value_name = "VAR")]
token_env: Option<String>,
#[arg(long, value_name = "USER")]
keyring: Option<String>,
#[arg(long, value_name = "VAR")]
user_env: Option<String>,
#[arg(long, value_name = "VAR")]
password_env: Option<String>,
#[arg(long)]
active: bool,
},
List,
Use {
name: String,
},
}