Skip to content

Commit

Permalink
#14: Add --by-steam-id in the CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
mtkennerly committed Jul 29, 2020
1 parent cb8c6fc commit e28e56f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Added:
* `--api` flag in CLI mode.
* `--by-steam-id` flag in CLI mode.
* Fixed:
* Registry values of type `EXPAND_SZ` and `MULTI_SZ` were converted to `SZ` when restored.
* Changed:
Expand Down
91 changes: 82 additions & 9 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ pub enum Subcommand {
#[structopt(long)]
update: bool,

/// When naming specific games to process, this means that you'll
/// provide the Steam IDs instead of the manifest names, and Ludusavi will
/// look up those IDs in the manifest to find the corresponding names.
#[structopt(long)]
by_steam_id: bool,

/// Print information to stdout in machine-readable JSON.
/// This replaces the default, human-readable output.
#[structopt(long)]
Expand All @@ -68,6 +74,12 @@ pub enum Subcommand {
#[structopt(long)]
force: bool,

/// When naming specific games to process, this means that you'll
/// provide the Steam IDs instead of the manifest names, and Ludusavi will
/// look up those IDs in the manifest to find the corresponding names.
#[structopt(long)]
by_steam_id: bool,

/// Print information to stdout in machine-readable JSON.
/// This replaces the default, human-readable output.
#[structopt(long)]
Expand Down Expand Up @@ -346,6 +358,7 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
path,
force,
update,
by_steam_id,
api,
games,
} => {
Expand All @@ -371,6 +384,7 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
}
}

let steam_ids_to_names = &manifest.map_steam_ids_to_names();
let mut all_games = manifest.0;
for custom_game in &config.custom_games {
all_games.insert(custom_game.name.clone(), Game::from(custom_game.to_owned()));
Expand All @@ -380,7 +394,18 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
let mut invalid_games: Vec<_> = games
.iter()
.filter_map(|game| {
if !all_games.contains_key(game) {
if by_steam_id {
match game.parse::<u32>() {
Ok(id) => {
if !steam_ids_to_names.contains_key(&id) {
Some(game.to_owned())
} else {
None
}
}
Err(_) => Some(game.to_owned()),
}
} else if !all_games.contains_key(game) {
Some(game.to_owned())
} else {
None
Expand All @@ -395,7 +420,15 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
}

let mut subjects: Vec<_> = if !&games.is_empty() {
games
if by_steam_id {
games
.iter()
.map(|game| &steam_ids_to_names[&game.parse::<u32>().unwrap()])
.cloned()
.collect()
} else {
games
}
} else {
all_games.keys().cloned().collect()
};
Expand Down Expand Up @@ -441,6 +474,7 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
preview,
path,
force,
by_steam_id,
api,
games,
} => {
Expand All @@ -450,6 +484,8 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
Reporter::standard(translator)
};

let manifest = Manifest::load(&mut config, false)?;

let restore_dir = match path {
None => config.restore.path.clone(),
Some(p) => p,
Expand All @@ -466,14 +502,28 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
}
}

let steam_ids_to_names = &manifest.map_steam_ids_to_names();
let restorables = scan_dir_for_restorable_games(&restore_dir);
let restorable_names: Vec<_> = restorables.iter().map(|(name, _)| name.to_owned()).collect();

let games_specified = !games.is_empty();
let mut invalid_games: Vec<_> = games
.iter()
.filter_map(|game| {
if !restorable_names.contains(game) {
if by_steam_id {
match game.parse::<u32>() {
Ok(id) => {
if !steam_ids_to_names.contains_key(&id)
|| !restorable_names.contains(&steam_ids_to_names[&id])
{
Some(game.to_owned())
} else {
None
}
}
Err(_) => Some(game.to_owned()),
}
} else if !restorable_names.contains(game) {
Some(game.to_owned())
} else {
None
Expand All @@ -490,7 +540,15 @@ pub fn run_cli(sub: Subcommand) -> Result<(), Error> {
let mut subjects: Vec<_> = if !&games.is_empty() {
restorables
.iter()
.filter_map(|x| if games.contains(&x.0) { Some(x.to_owned()) } else { None })
.filter_map(|x| {
if (by_steam_id && steam_ids_to_names.values().cloned().any(|y| y == x.0))
|| (games.contains(&x.0))
{
Some(x.to_owned())
} else {
None
}
})
.collect()
} else {
restorables.iter().cloned().collect()
Expand Down Expand Up @@ -576,6 +634,7 @@ mod tests {
path: None,
force: false,
update: false,
by_steam_id: false,
api: false,
games: vec![],
}),
Expand All @@ -594,6 +653,7 @@ mod tests {
"tests/backup",
"--force",
"--update",
"--by-steam-id",
"--api",
"game1",
"game2",
Expand All @@ -604,6 +664,7 @@ mod tests {
path: Some(StrictPath::new(s("tests/backup"))),
force: true,
update: true,
by_steam_id: true,
api: true,
games: vec![s("game1"), s("game2")],
}),
Expand All @@ -621,6 +682,7 @@ mod tests {
path: Some(StrictPath::new(s("tests/fake"))),
force: false,
update: false,
by_steam_id: false,
api: false,
games: vec![],
}),
Expand All @@ -637,6 +699,7 @@ mod tests {
preview: false,
path: None,
force: false,
by_steam_id: false,
api: false,
games: vec![],
}),
Expand All @@ -654,6 +717,7 @@ mod tests {
"--path",
"tests/backup",
"--force",
"--by-steam-id",
"--api",
"game1",
"game2",
Expand All @@ -663,6 +727,7 @@ mod tests {
preview: true,
path: Some(StrictPath::new(s("tests/backup"))),
force: true,
by_steam_id: true,
api: true,
games: vec![s("game1"), s("game2")],
}),
Expand All @@ -685,6 +750,14 @@ mod tests {
use maplit::hashset;
use pretty_assertions::assert_eq;

fn drive() -> String {
if cfg!(target_os = "windows") {
StrictPath::new(s("foo")).render()[..2].to_string()
} else {
s("")
}
}

#[test]
fn can_render_in_standard_mode_with_minimal_input() {
let mut reporter = Reporter::standard(Translator::default());
Expand All @@ -705,7 +778,7 @@ Overall:
Size: 0.00 MiB
Location: {}/dev/null
"#,
if cfg!(target_os = "windows") { "C:" } else { "" }
&drive()
)
.trim_end(),
reporter.render(&StrictPath::new(s("/dev/null")))
Expand Down Expand Up @@ -765,7 +838,7 @@ Overall:
Location: <drive>/dev/null
"#
.trim()
.replace("<drive>", if cfg!(target_os = "windows") { "C:" } else { "" }),
.replace("<drive>", &drive()),
reporter.render(&StrictPath::new(s("/dev/null")))
);
}
Expand Down Expand Up @@ -808,7 +881,7 @@ Overall:
Location: <drive>/dev/null
"#
.trim()
.replace("<drive>", if cfg!(target_os = "windows") { "C:" } else { "" }),
.replace("<drive>", &drive()),
reporter.render(&StrictPath::new(s("/dev/null")))
);
}
Expand Down Expand Up @@ -916,7 +989,7 @@ Overall:
}
"#
.trim()
.replace("<drive>", if cfg!(target_os = "windows") { "C:" } else { "" }),
.replace("<drive>", &drive()),
reporter.render(&StrictPath::new(s("/dev/null")))
);
}
Expand Down Expand Up @@ -973,7 +1046,7 @@ Overall:
}
"#
.trim()
.replace("<drive>", if cfg!(target_os = "windows") { "C:" } else { "" }),
.replace("<drive>", &drive()),
reporter.render(&StrictPath::new(s("/dev/null")))
);
}
Expand Down
13 changes: 13 additions & 0 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ impl Manifest {
_ => Err(Error::ManifestCannotBeUpdated),
}
}

pub fn map_steam_ids_to_names(&self) -> std::collections::HashMap<u32, String> {
self.0
.iter()
.filter_map(|(k, v)| match &v.steam {
None => None,
Some(steam) => match steam.id {
None => None,
Some(id) => Some((id, k.to_owned())),
},
})
.collect()
}
}

#[cfg(test)]
Expand Down

0 comments on commit e28e56f

Please sign in to comment.