Merge pull request #482 from iptv-org/create-lint-js

Create check.yml
This commit is contained in:
Aleksandr Statciuk 2022-02-03 04:49:30 +03:00 committed by GitHub
commit 7ab56f33e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 916 additions and 0 deletions

19
.github/workflows/_check.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: _check
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened, edited]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download channels from API
run: |
mkdir -p scripts/data
curl -L -o scripts/data/channels.json https://iptv-org.github.io/api/channels.json
- id: files
uses: jitterbit/get-changed-files@v1
- run: npm install
- run: npm run lint -- ${{ steps.files.outputs.added_modified }}
- run: npm run validate -- ${{ steps.files.outputs.added_modified }}

817
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
{
"name": "epg",
"scripts": {
"lint": "node scripts/commands/lint.js",
"validate": "node scripts/commands/validate.js",
"act": "act workflow_dispatch",
"test": "npx jest --runInBand",
@ -26,6 +27,7 @@
"glob": "^7.2.0",
"iconv-lite": "^0.4.24",
"jest": "^27.3.1",
"libxmljs": "^0.19.7",
"lodash": "^4.17.21",
"markdown-include": "^0.4.3",
"mockdate": "^3.0.5",

76
scripts/commands/lint.js Normal file
View file

@ -0,0 +1,76 @@
const chalk = require('chalk')
const libxml = require('libxmljs')
const { program } = require('commander')
const { logger, file } = require('../core')
const xsd = `<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="site">
<xs:complexType>
<xs:sequence>
<xs:element ref="channels"/>
</xs:sequence>
<xs:attribute name="site" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<xs:element name="channels">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="channel"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="channel">
<xs:complexType mixed="true">
<xs:attribute name="lang" use="required" type="xs:string"/>
<xs:attribute name="site_id" use="required" type="xs:string"/>
<xs:attribute name="xmltv_id" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:schema>`
program.argument('<filepath>', 'Path to file to validate').parse(process.argv)
async function main() {
if (!program.args.length) {
logger.error('required argument "filepath" not specified')
}
let errors = []
for (const filepath of program.args) {
if (!filepath.endsWith('.xml')) continue
const xml = await file.read(filepath)
let localErrors = []
try {
const xsdDoc = libxml.parseXml(xsd)
const doc = libxml.parseXml(xml)
if (!doc.validate(xsdDoc)) {
localErrors = doc.validationErrors
}
} catch (error) {
localErrors.push(error)
}
if (localErrors.length) {
logger.info(`\n${chalk.underline(filepath)}`)
localErrors.forEach(error => {
const position = `${error.line}:${error.column}`
logger.error(` ${chalk.gray(position.padEnd(4, ' '))} ${error.message.trim()}`)
})
errors = errors.concat(localErrors)
}
}
if (errors.length) {
logger.error(chalk.red(`\n${errors.length} error(s)`))
process.exit(1)
}
}
main()

View file

@ -17,6 +17,8 @@ async function main() {
}
for (const filepath of program.args) {
if (!filepath.endsWith('.xml')) continue
const { site, channels } = await parser.parseChannels(filepath)
const output = []