mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 03:25:23 +00:00
feat(cli): add argument to start tv in another working directory (#132)
Resolves #111 --------- Co-authored-by: Alexandre Pasmantier <alex.pasmant@gmail.com>
This commit is contained in:
parent
3b8ab1fbd8
commit
882737d147
@ -1,3 +1,5 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use color_eyre::{eyre::eyre, Result};
|
use color_eyre::{eyre::eyre, Result};
|
||||||
|
|
||||||
@ -14,8 +16,8 @@ use television_channels::{
|
|||||||
#[command(author, version = version(), about)]
|
#[command(author, version = version(), about)]
|
||||||
pub struct Cli {
|
pub struct Cli {
|
||||||
/// Which channel shall we watch?
|
/// Which channel shall we watch?
|
||||||
#[arg(value_enum, default_value = "files", value_parser = channel_parser)]
|
#[arg(value_enum, default_value = "files", index = 1)]
|
||||||
pub channel: ParsedCliChannel,
|
pub channel: String,
|
||||||
|
|
||||||
/// Use a custom preview command (currently only supported by the stdin channel)
|
/// Use a custom preview command (currently only supported by the stdin channel)
|
||||||
#[arg(short, long, value_name = "STRING")]
|
#[arg(short, long, value_name = "STRING")]
|
||||||
@ -40,11 +42,15 @@ pub struct Cli {
|
|||||||
#[arg(long, value_name = "STRING")]
|
#[arg(long, value_name = "STRING")]
|
||||||
pub passthrough_keybindings: Option<String>,
|
pub passthrough_keybindings: Option<String>,
|
||||||
|
|
||||||
|
/// The working directory to start in
|
||||||
|
#[arg(value_name = "PATH", index = 2)]
|
||||||
|
pub working_directory: Option<String>,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Option<Command>,
|
command: Option<Command>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug, PartialEq)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
/// Lists available channels
|
/// Lists available channels
|
||||||
ListChannels,
|
ListChannels,
|
||||||
@ -58,6 +64,7 @@ pub struct PostProcessedCli {
|
|||||||
pub frame_rate: f64,
|
pub frame_rate: f64,
|
||||||
pub passthrough_keybindings: Vec<String>,
|
pub passthrough_keybindings: Vec<String>,
|
||||||
pub command: Option<Command>,
|
pub command: Option<Command>,
|
||||||
|
pub working_directory: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Cli> for PostProcessedCli {
|
impl From<Cli> for PostProcessedCli {
|
||||||
@ -74,17 +81,48 @@ impl From<Cli> for PostProcessedCli {
|
|||||||
delimiter: cli.delimiter.clone(),
|
delimiter: cli.delimiter.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let channel: ParsedCliChannel;
|
||||||
|
let working_directory: Option<String>;
|
||||||
|
|
||||||
|
match channel_parser(&cli.channel) {
|
||||||
|
Ok(p) => {
|
||||||
|
channel = p;
|
||||||
|
working_directory = cli.working_directory;
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
// if the path is provided as first argument and it exists, use it as the working
|
||||||
|
// directory and default to the files channel
|
||||||
|
if cli.working_directory.is_none()
|
||||||
|
&& Path::new(&cli.channel).exists()
|
||||||
|
{
|
||||||
|
channel = ParsedCliChannel::Builtin(CliTvChannel::Files);
|
||||||
|
working_directory = Some(cli.channel.clone());
|
||||||
|
} else {
|
||||||
|
unknown_channel_exit(&cli.channel);
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
channel: cli.channel,
|
channel,
|
||||||
preview_command,
|
preview_command,
|
||||||
tick_rate: cli.tick_rate,
|
tick_rate: cli.tick_rate,
|
||||||
frame_rate: cli.frame_rate,
|
frame_rate: cli.frame_rate,
|
||||||
passthrough_keybindings,
|
passthrough_keybindings,
|
||||||
command: cli.command,
|
command: cli.command,
|
||||||
|
working_directory,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unknown_channel_exit(channel: &str) {
|
||||||
|
eprintln!("Unknown channel: {channel}\n");
|
||||||
|
// print the list of channels
|
||||||
|
list_channels();
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum ParsedCliChannel {
|
pub enum ParsedCliChannel {
|
||||||
Builtin(CliTvChannel),
|
Builtin(CliTvChannel),
|
||||||
@ -189,13 +227,14 @@ mod tests {
|
|||||||
#[allow(clippy::float_cmp)]
|
#[allow(clippy::float_cmp)]
|
||||||
fn test_from_cli() {
|
fn test_from_cli() {
|
||||||
let cli = Cli {
|
let cli = Cli {
|
||||||
channel: ParsedCliChannel::Builtin(CliTvChannel::Files),
|
channel: "files".to_string(),
|
||||||
preview: Some("bat -n --color=always {}".to_string()),
|
preview: Some("bat -n --color=always {}".to_string()),
|
||||||
delimiter: ":".to_string(),
|
delimiter: ":".to_string(),
|
||||||
tick_rate: 50.0,
|
tick_rate: 50.0,
|
||||||
frame_rate: 60.0,
|
frame_rate: 60.0,
|
||||||
passthrough_keybindings: Some("q,ctrl-w,ctrl-t".to_string()),
|
passthrough_keybindings: Some("q,ctrl-w,ctrl-t".to_string()),
|
||||||
command: None,
|
command: None,
|
||||||
|
working_directory: Some("/home/user".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let post_processed_cli: PostProcessedCli = cli.into();
|
let post_processed_cli: PostProcessedCli = cli.into();
|
||||||
@ -217,5 +256,36 @@ mod tests {
|
|||||||
post_processed_cli.passthrough_keybindings,
|
post_processed_cli.passthrough_keybindings,
|
||||||
vec!["q".to_string(), "ctrl-w".to_string(), "ctrl-t".to_string()]
|
vec!["q".to_string(), "ctrl-w".to_string(), "ctrl-t".to_string()]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
post_processed_cli.working_directory,
|
||||||
|
Some("/home/user".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::float_cmp)]
|
||||||
|
fn test_from_cli_no_args() {
|
||||||
|
let cli = Cli {
|
||||||
|
channel: ".".to_string(),
|
||||||
|
preview: None,
|
||||||
|
delimiter: ":".to_string(),
|
||||||
|
tick_rate: 50.0,
|
||||||
|
frame_rate: 60.0,
|
||||||
|
passthrough_keybindings: None,
|
||||||
|
command: None,
|
||||||
|
working_directory: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let post_processed_cli: PostProcessedCli = cli.into();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
post_processed_cli.channel,
|
||||||
|
ParsedCliChannel::Builtin(CliTvChannel::Files)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
post_processed_cli.working_directory,
|
||||||
|
Some(".".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(post_processed_cli.command, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
use std::env;
|
||||||
use std::io::{stdout, IsTerminal, Write};
|
use std::io::{stdout, IsTerminal, Write};
|
||||||
|
use std::path::Path;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@ -6,7 +8,7 @@ use cli::{list_channels, ParsedCliChannel, PostProcessedCli};
|
|||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use television_channels::channels::TelevisionChannel;
|
use television_channels::channels::TelevisionChannel;
|
||||||
use television_channels::entry::PreviewType;
|
use television_channels::entry::PreviewType;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::cli::Cli;
|
use crate::cli::Cli;
|
||||||
@ -45,6 +47,22 @@ async fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(working_directory) = args.working_directory {
|
||||||
|
let path = Path::new(&working_directory);
|
||||||
|
if !path.exists() {
|
||||||
|
error!(
|
||||||
|
"Working directory \"{}\" does not exist",
|
||||||
|
&working_directory
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"Error: Working directory \"{}\" does not exist",
|
||||||
|
&working_directory
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
env::set_current_dir(path)?;
|
||||||
|
}
|
||||||
|
|
||||||
match App::new(
|
match App::new(
|
||||||
{
|
{
|
||||||
if is_readable_stdin() {
|
if is_readable_stdin() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user