Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: group bin/cue files together when inferring games #1239

Merged
merged 99 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
c63d8eb
Draft
emmercm Mar 15, 2024
8b2a452
Update
emmercm Mar 15, 2024
5fb170d
Update
emmercm Mar 15, 2024
2635740
Update
emmercm Mar 15, 2024
59203a8
Update
emmercm Mar 16, 2024
4529420
Update
emmercm Mar 16, 2024
83d5b2d
Fix
emmercm Mar 16, 2024
c115554
Update
emmercm Mar 17, 2024
9a18709
Merge remote-tracking branch 'origin/main' into emmercm/file-factory-…
emmercm Mar 17, 2024
81ad036
Use timer
emmercm Mar 17, 2024
4e6f5e5
Feature: CHD support
emmercm Mar 18, 2024
0916ce2
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Mar 21, 2024
93a74f2
Merge fix
emmercm Mar 21, 2024
6515e72
Package only the needed chdman
emmercm Mar 21, 2024
d042d3f
Docs
emmercm Mar 23, 2024
a7bcf8b
Update
emmercm Mar 24, 2024
ac955c8
Update
emmercm Mar 24, 2024
65693f7
.gitignore
emmercm Mar 24, 2024
cd4db0d
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Mar 24, 2024
3b9854c
Parse GD-ROMs
emmercm Mar 24, 2024
b81a3b9
Fixes
emmercm Mar 25, 2024
a5d18d1
Tests
emmercm Mar 25, 2024
4f87ce4
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Mar 27, 2024
9b8785b
Merge fix
emmercm Mar 27, 2024
80c0e2c
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Apr 7, 2024
8ad88b1
Merge fix
emmercm Apr 7, 2024
de00e22
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Apr 7, 2024
df479c3
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Apr 7, 2024
1d1d256
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Apr 7, 2024
bd3d7fc
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Apr 13, 2024
ac4619a
Docs
emmercm May 8, 2024
3741230
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm May 9, 2024
2d5221f
Merge fix
emmercm May 9, 2024
7606d0e
Chd.SUPPORTED_FILES
emmercm May 9, 2024
40ad4d0
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Jul 21, 2024
9c13f14
Merge fix
emmercm Jul 21, 2024
00eae05
npm i
emmercm Jul 21, 2024
f2c06dc
Merge remote-tracking branch 'origin/main' into emmercm/chd
emmercm Jul 22, 2024
4fc6c1c
Test fixes
emmercm Jul 22, 2024
d211548
Merge branch 'emmercm/3.0.0-feature' into emmercm/chd
emmercm Jul 22, 2024
badc671
Test update
emmercm Jul 22, 2024
44b7b02
Bump chdman
emmercm Jul 22, 2024
f92de72
Update
emmercm Jul 22, 2024
c837805
.gitattributes?
emmercm Jul 23, 2024
58f4603
.gitattributes?
emmercm Jul 23, 2024
f90585b
.gitattributes
emmercm Jul 23, 2024
173d60c
GD-ROM.gdi
emmercm Jul 23, 2024
9556acb
Debug
emmercm Jul 23, 2024
9b14fa7
Debug
emmercm Jul 23, 2024
2df57cc
Debug
emmercm Jul 23, 2024
ed07510
Debug
emmercm Jul 23, 2024
4bef50e
Debug
emmercm Jul 23, 2024
6e3e2ec
macOS SDL2
emmercm Jul 23, 2024
c1c62ee
DEBUG
emmercm Jul 23, 2024
379b966
Debug
emmercm Jul 23, 2024
45ae97a
Ubuntu SDL2
emmercm Jul 23, 2024
e3a5092
Downgrade chdman
emmercm Jul 23, 2024
53a11f3
path.resolve
emmercm Jul 23, 2024
2aa1513
fail-fast: false
emmercm Jul 23, 2024
d909be6
Debug
emmercm Jul 23, 2024
d8d929e
Debug
emmercm Jul 23, 2024
b3cc613
Mutex
emmercm Jul 23, 2024
2e195b5
Mutex fix
emmercm Jul 23, 2024
0d0c95f
Debug
emmercm Jul 23, 2024
b771fc5
Test timeout 60sec
emmercm Jul 23, 2024
0be4a28
mkdir
emmercm Jul 23, 2024
bda9c36
Debug
emmercm Jul 23, 2024
83f15a3
Info mutex
emmercm Jul 23, 2024
b00f793
Debug
emmercm Jul 23, 2024
842513c
Debug
emmercm Jul 23, 2024
10e75bd
Debug
emmercm Jul 23, 2024
1d1fbde
Debug
emmercm Jul 23, 2024
6414474
Debug
emmercm Jul 23, 2024
fbb8913
Debug
emmercm Jul 23, 2024
f95aeca
Fix?
emmercm Jul 23, 2024
58b8d4a
Fix
emmercm Jul 23, 2024
bb1b40c
Reverts
emmercm Jul 23, 2024
d89c1b7
Revert
emmercm Jul 23, 2024
ca3b96f
Test fix
emmercm Jul 23, 2024
382a337
fail-fast: false
emmercm Jul 23, 2024
30bfcda
Icon update
emmercm Jul 23, 2024
eee2dc2
Debug
emmercm Jul 23, 2024
ad66b24
Debug
emmercm Jul 23, 2024
554b6e9
Debug
emmercm Jul 23, 2024
ec54606
Fix?
emmercm Jul 23, 2024
32318af
Debug
emmercm Jul 23, 2024
39850db
Debug
emmercm Jul 23, 2024
5aaaa30
Fix?
emmercm Jul 23, 2024
63d860d
Fix?
emmercm Jul 23, 2024
76468d8
Reverts
emmercm Jul 23, 2024
046e29d
Windows fix?
emmercm Jul 23, 2024
6a88d98
Update
emmercm Jul 25, 2024
8bed768
Windows test fix
emmercm Jul 26, 2024
bf6eab5
Feature: group bin/cue files together when inferring games
emmercm Jul 26, 2024
2457da6
Merge branch 'emmercm/3.0.0-feature' into emmercm/group-bin-cue-infer
emmercm Jul 26, 2024
9b24444
Merge branch 'emmercm/3.0.0-feature' into emmercm/group-bin-cue-infer
emmercm Jul 26, 2024
55760e2
Merge branch 'emmercm/3.0.0-feature' into emmercm/group-bin-cue-infer
emmercm Jul 26, 2024
50f3c9c
Fixes
emmercm Jul 26, 2024
caeb5bb
Test fix
emmercm Jul 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/igir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export default class Igir {
// Set up progress bar and input for DAT processing
const datProcessProgressBar = await this.logger.addProgressBar(chalk.underline('Processing DATs'), ProgressBarSymbol.NONE, dats.length);
if (dats.length === 0) {
dats = new DATGameInferrer(this.options, datProcessProgressBar).infer(roms);
dats = await new DATGameInferrer(this.options, datProcessProgressBar).infer(roms);
}

const datsToWrittenFiles = new Map<DAT, File[]>();
Expand Down
7 changes: 4 additions & 3 deletions src/modules/candidateGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export default class CandidateGenerator extends Module {
const inputChds = foundRomsWithFiles
.map((romWithFiles) => romWithFiles.getOutputFile())
.filter((file) => file.getFilePath().toLowerCase().endsWith('.chd'))
.filter(ArrayPoly.filterUniqueMapped((file) => file.hashCode()));
.filter(ArrayPoly.filterUniqueMapped((file) => file.getFilePath()));
if (inputChds.length === 1) {
this.progressBar.logTrace(`${dat.getNameShort()}: ${game.getName()}: `);
return new ReleaseCandidate(game, release, foundRomsWithFiles);
Expand Down Expand Up @@ -305,15 +305,16 @@ export default class CandidateGenerator extends Module {
// Filter to the Archives that contain every ROM in this Game
const archivesWithEveryRom = [...inputArchivesToRoms.entries()]
.filter(([archive, roms]) => {
if (roms.length === game.getRoms().length) {
if (roms.map((rom) => rom.hashCode()).join(',') === game.getRoms().map((rom) => rom.hashCode()).join(',')) {
return true;
}
// If there is a CHD with every .bin file, and we're raw-copying it, then assume its .cue
// file is accurate
return archive instanceof Chd
&& !game.getRoms().some((rom) => this.options.shouldZipFile(rom.getName()))
&& !this.options.shouldExtract()
&& CandidateGenerator.onlyCueFilesMissingFromChd(game, roms);
&& CandidateGenerator.onlyCueFilesMissingFromChd(game, roms)
&& this.options.getAllowExcessSets();
})
.map(([archive]) => archive);

Expand Down
166 changes: 120 additions & 46 deletions src/modules/datGameInferrer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import fs from 'node:fs';
import path from 'node:path';
import util from 'node:util';

import { parse } from '@gplane/cue';
import moment from 'moment';

import ProgressBar from '../console/progressBar.js';
Expand Down Expand Up @@ -34,7 +37,7 @@ export default class DATGameInferrer extends Module {
/**
* Infer {@link Game}s from input files.
*/
infer(romFiles: File[]): DAT[] {
async infer(romFiles: File[]): Promise<DAT[]> {
this.progressBar.logTrace(`inferring DATs for ${romFiles.length.toLocaleString()} ROM${romFiles.length !== 1 ? 's' : ''}`);

const normalizedInputPaths = this.options.getInputPaths()
Expand All @@ -57,14 +60,14 @@ export default class DATGameInferrer extends Module {
}, new Map<string, File[]>());
this.progressBar.logTrace(`inferred ${inputPathsToRomFiles.size.toLocaleString()} DAT${inputPathsToRomFiles.size !== 1 ? 's' : ''}`);

const dats = [...inputPathsToRomFiles.entries()]
.map(([inputPath, datRomFiles]) => DATGameInferrer.createDAT(inputPath, datRomFiles));
const dats = await Promise.all([...inputPathsToRomFiles.entries()]
.map(async ([inputPath, datRomFiles]) => this.createDAT(inputPath, datRomFiles)));

this.progressBar.logTrace('done inferring DATs');
return dats;
}

private static createDAT(inputPath: string, romFiles: File[]): DAT {
private async createDAT(inputPath: string, romFiles: File[]): Promise<DAT> {
const datName = path.basename(inputPath);
const date = moment().format('YYYYMMDD-HHmmss');
const header = new Header({
Expand All @@ -80,50 +83,46 @@ export default class DATGameInferrer extends Module {
].join('\n'),
});

// For all non-archived files, group files of the same filename without extension together
const gameNamesToRawFiles = romFiles
.filter((file) => !(file instanceof ArchiveEntry))
.reduce((map, file) => {
const gameName = DATGameInferrer.getGameName(file);
map.set(gameName, [...(map.get(gameName) ?? []), file]);
return map;
}, new Map<string, File[]>());
let remainingRomFiles = romFiles;
let gameNamesToRomFiles: [string, File[]][] = [];

// For each inference strategy
const inferFunctions = [
this.inferArchiveEntries,
this.inferBinCueFiles,
this.inferRawFiles,
];
for (const inferFunction of inferFunctions) {
// Infer the games and their files)
const result = await inferFunction.bind(this)(remainingRomFiles);

// Update the list of results
gameNamesToRomFiles = [...gameNamesToRomFiles, ...result];

// Remove the consumed files from further inference
const consumedFiles = new Set(result
.flatMap(([, resultFiles]) => resultFiles)
.map((file) => file.toString()));
remainingRomFiles = remainingRomFiles.filter((file) => !consumedFiles.has(file.toString()));
}

// For archives, assume the entire archive is one game
const archivePathsToArchiveEntries = romFiles
.filter((file) => file instanceof ArchiveEntry)
.reduce((map, file) => {
const archivePath = file.getFilePath();
map.set(archivePath, [...(map.get(archivePath) ?? []), file]);
return map;
}, new Map<string, ArchiveEntry<Archive>[]>());
const gameNamesToArchiveEntries = [...archivePathsToArchiveEntries.values()]
.map((archiveEntries) => {
const gameName = DATGameInferrer.getGameName(archiveEntries[0]);
return [gameName, archiveEntries] satisfies [string, ArchiveEntry<Archive>[]];
const games = gameNamesToRomFiles.map(([gameName, gameRomFiles]) => {
const roms = gameRomFiles
.map((romFile) => new ROM({
name: path.basename(romFile.getExtractedFilePath()),
size: romFile.getSize(),
crc32: romFile.getCrc32(),
md5: romFile.getMd5(),
sha1: romFile.getSha1(),
sha256: romFile.getSha256(),
}))
.filter(ArrayPoly.filterUniqueMapped((rom) => rom.getName()));
return new Game({
name: gameName,
description: gameName,
rom: roms,
});

const games = [
...gameNamesToRawFiles.entries(),
...gameNamesToArchiveEntries,
]
.map(([gameName, gameRomFiles]) => {
const roms = gameRomFiles
.map((romFile) => new ROM({
name: path.basename(romFile.getExtractedFilePath()),
size: romFile.getSize(),
crc32: romFile.getCrc32(),
md5: romFile.getMd5(),
sha1: romFile.getSha1(),
sha256: romFile.getSha256(),
}))
.filter(ArrayPoly.filterUniqueMapped((rom) => rom.getName()));
return new Game({
name: gameName,
description: gameName,
rom: roms,
});
})
})
// Filter out duplicate games
.filter(ArrayPoly.filterUniqueMapped((game) => game.hashCode()));

Expand All @@ -143,4 +142,79 @@ export default class DATGameInferrer extends Module {
.replace(/(\.[a-z0-9]+)+$/, '')
.trim();
}

private inferArchiveEntries(romFiles: File[]): [string, ArchiveEntry<Archive>[]][] {
this.progressBar.logTrace(`inferring games from archives from ${romFiles.length.toLocaleString()} file${romFiles.length !== 1 ? 's' : ''}`);

// For archives, assume the entire archive is one game
const archivePathsToArchiveEntries = romFiles
.filter((file) => file instanceof ArchiveEntry)
.reduce((map, file) => {
const archivePath = file.getFilePath();
map.set(archivePath, [...(map.get(archivePath) ?? []), file]);
return map;
}, new Map<string, ArchiveEntry<Archive>[]>());

const results = [...archivePathsToArchiveEntries.values()]
.map((archiveEntries) => {
const gameName = DATGameInferrer.getGameName(archiveEntries[0]);
return [gameName, archiveEntries] satisfies [string, ArchiveEntry<Archive>[]];
});

this.progressBar.logTrace(`inferred ${results.length.toLocaleString()} games from archives`);
return results;
}

private async inferBinCueFiles(romFiles: File[]): Promise<[string, File[]][]> {
const rawFiles = romFiles.filter((file) => !(file instanceof ArchiveEntry));
this.progressBar.logTrace(`inferring games from cue files from ${rawFiles.length.toLocaleString()} non-archive${rawFiles.length !== 1 ? 's' : ''}`);

const rawFilePathsToFiles = rawFiles
.reduce((map, file) => {
map.set(file.getFilePath(), file);
return map;
}, new Map<string, File>());

const results = (await Promise.all(rawFiles
.filter((file) => file.getExtractedFilePath().toLowerCase().endsWith('.cue'))
.map(async (cueFile): Promise<[string, File[]] | undefined> => {
try {
const cueData = await util.promisify(fs.readFile)(cueFile.getFilePath());
const cueSheet = parse(cueData.toString(), {
fatal: true,
}).sheet;

const binFiles = cueSheet.files
.map((binFile) => path.join(path.dirname(cueFile.getFilePath()), binFile.name))
.map((binFilePath) => rawFilePathsToFiles.get(binFilePath))
.filter(ArrayPoly.filterNotNullish);

if (binFiles.length > 0) {
const gameName = DATGameInferrer.getGameName(cueFile);
return [gameName, [cueFile, ...binFiles]];
}
return undefined;
} catch {
return undefined;
}
}))).filter(ArrayPoly.filterNotNullish);

this.progressBar.logTrace(`inferred ${results.length.toLocaleString()} games from cue files`);
return results;
}

private inferRawFiles(romFiles: File[]): [string, File[]][] {
this.progressBar.logTrace(`inferring games from raw files from ${romFiles.length.toLocaleString()} file${romFiles.length !== 1 ? 's' : ''}`);

const results = romFiles
.filter((file) => !(file instanceof ArchiveEntry))
.reduce((map, file) => {
const gameName = DATGameInferrer.getGameName(file);
map.set(gameName, [...(map.get(gameName) ?? []), file]);
return map;
}, new Map<string, File[]>());

this.progressBar.logTrace(`inferred ${results.size.toLocaleString()} games from raw files`);
return [...results.entries()];
}
}
6 changes: 3 additions & 3 deletions src/types/files/archives/chd/chdBinCueParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ export default class ChdBinCueParser {
// Junk size and checksums because we don't know what it should be
size: 0,
crc32: checksumBitmask & ChecksumBitmask.CRC32 ? 'x'.repeat(8) : undefined,
md5: checksumBitmask & ChecksumBitmask.CRC32 ? 'x'.repeat(32) : undefined,
sha1: checksumBitmask & ChecksumBitmask.CRC32 ? 'x'.repeat(40) : undefined,
sha256: checksumBitmask & ChecksumBitmask.CRC32 ? 'x'.repeat(64) : undefined,
md5: checksumBitmask & ChecksumBitmask.MD5 ? 'x'.repeat(32) : undefined,
sha1: checksumBitmask & ChecksumBitmask.SHA1 ? 'x'.repeat(40) : undefined,
sha256: checksumBitmask & ChecksumBitmask.SHA256 ? 'x'.repeat(64) : undefined,
});

return [cueFile, ...binFiles];
Expand Down
48 changes: 21 additions & 27 deletions test/igir.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ describe('with explicit DATs', () => {
[path.join('Headerless', 'allpads.nes'), '6339abe6'],
[path.join('Headerless', 'color_test.nes'), 'c9c1b7aa'],
[`${path.join('Headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc`, '8beffd94'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'],
[path.join('One', 'CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'],
[path.join('One', 'CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'],
[path.join('One', 'CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'],
[path.join('One', 'CD-ROM', 'CD-ROM.cue'), '4ce39e73'],
[path.join('One', 'Fizzbuzz.nes'), '370517b5'],
[path.join('One', 'Foobar.lnx'), 'b22c9747'],
[`${path.join('One', 'GameCube NKit ISO.nkit.iso')}|GameCube NKit ISO.iso`, '5bc2ce5b'],
Expand Down Expand Up @@ -218,10 +218,10 @@ describe('with explicit DATs', () => {
});

expect(result.outputFilesAndCrcs).toEqual([
['CD-ROM.chd|CD-ROM (Track 1).bin', '49ca35fb'],
['CD-ROM.chd|CD-ROM (Track 2).bin', '0316f720'],
['CD-ROM.chd|CD-ROM (Track 3).bin', 'a320af40'],
['CD-ROM.chd|CD-ROM.cue', 'xxxxxxxx'],
[path.join('CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'],
[path.join('CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'],
[path.join('CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'],
[path.join('CD-ROM', 'CD-ROM.cue'), '4ce39e73'],
// Fizzbuzz.nes is explicitly missing!
['Foobar.lnx', 'b22c9747'],
['GameCube NKit ISO.nkit.iso|GameCube NKit ISO.iso', '5bc2ce5b'],
Expand Down Expand Up @@ -273,16 +273,16 @@ describe('with explicit DATs', () => {

expect(result.outputFilesAndCrcs).toEqual([
[`${path.join('7z', 'Headered', 'diagnostic_test_cartridge.a78.7z')}|diagnostic_test_cartridge.a78`, 'f6cc9b1c'],
[`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'],
[`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'],
[`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'],
[`${path.join('chd', 'One', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'],
[path.join('bin', 'One', 'CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'],
[path.join('bin', 'One', 'CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'],
[path.join('bin', 'One', 'CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'],
[`${path.join('chd', 'One', 'GD-ROM.chd')}|track.gdi`, 'f16f621c'],
[`${path.join('chd', 'One', 'GD-ROM.chd')}|track01.bin`, '9796ed9a'],
[`${path.join('chd', 'One', 'GD-ROM.chd')}|track02.raw`, 'abc178d5'],
[`${path.join('chd', 'One', 'GD-ROM.chd')}|track03.bin`, '61a363f1'],
[`${path.join('chd', 'One', 'GD-ROM.chd')}|track04.bin`, 'fc5ff5a0'],
[path.join('cso', 'four.cso'), '00000000'], // explicitly not deleted, there were no input files with the extension "cso"
[path.join('cue', 'One', 'CD-ROM', 'CD-ROM.cue'), '4ce39e73'],
[`${path.join('gz', 'Headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc`, '8beffd94'],
[`${path.join('gz', 'Patchable', 'Best.gz')}|best.rom`, '1e3d78cf'],
[`${path.join('iso', 'One', 'GameCube NKit ISO.nkit.iso')}|GameCube NKit ISO.iso`, '5bc2ce5b'],
Expand Down Expand Up @@ -716,10 +716,10 @@ describe('with explicit DATs', () => {
[`${path.join('Headered', 'speed_test_v51.smc')} -> ${path.join('<input>', 'headered', 'speed_test_v51.smc')}`, '9adca6cc'],
[`${path.join('Headerless', 'color_test.nes')} -> ${path.join('<input>', 'headered', 'color_test.nintendoentertainmentsystem')}`, 'c9c1b7aa'],
[`${path.join('Headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc -> ${path.join('<input>', 'headerless', 'speed_test_v51.sfc.gz')}|speed_test_v51.sfc`, '8beffd94'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 1).bin -> ${path.join('<input>', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 1).bin`, '49ca35fb'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 2).bin -> ${path.join('<input>', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 2).bin`, '0316f720'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM (Track 3).bin -> ${path.join('<input>', 'chd', 'CD-ROM.chd')}|CD-ROM (Track 3).bin`, 'a320af40'],
[`${path.join('One', 'CD-ROM.chd')}|CD-ROM.cue -> ${path.join('<input>', 'chd', 'CD-ROM.chd')}|CD-ROM.cue`, 'xxxxxxxx'],
[`${path.join('One', 'CD-ROM', 'CD-ROM (Track 1).bin')} -> ${path.join('<input>', 'discs', 'CD-ROM (Track 1).bin')}`, '49ca35fb'],
[`${path.join('One', 'CD-ROM', 'CD-ROM (Track 2).bin')} -> ${path.join('<input>', 'discs', 'CD-ROM (Track 2).bin')}`, '0316f720'],
[`${path.join('One', 'CD-ROM', 'CD-ROM (Track 3).bin')} -> ${path.join('<input>', 'discs', 'CD-ROM (Track 3).bin')}`, 'a320af40'],
[`${path.join('One', 'CD-ROM', 'CD-ROM.cue')} -> ${path.join('<input>', 'discs', 'CD-ROM.cue')}`, '4ce39e73'],
[`${path.join('One', 'Fizzbuzz.nes')} -> ${path.join('<input>', 'raw', 'fizzbuzz.nes')}`, '370517b5'],
[`${path.join('One', 'Foobar.lnx')} -> ${path.join('<input>', 'foobar.lnx')}`, 'b22c9747'],
[`${path.join('One', 'GameCube NKit ISO.nkit.iso')}|GameCube NKit ISO.iso -> ${path.join('<input>', 'nkit', '5bc2ce5b.nkit.iso')}|GameCube NKit ISO.iso`, '5bc2ce5b'],
Expand Down Expand Up @@ -1009,7 +1009,10 @@ describe('with inferred DATs', () => {
const result = await runIgir({
commands: ['move', 'extract', 'test'],
input: [path.join(inputTemp, 'roms')],
inputExclude: [path.join(inputTemp, 'roms', 'nkit')],
inputExclude: [
path.join(inputTemp, 'roms', 'chd'),
path.join(inputTemp, 'roms', 'nkit'),
],
output: outputTemp,
dirGameSubdir: GameSubdirMode[GameSubdirMode.MULTIPLE].toLowerCase(),
fixExtension: FixExtension[FixExtension.AUTO].toLowerCase(),
Expand All @@ -1025,14 +1028,10 @@ describe('with inferred DATs', () => {
['before.rom', '0361b321'],
['best.rom', '1e3d78cf'],
['C01173E.rom', 'dfaebe28'],
['CD-ROM (Track 1).bin', '49ca35fb'],
['CD-ROM (Track 2).bin', '0316f720'],
['CD-ROM (Track 3).bin', 'a320af40'],
['CD-ROM.cue', '4ce39e73'],
[path.join('CD-ROM', 'CD-ROM (Track 1).bin'), '49ca35fb'],
[path.join('CD-ROM', 'CD-ROM (Track 2).bin'), '0316f720'],
[path.join('CD-ROM', 'CD-ROM (Track 3).bin'), 'a320af40'],
[path.join('CD-ROM', 'CD-ROM.cue'), '03924922'], // doesn't match the DAT CRC
[path.join('CD-ROM', 'CD-ROM.cue'), '4ce39e73'],
['color_test.nes', 'c9c1b7aa'],
['diagnostic_test_cartridge.a78', 'f6cc9b1c'],
['empty.rom', '00000000'],
Expand All @@ -1044,11 +1043,6 @@ describe('with inferred DATs', () => {
[path.join('fourfive', 'five.rom'), '3e5daf67'],
[path.join('fourfive', 'four.rom'), '1cf3ca74'],
['GD-ROM.gdi', 'f16f621c'],
[path.join('GD-ROM', 'track.gdi'), 'f16f621c'],
[path.join('GD-ROM', 'track01.bin'), '9796ed9a'],
[path.join('GD-ROM', 'track02.raw'), 'abc178d5'],
[path.join('GD-ROM', 'track03.bin'), '61a363f1'],
[path.join('GD-ROM', 'track04.bin'), 'fc5ff5a0'],
['KDULVQN.rom', 'b1c303e4'],
['LCDTestROM.lnx', '2d251538'],
['loremipsum.rom', '70856527'],
Expand Down
2 changes: 1 addition & 1 deletion test/modules/candidateCombiner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function runCombinedCandidateGenerator(
romFiles: File[],
): Promise<Map<Parent, ReleaseCandidate[]>> {
// Run DATGameInferrer, but condense all DATs down to one
const dats = new DATGameInferrer(options, new ProgressBarFake()).infer(romFiles);
const dats = await new DATGameInferrer(options, new ProgressBarFake()).infer(romFiles);
const dat = new DATCombiner(new ProgressBarFake()).combine(dats);

const indexedRomFiles = await new ROMIndexer(options, new ProgressBarFake()).index(romFiles);
Expand Down
Loading
Loading