fix: make icons + blog generators not break with eslint (presort) (#4980)

This commit is contained in:
Calum H.
2025-12-27 20:50:08 +00:00
committed by GitHub
parent 7de4e55bad
commit 3cabc3b967
6 changed files with 158 additions and 67 deletions

View File

@@ -1,3 +1,4 @@
import { compareImportSources } from '@modrinth/tooling-config/script-utils/import-sort'
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
@@ -22,15 +23,10 @@ function generateIconExports(): { imports: string; exports: string } {
throw new Error(`Icons directory not found: ${iconsDir}`) throw new Error(`Icons directory not found: ${iconsDir}`)
} }
const files = fs const files = fs.readdirSync(iconsDir).filter((file) => file.endsWith('.svg'))
.readdirSync(iconsDir)
.filter((file) => file.endsWith('.svg'))
.sort()
let imports = '' // Build icon data with import paths
let exports = '' const icons = files.map((file) => {
files.forEach((file) => {
const baseName = path.basename(file, '.svg') const baseName = path.basename(file, '.svg')
let pascalName = toPascalCase(baseName) let pascalName = toPascalCase(baseName)
@@ -42,9 +38,21 @@ function generateIconExports(): { imports: string; exports: string } {
pascalName += 'Icon' pascalName += 'Icon'
} }
const privateName = `_${pascalName}` return {
importPath: `./icons/${file}?component`,
pascalName,
privateName: `_${pascalName}`,
}
})
imports += `import ${privateName} from './icons/${file}?component'\n` // Sort by import path using simple-import-sort's algorithm
icons.sort((a, b) => compareImportSources(a.importPath, b.importPath))
let imports = ''
let exports = ''
icons.forEach(({ importPath, pascalName, privateName }) => {
imports += `import ${privateName} from '${importPath}'\n`
exports += `export const ${pascalName} = ${privateName}\n` exports += `export const ${pascalName} = ${privateName}\n`
}) })

View File

@@ -232,26 +232,26 @@ export const AlignLeftIcon = _AlignLeftIcon
export const ArchiveIcon = _ArchiveIcon export const ArchiveIcon = _ArchiveIcon
export const ArrowBigRightDashIcon = _ArrowBigRightDashIcon export const ArrowBigRightDashIcon = _ArrowBigRightDashIcon
export const ArrowBigUpDashIcon = _ArrowBigUpDashIcon export const ArrowBigUpDashIcon = _ArrowBigUpDashIcon
export const ArrowDownLeftIcon = _ArrowDownLeftIcon
export const ArrowDownIcon = _ArrowDownIcon export const ArrowDownIcon = _ArrowDownIcon
export const ArrowDownLeftIcon = _ArrowDownLeftIcon
export const ArrowLeftRightIcon = _ArrowLeftRightIcon export const ArrowLeftRightIcon = _ArrowLeftRightIcon
export const ArrowUpRightIcon = _ArrowUpRightIcon
export const ArrowUpIcon = _ArrowUpIcon export const ArrowUpIcon = _ArrowUpIcon
export const ArrowUpRightIcon = _ArrowUpRightIcon
export const AsteriskIcon = _AsteriskIcon export const AsteriskIcon = _AsteriskIcon
export const BadgeCheckIcon = _BadgeCheckIcon export const BadgeCheckIcon = _BadgeCheckIcon
export const BadgeDollarSignIcon = _BadgeDollarSignIcon export const BadgeDollarSignIcon = _BadgeDollarSignIcon
export const BanIcon = _BanIcon export const BanIcon = _BanIcon
export const BellRingIcon = _BellRingIcon
export const BellIcon = _BellIcon export const BellIcon = _BellIcon
export const BellRingIcon = _BellRingIcon
export const BlocksIcon = _BlocksIcon export const BlocksIcon = _BlocksIcon
export const BoldIcon = _BoldIcon export const BoldIcon = _BoldIcon
export const BookIcon = _BookIcon
export const BookOpenIcon = _BookOpenIcon export const BookOpenIcon = _BookOpenIcon
export const BookTextIcon = _BookTextIcon export const BookTextIcon = _BookTextIcon
export const BookIcon = _BookIcon
export const BookmarkIcon = _BookmarkIcon export const BookmarkIcon = _BookmarkIcon
export const BotIcon = _BotIcon export const BotIcon = _BotIcon
export const BoxImportIcon = _BoxImportIcon
export const BoxIcon = _BoxIcon export const BoxIcon = _BoxIcon
export const BoxImportIcon = _BoxImportIcon
export const BracesIcon = _BracesIcon export const BracesIcon = _BracesIcon
export const BrushCleaningIcon = _BrushCleaningIcon export const BrushCleaningIcon = _BrushCleaningIcon
export const BugIcon = _BugIcon export const BugIcon = _BugIcon
@@ -259,9 +259,9 @@ export const CalendarIcon = _CalendarIcon
export const CardIcon = _CardIcon export const CardIcon = _CardIcon
export const ChangeSkinIcon = _ChangeSkinIcon export const ChangeSkinIcon = _ChangeSkinIcon
export const ChartIcon = _ChartIcon export const ChartIcon = _ChartIcon
export const CheckIcon = _CheckIcon
export const CheckCheckIcon = _CheckCheckIcon export const CheckCheckIcon = _CheckCheckIcon
export const CheckCircleIcon = _CheckCircleIcon export const CheckCircleIcon = _CheckCircleIcon
export const CheckIcon = _CheckIcon
export const ChevronDownIcon = _ChevronDownIcon export const ChevronDownIcon = _ChevronDownIcon
export const ChevronLeftIcon = _ChevronLeftIcon export const ChevronLeftIcon = _ChevronLeftIcon
export const ChevronRightIcon = _ChevronRightIcon export const ChevronRightIcon = _ChevronRightIcon
@@ -293,20 +293,20 @@ export const EditIcon = _EditIcon
export const EllipsisVerticalIcon = _EllipsisVerticalIcon export const EllipsisVerticalIcon = _EllipsisVerticalIcon
export const ExpandIcon = _ExpandIcon export const ExpandIcon = _ExpandIcon
export const ExternalIcon = _ExternalIcon export const ExternalIcon = _ExternalIcon
export const EyeOffIcon = _EyeOffIcon
export const EyeIcon = _EyeIcon export const EyeIcon = _EyeIcon
export const EyeOffIcon = _EyeOffIcon
export const FileIcon = _FileIcon
export const FileArchiveIcon = _FileArchiveIcon export const FileArchiveIcon = _FileArchiveIcon
export const FileCodeIcon = _FileCodeIcon export const FileCodeIcon = _FileCodeIcon
export const FileImageIcon = _FileImageIcon export const FileImageIcon = _FileImageIcon
export const FileTextIcon = _FileTextIcon export const FileTextIcon = _FileTextIcon
export const FileIcon = _FileIcon
export const FilterXIcon = _FilterXIcon
export const FilterIcon = _FilterIcon export const FilterIcon = _FilterIcon
export const FilterXIcon = _FilterXIcon
export const FolderIcon = _FolderIcon
export const FolderArchiveIcon = _FolderArchiveIcon export const FolderArchiveIcon = _FolderArchiveIcon
export const FolderOpenIcon = _FolderOpenIcon export const FolderOpenIcon = _FolderOpenIcon
export const FolderSearchIcon = _FolderSearchIcon export const FolderSearchIcon = _FolderSearchIcon
export const FolderUpIcon = _FolderUpIcon export const FolderUpIcon = _FolderUpIcon
export const FolderIcon = _FolderIcon
export const GameIcon = _GameIcon export const GameIcon = _GameIcon
export const GapIcon = _GapIcon export const GapIcon = _GapIcon
export const GaugeIcon = _GaugeIcon export const GaugeIcon = _GaugeIcon
@@ -323,9 +323,9 @@ export const HashIcon = _HashIcon
export const Heading1Icon = _Heading1Icon export const Heading1Icon = _Heading1Icon
export const Heading2Icon = _Heading2Icon export const Heading2Icon = _Heading2Icon
export const Heading3Icon = _Heading3Icon export const Heading3Icon = _Heading3Icon
export const HeartIcon = _HeartIcon
export const HeartHandshakeIcon = _HeartHandshakeIcon export const HeartHandshakeIcon = _HeartHandshakeIcon
export const HeartMinusIcon = _HeartMinusIcon export const HeartMinusIcon = _HeartMinusIcon
export const HeartIcon = _HeartIcon
export const HistoryIcon = _HistoryIcon export const HistoryIcon = _HistoryIcon
export const HomeIcon = _HomeIcon export const HomeIcon = _HomeIcon
export const ImageIcon = _ImageIcon export const ImageIcon = _ImageIcon
@@ -342,15 +342,15 @@ export const LeftArrowIcon = _LeftArrowIcon
export const LibraryIcon = _LibraryIcon export const LibraryIcon = _LibraryIcon
export const LightBulbIcon = _LightBulbIcon export const LightBulbIcon = _LightBulbIcon
export const LinkIcon = _LinkIcon export const LinkIcon = _LinkIcon
export const ListIcon = _ListIcon
export const ListBulletedIcon = _ListBulletedIcon export const ListBulletedIcon = _ListBulletedIcon
export const ListEndIcon = _ListEndIcon export const ListEndIcon = _ListEndIcon
export const ListFilterIcon = _ListFilterIcon export const ListFilterIcon = _ListFilterIcon
export const ListOrderedIcon = _ListOrderedIcon export const ListOrderedIcon = _ListOrderedIcon
export const ListIcon = _ListIcon
export const LoaderCircleIcon = _LoaderCircleIcon
export const LoaderIcon = _LoaderIcon export const LoaderIcon = _LoaderIcon
export const LockOpenIcon = _LockOpenIcon export const LoaderCircleIcon = _LoaderCircleIcon
export const LockIcon = _LockIcon export const LockIcon = _LockIcon
export const LockOpenIcon = _LockOpenIcon
export const LogInIcon = _LogInIcon export const LogInIcon = _LogInIcon
export const LogOutIcon = _LogOutIcon export const LogOutIcon = _LogOutIcon
export const MailIcon = _MailIcon export const MailIcon = _MailIcon
@@ -361,8 +361,8 @@ export const MessageIcon = _MessageIcon
export const MicrophoneIcon = _MicrophoneIcon export const MicrophoneIcon = _MicrophoneIcon
export const MinimizeIcon = _MinimizeIcon export const MinimizeIcon = _MinimizeIcon
export const MinusIcon = _MinusIcon export const MinusIcon = _MinusIcon
export const MonitorSmartphoneIcon = _MonitorSmartphoneIcon
export const MonitorIcon = _MonitorIcon export const MonitorIcon = _MonitorIcon
export const MonitorSmartphoneIcon = _MonitorSmartphoneIcon
export const MoonIcon = _MoonIcon export const MoonIcon = _MoonIcon
export const MoreHorizontalIcon = _MoreHorizontalIcon export const MoreHorizontalIcon = _MoreHorizontalIcon
export const MoreVerticalIcon = _MoreVerticalIcon export const MoreVerticalIcon = _MoreVerticalIcon
@@ -371,16 +371,16 @@ export const NoSignalIcon = _NoSignalIcon
export const NotepadTextIcon = _NotepadTextIcon export const NotepadTextIcon = _NotepadTextIcon
export const OmorphiaIcon = _OmorphiaIcon export const OmorphiaIcon = _OmorphiaIcon
export const OrganizationIcon = _OrganizationIcon export const OrganizationIcon = _OrganizationIcon
export const PackageIcon = _PackageIcon
export const PackageClosedIcon = _PackageClosedIcon export const PackageClosedIcon = _PackageClosedIcon
export const PackageOpenIcon = _PackageOpenIcon export const PackageOpenIcon = _PackageOpenIcon
export const PackageIcon = _PackageIcon
export const PaintbrushIcon = _PaintbrushIcon export const PaintbrushIcon = _PaintbrushIcon
export const PickaxeIcon = _PickaxeIcon export const PickaxeIcon = _PickaxeIcon
export const PlayIcon = _PlayIcon export const PlayIcon = _PlayIcon
export const PlugIcon = _PlugIcon export const PlugIcon = _PlugIcon
export const PlusIcon = _PlusIcon export const PlusIcon = _PlusIcon
export const RadioButtonCheckedIcon = _RadioButtonCheckedIcon
export const RadioButtonIcon = _RadioButtonIcon export const RadioButtonIcon = _RadioButtonIcon
export const RadioButtonCheckedIcon = _RadioButtonCheckedIcon
export const ReceiptTextIcon = _ReceiptTextIcon export const ReceiptTextIcon = _ReceiptTextIcon
export const RedoIcon = _RedoIcon export const RedoIcon = _RedoIcon
export const RefreshCwIcon = _RefreshCwIcon export const RefreshCwIcon = _RefreshCwIcon
@@ -397,13 +397,13 @@ export const ScaleIcon = _ScaleIcon
export const ScanEyeIcon = _ScanEyeIcon export const ScanEyeIcon = _ScanEyeIcon
export const SearchIcon = _SearchIcon export const SearchIcon = _SearchIcon
export const SendIcon = _SendIcon export const SendIcon = _SendIcon
export const ServerPlusIcon = _ServerPlusIcon
export const ServerIcon = _ServerIcon export const ServerIcon = _ServerIcon
export const ServerPlusIcon = _ServerPlusIcon
export const SettingsIcon = _SettingsIcon export const SettingsIcon = _SettingsIcon
export const ShareIcon = _ShareIcon export const ShareIcon = _ShareIcon
export const ShieldIcon = _ShieldIcon
export const ShieldAlertIcon = _ShieldAlertIcon export const ShieldAlertIcon = _ShieldAlertIcon
export const ShieldCheckIcon = _ShieldCheckIcon export const ShieldCheckIcon = _ShieldCheckIcon
export const ShieldIcon = _ShieldIcon
export const SignalIcon = _SignalIcon export const SignalIcon = _SignalIcon
export const SkullIcon = _SkullIcon export const SkullIcon = _SkullIcon
export const SlashIcon = _SlashIcon export const SlashIcon = _SlashIcon
@@ -430,25 +430,25 @@ export const TrashIcon = _TrashIcon
export const TriangleAlertIcon = _TriangleAlertIcon export const TriangleAlertIcon = _TriangleAlertIcon
export const UnderlineIcon = _UnderlineIcon export const UnderlineIcon = _UnderlineIcon
export const UndoIcon = _UndoIcon export const UndoIcon = _UndoIcon
export const UnknownDonationIcon = _UnknownDonationIcon
export const UnknownIcon = _UnknownIcon export const UnknownIcon = _UnknownIcon
export const UnknownDonationIcon = _UnknownDonationIcon
export const UnlinkIcon = _UnlinkIcon export const UnlinkIcon = _UnlinkIcon
export const UnplugIcon = _UnplugIcon export const UnplugIcon = _UnplugIcon
export const UpdatedIcon = _UpdatedIcon export const UpdatedIcon = _UpdatedIcon
export const UploadIcon = _UploadIcon export const UploadIcon = _UploadIcon
export const UserIcon = _UserIcon
export const UserCogIcon = _UserCogIcon export const UserCogIcon = _UserCogIcon
export const UserPlusIcon = _UserPlusIcon export const UserPlusIcon = _UserPlusIcon
export const UserRoundIcon = _UserRoundIcon export const UserRoundIcon = _UserRoundIcon
export const UserSearchIcon = _UserSearchIcon export const UserSearchIcon = _UserSearchIcon
export const UserXIcon = _UserXIcon export const UserXIcon = _UserXIcon
export const UserIcon = _UserIcon
export const UsersIcon = _UsersIcon export const UsersIcon = _UsersIcon
export const VersionIcon = _VersionIcon export const VersionIcon = _VersionIcon
export const WikiIcon = _WikiIcon export const WikiIcon = _WikiIcon
export const WindowIcon = _WindowIcon export const WindowIcon = _WindowIcon
export const WorldIcon = _WorldIcon export const WorldIcon = _WorldIcon
export const WrenchIcon = _WrenchIcon export const WrenchIcon = _WrenchIcon
export const XCircleIcon = _XCircleIcon
export const XIcon = _XIcon export const XIcon = _XIcon
export const XCircleIcon = _XCircleIcon
export const ZoomInIcon = _ZoomInIcon export const ZoomInIcon = _ZoomInIcon
export const ZoomOutIcon = _ZoomOutIcon export const ZoomOutIcon = _ZoomOutIcon

View File

@@ -1,3 +1,4 @@
import { compareImportSources } from '@modrinth/tooling-config/script-utils/import-sort'
import { md } from '@modrinth/utils' import { md } from '@modrinth/utils'
import { promises as fs } from 'fs' import { promises as fs } from 'fs'
import { glob } from 'glob' import { glob } from 'glob'
@@ -165,12 +166,20 @@ export const article = {
console.log(`📂 Compiled ${files.length} articles.`) console.log(`📂 Compiled ${files.length} articles.`)
// Sort imports using simple-import-sort's algorithm to avoid ESLint reformatting
const articleData = articlesArray.map((varName, i) => ({
varName,
importPath: `./${varName}`,
exportLine: articleExports[i],
}))
articleData.sort((a, b) => compareImportSources(a.importPath, b.importPath))
const rootExport = ` const rootExport = `
// AUTO-GENERATED FILE - DO NOT EDIT // AUTO-GENERATED FILE - DO NOT EDIT
${articleExports.join('\n')} ${articleData.map((a) => a.exportLine).join('\n')}
export const articles = [ export const articles = [
${articlesArray.join(',\n ')} ${articleData.map((a) => a.varName).join(',\n ')}
]; ];
`.trimStart() `.trimStart()

View File

@@ -35,38 +35,38 @@ import { article as whats_modrinth } from "./whats_modrinth";
import { article as windows_borderless_malware_disclosure } from "./windows_borderless_malware_disclosure"; import { article as windows_borderless_malware_disclosure } from "./windows_borderless_malware_disclosure";
export const articles = [ export const articles = [
windows_borderless_malware_disclosure, a_new_chapter_for_modrinth_servers,
whats_modrinth, accelerating_development,
two_years_of_modrinth, becoming_sustainable,
two_years_of_modrinth_history, capital_return,
streamlined_version_creation, carbon_ads,
creator_monetization,
creator_update,
creator_updates_july_2025,
creator_withdrawals_overhaul,
design_refresh,
download_adjustment,
free_server_medal,
knossos_v2_1_0,
licensing_guide,
modpack_changes,
modpacks_alpha,
modrinth_app_beta,
modrinth_beta,
modrinth_servers_asia,
modrinth_servers_beta,
new_environments,
new_site_beta,
plugins_resource_packs,
pride_campaign_2025,
redesign,
russian_censorship,
skins_now_in_modrinth_app,
standing_by_our_values, standing_by_our_values,
standing_by_our_values_russian, standing_by_our_values_russian,
skins_now_in_modrinth_app, streamlined_version_creation,
russian_censorship, two_years_of_modrinth,
redesign, two_years_of_modrinth_history,
pride_campaign_2025, whats_modrinth,
plugins_resource_packs, windows_borderless_malware_disclosure
new_site_beta,
new_environments,
modrinth_servers_beta,
modrinth_servers_asia,
modrinth_beta,
modrinth_app_beta,
modpacks_alpha,
modpack_changes,
licensing_guide,
knossos_v2_1_0,
free_server_medal,
download_adjustment,
design_refresh,
creator_withdrawals_overhaul,
creator_updates_july_2025,
creator_update,
creator_monetization,
carbon_ads,
capital_return,
becoming_sustainable,
accelerating_development,
a_new_chapter_for_modrinth_servers
]; ];

View File

@@ -15,7 +15,8 @@
"./frontend.prettier.config.cjs": "./frontend.prettier.config.cjs", "./frontend.prettier.config.cjs": "./frontend.prettier.config.cjs",
"./app-lib.prettier.config.cjs": "./app-lib.prettier.config.cjs", "./app-lib.prettier.config.cjs": "./app-lib.prettier.config.cjs",
"./labrinth.prettier.config.cjs": "./labrinth.prettier.config.cjs", "./labrinth.prettier.config.cjs": "./labrinth.prettier.config.cjs",
"./tailwind/*": "./tailwind/*" "./tailwind/*": "./tailwind/*",
"./script-utils/*": "./script-utils/*"
}, },
"files": [ "files": [
"eslint/", "eslint/",

View File

@@ -0,0 +1,73 @@
/**
* Import sorting utility that matches eslint-plugin-simple-import-sort's algorithm.
* Use this to pre-sort generated imports so ESLint doesn't need to reformat them - which can cause it to have different diffs
*/
const collator = new Intl.Collator('en', {
sensitivity: 'base',
numeric: true,
})
function compare(a: string, b: string): number {
return collator.compare(a, b) || (a < b ? -1 : a > b ? 1 : 0)
}
/**
* Transforms an import source path the same way simple-import-sort does internally.
* This swaps certain characters to achieve the desired sort order:
* - `.` and `/` sort before other punctuation
* - `..` sorts like `../,` to come after `../../` but before `../a`
*/
function transformSource(source: string): string {
return source
.replace(/^[./]*\.$/, '$&/')
.replace(/^[./]*\/$/, '$&,')
.replace(/[./_-]/g, (char) => {
switch (char) {
case '.':
return '_'
case '/':
return '-'
case '_':
return '.'
case '-':
return '/'
default:
return char
}
})
}
/**
* Compares two import source paths using the same algorithm as simple-import-sort.
* Use this as a comparator function for Array.sort().
*
* @example
* const imports = ['./foo', './bar', './baz'];
* imports.sort(compareImportSources);
*/
export function compareImportSources(a: string, b: string): number {
return compare(transformSource(a), transformSource(b))
}
/**
* Sorts an array of import source paths using the same algorithm as simple-import-sort.
*
* @example
* const sorted = sortImportSources(['./z', './a', './m']);
* // Returns: ['./a', './m', './z']
*/
export function sortImportSources<T extends string>(sources: T[]): T[] {
return sources.slice().sort(compareImportSources)
}
/**
* Sorts an array of items by their import source path.
*
* @example
* const items = [{ path: './z' }, { path: './a' }];
* const sorted = sortByImportSource(items, item => item.path);
*/
export function sortByImportSource<T>(items: T[], getSource: (item: T) => string): T[] {
return items.slice().sort((a, b) => compareImportSources(getSource(a), getSource(b)))
}