1
0
Fork 0
forked from wry/wry

cli: add config subcommand

This commit is contained in:
Julian Orth 2026-03-20 18:49:39 +01:00
parent 6727f3e4bc
commit 668188ff43
4 changed files with 119 additions and 4 deletions

View file

@ -1,6 +1,7 @@
mod clients;
mod color;
mod color_management;
mod config;
mod control_center;
mod damage_tracking;
mod duration;
@ -25,7 +26,7 @@ mod xwayland;
use {
crate::{
cli::{
clients::ClientsArgs, color_management::ColorManagementArgs,
clients::ClientsArgs, color_management::ColorManagementArgs, config::ConfigArgs,
damage_tracking::DamageTrackingArgs, idle::IdleCmd, input::InputArgs, randr::RandrArgs,
reexec::ReexecArgs, run_tagged::RunTaggedArgs, tree::TreeArgs, xwayland::XwaylandArgs,
},
@ -58,6 +59,8 @@ pub struct GlobalArgs {
pub enum Cmd {
/// Run the compositor.
Run(RunArgs),
/// Create/modify the toml config.
Config(ConfigArgs),
/// Generate shell completion scripts for jay.
GenerateCompletion(GenerateArgs),
/// Open the log file.
@ -248,5 +251,6 @@ pub fn main() {
Cmd::RunTests => crate::it::run_tests(),
Cmd::Reexec(a) => reexec::main(cli.global, a),
Cmd::ControlCenter => control_center::main(cli.global),
Cmd::Config(a) => config::main(cli.global, a),
}
}

106
src/cli/config.rs Normal file
View file

@ -0,0 +1,106 @@
use {
crate::{cli::GlobalArgs, compositor::config_dir, logger::Logger, utils::errorfmt::ErrorFmt},
clap::{Args, Subcommand},
jay_toml_config::CONFIG_TOML,
std::path::Path,
uapi::{UstrPtr, c},
};
#[derive(Args, Debug)]
pub struct ConfigArgs {
#[clap(subcommand)]
pub command: ConfigCmd,
}
#[derive(Subcommand, Debug)]
pub enum ConfigCmd {
/// Initialize the toml config file.
Init(ConfigInitArgs),
/// Print the path to the config.
Path,
/// Open the config directory with xdg-open.
OpenDir,
}
#[derive(Args, Debug)]
pub struct ConfigInitArgs {
/// Overwrite an existing config.toml file.
///
/// The old file will be backed up to `config.toml.<n>`.
#[clap(long)]
overwrite: bool,
}
pub fn main(global: GlobalArgs, args: ConfigArgs) {
Logger::install_stderr(global.log_level);
let dir = || {
let Some(dir) = config_dir() else {
fatal!("Could not determine the config directory");
};
dir
};
match args.command {
ConfigCmd::Init(a) => {
let dir = dir();
if let Err(e) = std::fs::create_dir_all(&dir) {
fatal!("Could not create config directory: {}", ErrorFmt(e));
}
let toml_path = Path::new(&dir).join(CONFIG_TOML);
let mut write_real_path = toml_path.clone();
if matches!(std::fs::exists(&toml_path), Ok(true)) {
if !a.overwrite {
eprintln!("{} already exists", toml_path.display());
eprintln!("Pass --overwrite to overwrite the config file");
return;
}
for i in 1.. {
write_real_path = toml_path.with_added_extension(i.to_string());
if matches!(std::fs::exists(&write_real_path), Ok(false)) {
break;
}
}
}
let res = std::fs::write(&write_real_path, jay_toml_config::DEFAULT);
if let Err(e) = res {
fatal!("Could not write config: {}", ErrorFmt(e));
}
if write_real_path != toml_path {
let res = uapi::renameat2(
c::AT_FDCWD,
&*toml_path,
c::AT_FDCWD,
&*write_real_path,
c::RENAME_EXCHANGE,
);
if let Err(e) = res {
fatal!(
"Could not exchange {} and {}: {}",
toml_path.display(),
write_real_path.display(),
ErrorFmt(e),
);
}
eprintln!("Backed up old config.toml to {}", write_real_path.display());
}
eprintln!("Config written to {}", toml_path.display());
}
ConfigCmd::Path => {
let dir = dir();
let toml_path = Path::new(&dir).join(CONFIG_TOML);
println!("{}", toml_path.display());
}
ConfigCmd::OpenDir => {
const XDG_OPEN: &str = "xdg-open";
let dir = dir();
let mut args = UstrPtr::new();
args.push(XDG_OPEN);
args.push(&*dir);
if matches!(std::fs::exists(&dir), Ok(false)) {
fatal!("Use `jay config init` to initialize the config first");
}
if let Err(e) = uapi::execvp(XDG_OPEN, &args) {
fatal!("Could not start xdg-open: {}", ErrorFmt(e));
}
}
}
}