Skip to content

Commit

Permalink
fix(manifest): filter out duplicate names (#24)
Browse files Browse the repository at this point in the history
* fix(manifest): filter out duplicate names

* fix tests
  • Loading branch information
Zyie authored May 7, 2024
1 parent 255bf19 commit ae68e92
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 82 deletions.
63 changes: 62 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 33 additions & 6 deletions packages/manifest/src/pixiManifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ import {
stripTags
} from '@play-co/assetpack-core';

export interface PixiManifest
export interface PixiBundle
{
name: string;
assets: PixiManifestEntry[];
}

export interface PixiManifest
{
bundles: PixiBundle[];
}

export interface PixiManifestEntry
{
alias: string | string[];
Expand Down Expand Up @@ -79,29 +84,51 @@ export function pixiManifest(_options: PixiManifestOptions = {}): AssetPipe<Pixi
const newFileName = path.dirname(options.output) === '.'
? path.joinSafe(pipeSystem.outputPath, options.output) : options.output;

const defaultBundle = {
const defaultBundle: PixiBundle = {
name: 'default',
assets: []
};

const manifest = {
const manifest: PixiManifest = {
bundles: [defaultBundle]
};

collectAssets(asset, options, pipeSystem.outputPath, pipeSystem.entryPath, manifest.bundles, defaultBundle);

filterUniqueNames(manifest);
await fs.writeJSON(newFileName, manifest, { spaces: 2 });
}
};
}

function filterUniqueNames(manifest: PixiManifest)
{
const nameMap = new Map<PixiManifestEntry, string[]>();

manifest.bundles.forEach((bundle) =>
bundle.assets.forEach((asset) => nameMap.set(asset, asset.alias as string[])));

const arrays = Array.from(nameMap.values());
const sets = arrays.map((arr) => new Set(arr));
const uniqueArrays = arrays.map((arr, i) => arr.filter((x) => sets.every((set, j) => j === i || !set.has(x))));

manifest.bundles.forEach((bundle) =>
{
bundle.assets.forEach((asset) =>
{
const names = nameMap.get(asset) as string[];

asset.alias = uniqueArrays.find((arr) => arr.every((x) => names.includes(x))) as string[];
});
});
}

function collectAssets(
asset: Asset,
options: PixiManifestOptions,
outputPath = '',
entryPath = '',
bundles: PixiManifest[],
bundle: PixiManifest,
bundles: PixiBundle[],
bundle: PixiBundle,
)
{
if (asset.skip) return;
Expand Down
28 changes: 6 additions & 22 deletions packages/manifest/test/Manifest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,7 @@ describe('Manifest', () =>
{
alias: [
'folder/json.json',
'folder/json',
'json.json',
'json'
],
src: [
'folder/json.json'
Expand All @@ -368,9 +366,7 @@ describe('Manifest', () =>
{
alias: [
'folder/json.json5',
'folder/json',
'json.json5',
'json'
],
src: [
'folder/json.json5'
Expand All @@ -394,8 +390,6 @@ describe('Manifest', () =>
alias: [
'folder2/1.mp3',
'folder2/1',
'1.mp3',
'1'
],
src: [
'folder2/1.ogg',
Expand All @@ -406,8 +400,6 @@ describe('Manifest', () =>
alias: [
'folder2/folder3/1.mp3',
'folder2/folder3/1',
'1.mp3',
'1'
],
src: [
'folder2/folder3/1.ogg',
Expand All @@ -417,9 +409,7 @@ describe('Manifest', () =>
{
alias: [
'spine/dragon.json',
'spine/dragon',
'dragon.json',
'dragon'
],
src: [
'spine/dragon.json'
Expand All @@ -428,9 +418,7 @@ describe('Manifest', () =>
{
alias: [
'spine/dragon.atlas',
'spine/dragon',
'dragon.atlas',
'dragon'
],
src: [
'spine/[email protected]',
Expand Down Expand Up @@ -643,11 +631,11 @@ describe('Manifest', () =>
],
},
{
alias: ['folder2/1.mp3', '1.mp3'],
alias: ['folder2/1.mp3'],
src: ['folder2/1.ogg', 'folder2/1.mp3'],
},
{
alias: ['folder2/folder3/1.mp3', '1.mp3'],
alias: ['folder2/folder3/1.mp3'],
src: ['folder2/folder3/1.ogg', 'folder2/folder3/1.mp3'],
},
{
Expand Down Expand Up @@ -773,17 +761,15 @@ describe('Manifest', () =>
assets: [
{
alias: [
'folder/json.json',
'folder/json'
'folder/json.json'
],
src: [
'folder/json.json'
]
},
{
alias: [
'folder/json.json5',
'folder/json'
'folder/json.json5'
],
src: [
'folder/json.json5'
Expand Down Expand Up @@ -823,17 +809,15 @@ describe('Manifest', () =>
},
{
alias: [
'spine/dragon.json',
'spine/dragon'
'spine/dragon.json'
],
src: [
'spine/dragon.json'
]
},
{
alias: [
'spine/dragon.atlas',
'spine/dragon'
'spine/dragon.atlas'
],
src: [
'spine/[email protected]',
Expand Down
4 changes: 3 additions & 1 deletion packages/spine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
"devDependencies": {
"@play-co/assetpack-core": "1.4.3",
"@play-co/assetpack-plugin-image": "1.4.3",
"@play-co/assetpack-plugin-manifest": "1.4.3"
"@play-co/assetpack-plugin-manifest": "1.4.3",
"glob": "^8.0.3",
"glob-promise": "^6.0.0"
},
"peerDependencies": {
"@play-co/assetpack-core": ">=0.0.0",
Expand Down
82 changes: 54 additions & 28 deletions packages/spine/test/spineAtlasAll.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { existsSync, readFileSync } from 'fs-extra';
import { readFileSync } from 'fs-extra';
import glob from 'glob-promise';
import { assetPath, createFolder, getInputDir, getOutputDir } from '../../../shared/test';
import { spineAtlasCacheBuster } from '../src/spineAtlasCacheBuster';
import { spineAtlasCompress } from '../src/spineAtlasCompress';
Expand Down Expand Up @@ -128,37 +129,62 @@ describe('Spine Atlas All', () =>
});

await assetpack.run();
const globPath = `${outputDir}/*.{atlas,png,webp}`;
const files = await glob(globPath);

[
{
atlas: `[email protected]`,
png1: `[email protected]`,
png2: `[email protected]`
},
{
atlas: `dragon-spj8.webp.atlas`,
png1: `dragon-rSwKOg.webp`,
png2: `dragon2-ws3uhw.webp`
},
{
atlas: `[email protected]`,
png1: `[email protected]`,
png2: `[email protected]`
},
{
atlas: `dragon-O471eg.png.atlas`,
png1: `dragon-vezElA.png`,
png2: `dragon2-3UnJNw.png`
}
].forEach(({ atlas, png1, png2 }) =>
// need two sets of files
expect(files.length).toBe(12);
expect(files.filter((file) => file.endsWith('.atlas')).length).toBe(4);
expect(files.filter((file) => file.endsWith('.png')).length).toBe(4);
expect(files.filter((file) => file.endsWith('.webp')).length).toBe(4);
expect(files.filter((file) => file.endsWith('.jpg')).length).toBe(0);

const atlasFiles = files.filter((file) => file.endsWith('.atlas'));
const pngFiles = files.filter((file) => file.endsWith('.png'));
const webpFiles = files.filter((file) => file.endsWith('.webp'));

// check that the files are correct
atlasFiles.forEach((atlasFile) =>
{
const rawAtlas = readFileSync(`${outputDir}/${atlas}`);
const rawAtlas = readFileSync(atlasFile);
const isHalfSize = atlasFile.includes('@0.5x');
const isWebp = atlasFile.includes('.webp');
const isPng = atlasFile.includes('.png');

const checkFiles = (fileList: string[], isHalfSize: boolean, isFileType: boolean) =>
{
fileList.forEach((file) =>
{
// remove the outputDir
file = file.replace(`${outputDir}/`, '');
const isFileHalfSize = file.includes('@0.5x');
const isFileFileType = file.includes(isWebp ? '.webp' : '.png');
const shouldExist = isHalfSize === isFileHalfSize && isFileType === isFileFileType;

expect(rawAtlas.includes(png1)).toBeTruthy();
expect(rawAtlas.includes(png2)).toBeTruthy();
expect(rawAtlas.includes(file)).toBe(shouldExist);
});
};

expect(existsSync(`${outputDir}/${png1}`)).toBeTruthy();
expect(existsSync(`${outputDir}/${png2}`)).toBeTruthy();
if (isHalfSize)
{
if (isWebp)
{
checkFiles(webpFiles, true, true);
}
else if (isPng)
{
checkFiles(pngFiles, true, true);
}
}
else
if (isWebp)
{
checkFiles(webpFiles, false, true);
}
else if (isPng)
{
checkFiles(pngFiles, false, true);
}
});
});
});
Loading

0 comments on commit ae68e92

Please sign in to comment.