Use common command/args syntax
This commit is contained in:
parent
1238987732
commit
336a8f7eb2
10 changed files with 68 additions and 30 deletions
|
|
@ -41,7 +41,8 @@ icon = "scummvm"
|
||||||
|
|
||||||
[entries.kind]
|
[entries.kind]
|
||||||
type = "process"
|
type = "process"
|
||||||
argv = ["scummvm", "-f"]
|
command = "scummvm"
|
||||||
|
args = ["-f"]
|
||||||
|
|
||||||
[entries.availability]
|
[entries.availability]
|
||||||
[[entries.availability.windows]]
|
[[entries.availability.windows]]
|
||||||
|
|
@ -95,7 +96,7 @@ seconds_before = 30
|
||||||
severity = "critical"
|
severity = "critical"
|
||||||
message = "30 seconds! Save NOW!"
|
message = "30 seconds! Save NOW!"
|
||||||
|
|
||||||
# Example: Educational game - unrestricted
|
# Example: Educational game
|
||||||
[[entries]]
|
[[entries]]
|
||||||
id = "tuxmath"
|
id = "tuxmath"
|
||||||
label = "Tux Math"
|
label = "Tux Math"
|
||||||
|
|
@ -103,7 +104,21 @@ icon = "tuxmath"
|
||||||
|
|
||||||
[entries.kind]
|
[entries.kind]
|
||||||
type = "process"
|
type = "process"
|
||||||
argv = ["tuxmath"]
|
command = "tuxmath"
|
||||||
|
|
||||||
|
[entries.availability]
|
||||||
|
always = true
|
||||||
|
|
||||||
|
# Example: Steam game
|
||||||
|
[[entries]]
|
||||||
|
id = "steam-human-resource-machine"
|
||||||
|
label = "Human Resource Machine"
|
||||||
|
icon = "steam"
|
||||||
|
|
||||||
|
[entries.kind]
|
||||||
|
type = "snap"
|
||||||
|
snap_name = "steam"
|
||||||
|
args = ["steam://rungameid/375820"] # Steam App ID (passed to 'snap run steam')
|
||||||
|
|
||||||
[entries.availability]
|
[entries.availability]
|
||||||
always = true
|
always = true
|
||||||
|
|
@ -119,7 +134,8 @@ icon = "mpv"
|
||||||
|
|
||||||
[entries.kind]
|
[entries.kind]
|
||||||
type = "process"
|
type = "process"
|
||||||
argv = ["mpv", "https://www.youtube.com/watch?v=jfKfPfyJRdk"]
|
command = "mpv"
|
||||||
|
args = ["https://www.youtube.com/watch?v=jfKfPfyJRdk"]
|
||||||
|
|
||||||
[entries.availability]
|
[entries.availability]
|
||||||
always = true
|
always = true
|
||||||
|
|
@ -138,4 +154,4 @@ disabled_reason = "This game is being updated"
|
||||||
|
|
||||||
[entries.kind]
|
[entries.kind]
|
||||||
type = "process"
|
type = "process"
|
||||||
argv = ["/bin/false"]
|
command = "/bin/false"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,11 @@ pub enum EntryKindTag {
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
pub enum EntryKind {
|
pub enum EntryKind {
|
||||||
Process {
|
Process {
|
||||||
argv: Vec<String>,
|
/// Command to run (required)
|
||||||
|
command: String,
|
||||||
|
/// Additional command-line arguments
|
||||||
|
#[serde(default)]
|
||||||
|
args: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
env: HashMap<String, String>,
|
env: HashMap<String, String>,
|
||||||
cwd: Option<PathBuf>,
|
cwd: Option<PathBuf>,
|
||||||
|
|
@ -252,7 +256,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn entry_kind_serialization() {
|
fn entry_kind_serialization() {
|
||||||
let kind = EntryKind::Process {
|
let kind = EntryKind::Process {
|
||||||
argv: vec!["scummvm".into(), "-f".into()],
|
command: "scummvm".into(),
|
||||||
|
args: vec!["-f".into()],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ mod tests {
|
||||||
[[entries]]
|
[[entries]]
|
||||||
id = "test-game"
|
id = "test-game"
|
||||||
label = "Test Game"
|
label = "Test Game"
|
||||||
kind = { type = "process", argv = ["/usr/bin/game"] }
|
kind = { type = "process", command = "/usr/bin/game" }
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let policy = parse_config(config).unwrap();
|
let policy = parse_config(config).unwrap();
|
||||||
|
|
@ -91,7 +91,7 @@ mod tests {
|
||||||
[[entries]]
|
[[entries]]
|
||||||
id = "test"
|
id = "test"
|
||||||
label = "Test"
|
label = "Test"
|
||||||
kind = { type = "process", argv = ["/bin/test"] }
|
kind = { type = "process", command = "/bin/test" }
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let result = parse_config(config);
|
let result = parse_config(config);
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ pub struct LimitsPolicy {
|
||||||
|
|
||||||
fn convert_entry_kind(raw: RawEntryKind) -> EntryKind {
|
fn convert_entry_kind(raw: RawEntryKind) -> EntryKind {
|
||||||
match raw {
|
match raw {
|
||||||
RawEntryKind::Process { argv, env, cwd } => EntryKind::Process { argv, env, cwd },
|
RawEntryKind::Process { command, args, env, cwd } => EntryKind::Process { command, args, env, cwd },
|
||||||
RawEntryKind::Snap { snap_name, command, args, env } => EntryKind::Snap { snap_name, command, args, env },
|
RawEntryKind::Snap { snap_name, command, args, env } => EntryKind::Snap { snap_name, command, args, env },
|
||||||
RawEntryKind::Vm { driver, args } => EntryKind::Vm { driver, args },
|
RawEntryKind::Vm { driver, args } => EntryKind::Vm { driver, args },
|
||||||
RawEntryKind::Media { library_id, args } => EntryKind::Media { library_id, args },
|
RawEntryKind::Media { library_id, args } => EntryKind::Media { library_id, args },
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,11 @@ pub struct RawEntry {
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
pub enum RawEntryKind {
|
pub enum RawEntryKind {
|
||||||
Process {
|
Process {
|
||||||
argv: Vec<String>,
|
/// Command to run (required)
|
||||||
|
command: String,
|
||||||
|
/// Additional command-line arguments
|
||||||
|
#[serde(default)]
|
||||||
|
args: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
env: HashMap<String, String>,
|
env: HashMap<String, String>,
|
||||||
cwd: Option<PathBuf>,
|
cwd: Option<PathBuf>,
|
||||||
|
|
@ -189,7 +193,7 @@ mod tests {
|
||||||
[[entries]]
|
[[entries]]
|
||||||
id = "scummvm"
|
id = "scummvm"
|
||||||
label = "ScummVM"
|
label = "ScummVM"
|
||||||
kind = { type = "process", argv = ["scummvm", "-f"] }
|
kind = { type = "process", command = "scummvm", args = ["-f"] }
|
||||||
|
|
||||||
[entries.limits]
|
[entries.limits]
|
||||||
max_run_seconds = 3600
|
max_run_seconds = 3600
|
||||||
|
|
@ -208,7 +212,7 @@ mod tests {
|
||||||
[[entries]]
|
[[entries]]
|
||||||
id = "game"
|
id = "game"
|
||||||
label = "Game"
|
label = "Game"
|
||||||
kind = { type = "process", argv = ["/bin/game"] }
|
kind = { type = "process", command = "/bin/game" }
|
||||||
|
|
||||||
[entries.availability]
|
[entries.availability]
|
||||||
[[entries.availability.windows]]
|
[[entries.availability.windows]]
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,11 @@ fn validate_entry(entry: &RawEntry, config: &RawConfig) -> Vec<ValidationError>
|
||||||
|
|
||||||
// Validate kind
|
// Validate kind
|
||||||
match &entry.kind {
|
match &entry.kind {
|
||||||
RawEntryKind::Process { argv, .. } => {
|
RawEntryKind::Process { command, .. } => {
|
||||||
if argv.is_empty() {
|
if command.is_empty() {
|
||||||
errors.push(ValidationError::EntryError {
|
errors.push(ValidationError::EntryError {
|
||||||
entry_id: entry.id.clone(),
|
entry_id: entry.id.clone(),
|
||||||
message: "argv cannot be empty".into(),
|
message: "command cannot be empty".into(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -252,7 +252,8 @@ mod tests {
|
||||||
label: "Game 1".into(),
|
label: "Game 1".into(),
|
||||||
icon: None,
|
icon: None,
|
||||||
kind: RawEntryKind::Process {
|
kind: RawEntryKind::Process {
|
||||||
argv: vec!["game1".into()],
|
command: "game1".into(),
|
||||||
|
args: vec![],
|
||||||
env: Default::default(),
|
env: Default::default(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
},
|
},
|
||||||
|
|
@ -267,7 +268,8 @@ mod tests {
|
||||||
label: "Game 2".into(),
|
label: "Game 2".into(),
|
||||||
icon: None,
|
icon: None,
|
||||||
kind: RawEntryKind::Process {
|
kind: RawEntryKind::Process {
|
||||||
argv: vec!["game2".into()],
|
command: "game2".into(),
|
||||||
|
args: vec![],
|
||||||
env: Default::default(),
|
env: Default::default(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -559,7 +559,8 @@ mod tests {
|
||||||
label: "Test Game".into(),
|
label: "Test Game".into(),
|
||||||
icon_ref: None,
|
icon_ref: None,
|
||||||
kind: EntryKind::Process {
|
kind: EntryKind::Process {
|
||||||
argv: vec!["game".into()],
|
command: "game".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
},
|
},
|
||||||
|
|
@ -635,7 +636,8 @@ mod tests {
|
||||||
label: "Test".into(),
|
label: "Test".into(),
|
||||||
icon_ref: None,
|
icon_ref: None,
|
||||||
kind: EntryKind::Process {
|
kind: EntryKind::Process {
|
||||||
argv: vec!["test".into()],
|
command: "test".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
},
|
},
|
||||||
|
|
@ -697,7 +699,8 @@ mod tests {
|
||||||
label: "Test".into(),
|
label: "Test".into(),
|
||||||
icon_ref: None,
|
icon_ref: None,
|
||||||
kind: EntryKind::Process {
|
kind: EntryKind::Process {
|
||||||
argv: vec!["test".into()],
|
command: "test".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,8 @@ mod tests {
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let entry = EntryKind::Process {
|
let entry = EntryKind::Process {
|
||||||
argv: vec!["test".into()],
|
command: "test".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
};
|
};
|
||||||
|
|
@ -217,7 +218,8 @@ mod tests {
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let entry = EntryKind::Process {
|
let entry = EntryKind::Process {
|
||||||
argv: vec!["test".into()],
|
command: "test".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,10 @@ impl HostAdapter for LinuxHost {
|
||||||
) -> HostResult<HostSessionHandle> {
|
) -> HostResult<HostSessionHandle> {
|
||||||
// Extract argv, env, cwd, and snap_name based on entry kind
|
// Extract argv, env, cwd, and snap_name based on entry kind
|
||||||
let (argv, env, cwd, snap_name) = match entry_kind {
|
let (argv, env, cwd, snap_name) = match entry_kind {
|
||||||
EntryKind::Process { argv, env, cwd } => {
|
EntryKind::Process { command, args, env, cwd } => {
|
||||||
(argv.clone(), env.clone(), cwd.clone(), None)
|
let mut argv = vec![command.clone()];
|
||||||
|
argv.extend(args.clone());
|
||||||
|
(argv, env.clone(), cwd.clone(), None)
|
||||||
}
|
}
|
||||||
EntryKind::Snap { snap_name, command, args, env } => {
|
EntryKind::Snap { snap_name, command, args, env } => {
|
||||||
// For snap apps, we need to use 'snap run <snap_name>' to launch them.
|
// For snap apps, we need to use 'snap run <snap_name>' to launch them.
|
||||||
|
|
@ -318,7 +320,8 @@ mod tests {
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let entry = EntryKind::Process {
|
let entry = EntryKind::Process {
|
||||||
argv: vec!["true".into()],
|
command: "true".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
};
|
};
|
||||||
|
|
@ -348,7 +351,8 @@ mod tests {
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let entry = EntryKind::Process {
|
let entry = EntryKind::Process {
|
||||||
argv: vec!["sleep".into(), "60".into()],
|
command: "sleep".into(),
|
||||||
|
args: vec!["60".into()],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ fn make_test_policy() -> Policy {
|
||||||
label: "Test Game".into(),
|
label: "Test Game".into(),
|
||||||
icon_ref: None,
|
icon_ref: None,
|
||||||
kind: EntryKind::Process {
|
kind: EntryKind::Process {
|
||||||
argv: vec!["sleep".into(), "999".into()],
|
command: "sleep".into(),
|
||||||
|
args: vec!["999".into()],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
},
|
},
|
||||||
|
|
@ -227,7 +228,8 @@ async fn test_mock_host_integration() {
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let entry = EntryKind::Process {
|
let entry = EntryKind::Process {
|
||||||
argv: vec!["test".into()],
|
command: "test".into(),
|
||||||
|
args: vec![],
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
cwd: None,
|
cwd: None,
|
||||||
};
|
};
|
||||||
|
|
@ -262,7 +264,7 @@ fn test_config_parsing() {
|
||||||
[[entries]]
|
[[entries]]
|
||||||
id = "scummvm"
|
id = "scummvm"
|
||||||
label = "ScummVM"
|
label = "ScummVM"
|
||||||
kind = { type = "process", argv = ["scummvm", "-f"] }
|
kind = { type = "process", command = "scummvm", args = ["-f"] }
|
||||||
|
|
||||||
[entries.availability]
|
[entries.availability]
|
||||||
[[entries.availability.windows]]
|
[[entries.availability.windows]]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue