136 lines
4.8 KiB
TypeScript
136 lines
4.8 KiB
TypeScript
import { Command } from "cliffy";
|
|
import { DocParser, readDoc, writeDoc, Doc } from "./doc_load/load.ts";
|
|
import { expandGlob } from "https://deno.land/std@0.166.0/fs/mod.ts";
|
|
import ProgressBar from "https://deno.land/x/progress@v1.3.4/mod.ts";
|
|
|
|
function checkAndPrint(doc: Doc, another: Doc): [boolean, string[]] {
|
|
const diffs = [];
|
|
if (doc.name !== another.name) {
|
|
diffs.push(`name: ${doc.name} => ${another.name}`);
|
|
}
|
|
if (doc.author !== another.author) {
|
|
diffs.push(`author: ${doc.author} => ${another.author}`);
|
|
}
|
|
if (doc.star !== another.star) {
|
|
diffs.push(`star: ${doc.star} => ${another.star}`);
|
|
}
|
|
if (doc.fork !== another.fork) {
|
|
diffs.push(`fork: ${doc.fork} => ${another.fork}`);
|
|
}
|
|
if (doc.desc !== another.desc) {
|
|
diffs.push(`desc: "${doc.desc}" => ${another.desc}`);
|
|
}
|
|
if (doc.url !== another.url) {
|
|
diffs.push(`url: ${doc.url} => ${another.url}`);
|
|
}
|
|
if (doc.tags.length !== another.tags.length) {
|
|
diffs.push(`tags: ${doc.tags} => ${another.tags}`);
|
|
}
|
|
else {
|
|
doc.tags = doc.tags.sort();
|
|
another.tags = another.tags.sort();
|
|
for (let i = 0; i < doc.tags.length; i++) {
|
|
if (doc.tags[i] !== another.tags[i]) {
|
|
diffs.push(`tags: ${doc.tags} => ${another.tags}`);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (doc.readme !== another.readme) {
|
|
diffs.push(`readme: ${doc.readme} => ${another.readme}`);
|
|
}
|
|
if (doc.from_url !== another.from_url) {
|
|
diffs.push(`from_url: ${doc.from_url} => ${another.from_url}`);
|
|
}
|
|
return [diffs.length === 0, diffs];
|
|
}
|
|
|
|
async function validateDoc(path: string, parser: DocParser, fix?: boolean, log = console.log): Promise<void> {
|
|
try {
|
|
const content = await Deno.readTextFile(path);
|
|
const doc = parser.parseAlternative(content);
|
|
if (fix) {
|
|
await writeDoc(path, doc);
|
|
}
|
|
else {
|
|
try {
|
|
parser.parse(content);
|
|
const another = parser.parse(content);
|
|
const [isSame, errors] = checkAndPrint(doc, another);
|
|
if (!isSame) {
|
|
log(`File ${path} is not valid.`);
|
|
for (const error of errors) {
|
|
log("\t",error);
|
|
}
|
|
}
|
|
}
|
|
catch (e) {
|
|
if ( e instanceof Error) {
|
|
log(`File ${path} is not valid. error: ${e.name}`);
|
|
}
|
|
else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
log(`File ${path} is not valid. error: ${error.name}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
if(import.meta.main){
|
|
const app = new Command()
|
|
.name("validator")
|
|
.version("0.1.0")
|
|
.description("Validate and fix the doc files in the sample directory. glob is supported.")
|
|
.option("-v, --verbose", "Enable verbose mode.")
|
|
.option("-f, --fix", "Fix the doc files.")
|
|
.option("-p, --progress", "Show progress.")
|
|
.arguments("[pathes...:string]")
|
|
.action(async (options, ...pathes) => {
|
|
const { verbose, fix, progress } = options;
|
|
const parser = new DocParser();
|
|
if(pathes.length === 0){
|
|
console.log("No pathes specified. Use --help to see the usage.");
|
|
Deno.exit(1);
|
|
}
|
|
if (verbose) {
|
|
console.log("Verbose mode enabled.");
|
|
}
|
|
if (progress) {
|
|
console.log("Progress mode enabled.");
|
|
const targets = (await Promise.all(pathes.map(async (path) => {
|
|
const paths = [];
|
|
for await (const entry of expandGlob(path)) {
|
|
paths.push(entry.path);
|
|
}
|
|
return paths;
|
|
}))).flat();
|
|
|
|
const bar = new ProgressBar({
|
|
total: targets.length,
|
|
title: "Validating",
|
|
});
|
|
let count = 0;
|
|
for (const path of targets) {
|
|
await validateDoc(path, parser, fix, verbose ? (...args)=>{
|
|
bar.console(args.join(" "));
|
|
} : () => { });
|
|
bar.render(++count);
|
|
}
|
|
bar.end();
|
|
}
|
|
else {
|
|
for (const path of pathes) {
|
|
for await (const dir of expandGlob(path)) {
|
|
if (verbose) {
|
|
console.log(`Processing ${dir.path}`);
|
|
}
|
|
validateDoc(dir.path, parser, fix);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
await app.parse(Deno.args);
|
|
} |