Browse Source

dev(tools): add missing header adding to license-headers

KernelDeimos 10 months ago
parent
commit
713b1f5889
3 changed files with 171 additions and 5 deletions
  1. 1 1
      tools/comment-parser/main.js
  2. 3 1
      tools/file-walker/test.js
  3. 167 3
      tools/license-headers/main.js

+ 1 - 1
tools/comment-parser/main.js

@@ -235,7 +235,7 @@ const CommentParser = () => {
                         }],
                         block: ['block', {
                             start: '/*',
-                            end: '*/',
+                            end: ' */',
                             prefix: ' * ',
                         }]
                     },

+ 3 - 1
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/,
     ]
 };
 

+ 167 - 3
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 <https://www.gnu.org/licenses/>.
+ */
+
 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);