1
Fork 0
mirror of https://github.com/RGBCube/superfreq synced 2025-07-27 17:07:44 +00:00

package: make multicall

This commit is contained in:
RGBCube 2025-06-04 21:09:35 +03:00
parent a25ae59bde
commit b6dd9e78d4
Signed by: RGBCube
SSH key fingerprint: SHA256:CzqbPcfwt+GxFYNnFVCqoN5Itn4YFrshg1TrnACpA5M
2 changed files with 98 additions and 16 deletions

51
build.rs Normal file
View file

@ -0,0 +1,51 @@
use std::env;
use std::fs;
use std::path::PathBuf;
const MULTICALL_NAMES: &[&str] = &["cpu", "power"];
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
let target = out_dir
.parent() // target/debug/build/<pkg>-<hash>/out
.and_then(|p| p.parent()) // target/debug/build/<pkg>-<hash>
.and_then(|p| p.parent()) // target/debug/
.ok_or("failed to find target directory")?;
let main_binary_name = env::var("CARGO_PKG_NAME")?;
let main_binary_path = target.join(&main_binary_name);
let mut errored = false;
for name in MULTICALL_NAMES {
let hardlink_path = target.join(name);
if hardlink_path.exists() {
if hardlink_path.is_dir() {
fs::remove_dir_all(&hardlink_path)?;
} else {
fs::remove_file(&hardlink_path)?;
}
}
if let Err(error) = fs::hard_link(&main_binary_path, &hardlink_path) {
println!(
"cargo:warning=failed to create hard link '{path}': {error}",
path = hardlink_path.display(),
);
errored = true;
}
}
if errored {
println!(
"cargo:warning=this often happens because the target binary isn't built yet, try running `cargo build` again"
);
println!("cargo:warning=keep in mind that this is for development purposes only");
}
Ok(())
}

View file

@ -21,30 +21,52 @@ use yansi::Paint as _;
#[derive(clap::Parser, Debug)]
#[clap(author, version, about)]
struct Cli {
#[command(flatten)]
verbosity: clap_verbosity_flag::Verbosity,
#[clap(subcommand)]
command: Command,
}
#[derive(clap::Parser, Debug)]
#[clap(multicall = true)]
enum Command {
/// Display information.
Info,
/// Watt daemon.
Watt {
#[command(flatten)]
verbosity: clap_verbosity_flag::Verbosity,
/// Start the daemon.
Start {
/// The daemon config path.
#[arg(long, env = "WATT_CONFIG")]
config: PathBuf,
},
/// Modify CPU attributes.
CpuSet(config::CpuDelta),
/// CPU metadata and modification utility.
Cpu {
#[command(flatten)]
verbosity: clap_verbosity_flag::Verbosity,
#[clap(subcommand)]
command: CpuCommand,
},
/// Power supply metadata and modification utility.
Power {
#[command(flatten)]
verbosity: clap_verbosity_flag::Verbosity,
#[clap(subcommand)]
command: PowerCommand,
},
}
#[derive(clap::Parser, Debug)]
enum CpuCommand {
/// Modify CPU attributes.
Set(config::CpuDelta),
}
#[derive(clap::Parser, Debug)]
enum PowerCommand {
/// Modify power supply attributes.
PowerSet(config::PowerDelta),
Set(config::PowerDelta),
}
fn real_main() -> anyhow::Result<()> {
@ -52,24 +74,33 @@ fn real_main() -> anyhow::Result<()> {
yansi::whenever(yansi::Condition::TTY_AND_COLOR);
let (Command::Watt { verbosity, .. }
| Command::Cpu { verbosity, .. }
| Command::Power { verbosity, .. }) = cli.command;
env_logger::Builder::new()
.filter_level(cli.verbosity.log_level_filter())
.filter_level(verbosity.log_level_filter())
.format_timestamp(None)
.format_module_path(false)
.init();
match cli.command {
Command::Info => todo!(),
Command::Start { config } => {
Command::Watt { config, .. } => {
let config = config::DaemonConfig::load_from(&config)
.context("failed to load daemon config file")?;
daemon::run(config)
}
Command::CpuSet(delta) => delta.apply(),
Command::PowerSet(delta) => delta.apply(),
Command::Cpu {
command: CpuCommand::Set(delta),
..
} => delta.apply(),
Command::Power {
command: PowerCommand::Set(delta),
..
} => delta.apply(),
}
}