'use strict'
const path = require('node:path')
const fs = require('node:fs')
const readline = require('node:readline')
const basePathEcosystemDocFile = path.join('docs', 'Guides', 'Ecosystem.md')
const ecosystemDocFile = path.join(__dirname, '..', '..', basePathEcosystemDocFile)
const failureTypes = {
improperFormat: 'improperFormat',
outOfOrderItem: 'outOfOrderItem'
}
module.exports = async function ({ core }) {
const results = await runCheck()
await handleResults({ core }, results)
}
async function runCheck () {
const stream = await fs.createReadStream(ecosystemDocFile)
const rl = readline.createInterface({
input: stream,
crlfDelay: Infinity
})
const failures = []
const successes = []
const moduleNameRegex = /^- \[`(.+)`\]/
let lineNumber = 0
let modules = []
let grouping = 'core'
for await (const line of rl) {
lineNumber += 1
if (line.startsWith('#### [Community]')) {
grouping = 'community'
modules = []
}
if (line.startsWith('#### [Community Tools]')) {
grouping = 'community-tools'
modules = []
}
if (line.startsWith('- [') !== true) {
continue
}
const moduleNameTest = moduleNameRegex.exec(line)
if (moduleNameTest === null) {
failures.push({
lineNumber,
grouping,
moduleName: 'unknown',
type: failureTypes.improperFormat
})
continue
}
const moduleName = moduleNameTest[1]
if (modules.length > 0) {
if (compare(moduleName, modules.at(-1)) > 0) {
failures.push({
lineNumber,
moduleName,
grouping,
type: failureTypes.outOfOrderItem
})
} else {
successes.push({ moduleName, lineNumber, grouping })
}
} else {
successes.push({ moduleName, lineNumber, grouping })
}
modules.push(moduleName)
}
return { failures, successes }
}
async function handleResults (scriptLibs, results) {
const { core } = scriptLibs
const { failures, successes } = results
const isError = !!failures.length
await core.summary
.addHeading(isError ? `❌ Ecosystem.md Lint (${failures.length} error${failures.length === 1 ? '' : 's'})` : '✅ Ecosystem Lint (no errors found)')
.addTable([
[
{ data: 'Status', header: true },
{ data: 'Section', header: true },
{ data: 'Module', header: true },
{ data: 'Details', header: true }],
...failures.map((failure) => [
'❌',
failure.grouping,
failure.moduleName,
`Line Number: ${failure.lineNumber.toString()} - ${failure.type}`
]),
...successes.map((success) => [
'✅',
success.grouping,
success.moduleName,
'-'
])
])
.write()
if (isError) {
failures.forEach((failure) => {
if (failure.type === failureTypes.improperFormat) {
core.error('The module name should be enclosed with backticks', {
title: 'Improper format',
file: basePathEcosystemDocFile,
startLine: failure.lineNumber
})
} else if (failure.type === failureTypes.outOfOrderItem) {
core.error(`${failure.moduleName} not listed in alphabetical order`, {
title: 'Out of Order',
file: basePathEcosystemDocFile,
startLine: failure.lineNumber
})
} else {
core.error('Unknown error')
}
})
core.setFailed('Failed when linting Ecosystem.md')
}
}
function compare (current, previous) {
return previous.localeCompare(
current,
'en',
{ sensitivity: 'base' }
)
}