Skip to content

Commit 1317838

Browse files
feat: process paths passed to run
Signed-off-by: Oskar Manhart <[email protected]>
1 parent 6b44fb7 commit 1317838

File tree

10 files changed

+80
-45
lines changed

10 files changed

+80
-45
lines changed

Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

winapps-cli/src/main.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@ fn cli() -> Command {
1111
.arg_required_else_help(true)
1212
.allow_external_subcommands(true)
1313
.subcommand(Command::new("connect").about("Opens full session on remote"))
14+
.subcommand(Command::new("setup").about("Create desktop files for installed Windows apps"))
1415
.subcommand(
1516
Command::new("run")
1617
.about("Runs a configured app or an executable on the remote")
17-
.arg(arg!(NAME: "the name of the app/the path to the executable")),
18+
.arg(arg!(<NAME> "the name of the app/the path to the executable"))
19+
.arg(
20+
arg!([ARGS]... "Arguments to pass to the command")
21+
.trailing_var_arg(true)
22+
.allow_hyphen_values(true),
23+
),
1824
)
1925
.subcommand(
2026
Command::new("vm")
@@ -55,6 +61,11 @@ fn main() -> Result<()> {
5561
backend.check_depends()?;
5662

5763
match matches.subcommand() {
64+
Some(("setup", _)) => {
65+
info!("Running setup");
66+
todo!()
67+
}
68+
5869
Some(("connect", _)) => {
5970
info!("Connecting to remote");
6071

@@ -65,9 +76,13 @@ fn main() -> Result<()> {
6576
Some(("run", sub_matches)) => {
6677
info!("Connecting to app on remote");
6778

79+
let args = sub_matches
80+
.get_many::<String>("args")
81+
.map_or(Vec::new(), |args| args.map(|v| v.to_owned()).collect());
82+
6883
match sub_matches.get_one::<String>("name") {
6984
None => panic!("App is required and should never be None here"),
70-
Some(app) => client.run_app(app),
85+
Some(app) => client.run_app(app.to_owned(), args),
7186
}?;
7287

7388
Ok(())

winapps/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ miette = "7.2.0"
1616
thiserror = "2.0.9"
1717
enum_dispatch = "0.3.13"
1818
base64 = "0.22.1"
19+
regex = { version = "1.11.2", features = [] }

winapps/src/backend/container.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,4 @@ impl Backend for Container {
5252
fn get_host(&self) -> IpAddr {
5353
Ipv4Addr::new(127, 0, 0, 1).into()
5454
}
55-
56-
fn as_remote_command(&self, command: Command) -> Command {
57-
Command::new("sshpass")
58-
.args(["-p", &*self.config.auth.password])
59-
.args([
60-
"ssh",
61-
&*format!("{}@localhost", self.config.auth.username),
62-
"-p",
63-
&*self.config.auth.ssh_port.to_string(),
64-
])
65-
.arg(format!("{} {}", command.exec, command.args.join(" ")))
66-
}
6755
}

winapps/src/backend/manual.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{net::IpAddr, str::FromStr};
22

3-
use crate::{command::Command, ensure, Backend, Config, Error, Result};
3+
use crate::{ensure, Backend, Config, Error, Result};
44

55
#[derive(Debug, Clone)]
66
pub struct Manual {
@@ -35,16 +35,4 @@ impl Backend for Manual {
3535
// so it should always be valid at this point
3636
IpAddr::from_str(&self.config.manual.host).unwrap()
3737
}
38-
39-
fn as_remote_command(&self, command: Command) -> Command {
40-
Command::new("sshpass")
41-
.args(["-p", &*self.config.auth.password])
42-
.args([
43-
"ssh",
44-
&*format!("{}@{}", self.config.auth.username, self.config.manual.host),
45-
"-p",
46-
&*self.config.auth.ssh_port.to_string(),
47-
])
48-
.arg(format!("{} {}", command.exec, command.args.join(" ")))
49-
}
5038
}

winapps/src/backend/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ pub trait Backend {
1717
fn check_depends(&self) -> Result<()>;
1818

1919
fn get_host(&self) -> IpAddr;
20-
21-
fn as_remote_command(&self, command: Command) -> Command;
2220
}
2321

2422
#[enum_dispatch(Backend)]
@@ -48,13 +46,9 @@ impl Config {
4846
self.get_backend().get_host()
4947
}
5048

51-
pub fn as_remote_command(&'static self, command: Command) -> Command {
52-
self.get_backend().as_remote_command(command)
53-
}
54-
5549
fn get_installed_apps(&'static self) -> Result<Vec<App>> {
5650
let apps = Command::new("C:\\ExtractPrograms.ps1")
57-
.into_remote(self.get_backend())
51+
.into_remote(self)
5852
.wait_with_output()?
5953
.lines()
6054
.filter_map(|line| {

winapps/src/command.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{ensure, Backend, Backends, Error, IntoResult, Result};
1+
use crate::{ensure, Backend, Backends, Config, Error, IntoResult, Result};
22
use std::{
33
fmt::{Display, Formatter},
44
process::{Child, Command as StdCommand, Stdio},
@@ -60,8 +60,23 @@ impl Command {
6060
}
6161
}
6262

63-
pub fn into_remote(self, backend: &Backends) -> Self {
64-
backend.as_remote_command(self)
63+
pub fn into_remote(mut self, config: &'static Config) -> Self {
64+
let prev = format!("{} {}", self.exec, self.args.join(" "));
65+
66+
self.exec = "sshpass".to_string();
67+
self.clear_args()
68+
.args(["-p", &*config.auth.password])
69+
.args([
70+
"ssh",
71+
&*format!(
72+
"{}@{}",
73+
config.auth.username,
74+
config.get_backend().get_host()
75+
),
76+
"-p",
77+
&*config.auth.ssh_port.to_string(),
78+
])
79+
.arg(prev)
6580
}
6681

6782
pub fn with_err(mut self, message: &'static str) -> Self {

winapps/src/config/operations.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ use crate::{bail, dirs::path_ok, Config, Error, IntoResult, Result};
55

66
impl Config {
77
/// Reads the config from disk.
8-
///
9-
/// Panics if this is called a second time after already returning an `Ok`.
108
pub fn load() -> Result<&'static Config> {
119
static CONFIG: OnceLock<Config> = OnceLock::new();
1210

winapps/src/remote_client/freerdp.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
use crate::{bail, command::Command, Config, Error, RemoteClient, Result};
2+
use regex::Regex;
13
use std::{
24
net::{SocketAddr, TcpStream},
5+
path::{Path, PathBuf},
36
time::Duration,
47
};
58
use tracing::info;
69

7-
use crate::{command::Command, Config, Error, RemoteClient, Result};
8-
910
pub struct Freerdp {
1011
config: &'static Config,
1112
}
@@ -51,17 +52,39 @@ impl RemoteClient for Freerdp {
5152
Ok(())
5253
}
5354

54-
fn run_app(&self, app_name: &str) -> Result<()> {
55+
fn run_app(&self, app_name: String, args: Vec<String>) -> Result<()> {
5556
let path = self
5657
.config
5758
.linked_apps
5859
.iter()
59-
.filter_map(|app| app.id.eq(app_name).then_some(app.win_exec.clone()))
60+
.filter_map(|app| app.id.eq(&app_name).then_some(app.win_exec.clone()))
6061
.next()
61-
.unwrap_or(app_name.to_string());
62+
.unwrap_or(app_name);
63+
64+
let Some(home_regex) = dirs::home_dir().map(|home| {
65+
Regex::new(&format!(
66+
"^{}",
67+
home.into_os_string()
68+
.into_string()
69+
.expect("$HOME should always be a valid string")
70+
))
71+
.expect("'^$HOME' should always be a valid regex")
72+
}) else {
73+
bail!("Couldn't find $HOME")
74+
};
6275

6376
self.get_command()
6477
.arg(format!("/app:program:{path}"))
78+
.args(args.iter().map(|arg| {
79+
if arg.contains("/") && home_regex.is_match(arg) {
80+
home_regex
81+
.replace(arg, r"\\tsclient\\media")
82+
.to_string()
83+
.replace("/", r"\")
84+
} else {
85+
arg.to_owned()
86+
}
87+
}))
6588
.spawn()
6689
.map(|_| ())
6790
}

winapps/src/remote_client/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub(crate) mod freerdp;
55
pub trait RemoteClient {
66
fn check_depends(&self) -> Result<()>;
77

8-
fn run_app(&self, exec: &str) -> Result<()>;
8+
fn run_app(&self, exec: String, args: Vec<String>) -> Result<()>;
99

1010
fn run_full_session(&self) -> Result<()>;
1111
}

0 commit comments

Comments
 (0)