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 path from 'path'
@@ -22,15 +23,10 @@ function generateIconExports(): { imports: string; exports: string } {
throw new Error(`Icons directory not found: ${iconsDir}`)
}
const files = fs
.readdirSync(iconsDir)
.filter((file) => file.endsWith('.svg'))
.sort()
const files = fs.readdirSync(iconsDir).filter((file) => file.endsWith('.svg'))
let imports = ''
let exports = ''
files.forEach((file) => {
// Build icon data with import paths
const icons = files.map((file) => {
const baseName = path.basename(file, '.svg')
let pascalName = toPascalCase(baseName)
@@ -42,9 +38,21 @@ function generateIconExports(): { imports: string; exports: string } {
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`
})

View File

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

View File

@@ -15,7 +15,8 @@
"./frontend.prettier.config.cjs": "./frontend.prettier.config.cjs",
"./app-lib.prettier.config.cjs": "./app-lib.prettier.config.cjs",
"./labrinth.prettier.config.cjs": "./labrinth.prettier.config.cjs",
"./tailwind/*": "./tailwind/*"
"./tailwind/*": "./tailwind/*",
"./script-utils/*": "./script-utils/*"
},
"files": [
"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)))
}