mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 06:00:21 +08:00
131 lines
3.9 KiB
JavaScript
131 lines
3.9 KiB
JavaScript
/*
|
|
* Copyright (C) 2024-present Puter Technologies Inc.
|
|
*
|
|
* This file is part of Puter.
|
|
*
|
|
* Puter is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published
|
|
* by the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
const fs = require("fs");
|
|
const path_ = require("path");
|
|
|
|
const rootdir = path_.resolve(process.argv[2] ?? '.');
|
|
|
|
const parser = require('@babel/parser');
|
|
const traverse = require('@babel/traverse').default;
|
|
const { ModuleDoc } = require("./defs");
|
|
const processors = require("./processors");
|
|
|
|
const doc_module = new ModuleDoc();
|
|
|
|
const handle_file = (code, context) => {
|
|
const ast = parser.parse(code);
|
|
|
|
const traverse_callbacks = {};
|
|
for ( const processor of processors ) {
|
|
if ( processor.match(context) ) {
|
|
for ( const key in processor.traverse ) {
|
|
if ( ! traverse_callbacks[key] ) {
|
|
traverse_callbacks[key] = [];
|
|
}
|
|
traverse_callbacks[key].push(processor.traverse[key]);
|
|
}
|
|
}
|
|
}
|
|
for ( const key in traverse_callbacks ) {
|
|
traverse(ast, {
|
|
[key] (path) {
|
|
context.skip = false;
|
|
for ( const callback of traverse_callbacks[key] ) {
|
|
callback(path, context);
|
|
if ( context.skip ) return;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Module and class files
|
|
{
|
|
const files = fs.readdirSync(rootdir);
|
|
for ( const file of files ) {
|
|
const stat = fs.statSync(path_.join(rootdir, file));
|
|
if ( stat.isDirectory() ) {
|
|
continue;
|
|
}
|
|
if ( ! file.endsWith('.js') ) continue;
|
|
|
|
const type =
|
|
file.endsWith('Service.js') ? 'service' :
|
|
file.endsWith('Module.js') ? 'module' :
|
|
null;
|
|
|
|
if ( type === null ) continue;
|
|
|
|
console.log('file', file);
|
|
const code = fs.readFileSync(path_.join(rootdir, file), 'utf8');
|
|
|
|
const firstLine = code.slice(0, code.indexOf('\n'));
|
|
let metadata = {};
|
|
const METADATA_PREFIX = '// METADATA // ';
|
|
if ( firstLine.startsWith(METADATA_PREFIX) ) {
|
|
metadata = JSON.parse(firstLine.slice(METADATA_PREFIX.length));
|
|
}
|
|
|
|
const context = {
|
|
metadata,
|
|
type,
|
|
doc_module,
|
|
filename: file,
|
|
};
|
|
|
|
handle_file(code, context);
|
|
}
|
|
}
|
|
|
|
// Library files
|
|
if ( fs.existsSync(path_.join(rootdir, 'lib')) ) {
|
|
const files = fs.readdirSync(path_.join(rootdir, 'lib'));
|
|
for ( const file of files ) {
|
|
if ( file.startsWith('_') ) continue;
|
|
|
|
const code = fs.readFileSync(path_.join(rootdir, 'lib', file), 'utf8');
|
|
|
|
const firstLine = code.slice(0, code.indexOf('\n'));
|
|
let metadata = {};
|
|
const METADATA_PREFIX = '// METADATA // ';
|
|
if ( firstLine.startsWith(METADATA_PREFIX) ) {
|
|
metadata = JSON.parse(firstLine.slice(METADATA_PREFIX.length));
|
|
}
|
|
|
|
const doc_item = doc_module.add_lib();
|
|
doc_item.name = metadata.def ?? file.slice(0, -3);
|
|
|
|
const context = {
|
|
metadata,
|
|
type: 'lib',
|
|
doc_module,
|
|
doc_item,
|
|
filename: file,
|
|
};
|
|
|
|
handle_file(code, context);
|
|
}
|
|
}
|
|
|
|
const outfile = path_.join(rootdir, 'README.md');
|
|
|
|
const out = doc_module.toMarkdown();
|
|
|
|
fs.writeFileSync(outfile, out); |