From 1ffc73325a07bf9f5ac6d90eb5be0589c5bf15fd Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Sat, 24 May 2025 17:08:08 +0000 Subject: [PATCH] Bug 1881701 - Switch the main ESLint configuration to use the flat configuration. r=frontend-codestyle-reviewers,Gijs Differential Revision: https://phabricator.services.mozilla.com/D249952 --- .prettierignore | 3 +- eslint-file-globals.config.mjs | 558 +++++++++++++++++++++++++++++ eslint-rollouts.config.mjs | 75 ++-- eslint-subdirs.config.mjs | 340 ++++++++++++++++++ eslint.config.mjs | 626 +++++++++++++++++++-------------- moz.build | 3 + tools/lint/eslint/__init__.py | 2 - tools/lint/rejected-words.yml | 3 +- 8 files changed, 1318 insertions(+), 292 deletions(-) create mode 100644 eslint-file-globals.config.mjs create mode 100644 eslint-subdirs.config.mjs diff --git a/.prettierignore b/.prettierignore index 96dbc4e03eb0..84e246aed8a8 100644 --- a/.prettierignore +++ b/.prettierignore @@ -23,7 +23,8 @@ toolkit/components/extensions/types/ext-tabs-base.d.ts !browser/components/preferences/tests/chrome/*.html # This should be re-enabled in bug 1827456. -js/src/builtin +js/src/builtin/**/*.* +!js/src/builtin/.eslintrc.mjs # Don't format README files. README diff --git a/eslint-file-globals.config.mjs b/eslint-file-globals.config.mjs new file mode 100644 index 000000000000..31110905bc3c --- /dev/null +++ b/eslint-file-globals.config.mjs @@ -0,0 +1,558 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * This file defines the globals used for various files across the tree. + * + * Generally, most globals should be automatically set up. If you think you are + * missing some globals, and they are in one of the defined sections, you can + * generally add the file here. + * + * However, please use the defined patterns as follows: + * + * - ES modules should always use `.mjs` extensions. + * - System modules (accessed from privileged scope) should use `.sys.mjs`. + * - Workers should use `.worker.js` or `.worker.mjs`. + * + * Please also note the patters for tests - see the top of `.eslintrc-test-paths.js`. + * + */ + +import globals from "globals"; +import mozilla from "eslint-plugin-mozilla"; + +export default [ + { + name: "globals-amd", + files: ["devtools/shared/worker/helper.js"], + languageOptions: { globals: globals.amd }, + }, + { + name: "globals-browser", + files: [ + "devtools/client/aboutdebugging/test/browser/head.js", + "devtools/client/aboutdebugging/test/browser/resources/test-temporary-extension/script.js", + "devtools/client/application/test/browser/head.js", + "devtools/client/framework/toolbox-init.js", + "devtools/client/memory/components/tree-map/canvas-utils.js", + "devtools/client/responsive/actions/screenshot.js", + "devtools/client/responsive/actions/viewports.js", + "devtools/client/responsive/components/App.js", + "devtools/client/responsive/components/Device.js", + "devtools/client/responsive/components/DeviceAdder.js", + "devtools/client/responsive/components/DeviceForm.js", + "devtools/client/responsive/components/DeviceList.js", + "devtools/client/responsive/components/DeviceModal.js", + "devtools/client/responsive/components/DevicePixelRatioMenu.js", + "devtools/client/responsive/index.js", + "devtools/client/shared/components/HSplitBox.js", + "devtools/client/shared/components/menu/MenuButton.js", + "devtools/client/shared/components/menu/MenuItem.js", + "devtools/client/shared/components/menu/MenuList.js", + "devtools/client/shared/components/tabs/TabBar.js", + "devtools/client/shared/components/VirtualizedTree.js", + "devtools/client/shared/stylesheet-utils.js", + "devtools/client/shared/theme-switching.js", + "devtools/client/shared/vendor/fluent-react.js", + "devtools/startup/tests/browser/browser_command_line_urls.js", + "devtools/startup/tests/browser/browser_shim_disable_devtools.js", + ], + languageOptions: { globals: globals.browser }, + }, + { + name: "globals-commonjs", + files: [ + "browser/components/uitour/UITour-lib.js", + "mobile/shared/modules/dbg-browser-actors.js", + "toolkit/components/promiseworker/worker/PromiseWorker.template.worker.js", + "toolkit/components/workerloader/tests/moduleA-depends.js", + "toolkit/components/workerloader/tests/moduleB-dependency.js", + "toolkit/components/workerloader/tests/moduleC-circular.js", + "toolkit/components/workerloader/tests/moduleD-circular.js", + "toolkit/components/workerloader/tests/moduleE-throws-during-require.js", + "toolkit/components/workerloader/tests/moduleG-throws-later.js", + "toolkit/components/workerloader/tests/moduleH-module-dot-exports.js", + "toolkit/components/workerloader/tests/moduleI-depends.js", + "toolkit/components/workerloader/tests/moduleJ-dependency.js", + ], + languageOptions: { globals: globals.commonjs }, + }, + { + name: "globals-jest", + files: ["tools/ts/test/dom.test.js", "tools/ts/test/xpcom.test.js"], + languageOptions: { globals: globals.jest }, + }, + { + name: "globals-browser-window", + files: [ + "browser/actors/ScreenshotsComponentChild.sys.mjs", + "browser/base/content/browser-a11yUtils.js", + "browser/base/content/browser-addons.js", + "browser/base/content/browser-commands.js", + "browser/base/content/browser-context.js", + "browser/base/content/browser-customization.js", + "browser/base/content/browser-fullScreenAndPointerLock.js", + "browser/base/content/browser-gestureSupport.js", + "browser/base/content/browser-graphics-utils.js", + "browser/base/content/browser-main.js", + "browser/base/content/browser-menubar.js", + "browser/base/content/browser-pagestyle.js", + "browser/base/content/browser-places.js", + "browser/base/content/browser-profiles.js", + "browser/base/content/browser-safebrowsing.js", + "browser/base/content/browser-siteIdentity.js", + "browser/base/content/browser-sitePermissionPanel.js", + "browser/base/content/browser-siteProtections.js", + "browser/base/content/browser-sync.js", + "browser/base/content/browser-thumbnails.js", + "browser/base/content/browser-toolbarKeyNav.js", + "browser/base/content/browser-unified-extensions.js", + "browser/base/content/browser-webrtc.js", + "browser/base/content/global-scripts.js", + "browser/base/content/main-popupset.js", + "browser/base/content/navigator-toolbox.js", + "browser/base/content/nonbrowser-mac.js", + "browser/components/downloads/content/allDownloadsView.js", + "browser/components/downloads/content/downloads.js", + "browser/components/downloads/content/indicator.js", + "browser/components/places/content/browserPlacesViews.js", + "browser/components/places/content/places-commands.js", + "browser/components/places/content/places-menupopup.js", + "browser/components/places/content/placesContextMenu.js", + "browser/components/pocket/content/pktUI.js", + "browser/components/screenshots/screenshots-buttons.js", + "browser/components/tabbrowser/content/browser-allTabsMenu.js", + "browser/components/tabbrowser/content/browser-ctrlTab.js", + "browser/components/tabbrowser/content/browser-fullZoom.js", + "browser/components/tabbrowser/content/tabbrowser.js", + "browser/components/tabbrowser/content/tabs.js", + "browser/components/translations/content/fullPageTranslationsPanel.js", + "browser/components/translations/content/selectTranslationsPanel.js", + "browser/fxr/content/fxr-fullScreen.js", + "testing/mochitest/browser-test.js", + "toolkit/components/printing/content/printPreviewPagination.js", + "toolkit/components/printing/content/printUtils.js", + ], + languageOptions: { + globals: mozilla.environments["browser-window"].globals, + }, + }, + { + name: "globals-chrome-script", + files: [ + "browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js", + "browser/tools/mozscreenshots/mozscreenshots/extension/configurations/PermissionPrompts.sys.mjs", + "docshell/test/mochitest/test_bug509055.html", + "docshell/test/navigation/test_bug1300461.html", + "docshell/test/navigation/test_bug1375833.html", + "docshell/test/navigation/test_online_offline_bfcache.html", + "docshell/test/navigation/test_online_offline_bfcache.html", + "dom/base/test/bug403852_fileOpener.js", + "dom/base/test/bug578096LoadChromeScript.js", + "dom/base/test/file_bug1198095.js", + "dom/base/test/script_bug1238440.js", + "dom/base/test/script_postmessages_fileList.js", + "dom/base/test/test_bug375314-2.html", + "dom/base/test/test_input_vsync_alignment_input_while_vsync.html", + "dom/events/test/file_coalesce_touchmove_browserchild.html", + "dom/events/test/file_coalesce_touchmove_browserchild2.html", + "dom/events/test/file_coalesce_touchmove_browserchild2.html", + "dom/events/test/file_coalesce_touchmove_browserchild2.html", + "dom/events/test/file_coalesce_touchmove_ipc.html", + "dom/events/test/file_coalesce_touchmove_ipc.html", + "dom/events/test/file_coalesce_touchmove_ipc.html", + "dom/events/test/test_bug574663.html", + "dom/events/test/window_wheel_default_action.html", + "dom/file/ipc/tests/script_file.js", + "dom/file/tests/create_file_objects.js", + "dom/file/tests/fileapi_chromeScript.js", + "dom/filesystem/compat/tests/script_entries.js", + "dom/filesystem/tests/script_fileList.js", + "dom/filesystem/tests/script_promptHandler.js", + "dom/html/test/file_cookiemanager.js", + "dom/html/test/formSubmission_chrome.js", + "dom/html/test/script_fakepath.js", + "dom/html/test/simpleFileOpener.js", + "dom/ipc/tests/test_Preallocated.html", + "dom/media/autoplay/test/mochitest/file_autoplay_policy_key_blacklist.html", + "dom/media/test/chromeHelper.js", + "dom/media/webrtc/tests/mochitests/addTurnsSelfsignedCert.js", + "dom/notification/test/mochitest/MockAlertsService.js", + "dom/notification/test/mochitest/test_notification_insecure_context.html", + "dom/notification/test/mochitest/test_notification_tag.html", + "dom/payments/test/BasiccardChromeScript.js", + "dom/payments/test/BasicCardErrorsChromeScript.js", + "dom/payments/test/Bug1478740ChromeScript.js", + "dom/payments/test/Bug1490698ChromeScript.js", + "dom/payments/test/ClosePaymentChromeScript.js", + "dom/payments/test/ConstructorChromeScript.js", + "dom/payments/test/CurrencyAmountValidationChromeScript.js", + "dom/payments/test/GeneralChromeScript.js", + "dom/payments/test/PayerDetailsChromeScript.js", + "dom/payments/test/PMIValidationChromeScript.js", + "dom/payments/test/RequestShippingChromeScript.js", + "dom/payments/test/RetryPaymentChromeScript.js", + "dom/payments/test/ShippingOptionsChromeScript.js", + "dom/payments/test/ShowPaymentChromeScript.js", + "dom/payments/test/UpdateErrorsChromeScript.js", + "dom/push/test/mockpushserviceparent.js", + "dom/push/test/test_try_registering_offline_disabled.html", + "dom/security/test/csp/file_report_chromescript.js", + "dom/security/test/csp/test_ignore_xfo.html", + "dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html", + "dom/security/test/general/test_meta_referrer.html", + "dom/security/test/general/test_same_site_cookies_laxByDefault.html", + "dom/security/test/mixedcontentblocker/file_main_bug803225.html", + "dom/security/test/sec-fetch/test_iframe_history_manipulation.html", + "dom/security/test/sec-fetch/test_iframe_src_metaRedirect.html", + "dom/security/test/sec-fetch/test_iframe_srcdoc_metaRedirect.html", + "dom/security/test/sec-fetch/test_iframe_window_open_metaRedirect.html", + "dom/security/test/sec-fetch/test_trustworthy_loopback.html", + "dom/security/test/sec-fetch/test_websocket.html", + "dom/security/test/sec-fetch/test_window_open_popupBlockerEnabled.html", + "dom/serviceworkers/test/console_monitor.js", + "dom/serviceworkers/test/script_file_upload.js", + "dom/serviceworkers/test/test_scopes.html", + "dom/serviceworkers/test/test_third_party_iframes.html", + "dom/tests/mochitest/bugs/test_no_find_showDialog.html", + "dom/workers/test/script_createFile.js", + "dom/xhr/tests/file_sync_xhr_event_handling_helper.html", + "dom/xhr/tests/file_sync_xhr_nested_helper.html", + "editor/libeditor/tests/test_bug569988.html", + "editor/spellchecker/tests/test_bug1200533.html", + "editor/spellchecker/tests/test_bug1204147.html", + "editor/spellchecker/tests/test_bug1205983.html", + "editor/spellchecker/tests/test_bug1209414.html", + "editor/spellchecker/tests/test_bug1402822.html", + "editor/spellchecker/tests/test_bug1761273.html", + "editor/spellchecker/tests/test_bug1773802.html", + "editor/spellchecker/tests/test_bug678842.html", + "editor/spellchecker/tests/test_bug697981.html", + "editor/spellchecker/tests/test_bug717433.html", + "editor/spellchecker/tests/test_multiple_content_languages.html", + "extensions/spellcheck/tests/mochitest/helper_bug1170484.js", + "extensions/spellcheck/tests/mochitest/test_bug1272623.html", + "gfx/layers/apz/test/mochitest/apz_test_utils.js", + "gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html", + "gfx/layers/apz/test/mochitest/helper_hittest_overscroll.html", + "gfx/layers/apz/test/mochitest/helper_touch_action_regions.html", + "mobile/shared/actors/tests/mochitests/test_geckoview_experiment_delegate.html", + "mobile/shared/modules/geckoview/test/mochitest/test_geckoview_translations.html", + "netwerk/cookie/test/mochitest/cookiesHelper.js", + "netwerk/test/mochitests/file_1331680.js", + "netwerk/test/mochitests/file_chromecommon.js", + "netwerk/test/mochitests/file_documentcookie_maxage_chromescript.js", + "netwerk/test/mochitests/file_testloadflags_chromescript.js", + "netwerk/test/mochitests/test_1396395.html", + "security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html", + "testing/mochitest/tests/Harness_sanity/specialPowers_framescript.js", + "testing/mochitest/tests/Harness_sanity/SpecialPowersLoadChromeScript.js", + "testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript_function.html", + "testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript.html", + "testing/mochitest/tests/Harness_sanity/test_SpecialPowersSandbox.html", + "testing/mochitest/tests/Harness_sanity/test_SpecialPowersSandbox.js", + "testing/mochitest/tests/SimpleTest/ChromeTask.js", + "toolkit/components/alerts/test/chrome/test_alerts_noobserve.html", + "toolkit/components/alerts/test/chrome/test_alerts_requireinteraction.html", + "toolkit/components/alerts/test/chrome/test_multiple_alerts.html", + "toolkit/components/alerts/test/chrome/test_principal.html", + "toolkit/components/antitracking/test/browser/browser_permissionInNormalWindows.js", + "toolkit/components/extensions/test/mochitest/chrome_cleanup_script.js", + "toolkit/components/extensions/test/mochitest/mochitest_console.js", + "toolkit/components/extensions/test/mochitest/test_ext_browsingData_localStorage.html", + "toolkit/components/extensions/test/mochitest/test_ext_contentscript_cache.html", + "toolkit/components/extensions/test/mochitest/test_ext_cookies_incognito.html", + "toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html", + "toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html", + "toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html", + "toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html", + "toolkit/components/extensions/test/mochitest/test_ext_protocolHandlers.html", + "toolkit/components/extensions/test/mochitest/test_ext_request_urlClassification.html", + "toolkit/components/extensions/test/mochitest/test_ext_request_urlClassification.html", + "toolkit/components/extensions/test/mochitest/test_ext_unlimitedStorage.html", + "toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html", + "toolkit/components/extensions/test/mochitest/test_ext_webrequest_auth.html", + "toolkit/components/extensions/test/mochitest/test_verify_non_remote_mode.html", + "toolkit/components/passwordmgr/test/mochitest/chrome_timeout.js", + "toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js", + "toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js", + "toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js", + "toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js", + "toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js", + "toolkit/components/prompts/test/chromeScript.js", + "toolkit/components/satchel/test/parent_utils.js", + "toolkit/components/url-classifier/tests/mochitest/classifierCommon.js", + "toolkit/components/url-classifier/tests/mochitest/features.js", + "toolkit/components/url-classifier/tests/mochitest/test_classify_top_sandboxed.html", + "toolkit/components/url-classifier/tests/mochitest/test_cryptomining.html", + "toolkit/components/url-classifier/tests/mochitest/test_emailtracking.html", + "toolkit/components/url-classifier/tests/mochitest/test_fingerprinting.html", + "toolkit/components/url-classifier/tests/mochitest/test_socialtracking.html", + "toolkit/content/tests/chrome/test_autocomplete_with_composition_on_input.html", + "toolkit/content/tests/chrome/test_editor_for_input_with_autocomplete.html", + "toolkit/content/tests/mochitest/test_autocomplete_change_after_focus.html", + "toolkit/content/tests/mochitest/test_autocomplete_change_after_focus.html", + "uriloader/exthandler/tests/mochitest/HelperAppLauncherDialog_chromeScript.js", + ], + languageOptions: { globals: mozilla.environments["chrome-script"].globals }, + }, + { + name: "globals-frame-script", + files: [ + "browser/base/content/test/performance/browser_startup_content.js", + "devtools/server/startup/frame.js", + "docshell/test/browser/file_bug1328501_framescript.js", + "dom/indexedDB/test/test_message_manager_ipc.html", + "dom/ipc/tests/test_blob_sliced_from_child_process.js", + "dom/ipc/tests/test_blob_sliced_from_parent_process.js", + "dom/ipc/tests/test_bug1086684.js", + "dom/ipc/tests/test_child_docshell.js", + "dom/messagechannel/tests/mm_messageChannel.js", + "layout/tools/reftest/reftest-content.js", + "mobile/shared/chrome/geckoview/SessionStateAggregator.js", + "netwerk/test/browser/browser_nsIFormPOSTActionChannel.js", + "remote/cdp/sessions/frame-script.js", + "remote/marionette/reftest-content.js", + "testing/mochitest/BrowserTestUtils/content/content-task.js", + "testing/mochitest/shutdown-leaks-collector.js", + "testing/talos/talos/pageloader/chrome/a11y.js", + "testing/talos/talos/pageloader/chrome/lh_dummy.js", + "testing/talos/talos/pageloader/chrome/lh_fnbpaint.js", + "testing/talos/talos/pageloader/chrome/lh_hero.js", + "testing/talos/talos/pageloader/chrome/lh_moz.js", + "testing/talos/talos/pageloader/chrome/lh_pdfpaint.js", + "testing/talos/talos/pageloader/chrome/Profiler.js", + "testing/talos/talos/pageloader/chrome/talos-content.js", + "testing/talos/talos/pageloader/chrome/tscroll.js", + "testing/talos/talos/pageloader/chrome/utils.js", + "testing/talos/talos/talos-powers/chrome/talos-powers-content.js", + "testing/talos/talos/talos-powers/content/TalosContentProfiler.js", + "testing/talos/talos/tests/cpstartup/extension/framescript.js", + "testing/talos/talos/tests/tabpaint/framescript.js", + "testing/talos/talos/tests/tart/addon/content/framescript.js", + "testing/talos/talos/tests/tresize/addon/content/framescript.js", + "toolkit/components/extensions/ext-browser-content.js", + "toolkit/components/gfx/content/gfxFrameScript.js", + ], + languageOptions: { globals: mozilla.environments["frame-script"].globals }, + }, + { + name: "globals-process-script", + files: [ + "browser/extensions/webcompat/about-compat/aboutPageProcessScript.js", + "devtools/client/shared/test/shared-head.js", + "devtools/server/startup/content-process-script.js", + "devtools/server/startup/content-process.js", + "devtools/server/tests/browser/browser_getProcess.js", + "dom/base/test/browser_messagemanager_loadprocessscript.js", + "dom/base/test/browser_messagemanager_loadprocessscript.js", + "dom/base/test/chrome/file_bug1139964.xhtml", + "dom/security/test/mixedcontentblocker/file_main_bug803225.html", + "testing/mochitest/BrowserTestUtils/content/content-about-page-utils.js", + "testing/talos/talos/tests/tabswitch/content/tabswitch-content-process.js", + "toolkit/components/extensions/extensionProcessScriptLoader.js", + "toolkit/content/process-content.js", + ], + languageOptions: { + globals: mozilla.environments["process-script"].globals, + }, + }, + { + name: "globals-remote-page", + files: [ + "browser/base/content/aboutRestartRequired.js", + "browser/base/content/aboutTabCrashed.js", + "browser/components/privatebrowsing/content/aboutPrivateBrowsing.js", + "browser/components/profiles/content/delete-profile-card.mjs", + "browser/components/profiles/content/edit-profile-card.mjs", + "browser/components/profiles/content/new-profile-card.mjs", + "browser/components/protections/content/lockwise-card.mjs", + "browser/components/protections/content/monitor-card.mjs", + "browser/components/protections/content/protections.mjs", + "browser/components/protections/content/proxy-card.mjs", + "browser/components/protections/content/vpn-card.mjs", + "browser/components/shopping/content/settings.mjs", + "browser/components/shopping/content/shopping-container.mjs", + "browser/components/shopping/content/shopping-message-bar.mjs", + "browser/extensions/newtab/content-src/lib/init-store.mjs", + "browser/extensions/newtab/data/content/activity-stream.bundle.js", + "toolkit/components/certviewer/content/certviewer.mjs", + "toolkit/components/certviewer/content/components/about-certificate-items.mjs", + "toolkit/components/certviewer/content/components/about-certificate-section.mjs", + "toolkit/components/httpsonlyerror/content/errorpage.js", + "toolkit/content/aboutNetError.mjs", + "toolkit/content/aboutNetErrorHelpers.mjs", + "toolkit/content/net-error-card.mjs", + ], + languageOptions: { globals: mozilla.environments["remote-page"].globals }, + }, + { + name: "globals-simpletest", + files: [ + "dom/quota/test/modules/content/Assert.mjs", + "netwerk/test/browser/cookie_filtering_helper.sys.mjs", + "xpcom/ioutils/tests/file_ioutils_test_fixtures.js", + ], + languageOptions: { globals: mozilla.environments.simpletest.globals }, + }, + { + name: "globals-testharness", + files: [ + "dom/encoding/test/test_BOMEncoding.js", + "dom/encoding/test/test_TextDecoder.js", + "dom/encoding/test/test_TextEncoder.js", + ], + languageOptions: { globals: mozilla.environments.testharness.globals }, + }, + { + name: "globals-node", + files: [ + "browser/base/content/test/perftest_browser_xhtml_dom.js", + "browser/components/storybook/.storybook/addon-component-status/index.js", + "browser/components/storybook/.storybook/addon-fluent/index.js", + "browser/components/storybook/.storybook/chrome-styles-loader.js", + "browser/components/storybook/.storybook/chrome-uri-utils.js", + "browser/components/storybook/.storybook/main.js", + "browser/components/storybook/.storybook/markdown-story-indexer.js", + "browser/components/storybook/.storybook/markdown-story-loader.js", + "browser/components/storybook/.storybook/markdown-story-utils.js", + "browser/tools/mozsrcUriPlugin.js", + "browser/tools/resourceUriPlugin.js", + "dom/media/webrtc/tests/mochitests/helpers_from_wpt/sdp.js", + "dom/media/webvtt/update-webvtt.js", + "netwerk/test/perf/perftest_http3_cloudflareblog.js", + "netwerk/test/perf/perftest_http3_controlled.js", + "netwerk/test/perf/perftest_http3_facebook_scroll.js", + "netwerk/test/perf/perftest_http3_google_image.js", + "netwerk/test/perf/perftest_http3_google_search.js", + "netwerk/test/perf/perftest_http3_lucasquicfetch.js", + "netwerk/test/perf/perftest_http3_youtube_watch_scroll.js", + "netwerk/test/perf/perftest_http3_youtube_watch.js", + "netwerk/test/unit/test_http_server_timing.js", + "netwerk/test/unit/test_http2-proxy-failing.js", + "netwerk/test/unit/test_http2-proxy.js", + "python/mozperftest/mozperftest/tests/data/failing-samples/perftest_doc_failure_example.js", + "python/mozperftest/mozperftest/tests/data/samples/perftest_example.js", + "python/mozperftest/mozperftest/tests/data/samples/test_perftest_WPT_init_file.js", + "testing/performance/perftest_record.js", + "testing/performance/perftest_WPT_chrome_init_file.js", + "testing/performance/perftest_WPT_firefox_init_file.js", + "testing/raptor/browsertime/browsertime_benchmark.js", + "testing/raptor/browsertime/browsertime_interactive.js", + "testing/raptor/browsertime/browsertime_pageload.js", + "testing/raptor/browsertime/browsertime_scenario.js", + "testing/raptor/browsertime/browsertime_tp6_bench.js", + "testing/raptor/browsertime/constant_regression_test.js", + "testing/raptor/browsertime/indexeddb_getkeyrange.js", + "testing/raptor/browsertime/indexeddb_open.js", + "testing/raptor/browsertime/indexeddb_write.js", + "testing/raptor/browsertime/jetstream3.js", + "testing/raptor/browsertime/motionmark-1-3.js", + "testing/raptor/browsertime/network_bench.js", + "testing/raptor/browsertime/process_switch.js", + "testing/raptor/browsertime/speculative-connect.js", + "testing/raptor/browsertime/speedometer3.js", + "testing/raptor/browsertime/throttled_pageload.js", + "testing/raptor/browsertime/trr_performance.js", + "testing/raptor/browsertime/utils/profiling.js", + "testing/raptor/browsertime/utils/support_measurements.js", + "testing/raptor/browsertime/welcome.js", + "testing/web-platform/tests/webrtc/third_party/sdp/sdp.js", + "testing/xpcshell/moz-http2/moz-http2-child.js", + "testing/xpcshell/moz-http2/moz-http2.js", + "toolkit/components/normandy/actions/schemas/export_json.js", + "toolkit/themes/shared/design-system/figma-tokens-config.js", + "toolkit/themes/shared/design-system/tests/try-runner.js", + "toolkit/themes/shared/design-system/tokens-config.js", + "tools/lint/stylelint/stylelint-plugin-mozilla/helpers.mjs", + "tools/lint/stylelint/stylelint-plugin-mozilla/index.mjs", + "tools/lint/stylelint/stylelint-plugin-mozilla/reporters/mozilla-format.mjs", + "tools/lint/stylelint/stylelint-plugin-mozilla/rules/index.mjs", + "tools/lint/stylelint/stylelint-plugin-mozilla/rules/no-base-design-tokens.mjs", + "tools/lint/stylelint/stylelint-plugin-mozilla/tests/no-base-design-tokens.mjs", + "tools/ts/plugins/checkRootOnly.js", + "tools/ts/test/dom.test.js", + "tools/ts/test/xpcom.test.js", + ], + languageOptions: { globals: globals.node }, + }, + { + name: "globals-serviceworker", + files: [ + "dom/notification/test/browser/file_userContextId_openWindow.js", + "dom/notification/test/mochitest/notification_openWindow_worker.js", + "dom/notification/test/mochitest/notificationclick_focus.js", + "dom/notification/test/mochitest/notificationclick.js", + "dom/notification/test/mochitest/notificationclose.js", + "dom/notification/test/mochitest/openWindow_worker.js", + "dom/security/test/general/file_block_script_wrong_mime_sw.js", + ], + languageOptions: { globals: globals.serviceworker }, + }, + { + name: "globals-webextensions", + files: [ + "browser/components/preferences/tests/browser_contentblocking_categories.js", + "browser/components/preferences/tests/browser_contentblocking.js", + "browser/components/preferences/tests/browser_extension_controlled.js", + "browser/extensions/formautofill/background.js", + "browser/extensions/newtab/webext-glue/background.js", + "devtools/client/responsive/test/browser/browser_ext_messaging.js", + "dom/fetch/tests/test_ext_response_constructor.html", + "mobile/android/android-components/components/browser/icons/src/main/assets/extensions/browser-icons/icons.js", + "mobile/android/android-components/components/feature/accounts/src/main/assets/extensions/fxawebchannel/background.js", + "mobile/android/android-components/components/feature/accounts/src/main/assets/extensions/fxawebchannel/fxawebchannel.js", + "mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-background.js", + "mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview-content.js", + "mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readerview.js", + "mobile/android/android-components/components/feature/search/src/main/assets/extensions/ads/adsTelemetry.js", + "mobile/android/android-components/components/feature/search/src/main/assets/extensions/search/searchTelemetry.js", + "mobile/android/android-components/samples/browser/src/main/assets/extensions/test/background.js", + "testing/talos/talos/tests/devtools/addon/driver.js", + "testing/talos/talos/tests/twinopen/driver.js", + "testing/talos/talos/webextensions/dummy/background.js", + "testing/talos/talos/webextensions/dummy/content.js", + "toolkit/components/ml/docs/extensions-api-example/background.js", + "toolkit/components/ml/docs/extensions-api-example/contextmenu-shim.js", + "toolkit/components/remotebrowserutils/tests/browser/browser_documentChannel.js", + ], + languageOptions: { globals: globals.webextensions }, + }, + { + name: "globals-worker", + files: [ + "devtools/shared/heapsnapshot/tests/xpcshell/dominator-tree-worker.js", + "devtools/shared/heapsnapshot/tests/xpcshell/heap-snapshot-worker.js", + "dom/broadcastchannel/tests/broadcastchannel_sharedWorker.js", + "dom/cache/test/mochitest/worker_wrapper.js", + "dom/crypto/test/test-worker.js", + "dom/filesystem/tests/worker_basic.js", + "dom/indexedDB/test/blob_worker_crash_iframe.html", + "dom/indexedDB/test/browser_private_idb.js", + "dom/indexedDB/test/test_blob_simple.html", + "dom/indexedDB/test/test_blob_worker_xhr_post_multifile.html", + "dom/indexedDB/test/test_blob_worker_xhr_post.html", + "dom/indexedDB/test/test_blob_worker_xhr_read_slice.html", + "dom/indexedDB/test/test_blob_worker_xhr_read.html", + "dom/messagechannel/tests/sharedWorker_messageChannel.js", + "dom/messagechannel/tests/sharedWorker2_messageChannel.js", + "dom/quota/test/modules/content/worker/head.js", + "dom/url/tests/esm_url_worker.js", + "dom/url/tests/url_worker.js", + "dom/url/tests/urlApi_worker.js", + "dom/url/tests/urlSearchParams_worker.js", + "dom/xhr/tests/relativeLoad_worker.js", + "dom/xhr/tests/relativeLoad_worker2.js", + "dom/xhr/tests/subdir/relativeLoad_sub_worker.js", + "dom/xhr/tests/subdir/relativeLoad_sub_worker2.js", + "dom/xhr/tests/worker_temporaryFileBlob.js", + "dom/xhr/tests/xhr_sharedworker.js", + "dom/xhr/tests/xhr2_worker.js", + "dom/xhr/tests/xhrAbort_worker.js", + "xpcom/ioutils/tests/file_ioutils_worker.js", + "xpcom/ioutils/tests/pathutils_worker.js", + ], + languageOptions: { globals: globals.worker }, + }, +]; diff --git a/eslint-rollouts.config.mjs b/eslint-rollouts.config.mjs index 6d4c05bac39e..d6db4952869b 100644 --- a/eslint-rollouts.config.mjs +++ b/eslint-rollouts.config.mjs @@ -2,7 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; +import eslintPluginImport from "eslint-plugin-import"; +import mozilla from "eslint-plugin-mozilla"; +import sdl from "@microsoft/eslint-plugin-sdl"; /** * This is the current list of rollouts for ESLint rules in mozilla-central. The @@ -15,8 +17,9 @@ * See https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint/enabling-rules.html#enabling-a-new-rule * for more information about roll-outs. */ -const rollouts = [ +export default [ { + name: "rollout-import-no-unresolved", files: [ // Bug 1773475 - For now, turn off no-unresolved on some paths where we import // from node_modules, as the ESLint setup only installs modules at the @@ -24,12 +27,14 @@ const rollouts = [ "devtools/shared/compatibility/**", "browser/components/storybook/**", ], + plugins: { import: eslintPluginImport }, rules: { "import/no-unresolved": "off", }, }, { - files: ["*.html", "*.xhtml", "*.xml"], + name: "rollout-curly", + files: ["**/*.html", "**/*.xhtml"], rules: { // Curly brackets are required for all the tree via recommended.js, // however these files aren't auto-fixable at the moment. @@ -38,7 +43,8 @@ const rollouts = [ }, { // TODO: Bug 1515949. Enable no-undef for gfx/ - files: "gfx/layers/apz/test/mochitest/**", + name: "rollout-gfx-no-undef", + files: ["gfx/layers/apz/test/mochitest/**"], rules: { "no-undef": "off", }, @@ -47,6 +53,7 @@ const rollouts = [ // Bug 881389 - Complete switching to console.createInstance from custom // modules. To support the gradual switch, we log these as warnings until // they have been transitioned. + name: "rollout-use-console-createInstance", files: [ "browser/base/content/browser-data-submission-info-bar.js", "browser/base/content/browser-sync.js", @@ -93,12 +100,14 @@ const rollouts = [ "toolkit/mozapps/extensions/**", "toolkit/mozapps/update/**", ], + plugins: { mozilla }, rules: { "mozilla/use-console-createInstance": "off", }, }, { // Bug 1881270 - Gradually roll-out no-case-declarations to more areas. + name: "rollout-no-case-declarations", files: [ "accessible/tests/mochitest/promisified-events.js", "browser/actors/**", @@ -154,6 +163,7 @@ const rollouts = [ }, { // Bug 1881268 - Gradually roll-out no-constant-condition to more areas. + name: "rollout-no-constant-condition", files: [ "accessible/tests/browser/mac/browser_attributed_text.js", "accessible/tests/mochitest/text.js", @@ -242,6 +252,7 @@ const rollouts = [ rules: { "no-constant-condition": "warn" }, }, { + name: "rollout-no-console", files: [ "browser/actors/AboutPocketParent.sys.mjs", "browser/actors/SpeechDispatcherParent.sys.mjs", @@ -298,18 +309,21 @@ const rollouts = [ { // Bug 877389 - Gradually migrate from Cu.reportError to console.error. // Enable these as we fix more areas. + name: "rollout-no-cu-reportError", files: [ "browser/components/extensions/**", "toolkit/components/extensions/**", "toolkit/mozapps/extensions/**", ], + plugins: { mozilla }, rules: { "mozilla/no-cu-reportError": "off", }, }, { - files: ["**"], - excludedFiles: [ + name: "rollout-valid-jsdoc", + files: [`**/*.{${mozilla.allFileExtensions.join(",")}}`], + ignores: [ "accessible/tests/**", "browser/actors/**", "browser/base/content/**", @@ -374,16 +388,16 @@ const rollouts = [ "toolkit/components/pdfjs/**", "toolkit/components/pictureinpicture/**", "toolkit/components/places/**", - "toolkit/components/printing/content/print*.*", + "toolkit/components/printing/content/**", "toolkit/components/processtools/tests/browser/browser_test_powerMetrics.js", - "toolkit/components/promiseworker/**/PromiseWorker.*", + "toolkit/components/promiseworker/worker/PromiseWorker.template.worker.js", "toolkit/components/prompts/**", "toolkit/components/reader/**", "toolkit/components/reputationservice/test/unit/test_app_rep_windows.js", - "toolkit/components/taskscheduler/TaskScheduler*.*", + "toolkit/components/taskscheduler/TaskScheduler*.sys.mjs", "toolkit/components/telemetry/**", "toolkit/components/thumbnails/**", - "toolkit/components/timermanager/UpdateTimerManager.*", + "toolkit/components/timermanager/UpdateTimerManager.sys.mjs", "toolkit/components/url-classifier/**", "toolkit/components/utils/**", "toolkit/components/viewsource/**", @@ -406,11 +420,12 @@ const rollouts = [ "uriloader/**", "widget/tests/window_composition_text_querycontent.xhtml", ], - extends: ["plugin:mozilla/valid-jsdoc"], + ...mozilla.configs["flat/valid-jsdoc"], }, { - files: ["**"], - excludedFiles: [ + name: "rollout-require-jsdoc", + files: [`**/*.{${mozilla.allFileExtensions.join(",")}}`], + ignores: [ "accessible/tests/**", "browser/actors/**", "browser/base/content/**", @@ -528,10 +543,10 @@ const rollouts = [ "toolkit/components/pdfjs/**", "toolkit/components/pictureinpicture/**", "toolkit/components/places/**", - "toolkit/components/printing/content/print*.*", + "toolkit/components/printing/content/**", "toolkit/components/printing/tests/head.js", "toolkit/components/processtools/tests/browser/browser_test_powerMetrics.js", - "toolkit/components/promiseworker/**/PromiseWorker.*", + "toolkit/components/promiseworker/**/PromiseWorker.template.worker.js", "toolkit/components/prompts/**", "toolkit/components/reader/**", "toolkit/components/remotebrowserutils/RemoteWebNavigation.sys.mjs", @@ -540,10 +555,10 @@ const rollouts = [ "toolkit/components/resistfingerprinting/**", "toolkit/components/satchel/**", "toolkit/components/shopping/content/ShoppingProduct.mjs", - "toolkit/components/taskscheduler/TaskScheduler*.*", + "toolkit/components/taskscheduler/TaskScheduler*.sys.mjs", "toolkit/components/telemetry/**", "toolkit/components/thumbnails/**", - "toolkit/components/timermanager/UpdateTimerManager.*", + "toolkit/components/timermanager/UpdateTimerManager.sys.mjs", "toolkit/components/translations/**", "toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_callbacks.js", "toolkit/components/uniffi-js/js/UniFFI.sys.mjs", @@ -573,11 +588,13 @@ const rollouts = [ "widget/tests/file*.js", "widget/tests/window_composition_text_querycontent.xhtml", ], - extends: ["plugin:mozilla/require-jsdoc"], + ...mozilla.configs["flat/valid-jsdoc"], }, { + name: "rollout-layout", files: ["layout/**"], - excludedFiles: ["layout/tools/reftest/**"], + ignores: ["layout/tools/reftest/**"], + plugins: { mozilla }, rules: { "object-shorthand": "off", "mozilla/avoid-removeChild": "off", @@ -615,9 +632,10 @@ const rollouts = [ }, }, { + name: "rollout-dom", files: [ "dom/animation/test/**", - "dom/base/test/*.*", + "dom/base/test/**", "dom/base/test/jsmodules/**", "dom/canvas/test/**", "dom/events/test/**", @@ -639,6 +657,7 @@ const rollouts = [ "dom/webauthn/tests/**", "dom/workers/test/**", ], + plugins: { mozilla }, rules: { "mozilla/avoid-removeChild": "off", "mozilla/no-compare-against-boolean-literals": "off", @@ -669,9 +688,10 @@ const rollouts = [ { // Bug 1792693: Gradually enable no-undef and no-unused-vars on these // directories. + name: "rollout-no-undef-no-unused-vars-for-dom", files: [ "dom/animation/test/**", - "dom/base/test/*.*", + "dom/base/test/**", "dom/base/test/unit/test_serializers_entities*.js", "dom/base/test/jsmodules/**", "dom/canvas/test/**", @@ -706,6 +726,7 @@ const rollouts = [ { // Exempt all components and test files that explicitly want to test http urls from 'no-insecure-url' rule. // Gradually change test cases such that this list gets smaller and more precisely. Bug 1758951 + name: "rollout-no-insecure-url", files: [ // Exempt tests that set https_first_disable to true Bug 1758951 "browser/components/downloads/test/browser/browser_image_mimetype_issues.js", @@ -1116,6 +1137,7 @@ const rollouts = [ "devtools/client/framework/test/allocations/browser_allocations_reload_no_devtools.js", "devtools/client/framework/test/allocations/reload-test.js", "devtools/client/framework/test/browser_toolbox_error_count_reset_on_navigation.js", + "devtools/client/framework/test/node/components/debug-target-info.test.js", "devtools/client/inspector/markup/test/browser_markup_tag_edit_05.js", "devtools/client/inspector/shared/test/browser_styleinspector_output-parser.js", "devtools/client/inspector/shared/test/head.js", @@ -1885,13 +1907,16 @@ const rollouts = [ "uriloader/exthandler/tests/mochitest/head.js", "xpfe/appshell/test/test_windowlessBrowser.xhtml", ], + plugins: { "@microsoft/sdl": sdl }, rules: { "@microsoft/sdl/no-insecure-url": "off", }, }, { + name: "rollout-no-browser-refs-in-toolkit", files: ["toolkit/**"], - excludedFiles: ["toolkit/**/test/**", "toolkit/**/tests/**"], + ignores: ["toolkit/**/test/**", "toolkit/**/tests/**"], + plugins: { mozilla }, rules: { "mozilla/no-browser-refs-in-toolkit": "warn", }, @@ -1899,6 +1924,7 @@ const rollouts = [ { // TODO: Bug TBD - Finish enabling no-shadow with builtinGlobals: true // for system modules. + name: "rollout-no-shadow-system-modules", files: [ "browser/components/extensions/Extension*.sys.mjs", "devtools/client/shared/components/reps/reps/**.mjs", @@ -1939,6 +1965,7 @@ const rollouts = [ }, { // TODO: Bug TBD - Finish enabling no-shadow for all files. + name: "rollout-no-shadow-everywhere", files: [ "browser/components/extensions/**", "docshell/test/**", @@ -1977,7 +2004,7 @@ const rollouts = [ "tools/profiler/tests/**", "tools/tryselect/selectors/chooser/static/filter.js", ], - excludedFiles: [ + ignores: [ "**/*.sys.mjs", "toolkit/components/narrate/**", "toolkit/components/reader/**", @@ -1987,5 +2014,3 @@ const rollouts = [ }, }, ]; - -module.exports = { rollouts }; diff --git a/eslint-subdirs.config.mjs b/eslint-subdirs.config.mjs new file mode 100644 index 000000000000..321801f672b9 --- /dev/null +++ b/eslint-subdirs.config.mjs @@ -0,0 +1,340 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * ESLint's flat configuration doesn't automatically read sub-configuration files. + * Hence, we import them here, adjusting paths as we go. + * + * Over time we would like to reduce this list. Ideally, this file would not exist. + * The aim is for our rules to be consistently applied across the code base. + * + * If you are seeking to add a new sub-file here, please talk to the "JavaScript + * usage, tools, and style" team first (aka #frontend-codestyle-reviewers). + */ + +import config0 from "./accessible/tests/browser/.eslintrc.mjs"; +import config1 from "./accessible/tests/mochitest/.eslintrc.mjs"; +import config2 from "./browser/.eslintrc.mjs"; +import config3 from "./browser/base/content/test/webextensions/.eslintrc.mjs"; +import config4 from "./browser/components/.eslintrc.mjs"; +import config5 from "./browser/components/aboutlogins/tests/chrome/.eslintrc.mjs"; +import config6 from "./browser/components/aboutwelcome/.eslintrc.mjs"; +import config7 from "./browser/components/asrouter/.eslintrc.mjs"; +import config8 from "./browser/components/customizableui/.eslintrc.mjs"; +import config9 from "./browser/components/customizableui/content/.eslintrc.mjs"; +import config10 from "./browser/components/enterprisepolicies/tests/xpcshell/.eslintrc.mjs"; +import config11 from "./browser/components/extensions/.eslintrc.mjs"; +import config12 from "./browser/components/extensions/child/.eslintrc.mjs"; +import config13 from "./browser/components/extensions/parent/.eslintrc.mjs"; +import config14 from "./browser/components/extensions/test/browser/.eslintrc.mjs"; +import config15 from "./browser/components/extensions/test/mochitest/.eslintrc.mjs"; +import config16 from "./browser/components/extensions/test/xpcshell/.eslintrc.mjs"; +import config17 from "./browser/components/migration/.eslintrc.mjs"; +import config18 from "./browser/components/pagedata/.eslintrc.mjs"; +import config19 from "./browser/components/pocket/.eslintrc.mjs"; +import config20 from "./browser/components/resistfingerprinting/test/mochitest/.eslintrc.mjs"; +import config21 from "./browser/components/search/.eslintrc.mjs"; +import config22 from "./browser/components/urlbar/.eslintrc.mjs"; +import config23 from "./browser/extensions/newtab/.eslintrc.mjs"; +import config24 from "./browser/extensions/pictureinpicture/tests/browser/.eslintrc.mjs"; +import config25 from "./browser/extensions/search-detection/tests/browser/.eslintrc.mjs"; +import config26 from "./devtools/.eslintrc.mjs"; +import config28 from "./devtools/client/.eslintrc.mjs"; +import config34 from "./devtools/client/debugger/src/.eslintrc.mjs"; +import config37 from "./devtools/client/dom/.eslintrc.mjs"; +import config39 from "./devtools/client/framework/test/reload/.eslintrc.mjs"; +import config45 from "./devtools/client/jsonview/.eslintrc.mjs"; +import config46 from "./devtools/client/memory/.eslintrc.mjs"; +import config48 from "./devtools/client/netmonitor/test/.eslintrc.mjs"; +import config50 from "./devtools/client/performance-new/.eslintrc.mjs"; +import config53 from "./devtools/client/shared/components/.eslintrc.mjs"; +import config63 from "./devtools/server/tests/xpcshell/.eslintrc.mjs"; +import config64 from "./devtools/shared/.eslintrc.mjs"; +import config74 from "./dom/base/test/jsmodules/.eslintrc.mjs"; +import config75 from "./dom/fs/test/common/.eslintrc.mjs"; +import config76 from "./dom/fs/test/mochitest/worker/.eslintrc.mjs"; +import config77 from "./dom/fs/test/xpcshell/worker/.eslintrc.mjs"; +import config78 from "./dom/media/mediasource/test/.eslintrc.mjs"; +import config79 from "./dom/quota/test/modules/system/worker/.eslintrc.mjs"; +import config80 from "./js/src/builtin/.eslintrc.mjs"; +import config81 from "./mobile/android/.eslintrc.mjs"; +import config82 from "./mobile/android/android-components/components/feature/webcompat-reporter/src/main/assets/extensions/webcompat-reporter/.eslintrc.mjs"; +import config83 from "./mobile/android/examples/messaging_example/app/src/main/assets/messaging/.eslintrc.mjs"; +import config84 from "./mobile/android/examples/port_messaging_example/app/src/main/assets/messaging/.eslintrc.mjs"; +import config85 from "./mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/.eslintrc.mjs"; +import config86 from "./mobile/android/geckoview/src/androidTest/assets/web_extensions/.eslintrc.mjs"; +import config87 from "./mobile/shared/.eslintrc.mjs"; +import config88 from "./mobile/shared/components/extensions/.eslintrc.mjs"; +import config89 from "./mobile/shared/components/extensions/test/mochitest/.eslintrc.mjs"; +import config90 from "./mobile/shared/components/extensions/test/xpcshell/.eslintrc.mjs"; +import config91 from "./netwerk/test/perf/.eslintrc.mjs"; +import config92 from "./remote/marionette/.eslintrc.mjs"; +import config93 from "./remote/marionette/test/xpcshell/.eslintrc.mjs"; +import config94 from "./security/.eslintrc.mjs"; +import config95 from "./security/manager/ssl/tests/.eslintrc.mjs"; +import config96 from "./security/manager/tools/.eslintrc.mjs"; +import config97 from "./services/sync/tests/tps/.eslintrc.mjs"; +import config98 from "./taskcluster/docker/index-task/.eslintrc.mjs"; +import config99 from "./taskcluster/docker/periodic-updates/.eslintrc.mjs"; +import config100 from "./testing/talos/talos/tests/perf-reftest-singletons/.eslintrc.mjs"; +import config101 from "./testing/mozbase/mozprofile/tests/files/dummy-profile/.eslintrc.mjs"; +import config102 from "./testing/performance/.eslintrc.mjs"; +import config103 from "./testing/raptor/.eslintrc.mjs"; +import config104 from "./testing/talos/.eslintrc.mjs"; +import config105 from "./testing/talos/talos/tests/devtools/addon/content/.eslintrc.mjs"; +import config106 from "./testing/talos/talos/tests/perf-reftest/.eslintrc.mjs"; +import config107 from "./toolkit/.eslintrc.mjs"; +import config108 from "./toolkit/components/antitracking/test/browser/.eslintrc.mjs"; +import config109 from "./toolkit/components/extensions/.eslintrc.mjs"; +import config110 from "./toolkit/components/extensions/child/.eslintrc.mjs"; +import config111 from "./toolkit/components/extensions/parent/.eslintrc.mjs"; +import config112 from "./toolkit/components/extensions/test/browser/.eslintrc.mjs"; +import config113 from "./toolkit/components/extensions/test/mochitest/.eslintrc.mjs"; +import config114 from "./toolkit/components/extensions/test/xpcshell/.eslintrc.mjs"; +import config115 from "./toolkit/components/extensions/test/xpcshell/webidl-api/.eslintrc.mjs"; +import config116 from "./toolkit/components/narrate/.eslintrc.mjs"; +import config117 from "./toolkit/components/normandy/test/.eslintrc.mjs"; +import config118 from "./toolkit/components/passwordmgr/test/browser/.eslintrc.mjs"; +import config119 from "./toolkit/components/passwordmgr/test/mochitest/.eslintrc.mjs"; +import config120 from "./toolkit/components/prompts/test/.eslintrc.mjs"; +import config121 from "./toolkit/components/reader/.eslintrc.mjs"; +import config122 from "./toolkit/content/.eslintrc.mjs"; +import config123 from "./toolkit/modules/subprocess/.eslintrc.mjs"; +import config124 from "./toolkit/mozapps/extensions/.eslintrc.mjs"; +import config125 from "./toolkit/mozapps/extensions/test/browser/.eslintrc.mjs"; +import config126 from "./toolkit/mozapps/extensions/test/xpcshell/.eslintrc.mjs"; +import config127 from "./tools/lint/eslint/.eslintrc.mjs"; +import config128 from "./tools/lint/eslint/eslint-plugin-mozilla/lib/configs/.eslintrc.mjs"; +import config130 from "./tools/tryselect/selectors/chooser/.eslintrc.mjs"; +import config131 from "./tools/ts/.eslintrc.mjs"; + +function convertConfigurationFile(path, config) { + let sectionId = 0; + let newConfig = []; + for (let section of config) { + let newSection = { ...section }; + newSection.name = path + ".eslintrc.js-" + sectionId++; + + if (!newSection.files) { + newSection.files = [path]; + } else if (Array.isArray(newSection.files)) { + newSection.files = newSection.files.map(f => path + f); + } else if (typeof newSection.files == "string") { + newSection.files = [path + newSection.files]; + } else { + throw new Error( + "Unexpected type for the files property in configuration for", + path + ); + } + newConfig.push(newSection); + } + return newConfig; +} + +export default [ + ...convertConfigurationFile("accessible/tests/browser/", config0), + ...convertConfigurationFile("accessible/tests/mochitest/", config1), + ...convertConfigurationFile("browser/", config2), + ...convertConfigurationFile( + "browser/base/content/test/webextensions/", + config3 + ), + ...convertConfigurationFile("browser/components/", config4), + ...convertConfigurationFile( + "browser/components/aboutlogins/tests/chrome/", + config5 + ), + ...convertConfigurationFile("browser/components/aboutwelcome/", config6), + ...convertConfigurationFile("browser/components/asrouter/", config7), + ...convertConfigurationFile("browser/components/customizableui/", config8), + ...convertConfigurationFile( + "browser/components/customizableui/content/", + config9 + ), + ...convertConfigurationFile( + "browser/components/enterprisepolicies/tests/xpcshell/", + config10 + ), + ...convertConfigurationFile("browser/components/extensions/", config11), + ...convertConfigurationFile("browser/components/extensions/child/", config12), + ...convertConfigurationFile( + "browser/components/extensions/parent/", + config13 + ), + ...convertConfigurationFile( + "browser/components/extensions/test/browser/", + config14 + ), + ...convertConfigurationFile( + "browser/components/extensions/test/mochitest/", + config15 + ), + ...convertConfigurationFile( + "browser/components/extensions/test/xpcshell/", + config16 + ), + ...convertConfigurationFile("browser/components/migration/", config17), + ...convertConfigurationFile("browser/components/pagedata/", config18), + ...convertConfigurationFile("browser/components/pocket/", config19), + ...convertConfigurationFile( + "browser/components/resistfingerprinting/test/mochitest/", + config20 + ), + ...convertConfigurationFile("browser/components/search/", config21), + ...convertConfigurationFile("browser/components/urlbar/", config22), + ...convertConfigurationFile("browser/extensions/newtab/", config23), + ...convertConfigurationFile( + "browser/extensions/pictureinpicture/tests/browser/", + config24 + ), + ...convertConfigurationFile( + "browser/extensions/search-detection/tests/browser/", + config25 + ), + ...convertConfigurationFile("devtools/", config26), + ...convertConfigurationFile("devtools/client/", config28), + ...convertConfigurationFile("devtools/client/debugger/src/", config34), + ...convertConfigurationFile("devtools/client/dom/", config37), + ...convertConfigurationFile( + "devtools/client/framework/test/reload/", + config39 + ), + ...convertConfigurationFile("devtools/client/jsonview/", config45), + ...convertConfigurationFile("devtools/client/memory/", config46), + ...convertConfigurationFile("devtools/client/netmonitor/test/", config48), + ...convertConfigurationFile("devtools/client/performance-new/", config50), + ...convertConfigurationFile("devtools/client/shared/components/", config53), + ...convertConfigurationFile("devtools/server/tests/xpcshell/", config63), + ...convertConfigurationFile("devtools/shared/", config64), + ...convertConfigurationFile("dom/base/test/jsmodules/", config74), + ...convertConfigurationFile("dom/fs/test/common/", config75), + ...convertConfigurationFile("dom/fs/test/mochitest/worker/", config76), + ...convertConfigurationFile("dom/fs/test/xpcshell/worker/", config77), + ...convertConfigurationFile("dom/media/mediasource/test/", config78), + ...convertConfigurationFile( + "dom/quota/test/modules/system/worker/", + config79 + ), + ...convertConfigurationFile("js/src/builtin/", config80), + ...convertConfigurationFile("mobile/android/", config81), + ...convertConfigurationFile( + "mobile/android/android-components/components/feature/webcompat-reporter/src/main/assets/extensions/webcompat-reporter/", + config82 + ), + ...convertConfigurationFile( + "mobile/android/examples/messaging_example/app/src/main/assets/messaging/", + config83 + ), + ...convertConfigurationFile( + "mobile/android/examples/port_messaging_example/app/src/main/assets/messaging/", + config84 + ), + ...convertConfigurationFile( + "mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/", + config85 + ), + ...convertConfigurationFile( + "mobile/android/geckoview/src/androidTest/assets/web_extensions/", + config86 + ), + ...convertConfigurationFile("mobile/shared/", config87), + ...convertConfigurationFile("mobile/shared/components/extensions/", config88), + ...convertConfigurationFile( + "mobile/shared/components/extensions/test/mochitest/", + config89 + ), + ...convertConfigurationFile( + "mobile/shared/components/extensions/test/xpcshell/", + config90 + ), + ...convertConfigurationFile("netwerk/test/perf/", config91), + ...convertConfigurationFile("remote/marionette/", config92), + ...convertConfigurationFile("remote/marionette/test/xpcshell/", config93), + ...convertConfigurationFile("security/", config94), + ...convertConfigurationFile("security/manager/ssl/tests/", config95), + ...convertConfigurationFile("security/manager/tools/", config96), + ...convertConfigurationFile("services/sync/tests/tps/", config97), + ...convertConfigurationFile("taskcluster/docker/index-task/", config98), + ...convertConfigurationFile("taskcluster/docker/periodic-updates/", config99), + ...convertConfigurationFile( + "testing/talos/talos/tests/perf-reftest-singletons/", + config100 + ), + ...convertConfigurationFile( + "testing/mozbase/mozprofile/tests/files/dummy-profile/", + config101 + ), + ...convertConfigurationFile("testing/performance/", config102), + ...convertConfigurationFile("testing/raptor/", config103), + ...convertConfigurationFile("testing/talos/", config104), + ...convertConfigurationFile( + "testing/talos/talos/tests/devtools/addon/content/", + config105 + ), + ...convertConfigurationFile( + "testing/talos/talos/tests/perf-reftest/", + config106 + ), + ...convertConfigurationFile("toolkit/", config107), + ...convertConfigurationFile( + "toolkit/components/antitracking/test/browser/", + config108 + ), + ...convertConfigurationFile("toolkit/components/extensions/", config109), + ...convertConfigurationFile( + "toolkit/components/extensions/child/", + config110 + ), + ...convertConfigurationFile( + "toolkit/components/extensions/parent/", + config111 + ), + ...convertConfigurationFile( + "toolkit/components/extensions/test/browser/", + config112 + ), + ...convertConfigurationFile( + "toolkit/components/extensions/test/mochitest/", + config113 + ), + ...convertConfigurationFile( + "toolkit/components/extensions/test/xpcshell/", + config114 + ), + ...convertConfigurationFile( + "toolkit/components/extensions/test/xpcshell/webidl-api/", + config115 + ), + ...convertConfigurationFile("toolkit/components/narrate/", config116), + ...convertConfigurationFile("toolkit/components/normandy/test/", config117), + ...convertConfigurationFile( + "toolkit/components/passwordmgr/test/browser/", + config118 + ), + ...convertConfigurationFile( + "toolkit/components/passwordmgr/test/mochitest/", + config119 + ), + ...convertConfigurationFile("toolkit/components/prompts/test/", config120), + ...convertConfigurationFile("toolkit/components/reader/", config121), + ...convertConfigurationFile("toolkit/content/", config122), + ...convertConfigurationFile("toolkit/modules/subprocess/", config123), + ...convertConfigurationFile("toolkit/mozapps/extensions/", config124), + ...convertConfigurationFile( + "toolkit/mozapps/extensions/test/browser/", + config125 + ), + ...convertConfigurationFile( + "toolkit/mozapps/extensions/test/xpcshell/", + config126 + ), + ...convertConfigurationFile("tools/lint/eslint/", config127), + ...convertConfigurationFile( + "tools/lint/eslint/eslint-plugin-mozilla/lib/configs/", + config128 + ), + ...convertConfigurationFile("tools/tryselect/selectors/chooser/", config130), + ...convertConfigurationFile("tools/ts/", config131), +]; diff --git a/eslint.config.mjs b/eslint.config.mjs index c57a1e8ea546..62c825fc3cac 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -2,14 +2,31 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; +import sdl from "@microsoft/eslint-plugin-sdl"; +import eslintConfigPrettier from "eslint-config-prettier"; +import html from "eslint-plugin-html"; +import importPlugin from "eslint-plugin-import"; +import json from "eslint-plugin-json"; +import lit from "eslint-plugin-lit"; +import mozilla from "eslint-plugin-mozilla"; +import reactHooks from "eslint-plugin-react-hooks"; -const mozilla = require("eslint-plugin-mozilla"); -const globalIgnores = require("./.eslintrc-ignores.js"); -const { testPaths } = require("./.eslintrc-test-paths.js"); -const { rollouts } = require("./.eslintrc-rollouts.js"); -const fs = require("fs"); -const path = require("path"); +import fs from "fs"; +import globals from "globals"; +import path from "path"; +import { fileURLToPath } from "url"; + +import globalIgnores from "./.eslintrc-ignores.js"; +import testPathsConfig from "./.eslintrc-test-paths.js"; +import repositoryGlobals from "./eslint-file-globals.config.mjs"; +import rollouts from "./eslint-rollouts.config.mjs"; +import subdirConfigs from "./eslint-subdirs.config.mjs"; + +// Compatibility handling for Node v18. When we update to v20+, we can replace +// this with `import.meta.dirname`. +const dirname = path.dirname(fileURLToPath(import.meta.url)); + +const testPaths = testPathsConfig.testPaths; function readFile(filePath) { return fs @@ -18,289 +35,372 @@ function readFile(filePath) { .filter(p => p && !p.startsWith("#")); } -const ignorePatterns = [ - ...globalIgnores, - ...readFile( - path.join(__dirname, "tools", "rewriting", "ThirdPartyPaths.txt") - ), - ...readFile(path.join(__dirname, "tools", "rewriting", "Generated.txt")), - ...readFile( - path.join( - __dirname, - "devtools", - "client", - "debugger", - "src", - ".eslintignore" - ) - ).map(p => `devtools/client/debugger/src/${p}`), -]; const httpTestingPaths = [ - "**/*mixedcontent", - "**/*CrossOrigin", - "**/*crossorigin", - "**/*cors", - "**/*downgrade", - "**/*Downgrade", + `**/*mixedcontent*.{${mozilla.allFileExtensions.join(",")}}`, + `**/*CrossOrigin*.{${mozilla.allFileExtensions.join(",")}}`, + `**/*crossorigin*.{${mozilla.allFileExtensions.join(",")}}`, + `**/*cors*.{${mozilla.allFileExtensions.join(",")}}`, + `**/*downgrade*.{${mozilla.allFileExtensions.join(",")}}`, + `**/*Downgrade*.{${mozilla.allFileExtensions.join(",")}}`, ]; -module.exports = { - settings: { - "import/extensions": [".mjs"], - "import/resolver": { - [path.resolve(__dirname, "srcdir-resolver.js")]: {}, - node: {}, +function wrapPathsWithAllExts(paths, excludedExts = []) { + let extensions = mozilla.allFileExtensions.filter( + f => !excludedExts.includes(f) + ); + return paths.map(p => { + if (p.endsWith("**")) { + return p + `/*.{${extensions.join(",")}}`; + } + if (p.endsWith("/")) { + return p + `**/*.{${extensions.join(",")}}`; + } + return p; + }); +} + +function wrapPathsInConfig(configs) { + for (let config of configs) { + config.files = wrapPathsWithAllExts(config.files); + } + return configs; +} + +let config = [ + { + name: "import-plugin-settings", + settings: { + "import/extensions": [".mjs"], + "import/resolver": { + [path.resolve(dirname, "srcdir-resolver.js")]: {}, + node: {}, + }, }, }, - ignorePatterns, - // Ignore eslint configurations in parent directories. - root: true, - env: { - es2024: true, + { + name: "ignores", + ignores: [ + ...globalIgnores, + ...readFile( + path.join(dirname, "tools", "rewriting", "ThirdPartyPaths.txt") + ), + ...readFile(path.join(dirname, "tools", "rewriting", "Generated.txt")), + ...readFile( + path.join( + dirname, + "devtools", + "client", + "debugger", + "src", + ".eslintignore" + ) + ).map(p => `devtools/client/debugger/src/${p}`), + ], }, - // New rules and configurations should generally be added in - // tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js to - // allow external repositories that use the plugin to pick them up as well. - extends: [ - "plugin:mozilla/recommended", - "plugin:json/recommended-with-comments-legacy", - "prettier", - ], - plugins: ["mozilla", "html", "import", "json", "promise", "lit"], - rules: { - "lit/quoted-expressions": ["error", "never"], - "lit/no-invalid-html": "error", + { + name: "all-files", + files: wrapPathsWithAllExts(["**"]), + plugins: { lit }, + rules: { + "lit/quoted-expressions": ["error", "never"], + "lit/no-invalid-html": "error", + }, }, - overrides: [ - { - files: ["*.*"], + { + name: "source-type-script", + files: ["**/*.{js,json,html,sjs,xhtml}"], + languageOptions: { + sourceType: "script", + }, + }, + ...mozilla.configs["flat/recommended"], + { + name: "json-recommended-with-comments", + files: ["**/*.json"], + ...json.configs["recommended-with-comments"], + }, + { + name: "eslint-plugin-html", + files: ["**/*.html", "**/*.xhtml"], + plugins: { html }, + }, + + { + name: "define-globals-for-browser-env", + files: wrapPathsWithAllExts(["**"], ["sjs"]), + ignores: [ // The browser environment is not available for system modules, sjs, workers // or any of the xpcshell-test files. - excludedFiles: [ - "*.sys.mjs", - "*.sjs", - "**/?(*.)worker.?(m)js", - ...testPaths.xpcshell.map(filePath => `${filePath}**`), - ], - env: { - browser: true, + "**/*.sys.mjs", + "**/?(*.)worker.?(m)js", + ...wrapPathsWithAllExts(testPaths.xpcshell, ["mjs", "sjs"]), + ], + languageOptions: { + globals: globals.browser, + }, + }, + { + // Generally we assume that all files, except mjs ones are in our + // privileged and specific environment. mjs are handled separately by + // the recommended configuration in eslint-plugin-mozilla. + name: "define-privileged-and-specific-globas-for-most-files", + files: wrapPathsWithAllExts(["**"], ["json"]), + ignores: ["browser/components/storybook/**", "tools"], + languageOptions: { + globals: { + ...mozilla.environments.privileged.globals, + ...mozilla.environments.specific.globals, }, }, - { - files: ["*.*"], - env: { - "mozilla/privileged": true, - "mozilla/specific": true, - }, - rules: { - // Require braces around blocks that start a new line. This must be - // configured after eslint-config-prettier is included (via `extends` - // above), as otherwise that configuration disables it. Hence, we do - // not include it in - // `tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js`. - curly: ["error", "all"], - }, + }, + { + name: "define-globals-for-node-files", + files: [ + // All .eslintrc.mjs files are in the node environment, so turn that + // on here. + "**/.eslintrc*.mjs", + // .js files in the top-level are generally assumed to be node. + "\.*.js", + // *.config.js files are generally assumed to be configuration files + // based for node. + "**/*.config.js", + // The resolver for moz-src for eslint, vscode etc. + "srcdir-resolver.js", + ], + languageOptions: { + globals: { ...globals.node, ...mozilla.turnOff(globals.browser) }, }, - { - files: [ - // All .eslintrc.js files are in the node environment, so turn that - // on here. - // https://github.com/eslint/eslint/issues/13008 - ".eslintrc*.js", - // *.config.js files are generally assumed to be configuration files - // based for node. - "*.config.?(m)js", - // The resolver for moz-src for eslint, vscode etc. - "srcdir-resolver.js", - ], - env: { - node: true, - browser: false, - }, + }, + + { + name: "browser-no-more-globals", + files: ["browser/base/content/browser.js"], + rules: { + "mozilla/no-more-globals": "error", }, - { - files: ["browser/base/content/browser.js"], - rules: { - "mozilla/no-more-globals": "error", - }, - }, - { - files: [ - "**/*.jsx", - "browser/components/pocket/content/**/*.js", - "browser/components/storybook/.storybook/**/*.mjs", - ], + }, + { + name: "jsx-files", + files: [ + "**/*.jsx", + "browser/components/pocket/content/**/*.js", + "browser/components/storybook/.storybook/**/*.mjs", + ], + languageOptions: { parserOptions: { ecmaFeatures: { jsx: true, }, }, }, - { - files: ["browser/components/storybook/**"], - env: { - "mozilla/privileged": false, - }, + }, + { + name: "eslint-plugin-import-rules", + files: ["**/*.mjs"], + plugins: { import: importPlugin }, + rules: { + "import/default": "error", + "import/export": "error", + "import/named": "error", + "import/namespace": "error", + "import/newline-after-import": "error", + "import/no-duplicates": "error", + "import/no-absolute-path": "error", + "import/no-named-default": "error", + "import/no-named-as-default": "error", + "import/no-named-as-default-member": "error", + "import/no-self-import": "error", + "import/no-unassigned-import": "error", + "import/no-unresolved": [ + "error", + // Bug 1773473 - Ignore resolver URLs for chrome and resource as we + // do not yet have a resolver for them. + { ignore: ["chrome://", "resource://"] }, + ], + "import/no-useless-path-segments": "error", }, - { - files: ["*.mjs"], - rules: { - "import/default": "error", - "import/export": "error", - "import/named": "error", - "import/namespace": "error", - "import/newline-after-import": "error", - "import/no-duplicates": "error", - "import/no-absolute-path": "error", - "import/no-named-default": "error", - "import/no-named-as-default": "error", - "import/no-named-as-default-member": "error", - "import/no-self-import": "error", - "import/no-unassigned-import": "error", - "import/no-unresolved": [ - "error", - // Bug 1773473 - Ignore resolver URLs for chrome and resource as we - // do not yet have a resolver for them. - { ignore: ["chrome://", "resource://"] }, - ], - "import/no-useless-path-segments": "error", - }, + }, + { + name: "turn-off-unassigned-import-for-stories", + // Turn off no-unassigned-import for files that typically test our + // custom elements, which are imported for the side effects (ie + // the custom element being registered) rather than any particular + // export: + files: ["**/*.stories.mjs"], + plugins: { import: importPlugin }, + rules: { + "import/no-unassigned-import": "off", }, - { - // Turn off no-unassigned-import for files that typically test our - // custom elements, which are imported for the side effects (ie - // the custom element being registered) rather than any particular - // export: - files: ["**/*.stories.mjs"], - rules: { - "import/no-unassigned-import": "off", - }, - }, - { - files: ["**/test/**", "**/tests/**"], - extends: ["plugin:mozilla/general-test"], - }, - { - ...mozilla.configs["xpcshell-test"], - files: testPaths.xpcshell.map(filePath => `${filePath}**`), - excludedFiles: ["**/*.mjs", "**/*.sjs"], - }, - { - // If it is an xpcshell head file, we turn off global unused variable checks, as it - // would require searching the other test files to know if they are used or not. - // This would be expensive and slow, and it isn't worth it for head files. - // We could get developers to declare as exported, but that doesn't seem worth it. - files: testPaths.xpcshell.map(filePath => `${filePath}head*.js`), - rules: { - "no-unused-vars": [ - "error", - { - argsIgnorePattern: "^_", - vars: "local", - }, - ], - }, - }, - { - // This section enables errors of no-unused-vars globally for all test*.js - // files in xpcshell test paths. - // This is not done in the xpcshell-test configuration as we cannot pull - // in overrides from there. We should at some stage, aim to enable this - // for all files in xpcshell-tests. - files: testPaths.xpcshell.map(filePath => `${filePath}test*.js`), - rules: { - // No declaring variables that are never used - "no-unused-vars": [ - "error", - { - argsIgnorePattern: "^_", - vars: "all", - }, - ], - }, - }, - { - ...mozilla.configs["browser-test"], - files: testPaths.browser.map(filePath => `${filePath}**`), - excludedFiles: ["**/*.mjs", "**/*.sjs"], - }, - { - ...mozilla.configs["mochitest-test"], - files: testPaths.mochitest.map(filePath => `${filePath}**`), - excludedFiles: [ - "**/*.mjs", - "security/manager/ssl/tests/mochitest/browser/**", + }, + { + ...mozilla.configs["flat/general-test"], + files: wrapPathsWithAllExts(["**/test/**", "**/tests/**"]), + }, + { + ...mozilla.configs["flat/xpcshell-test"], + files: wrapPathsWithAllExts(testPaths.xpcshell, ["mjs", "sjs"]), + }, + { + name: "no-unused-vars-disable-on-headjs", + // If it is an xpcshell head file, we turn off global unused variable checks, as it + // would require searching the other test files to know if they are used or not. + // This would be expensive and slow, and it isn't worth it for head files. + // We could get developers to declare as exported, but that doesn't seem worth it. + files: testPaths.xpcshell.map(filePath => `${filePath}head*.js`), + rules: { + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + vars: "local", + }, ], }, - { - ...mozilla.configs["chrome-test"], - files: testPaths.chrome.map(filePath => `${filePath}**`), - excludedFiles: ["**/*.mjs", "**/*.sjs"], - }, - { - env: { - // Ideally we wouldn't be using the simpletest env here, but our uses of - // js files mean we pick up everything from the global scope, which could - // be any one of a number of html files. So we just allow the basics... - "mozilla/simpletest": true, - }, - files: [ - ...testPaths.mochitest.map(filePath => `${filePath}/**/*.js`), - ...testPaths.chrome.map(filePath => `${filePath}/**/*.js`), + }, + { + name: "no-unused-vars-for-xpcshell", + // This section enables errors of no-unused-vars globally for all test*.js + // files in xpcshell test paths. + // This is not done in the xpcshell-test configuration as we cannot pull + // in overrides from there. We should at some stage, aim to enable this + // for all files in xpcshell-tests. + files: testPaths.xpcshell.map(filePath => `${filePath}test*.js`), + rules: { + // No declaring variables that are never used + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + vars: "all", + }, ], - excludedFiles: ["**/*.mjs", "**/*.sjs"], }, - { - // Some directories have multiple kinds of tests, and some rules - // don't work well for HTML-based mochitests, so disable those. - files: testPaths.xpcshell - .concat(testPaths.browser) - .map(filePath => [`${filePath}/**/*.html`, `${filePath}/**/*.xhtml`]) - .flat(), - rules: { - // plain/chrome mochitests don't automatically include Assert, so - // autofixing `ok()` to Assert.something is bad. - "mozilla/no-comparison-or-assignment-inside-ok": "off", + }, + { + ...mozilla.configs["flat/browser-test"], + files: wrapPathsWithAllExts(testPaths.browser, ["mjs", "sjs"]), + }, + { + ...mozilla.configs["flat/mochitest-test"], + files: wrapPathsWithAllExts(testPaths.mochitest, ["mjs"]), + ignores: ["security/manager/ssl/tests/mochitest/browser/**"], + }, + { + ...mozilla.configs["flat/chrome-test"], + files: wrapPathsWithAllExts(testPaths.chrome, ["mjs", "sjs"]), + }, + { + name: "simpletest", + languageOptions: { + globals: { + ...mozilla.environments.simpletest.globals, }, }, - { - // Some directories reuse `test_foo.js` files between mochitest-plain and - // unit tests, or use custom postMessage-based assertion propagation into - // browser tests. Ignore those too: - files: [ - // Reuses xpcshell unit test scripts in mochitest-plain HTML files. - "dom/indexedDB/test/**", - // Dispatches functions to the webpage in ways that are hard to detect. - "toolkit/components/antitracking/test/**", - ], - rules: { - "mozilla/no-comparison-or-assignment-inside-ok": "off", - }, + files: [ + ...testPaths.mochitest.map(filePath => `${filePath}/**/*.js`), + ...testPaths.chrome.map(filePath => `${filePath}/**/*.js`), + ], + }, + { + name: "multiple-test-kinds", + // Some directories have multiple kinds of tests, and some rules + // don't work well for HTML-based mochitests, so disable those. + files: testPaths.xpcshell + .concat(testPaths.browser) + .map(filePath => [`${filePath}/**/*.html`, `${filePath}/**/*.xhtml`]) + .flat(), + rules: { + // plain/chrome mochitests don't automatically include Assert, so + // autofixing `ok()` to Assert.something is bad. + "mozilla/no-comparison-or-assignment-inside-ok": "off", }, - { - // Rules of Hooks broadly checks for camelCase "use" identifiers, so - // enable only for paths actually using React to avoid false positives. - extends: ["plugin:react-hooks/recommended"], - files: [ - "browser/components/aboutwelcome/**", - "browser/components/asrouter/**", - "browser/components/pocket/**", - "browser/extensions/newtab/**", - "devtools/**", - ], - rules: { - // react-hooks/recommended has exhaustive-deps as a warning, we prefer - // errors, so that raised issues get addressed one way or the other. - "react-hooks/exhaustive-deps": "error", - }, + }, + { + name: "test-file-reuse", + // Some directories reuse `test_foo.js` files between mochitest-plain and + // unit tests, or use custom postMessage-based assertion propagation into + // browser tests. Ignore those too: + files: wrapPathsWithAllExts([ + // Reuses xpcshell unit test scripts in mochitest-plain HTML files. + "dom/indexedDB/test/**", + // Dispatches functions to the webpage in ways that are hard to detect. + "toolkit/components/antitracking/test/**", + ]), + rules: { + "mozilla/no-comparison-or-assignment-inside-ok": "off", }, - { - // Exempt files with these paths since they have to use http for full coverage - files: httpTestingPaths.map(filePath => `${filePath}**`), - rules: { - "@microsoft/sdl/no-insecure-url": "off", - }, + }, + { + // Rules of Hooks broadly checks for camelCase "use" identifiers, so + // enable only for paths actually using React to avoid false positives. + name: "react-hooks", + files: [ + "browser/components/aboutwelcome/**", + "browser/components/asrouter/**", + "browser/components/pocket/**", + "browser/extensions/newtab/**", + "devtools/**", + ], + ...reactHooks.configs["recommended-latest"], + plugins: { "react-hooks": reactHooks }, + rules: { + // react-hooks/recommended has exhaustive-deps as a warning, we prefer + // errors, so that raised issues get addressed one way or the other. + "react-hooks/exhaustive-deps": "error", }, - ...rollouts, - ], -}; + }, + { + name: "disable-no-insecure-url-for-http-testing", + // Exempt files with these paths since they have to use http for full coverage + files: httpTestingPaths, + plugins: { "@microsoft/sdl": sdl }, + rules: { + "@microsoft/sdl/no-insecure-url": "off", + }, + }, + + ...wrapPathsInConfig(subdirConfigs), + ...wrapPathsInConfig(repositoryGlobals), + + /** + * The items below should always be the last items in this order: + * + * - Enable eslint-config-prettier. + * - Enable curly. + * - Rollouts + */ + + // Turn off rules that conflict with Prettier. + { name: "eslint-config-prettier", ...eslintConfigPrettier }, + { + name: "enable-curly", + files: wrapPathsWithAllExts(["**/"]), + rules: { + // Require braces around blocks that start a new line. This must be + // configured after eslint-config-prettier is included, as otherwise + // eslint-config-prettier disables the curly rule. Hence, we do + // not include it in + // `tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js`. + curly: ["error", "all"], + }, + }, + ...wrapPathsInConfig(rollouts), +]; + +// The various places we get our globals from use true/false rather than +// the strings required by ESLint, so translate those here. +config.map(entry => { + if (entry.languageOptions?.globals) { + let newGlobals = {}; + for (let [key, value] of Object.entries(entry.languageOptions.globals)) { + if (typeof entry.languageOptions.globals[key] == "boolean") { + newGlobals[key] = value ? "writable" : "readonly"; + } else { + newGlobals[key] = value; + } + } + } + return entry; +}); + +export default config; diff --git a/moz.build b/moz.build index 14a57872e873..a931749b4581 100644 --- a/moz.build +++ b/moz.build @@ -29,6 +29,9 @@ with Files("docs/**"): BUG_COMPONENT = ("Developer Infrastructure", "Source Documentation") SCHEDULES.exclusive = ["docs"] +with Files("eslint*"): + BUG_COMPONENT = ("Developer Infrastructure", "Lint and Formatting") + with Files("mach*"): BUG_COMPONENT = ("Firefox Build System", "Mach Core") diff --git a/tools/lint/eslint/__init__.py b/tools/lint/eslint/__init__.py index d33c73b0cc98..4707dcd6045f 100644 --- a/tools/lint/eslint/__init__.py +++ b/tools/lint/eslint/__init__.py @@ -92,8 +92,6 @@ def lint(paths, config, binary=None, fix=None, rules=[], setup=None, **lintargs) binary, os.path.join(module_path, "node_modules", "eslint", "bin", "eslint.js"), # This keeps ext as a single argument. - "--ext", - "[{}]".format(",".join(config["extensions"])), "--format", "json", "--no-error-on-unmatched-pattern", diff --git a/tools/lint/rejected-words.yml b/tools/lint/rejected-words.yml index 991add8a6303..18b31fdd1b81 100644 --- a/tools/lint/rejected-words.yml +++ b/tools/lint/rejected-words.yml @@ -29,7 +29,8 @@ avoid-blacklist-and-whitelist: - java - kt exclude: - - '**/.eslintrc-rollouts.js' + - eslint-rollouts.config.mjs + - eslint-file-globals.config.mjs - browser/app/profile/firefox.js - browser/app/winlauncher/LauncherProcessWin.cpp - browser/base/content/browser.js