TeaWeb/tools/dtsgen/index.ts

130 lines
4.4 KiB
TypeScript
Raw Normal View History

2020-03-28 13:58:36 +01:00
import {readFileSync, writeFileSync, mkdir, existsSync} from "fs";
2018-12-04 18:48:05 +01:00
import * as ts from "typescript";
import * as decl from "./declarator";
import * as glob from "glob";
import * as path from "path";
import * as mkdirp from "mkdirp";
2020-03-28 13:58:36 +01:00
import {removeSync} from "fs-extra";
import * as import_organizer from "./import_organizer";
import * as declare_fixup from "./declare_fixup";
2018-12-04 18:48:05 +01:00
let source_files: string[] = [];
let exclude_files: string[] = [];
2020-03-28 13:58:36 +01:00
let target_directory: string = "out.d/";
2018-12-04 18:48:05 +01:00
let verbose: boolean = false;
let config_file: string = undefined;
let base_path = process.cwd();
2020-03-28 13:58:36 +01:00
let module_mode: boolean = false;
2018-12-04 18:48:05 +01:00
let args = process.argv.slice(2);
while(args.length > 0) {
2020-03-28 13:58:36 +01:00
if(args[0] === "--file") {
2018-12-04 18:48:05 +01:00
source_files.push(args[1]);
args = args.slice(2);
2020-03-28 13:58:36 +01:00
} else if(args[0] === "--exclude") {
2018-12-04 18:48:05 +01:00
exclude_files.push(args[1]);
args = args.slice(2);
2020-03-28 13:58:36 +01:00
} else if(args[0] === "--destination") {
target_directory = args[1];
2018-12-04 18:48:05 +01:00
args = args.slice(2);
2020-03-28 13:58:36 +01:00
} else if(args[0] === "-v" || args[0] === "--verbose") {
2018-12-04 18:48:05 +01:00
verbose = true;
args = args.slice(1);
2020-03-28 13:58:36 +01:00
} else if(args[0] === "-c" || args[0] === "--config") {
2018-12-04 18:48:05 +01:00
config_file = args[1];
base_path = path.normalize(path.dirname(config_file));
args = args.slice(2);
2020-03-28 13:58:36 +01:00
} else if(args[0] === "-b" || args[0] === "--base-directory") {
base_path = args[1];
base_path = path.normalize(base_path);
args = args.slice(2);
2020-03-28 13:58:36 +01:00
} else if(args[0] === "-m" || args[0] === "--module") {
module_mode = true;
args = args.slice(1);
2018-12-04 18:48:05 +01:00
} else {
console.error("Invalid command line option %s", args[0]);
process.exit(1);
}
}
if(config_file) {
console.log("Loading config file");
const json = JSON.parse(readFileSync(config_file).toString());
if(!json) {
console.error("Failed to parse config!");
process.exit(1);
}
2020-03-28 13:58:36 +01:00
if(Array.isArray(json["source_files"]))
2018-12-04 18:48:05 +01:00
source_files.push(...json["source_files"]);
2020-03-28 13:58:36 +01:00
if(Array.isArray(json["exclude"]))
2018-12-04 18:48:05 +01:00
exclude_files.push(...json["exclude"]);
2020-03-28 13:58:36 +01:00
if(typeof json["target_directory"] === "string")
target_directory = json["target_directory"];
if(typeof json["base_directory"] === "string")
base_path = json["base_directory"];
if(typeof json["modular"] === "boolean")
module_mode = json["modular"];
2018-12-04 18:48:05 +01:00
}
if(verbose) {
console.log("Base path: " + base_path);
console.log("Input files:");
for(const file of source_files)
console.log(" - " + file);
2020-03-28 13:58:36 +01:00
console.log("Target directory: " + target_directory);
}
if(existsSync(target_directory)) {
removeSync(target_directory);
if(existsSync(target_directory)) {
console.error("Failed to remove target directory (%s)", target_directory);
process.exit(1);
}
2018-12-04 18:48:05 +01:00
}
const negate_files: string[] = [].concat.apply([], exclude_files.map(file => glob.sync(base_path + "/" + file))).map(file => path.normalize(file));
source_files.forEach(file => {
2020-03-28 13:58:36 +01:00
const glob_base = path.normalize(path.join(process.cwd(), base_path));
if(verbose)
console.log("Globbing %s", glob_base);
glob.sync(glob_base + "/" + file).forEach(_file => {
2018-12-04 18:48:05 +01:00
_file = path.normalize(_file);
2020-03-28 13:58:36 +01:00
if(!_file.startsWith(glob_base)) {
/* this should never happen */
console.log("Skipping %s because of unmatching base directory.", _file);
return;
}
2018-12-04 18:48:05 +01:00
for(const n_file of negate_files) {
if(n_file == _file) {
console.log("Skipping %s", _file);
return;
}
}
2020-03-28 13:58:36 +01:00
const relpath = _file.substr(glob_base.length);
2018-12-04 18:48:05 +01:00
let source = ts.createSourceFile(
_file,
readFileSync(_file).toString(),
ts.ScriptTarget.ES2015,
true
);
2020-03-28 13:58:36 +01:00
console.log("Compile %s (%s)", _file, relpath);
const decl_nodes = decl.generate(source, {
2020-05-03 23:32:04 +02:00
remove_private: true,
2020-03-28 13:58:36 +01:00
module_mode: module_mode
});
const result = decl.print(source, declare_fixup.fix_declare_global(import_organizer.remove_unused(source, decl_nodes)));
2020-03-28 13:58:36 +01:00
let fpath = path.join(base_path, target_directory, relpath);
fpath = fpath.substr(0, fpath.lastIndexOf(".")) + ".d.ts";
mkdirp(path.normalize(path.dirname(fpath)), error => {
if(error) throw error;
writeFileSync(fpath, result);
});
2018-12-04 18:48:05 +01:00
});
});