Skip to content

Commit

Permalink
#209: Fix Lutris configpath handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mtkennerly committed Jun 20, 2024
1 parent 669ceb8 commit 1abc826
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Unreleased

* Fixed:
* For Lutris roots, after reading `pga.db`,
Ludusavi did not properly combine that data with the data from the `games/*.yml` files.

## v0.24.1 (2024-06-15)

* Fixed:
Expand Down
70 changes: 64 additions & 6 deletions src/scan/launchers/lutris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ impl From<rusqlite::Error> for Error {
mod spec {
use super::*;

/// For `games/foo.yml`, this would be `foo`.
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BareName(pub String);

impl std::fmt::Display for BareName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.0)
}
}

#[derive(serde::Deserialize)]
pub struct Data {
pub game: Game,
Expand Down Expand Up @@ -105,8 +115,10 @@ pub fn scan(root: &RootsConfig, title_finder: &TitleFinder) -> HashMap<String, H
match scan_db(root) {
Ok(db_games) => {
for (spec, db_pending) in db_games {
let spec_pending = read_spec(&spec);
log::trace!("Evaluating game from DB: {db_pending:?} + from spec: {spec_pending:?}");
let spec_pending = find_spec(&spec, &root.path);
log::trace!(
"Evaluating game, bare name: {spec}, from DB: {db_pending:?} + from spec: {spec_pending:?}"
);

if let Some((title, game)) = db_pending.merge(spec_pending).evaluate(title_finder) {
log::trace!("Evaluated to '{title}': {game:?}");
Expand Down Expand Up @@ -148,7 +160,7 @@ pub fn scan(root: &RootsConfig, title_finder: &TitleFinder) -> HashMap<String, H
games
}

fn scan_db(root: &RootsConfig) -> Result<HashMap<StrictPath, Pending>, Error> {
fn scan_db(root: &RootsConfig) -> Result<HashMap<spec::BareName, Pending>, Error> {
#[derive(Debug)]
struct Row {
name: Option<String>,
Expand All @@ -164,7 +176,7 @@ fn scan_db(root: &RootsConfig) -> Result<HashMap<StrictPath, Pending>, Error> {
return Err(Error::NoDatabase);
}

let mut games = HashMap::<StrictPath, Pending>::new();
let mut games = HashMap::<spec::BareName, Pending>::new();

let Ok(file) = db_file.as_std_path_buf() else {
return Ok(games);
Expand All @@ -189,7 +201,11 @@ fn scan_db(root: &RootsConfig) -> Result<HashMap<StrictPath, Pending>, Error> {
log::trace!("Row = {row:?}");

let spec = if let Some(spec) = row.configpath {
StrictPath::new(spec)
if spec.trim().is_empty() {
log::warn!("Ignoring row with empty `configpath`");
continue;
}
spec::BareName(spec)
} else {
log::warn!("Ignoring row without `configpath`");
continue;
Expand All @@ -205,7 +221,9 @@ fn scan_db(root: &RootsConfig) -> Result<HashMap<StrictPath, Pending>, Error> {

if pending.platform.is_some_and(|x| x == Os::Windows) && row.runner.is_some_and(|x| x == "wine") {
if let Some(directory) = row.directory {
pending.prefix = Some(StrictPath::new(directory));
if !directory.trim().is_empty() {
pending.prefix = Some(StrictPath::new(directory));
}
}
}

Expand All @@ -220,6 +238,16 @@ fn scan_db(root: &RootsConfig) -> Result<HashMap<StrictPath, Pending>, Error> {
Ok(games)
}

fn find_spec(name: &spec::BareName, root: &StrictPath) -> Option<Pending> {
for candidate in root.joined(&format!("games/{name}.y*ml")).glob() {
if candidate.is_file() {
return read_spec(&candidate);
}
}

None
}

fn read_spec(file: &StrictPath) -> Option<Pending> {
log::debug!("Inspecting Lutris game file: {:?}", file);

Expand Down Expand Up @@ -300,6 +328,12 @@ mod tests {
windows-game:
files:
<base>/file1.txt: {}
Windows Game 1:
files:
<base>/file1.txt: {}
Windows Game 2:
files:
<base>/file1.txt: {}
windows-game-with-absolute-exe:
files:
<base>/file1.txt: {}
Expand Down Expand Up @@ -363,6 +397,30 @@ mod tests {
);
}

#[test]
fn scan_finds_all_games_with_spec_and_database_merged() {
let root = RootsConfig {
path: StrictPath::new(format!("{}/tests/launchers/lutris-merged", repo())),
store: Store::Lutris,
};
let games = scan(&root, &title_finder());
assert_eq!(
hash_map! {
"Windows Game 1".to_string(): hash_set![LauncherGame {
install_dir: Some(StrictPath::new("/home/deck/Games/service/windows-game/drive_c/game".to_string())),
prefix: Some(StrictPath::new("/home/deck/Games/service/windows-game-1".to_string())),
platform: Some(Os::Windows),
}],
"Windows Game 2".to_string(): hash_set![LauncherGame {
install_dir: Some(StrictPath::new("/home/deck/Games/service".to_string())),
prefix: Some(StrictPath::new("/home/deck/Games/service/windows-game-2".to_string())),
platform: Some(Os::Windows),
}],
},
games,
);
}

#[test]
fn can_scan_spec_with_absolute_exe() {
let spec = spec::Data {
Expand Down
34 changes: 34 additions & 0 deletions tests/launchers/lutris-merged/games/windows-game-1683516078.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
game:
args: ''
exe: /home/deck/Games/service/windows-game/drive_c/game/YookaLaylee64.exe
prefix: /home/deck/Games/service/windows-game
working_dir: /home/deck/Games/service/windows-game/drive_c/game
game_slug: windows-game
name: Windows Game
requires: null
script:
files: [] # omitted
game:
args: ''
exe: $GAMEDIR/drive_c/game/YookaLaylee64.exe
prefix: $GAMEDIR
working_dir: $GAMEDIR/drive_c/game
installer:
- task:
arch: win64
prefix: /home/deck/Games/service/windows-game
wine_path: /home/deck/.var/app/net.lutris.Lutris/data/lutris/runners/wine/lutris-7.2-2-x86_64/bin/wine
- mkdir: $GAMEDIR/drive_c/game
- move: ~ # omitted
system: {}
wine:
version: lutris-7.2-2-x86_64
service: service
service_id: ...
slug: windows-game
system: {}
variables: {}
version: Service Name
wine:
version: lutris-7.2-2-x86_64
year: null
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
game:
exe: /home/deck/Games/service/game.exe
prefix: /home/deck/Games/service/windows-game-2
system: {}
wine: {}
Binary file added tests/launchers/lutris-merged/pga.db
Binary file not shown.

0 comments on commit 1abc826

Please sign in to comment.