add file-list option

This commit is contained in:
Robin Appelman 2025-06-21 15:04:21 +02:00
commit 7dff851498
4 changed files with 42 additions and 10 deletions

12
Cargo.lock generated
View file

@ -191,7 +191,7 @@ dependencies = [
"bitflags", "bitflags",
"cexpr", "cexpr",
"clang-sys", "clang-sys",
"itertools", "itertools 0.12.1",
"lazy_static", "lazy_static",
"lazycell", "lazycell",
"log", "log",
@ -507,6 +507,7 @@ name = "depot-prefetch"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"itertools 0.14.0",
"main_error", "main_error",
"serde", "serde",
"serde_json", "serde_json",
@ -1037,6 +1038,15 @@ dependencies = [
"either", "either",
] ]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.15"

View file

@ -15,4 +15,5 @@ main_error = "0.1.2"
clap = { version = "4.5.40", features = ["derive"] } clap = { version = "4.5.40", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
tracing = "0.1.41" tracing = "0.1.41"
tracing-subscriber = "0.3.19" tracing-subscriber = "0.3.19"
itertools = "0.14.0"

View file

@ -21,13 +21,22 @@ struct Args {
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
enum ArgsCommand { enum ArgsCommand {
/// Get the latest manifest and pre-fetch it /// Get the latest manifest and pre-fetch it
Fetch(ProductArgs), Fetch(FetchArgs),
/// Get the latest manifest without fetching /// Get the latest manifest without fetching
Manifest(ProductArgs), Manifest(ProductArgs),
/// Watch for manifest changes and pre-fetch any updates /// Watch for manifest changes and pre-fetch any updates
Watch(WatchArgs), Watch(WatchArgs),
} }
#[derive(Debug, Parser)]
struct FetchArgs {
#[clap(flatten)]
product_args: ProductArgs,
/// Only download specific files, either raw files names, or regexes prefixed with 'regex:'
#[clap(long)]
file_list: Vec<String>,
}
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
struct ProductArgs { struct ProductArgs {
/// App to prefetch depots for /// App to prefetch depots for
@ -50,6 +59,9 @@ struct WatchArgs {
/// Command to run when updates are detected, the manifest data will be passed as the first argument as json. /// Command to run when updates are detected, the manifest data will be passed as the first argument as json.
#[clap(long)] #[clap(long)]
run: Option<String>, run: Option<String>,
/// Only download specific files, either raw files names, or regexes prefixed with 'regex:'
#[clap(long)]
file_list: Vec<String>,
} }
#[tokio::main] #[tokio::main]
@ -61,8 +73,8 @@ async fn main() -> MainResult {
match args.command { match args.command {
ArgsCommand::Fetch(args) => { ArgsCommand::Fetch(args) => {
let inputs = get_manifests(&info_fetcher, &args).await?; let inputs = get_manifests(&info_fetcher, &args.product_args).await?;
let outputs = fetch_inputs(inputs)?; let outputs = fetch_inputs(inputs, &args.file_list)?;
serde_json::to_writer_pretty(std::io::stdout(), &outputs)?; serde_json::to_writer_pretty(std::io::stdout(), &outputs)?;
} }
@ -81,7 +93,7 @@ async fn main() -> MainResult {
let inputs_json = serde_json::to_string(&new_inputs)?; let inputs_json = serde_json::to_string(&new_inputs)?;
debug!(inputs = inputs_json, "updated detected"); debug!(inputs = inputs_json, "updated detected");
let outputs = fetch_inputs(new_inputs)?; let outputs = fetch_inputs(new_inputs, &args.file_list)?;
let output_json = serde_json::to_string(&outputs)?; let output_json = serde_json::to_string(&outputs)?;
info!(outputs = ?output_json, "prefetch complete"); info!(outputs = ?output_json, "prefetch complete");
@ -133,10 +145,10 @@ async fn get_manifests(
.collect()) .collect())
} }
fn fetch_inputs(inputs: impl IntoIterator<Item = ManifestInput>) -> Result<Vec<ManifestOutput>, PrefetchError> { fn fetch_inputs(inputs: impl IntoIterator<Item = ManifestInput>, file_list: &[String]) -> Result<Vec<ManifestOutput>, PrefetchError> {
inputs.into_iter() inputs.into_iter()
.map(|input| { .map(|input| {
prefetch(&input).map(|hash| ManifestOutput { prefetch(&input, file_list).map(|hash| ManifestOutput {
app_id: input.app_id, app_id: input.app_id,
depot_id: input.depot_id, depot_id: input.depot_id,
manifest: input.manifest, manifest: input.manifest,

View file

@ -1,4 +1,5 @@
use crate::ManifestInput; use crate::ManifestInput;
use itertools::Itertools;
use std::process::Command; use std::process::Command;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use thiserror::Error; use thiserror::Error;
@ -23,14 +24,22 @@ in fetchSteam {
depotId = "DEPOT_ID"; depotId = "DEPOT_ID";
manifestId = "MANIFEST_ID"; manifestId = "MANIFEST_ID";
hash = ""; hash = "";
fileList = [FILE_LIST];
} }
"#; "#;
pub fn prefetch(manifest: &ManifestInput) -> Result<String, PrefetchError> { pub fn prefetch(manifest: &ManifestInput, file_list: &[String]) -> Result<String, PrefetchError> {
let file_list_nix = file_list
.iter()
.map(|filter| serde_json::to_string(filter).unwrap_or_default())
.join(" ");
dbg!(&file_list_nix);
let expression = EXPRESSION_TEMPLATE let expression = EXPRESSION_TEMPLATE
.replace("APP_ID", &manifest.app_id.to_string()) .replace("APP_ID", &manifest.app_id.to_string())
.replace("DEPOT_ID", &manifest.depot_id.to_string()) .replace("DEPOT_ID", &manifest.depot_id.to_string())
.replace("MANIFEST_ID", &manifest.manifest.to_string()); .replace("MANIFEST_ID", &manifest.manifest.to_string())
.replace("FILE_LIST", &file_list_nix);
let command = Command::new("nix-build") let command = Command::new("nix-build")
.arg("-E") .arg("-E")