From 713b1f5889c2e4055e054f4815b74f934451e520 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Wed, 10 Jul 2024 14:01:28 -0400 Subject: [PATCH] dev(tools): add missing header adding to license-headers --- tools/comment-parser/main.js | 2 +- tools/file-walker/test.js | 4 +- tools/license-headers/main.js | 170 +++++++++++++++++++++++++++++++++- 3 files changed, 171 insertions(+), 5 deletions(-) diff --git a/tools/comment-parser/main.js b/tools/comment-parser/main.js index 04412915..a6ddb8e7 100644 --- a/tools/comment-parser/main.js +++ b/tools/comment-parser/main.js @@ -235,7 +235,7 @@ const CommentParser = () => { }], block: ['block', { start: '/*', - end: '*/', + end: ' */', prefix: ' * ', }] }, diff --git a/tools/file-walker/test.js b/tools/file-walker/test.js index 603dd4bb..eec352f9 100644 --- a/tools/file-walker/test.js +++ b/tools/file-walker/test.js @@ -28,8 +28,10 @@ const EXCLUDE_LISTS = { /\/node_modules$/, /^node_modules$/, /package-lock\.json/, + /^src\/dev-center\/js/, /src\/backend\/src\/public\/assets/, - /^src\/gui\/src\/lib/ + /^src\/gui\/src\/lib/, + /^src\/puter\.js/, ] }; diff --git a/tools/license-headers/main.js b/tools/license-headers/main.js index 8c4a6bbe..97c6414e 100644 --- a/tools/license-headers/main.js +++ b/tools/license-headers/main.js @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2024 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 . + */ + const levenshtein = require('js-levenshtein'); const DiffMatchPatch = require('diff-match-patch'); const dmp = new DiffMatchPatch(); @@ -307,6 +326,153 @@ const cmd_check_fn = async () => { t.printTable(); }; +const cmd_sync_fn = async () => { + const comment_parser = CommentParser(); + const desired_header = fs.readFileSync( + path_.join(__dirname, '../../doc/license_header.txt'), + 'utf-8', + ); + const license_checker = LicenseChecker({ + comment_parser, + desired_header, + }); + + const counts = { + ok: 0, + missing: 0, + conflict: 0, + error: 0, + unsupported: 0, + }; + + const walk_iterator = walk({ + excludes: EXCLUDE_LISTS.NOT_SOURCE, + }, '.'); + for await ( const value of walk_iterator ) { + if ( value.is_dir ) continue; + + process.stdout.write(value.path + ' ... '); + + if ( ! license_checker.supports({ filename: value.name }) ) { + process.stdout.write(`\x1B[37;1mUNSUPPORTED\x1B[0m\n`); + counts.unsupported++; + continue; + } + + const source = fs.readFileSync(value.path, 'utf-8'); + const diff_info = await license_checker.compare({ + filename: value.name, + source, + }) + if ( ! diff_info ) { + counts.error++; + continue; + } + if ( ! diff_info.has_header ) { + if ( false ) fs.writeFileSync( + value.path, + comment_parser.output_comment({ + style: 'block', + filename: value.name, + text: desired_header, + }) + + '\n' + + source + ); + continue; + } + if ( diff_info ) { + if ( diff_info.distance !== 0 ) { + counts.conflict++; + process.stdout.write(`\x1B[31;1mCONFLICT\x1B[0m\n`); + } else { + counts.ok++; + process.stdout.write(`\x1B[32;1mOK\x1B[0m\n`); + } + } else { + console.log('NO COMMENT'); + } + } + + const { Table } = require('console-table-printer'); + const t = new Table({ + columns: [ + { + title: 'License Header', + name: 'situation', alignment: 'left', color: 'white_bold' }, + { + title: 'Number of Files', + name: 'count', alignment: 'right' }, + ], + colorMap: { + green: '\x1B[32;1m', + yellow: '\x1B[33;1m', + red: '\x1B[31;1m', + } + }); + + console.log(''); + + if ( counts.error > 0 ) { + console.log(`\x1B[31;1mTHERE WERE SOME ERRORS!\x1B[0m`); + console.log('check the log above for the stack trace'); + console.log(''); + t.addRow({ situation: 'error', count: counts.error }, + { color: 'red' }); + } + + console.log(dedent(` + \x1B[31;1mAny text below is mostly lies!\x1B[0m + This tool is still being developed and most of what's + described is "the plan" rather than a thing that will + actually happen. + \x1B[31;1m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\x1B[0m + `)); + + if ( counts.conflict ) { + console.log(dedent(` + \x1B[37;1mIt looks like you have some conflicts!\x1B[0m + Run the following command to update license headers: + + \x1B[36;1maddlicense sync\x1B[0m + + This will begin an interactive license update. + Any time the license doesn't quite match you will + be given the option to replace it or skip the file. + \x1B[90mSee \`addlicense help sync\` for other options.\x1B[0m + + You will also be able to choose + "remember for headers matching this one" + if you know the same issue will come up later. + `)); + } else if ( counts.missing ) { + console.log(dedent(` + \x1B[37;1mSome missing license headers!\x1B[0m + Run the following command to add the missing license headers: + + \x1B[36;1maddlicense sync\x1B[0m + `)); + } else { + console.log(dedent(` + \x1B[37;1mNo action to perform!\x1B[0m + Run the following command to do absolutely nothing: + + \x1B[36;1maddlicense sync\x1B[0m + `)); + } + + console.log(''); + + t.addRow({ situation: 'ok', count: counts.ok }, + { color: 'green' }); + t.addRow({ situation: 'missing', count: counts.missing }, + { color: 'yellow' }); + t.addRow({ situation: 'conflict', count: counts.conflict }, + { color: 'red' }); + t.addRow({ situation: 'unsupported', count: counts.unsupported }); + t.printTable(); +}; + const main = async () => { const { program } = require('commander'); const helptext = dedent(` @@ -343,9 +509,7 @@ const main = async () => { .description('synchronize files with license header rules') .option('-n, --non-interactive', 'disable prompting') .action(() => { - console.log('called sync'); - console.log(program.opts()); - console.log(cmd_sync.opts()); + run_command({ cmd: cmd_sync, cmd_fn: cmd_sync_fn }) }) program.parse(process.argv);