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

Fix: sort icons to group variants #476

Merged
merged 3 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 16 additions & 17 deletions src/config-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,15 @@ const MAX_ICON_SIZE = 10_000_000
export async function readConfig(configPath) {
/** @type {Error[]} */
const warnings = []
/** @type {yauzl.ZipFile} */
let iconsZip

const presetsZip = await yauzl.open(configPath)
if (presetsZip.entryCount > MAX_ENTRIES) {
const zip = await yauzl.open(configPath)
if (zip.entryCount > MAX_ENTRIES) {
// MAX_ENTRIES in MAC can be inacurrate
throw new Error(`Zip file contains too many entries. Max is ${MAX_ENTRIES}`)
}
const entries = await zip.readEntries(MAX_ENTRIES)
/** @type {undefined | Entry} */
let presetsEntry
for await (const entry of presetsZip) {
if (entry.filename === 'presets.json') {
presetsEntry = entry
break
}
}
let presetsEntry = entries.find((entry) => entry.filename === 'presets.json')
if (!presetsEntry) {
throw new Error('Zip file does not contain presets.json')
}
Expand All @@ -54,8 +47,7 @@ export async function readConfig(configPath) {
},

async close() {
presetsZip.close()
iconsZip.close()
zip.close()
},

/**
Expand All @@ -65,10 +57,14 @@ export async function readConfig(configPath) {
/** @type {IconData | undefined} */
let icon

iconsZip = await yauzl.open(configPath)
const entries = await iconsZip.readEntries(MAX_ENTRIES)
for (const entry of entries) {
if (!entry.filename.match(/^icons\/([^/]+)$/)) continue
// we sort the icons by filename so we can group variants together
const iconEntries = entries
.filter((entry) => entry.filename.match(/^icons\/([^/]+)$/))
tomasciccola marked this conversation as resolved.
Show resolved Hide resolved
.sort((icon, nextIcon) =>
icon.filename.localeCompare(nextIcon.filename)
)

for (const entry of iconEntries) {
if (entry.uncompressedSize > MAX_ICON_SIZE) {
warnings.push(
new Error(
Expand All @@ -81,14 +77,17 @@ export async function readConfig(configPath) {
const iconFilename = entry.filename.replace(/^icons\//, '')
try {
const { name, variant } = parseIcon(iconFilename, buf)
// new icon (first pass)
if (!icon) {
icon = {
name,
variants: [variant],
}
// icon already exists, push new variant
} else if (icon.name === name) {
icon.variants.push(variant)
} else {
// icon has change
yield icon
icon = {
name,
Expand Down
13 changes: 6 additions & 7 deletions tests/config-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,17 @@ test('config import - icons', async (t) => {
)

config = await readConfig('./tests/fixtures/config/validIcons.zip')
t.plan(15) // 2 icon assertions + (3+9) variant assertions + 1 no warnings
for await (const icon of config.icons()) {
t.is(icon.name, 'plant', 'icon name is `plant`')
t.is(
icon.variants.length,
9,
'9 variants of icons (dot product of density and size)'
)
if (icon.name === 'plant') {
t.is(icon.variants.length, 3, '3 variants of plant icons')
} else if (icon.name === 'tree') {
t.is(icon.variants.length, 9, '9 - all - variants of tree icons')
}
for (let variant of icon.variants) {
t.is(variant.mimeType, 'image/png', 'variant is a png')
}
}

t.is(config.warnings.length, 0, 'no warnings on the file')
})

Expand Down
Binary file modified tests/fixtures/config/validIcons.zip
Binary file not shown.
Loading