Skip to content

Commit

Permalink
Migrate Openverse ESLint plugin to FlatConfig (#5049)
Browse files Browse the repository at this point in the history
* Migrate the plugin to ESLint v9
* Fix auto-fixable problems
* Fix other problems
* Update code owners
* Use ts config for js files
* Simplify gitignore handling
* Re-add vitest eslint rules to tests
* Downgrade ESLint to fix typescript-eslint/typescript-eslint#10191
* Add suggestions from the code review
* Update dependencies
---------

Signed-off-by: Olga Bulat <[email protected]>
  • Loading branch information
obulat authored Oct 31, 2024
1 parent 77cc631 commit 01dfe6f
Show file tree
Hide file tree
Showing 61 changed files with 1,746 additions and 1,265 deletions.
17 changes: 0 additions & 17 deletions .eslintignore

This file was deleted.

5 changes: 0 additions & 5 deletions .eslintrc.js

This file was deleted.

3 changes: 1 addition & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

/frontend/ @WordPress/openverse-frontend
/packages/js/ @WordPress/openverse-frontend
/.eslintignore @WordPress/openverse-frontend
/.eslintrc.js @WordPress/openverse-frontend
/eslint.config.mjs @WordPress/openverse-frontend
/.npmrc @WordPress/openverse-frontend
/.pnpmfile.cjs @WordPress/openverse-frontend
/.prettierignore @WordPress/openverse-frontend
Expand Down
2 changes: 1 addition & 1 deletion automations/js/src/count_user_reviewable_prs.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ query ($repoOwner: String!, $repo: String!, $cursor: String) {
try {
let hasNextPage = true
let cursor = null
let reviewablePrs = []
const reviewablePrs = []
const pullRequest = context.payload.pull_request
const result = {
pr_count: 0,
Expand Down
9 changes: 5 additions & 4 deletions automations/js/src/label_pr.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { readFileSync } from "fs"

import { PullRequest } from "./utils/pr.mjs"
import { IdSet } from "./utils/id_set.mjs"

Expand Down Expand Up @@ -40,12 +41,12 @@ function getLabelsFromChanges(allLabels, changes) {
* @returns {boolean} whether the list of labels covers all requirements
*/
function getIsFullyLabeled(labels) {
for (let req of exactlyOne) {
for (const req of exactlyOne) {
if (labels.filter((label) => label.name.includes(req)).length !== 1) {
return false
}
}
for (let req of atleastOne) {
for (const req of atleastOne) {
if (labels.filter((label) => label.name.includes(req)).length < 1) {
return false
}
Expand Down Expand Up @@ -133,7 +134,7 @@ export const main = async (octokit, core) => {
// For each label that we only need one of, we check if the PR already has
// such a label. If not, we check if the label pool contains any valid labels
// and add the first one we find.
for (let rule of exactlyOne) {
for (const rule of exactlyOne) {
if (finalLabels.items.some((label) => label.name.includes(rule))) {
core.info(`PR already has a "${rule}" label.`)
continue
Expand All @@ -147,7 +148,7 @@ export const main = async (octokit, core) => {

// For each label that we need at least one of, we add all the valid labels
// from the label pool. Our ID set implementation will weed out duplicates.
for (let rule of atleastOne) {
for (const rule of atleastOne) {
const validLabels = labelPool.filter((label) => label.name.includes(rule))
core.info(
`Adding labels "${validLabels
Expand Down
3 changes: 2 additions & 1 deletion automations/js/src/last_week_tonight.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if (!(pat && username && password)) process.exit(1)
/* Read GitHub information from the data files */

const githubDataFile = resolve("../data/github.yml") // resolved from `package.json`
// eslint-disable-next-line import/no-named-as-default-member
const githubInfo = yaml.load(readFileSync(githubDataFile))
const org = githubInfo.org
const repos = Object.values(githubInfo.repos)
Expand Down Expand Up @@ -87,7 +88,7 @@ const getItemsHtml = (title, items) => {
].sort()

// Aggregate items by stack
let itemsByStack = {}
const itemsByStack = {}

for (const stack of stacks) {
const stackName = stack.split(":")[1].trim()
Expand Down
2 changes: 1 addition & 1 deletion automations/js/src/project_automation/prs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async function syncReviews(core, pr, prBoard, prCard) {
async function syncIssues(core, pr, backlogBoard, destColumn) {
core.info(`Synchronizing issues for PR ${pr.nodeId}.`)

for (let linkedIssue of pr.linkedIssues) {
for (const linkedIssue of pr.linkedIssues) {
core.info(`Syncing issue ${linkedIssue.id}.`)

// Create new, or get the existing, card for the current issue.
Expand Down
2 changes: 1 addition & 1 deletion automations/js/src/project_thread_updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const GET_PROJECT_CARDS = `
*/
module.exports = async ({ github, core }) => {
try {
const isDryRun = process.env.DRY_RUN === "true" ?? false
const isDryRun = process.env.DRY_RUN === "true"

const currentDate = new Date()
// Create a date by subtracting DAYS_UPDATED_WITHIN days
Expand Down
2 changes: 1 addition & 1 deletion automations/js/src/sync_labels.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const main = async (octokit, core) => {
infraLabels.map((label) => [label.name, label])
)

for (let label of monoLabels) {
for (const label of monoLabels) {
if (exclusions.some((rule) => label.name.match(rule))) {
core.info(`Label "${label.name}" is excluded from sync.`)
continue
Expand Down
2 changes: 1 addition & 1 deletion automations/js/src/utils/pr.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export class PullRequest {
DISMISSED: 0,
PENDING: 0,
}
for (let reviewState of this.reviewStates) {
for (const reviewState of this.reviewStates) {
reviewCounts[reviewState] += 1
}
return reviewCounts
Expand Down
72 changes: 72 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { fileURLToPath } from "node:url"
import path from "node:path"
import fs from "node:fs"

// eslint-disable-next-line import/no-unresolved
import { config as defineConfig } from "typescript-eslint"
import { convertIgnorePatternToMinimatch } from "@eslint/compat"
import openverse from "@openverse/eslint-plugin"

const __dirname = path.dirname(fileURLToPath(import.meta.url))

const gitignoreFiles = [
path.resolve(__dirname, ".gitignore"),
path.resolve(__dirname, "frontend", ".gitignore"),
path.resolve(__dirname, "automations", "js", ".gitignore"),
path.resolve(__dirname, "packages", "js", "api-client", ".gitignore"),
]

/**
* Vendored in from `@eslint/compat` to support multiple ignore files.
* Reads an ignore file and returns a list of ignore patterns.
* @param {string[]} ignoreFilePaths The absolute path to the ignore file.
* @returns {string[]} An array of ignore patterns.
* @throws {Error} If the ignore file path is not an absolute path.
*/
function mapIgnoreFiles(ignoreFilePaths) {
for (const ignoreFilePath of ignoreFilePaths) {
if (!path.isAbsolute(ignoreFilePath)) {
throw new Error("The ignore file location must be an absolute path.")
}
}

/** @type {string[]} */
const ignores = []
for (const ignoreFilePath of ignoreFilePaths) {
const ignoreFile = fs.readFileSync(ignoreFilePath, "utf8")
const lines = ignoreFile.split(/\r?\n/u)
ignores.push(
...lines
.map((line) => line.trim())
.filter((line) => line && !line.startsWith("#"))
.map(convertIgnorePatternToMinimatch)
)
}

return ignores
}

// List of files from old .eslintignore
const eslintIgnores = [
"**/dist/**",
"frontend/.pnpm-store/**",
"frontend/.nuxt/**",
"frontend/.output/**",
"frontend/.remake/**",
"frontend/src/locales/*.json",
// Vendored module. See explanation in file
"frontend/test/unit/test-utils/render-suspended.ts",
"**/coverage/**",
"frontend/test/tapes/**",
"frontend/storybook-static/**",
"packages/**/dist/**",
]

export default defineConfig(
{
name: "openverse:ignore-files",
ignores: [...mapIgnoreFiles(gitignoreFiles), ...eslintIgnores],
},
{ files: [".pnpmfile.cjs"] },
...openverse.default.configs.project
)
6 changes: 3 additions & 3 deletions frontend/scripts/document-media.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function getInterfaceFields(node, ast) {
function extractComments(node, ast) {
const fullText = node.getFullText(ast)

let commentRanges = ts.getLeadingCommentRanges(fullText, 0)
const commentRanges = ts.getLeadingCommentRanges(fullText, 0)
if (!commentRanges) {
return undefined
}
Expand All @@ -140,8 +140,8 @@ function extractComments(node, ast) {
return undefined
}

let links = []
let text = comments
const links = []
const text = comments
.at(-1) // retain only the last doc comment
.split("\n")
.map((line) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const handleSubmit = async (event: Event) => {
},
})
updateStatus(SENT)
} catch (error) {
} catch {
updateStatus(FAILED)
}
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VErrorSection/VErrorImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const i18n = useI18n({ useScope: "global" })
const images = Object.fromEntries(
imageInfo.errors.map((errorItem) => {
let image = errorItem.image
const image = errorItem.image
const errorImage: ErrorImage = {
...image,
originalTitle: image.title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const Template = (args) => ({
// Skip license type filters as they can disable license filters
let filterTypeIdx = 1
for (let i = 0; i < filterCount; i++) {
let filterType = filterTypes[filterTypeIdx]
const filterType = filterTypes[filterTypeIdx]
searchStore.toggleFilter({
filterType,
codeIdx: filterIdx,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VMediaInfo/VMediaDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const metadata = computed<null | Metadata[]>(() => {
if (!props.media) {
return null
}
let imageInfo =
const imageInfo =
props.media.frontendMediaType === IMAGE
? {
width: props.media.width,
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/VSafeBrowsing/VSafeBrowsing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ const sensitivityPath = computed(() => localePath("/sensitive-content"))
const featureFlagStore = useFeatureFlagStore()
const { $sendCustomEvent } = useNuxtApp()
let fetchSensitive = computed(() => featureFlagStore.isOn("fetch_sensitive"))
let setFetchSensitive = (data: Omit<CheckboxAttrs, "disabled">) => {
const fetchSensitive = computed(() => featureFlagStore.isOn("fetch_sensitive"))
const setFetchSensitive = (data: Omit<CheckboxAttrs, "disabled">) => {
const checked = data.checked ?? false
featureFlagStore.toggleFeature("fetch_sensitive", checked ? ON : OFF)
$sendCustomEvent("TOGGLE_FETCH_SENSITIVE", { checked })
Expand All @@ -36,8 +36,8 @@ let setFetchSensitive = (data: Omit<CheckboxAttrs, "disabled">) => {
}
const uiStore = useUiStore()
let blurSensitive = computed(() => uiStore.shouldBlurSensitive)
let setBlurSensitive = (data: { checked?: boolean }) => {
const blurSensitive = computed(() => uiStore.shouldBlurSensitive)
const setBlurSensitive = (data: { checked?: boolean }) => {
const checked = data.checked ?? false
uiStore.setShouldBlurSensitive(checked)
$sendCustomEvent("TOGGLE_BLUR_SENSITIVE", { checked })
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/VScrollableLine.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const scroll = (to: "start" | "end") => {
showScrollButton[to === "start" ? "end" : "start"] = true
let distToSide = getDistToSide(to, dir.value, innerContainer)
const distToSide = getDistToSide(to, dir.value, innerContainer)
let adjustedScrollStep = scrollStep
// If the scroll step is larger than the distance to the side, scroll
Expand All @@ -127,7 +127,7 @@ const scroll = (to: "start" | "end") => {
adjustedScrollStep = -adjustedScrollStep
}
let left = to === "start" ? -adjustedScrollStep : adjustedScrollStep
const left = to === "start" ? -adjustedScrollStep : adjustedScrollStep
buttonsRef.value?.scrollBy({ left, behavior: "smooth" })
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VTabs/VTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const getFocusDirection = (
}
const handleKeyDown = (event: KeyboardEvent) => {
let list = tabContext.tabs.value
const list = tabContext.tabs.value
.map((tab) => getDomElement(tab))
.filter(Boolean) as HTMLElement[]
const tabControlKeys = [
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/VTabs/VTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const tabGroupContext: TabsState = {
}
},
unregisterTab(tab: (typeof tabs)["value"][number]) {
let idx = tabs.value.indexOf(tab)
const idx = tabs.value.indexOf(tab)
if (idx !== -1) {
tabs.value.splice(idx, 1)
}
Expand All @@ -92,7 +92,7 @@ const tabGroupContext: TabsState = {
}
},
unregisterPanel(panel: (typeof panels)["value"][number]) {
let idx = panels.value.indexOf(panel)
const idx = panels.value.indexOf(panel)
if (idx !== -1) {
panels.value.splice(idx, 1)
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/composables/use-dialog-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export function useDialogControl({
watch(internalVisibleRef, (visible, _, onCleanup) => {
triggerA11yProps["aria-expanded"] = visible
if (shouldLockBodyScroll.value) {
visible ? lock() : unlock()
if (visible) {
lock()
} else {
unlock()
}
}
emit(visible ? "open" : "close")
onCleanup(() => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/layouts/search-layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const showScrollButton = ref(false)
*
* Note: template refs do not work in a Nuxt layout, so we get the `main-page` element using `document.getElementById`.
*/
let mainPageElement = ref<HTMLElement | null>(null)
const mainPageElement = ref<HTMLElement | null>(null)
const { y: mainPageY } = useScroll(mainPageElement)
watch(mainPageY, (y) => {
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/locales/scripts/json-pot-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ const getComment = (entry) => {
}

// comments given by the programmer, directed at the translator (#.)
let vars = checkStringForVars(entry.value)
const vars = checkStringForVars(entry.value)
if (vars) {
comment.push(vars)
}

// comments containing references to the program’s source code (#:)
let refComments = getRefComments(entry.lineage)
const refComments = getRefComments(entry.lineage)
if (refComments.length) {
comment.push(...refComments)
}
Expand All @@ -128,8 +128,8 @@ const toPot = (entry) => {
}

// string-string type mapping
let poEntry = []
let comment = getComment(entry)
const poEntry = []
const comment = getComment(entry)
if (comment) {
poEntry.push(comment)
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/locales/scripts/read-i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ const parseValue = (entry, valueNode) => {
* @return {Entry} the entry generated by parsing the node
*/
const parseObjProperty = (node) => {
let key = parseKey(node.key)
let comments = node.leadingComments?.map(parseComment).join("")
let entry = new Entry(key, comments)
const key = parseKey(node.key)
const comments = node.leadingComments?.map(parseComment).join("")
const entry = new Entry(key, comments)
parseValue(entry, node.value)
return entry
}
Expand Down
Loading

0 comments on commit 01dfe6f

Please sign in to comment.