mirror of
https://codeberg.org/spire/depot-prefetch.git
synced 2026-06-04 02:24:08 +02:00
add watch command
This commit is contained in:
parent
182b067fad
commit
c89efc87e7
3 changed files with 164 additions and 18 deletions
88
src/main.rs
88
src/main.rs
|
|
@ -1,8 +1,12 @@
|
|||
use crate::prefetch::prefetch;
|
||||
use std::process::Command;
|
||||
use std::time::Duration;
|
||||
use crate::prefetch::{prefetch, PrefetchError};
|
||||
use crate::product_info::{ProductInfoError, ProductInfoFetcher};
|
||||
use clap::Parser;
|
||||
use main_error::MainResult;
|
||||
use serde::Serialize;
|
||||
use tokio::time::sleep;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
mod error;
|
||||
mod prefetch;
|
||||
|
|
@ -11,15 +15,17 @@ mod product_info;
|
|||
#[derive(Debug, Parser)]
|
||||
struct Args {
|
||||
#[command(subcommand)]
|
||||
command: Command,
|
||||
command: ArgsCommand,
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
enum Command {
|
||||
enum ArgsCommand {
|
||||
/// Get the latest manifest and pre-fetch it
|
||||
Fetch(ProductArgs),
|
||||
/// Get the latest manifest without fetching
|
||||
Manifest(ProductArgs),
|
||||
/// Watch for manifest changes and pre-fetch any updates
|
||||
Watch(WatchArgs),
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
|
@ -34,32 +40,68 @@ struct ProductArgs {
|
|||
depot: Vec<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct WatchArgs {
|
||||
#[clap(flatten)]
|
||||
product_args: ProductArgs,
|
||||
/// How often to check for updates
|
||||
#[clap(long, default_value_t = 300)]
|
||||
interval: u64,
|
||||
/// Command to run when updates are detected, the manifest data will be passed as the first argument as json.
|
||||
#[clap(long)]
|
||||
run: Option<String>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> MainResult {
|
||||
let args = Args::parse();
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let info_fetcher = ProductInfoFetcher::new().await?;
|
||||
|
||||
|
||||
match args.command {
|
||||
Command::Fetch(args) => {
|
||||
ArgsCommand::Fetch(args) => {
|
||||
let inputs = get_manifests(&info_fetcher, &args).await?;
|
||||
let outputs = inputs.into_iter()
|
||||
.map(|input| {
|
||||
prefetch(&input).map(|hash| ManifestOutput {
|
||||
app_id: input.app_id,
|
||||
depot_id: input.depot_id,
|
||||
manifest: input.manifest,
|
||||
hash,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let outputs = fetch_inputs(inputs)?;
|
||||
|
||||
serde_json::to_writer_pretty(std::io::stdout(), &outputs)?;
|
||||
}
|
||||
Command::Manifest(args) => {
|
||||
ArgsCommand::Manifest(args) => {
|
||||
let inputs = get_manifests(&info_fetcher, &args).await?;
|
||||
serde_json::to_writer_pretty(std::io::stdout(), &inputs)?;
|
||||
}
|
||||
ArgsCommand::Watch(args) => {
|
||||
let mut last_inputs = get_manifests(&info_fetcher, &args.product_args).await?;
|
||||
|
||||
loop {
|
||||
sleep(Duration::from_secs(args.interval)).await;
|
||||
let new_inputs = get_manifests(&info_fetcher, &args.product_args).await?;
|
||||
if new_inputs != last_inputs {
|
||||
last_inputs = new_inputs.clone();
|
||||
let inputs_json = serde_json::to_string(&new_inputs)?;
|
||||
debug!(inputs = inputs_json, "updated detected");
|
||||
|
||||
let outputs = fetch_inputs(new_inputs)?;
|
||||
let output_json = serde_json::to_string(&outputs)?;
|
||||
info!(outputs = ?output_json, "prefetch complete");
|
||||
|
||||
if let Some(run) = args.run.as_deref() {
|
||||
match Command::new(run)
|
||||
.arg(output_json)
|
||||
.status() {
|
||||
Ok(status) => {
|
||||
info!(%status, "Command existed");
|
||||
}
|
||||
Err(error) => {
|
||||
error!(%error, "Failed to run command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -91,7 +133,19 @@ async fn get_manifests(
|
|||
.collect())
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
fn fetch_inputs(inputs: impl IntoIterator<Item = ManifestInput>) -> Result<Vec<ManifestOutput>, PrefetchError> {
|
||||
inputs.into_iter()
|
||||
.map(|input| {
|
||||
prefetch(&input).map(|hash| ManifestOutput {
|
||||
app_id: input.app_id,
|
||||
depot_id: input.depot_id,
|
||||
manifest: input.manifest,
|
||||
hash,
|
||||
})
|
||||
}).collect()
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Eq, PartialEq, Copy, Clone)]
|
||||
struct ManifestInput {
|
||||
app_id: u32,
|
||||
depot_id: u32,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue