Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ci): add anrlt4 judge in ci #373

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
- name: Run tsc check
run: pnpm check-types

- name: Run antlr4 all sql
run: pnpm antlr4 --all --check

test:
runs-on: ubuntu-latest
strategy:
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"chalk": "4.1.2",
"commitizen": "^4.3.0",
"console-table-printer": "^2.12.0",
"crypto": "^1.0.1",
"envinfo": "^7.11.1",
"glob": "^10.3.10",
"husky": "^8.0.3",
Expand All @@ -70,7 +71,7 @@
},
"repository": {
"type": "git",
"url": "https://github.com/DTStack/dt-sql-parser.git"
"url": "https://github.com/DTStack/dt-sql-parser.git"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
Expand All @@ -89,6 +90,8 @@
"*": [
"prettier --write --ignore-unknown"
],
"*.g4": ["antlr-format -c ./antlr.format.json -v"]
"*.g4": [
"antlr-format -c ./antlr.format.json -v"
]
}
}
16 changes: 12 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 66 additions & 24 deletions scripts/antlr4.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const fs = require('fs');
const argv = require('yargs-parser')(process.argv.slice(2));
const inquirer = require('inquirer');
const chalk = require('chalk');
const crypto = require('crypto');
const { cleanComment } = require('./cleanComment');

const grammarsPath = path.resolve(__dirname, '../src/grammar');
Expand All @@ -13,26 +14,57 @@ const languageEntries = fs.readdirSync(grammarsPath);

const baseCmd = 'antlr4ng -Dlanguage=TypeScript -visitor -listener -Xexact-output-dir -o';

function compile(language) {
const cmd = `${baseCmd} ${outputPath}/${language} ${grammarsPath}/${language}/*.g4`;
function getFileHash(filePath) {
if (!fs.existsSync(filePath)) return null;

if (language !== 'plsql' && fs.existsSync(`${outputPath}/${language}`)) {
console.info(chalk.green(`\nRemoving:`, chalk.gray(`${outputPath}/${language}/*`)));
fs.rmSync(`${outputPath}/${language}`, { recursive: true });
}
const fileBuffer = fs.readFileSync(filePath);
const hashSum = crypto.createHash('sha256');
hashSum.update(fileBuffer);

console.info(chalk.green('Executing:'), chalk.gray(cmd));
exec(cmd, (err) => {
if (err) {
console.error(
chalk.redBright(`\n[Antlr4 compile error]:`),
chalk.cyan(language),
chalk.gray(err)
);
} else {
cleanComment(language);
console.info(chalk.greenBright(`Compile ${language} succeeded!`));
return hashSum.digest('hex');
}

function compile(language) {
return new Promise((resolve, reject) => {
const outputDir = `${outputPath}/${language}`;
const grammarFiles = fs
.readdirSync(`${grammarsPath}/${language}`)
.filter((file) => file.endsWith('.g4'));
const previousHashes = grammarFiles.map((file) => ({
file,
hash: getFileHash(path.join(outputDir, file.replace('.g4', '.ts'))),
}));

if (language !== 'plsql' && fs.existsSync(`${outputPath}/${language}`)) {
console.info(chalk.green(`\nRemoving:`, chalk.gray(`${outputPath}/${language}/*`)));
fs.rmSync(`${outputPath}/${language}`, { recursive: true });
}

const cmd = `${baseCmd} ${outputDir} ${grammarsPath}/${language}/*.g4`;
console.info(chalk.green('Executing:'), chalk.gray(cmd));
exec(cmd, (err) => {
if (err) {
console.error(
chalk.redBright(`\n[Antlr4 compile error]:`),
chalk.cyan(language),
chalk.gray(err)
);
} else {
cleanComment(language);
console.info(chalk.greenBright(`Compile ${language} succeeded!`));

const changedFiles = grammarFiles.filter((file) => {
const newHash = getFileHash(path.join(outputDir, file.replace('.g4', '.ts')));
const prevHash = previousHashes.find((h) => h.file === file)?.hash;
return newHash !== prevHash;
});

if (changedFiles.length > 0) {
return reject(`${language} not run antlr4`);
}
resolve();
}
});
});
}

Expand All @@ -59,22 +91,32 @@ function prompt() {
});
}

async function antlr4AllSql() {
const errors = [];

const tasks = languageEntries.map((language) =>
compile(language).catch((err) => errors.push(err))
);

await Promise.all(tasks);

if (errors.length > 0 && argv.check) {
errors.forEach((error) => console.error(chalk.red(`- ${error}`)));
process.exit(1); // 非零退出表示错误
}
}

function main() {
if (argv.all) {
// compile all: yarn antlr4 --all
languageEntries.forEach((language) => {
compile(language);
});
antlr4AllSql();
} else if (argv.lang) {
// compile single: yarn antlr4 --lang=mysql
const supportedLanguage = languageEntries.find((language) =>
language.startsWith(argv.lang)
);

if (argv.lang === 'all') {
languageEntries.forEach((language) => {
compile(language);
});
antlr4AllSql();
} else if (supportedLanguage) {
compile(supportedLanguage);
} else {
Expand Down
Loading