From 9aeecb650a4ccb67ca28ef7ac25edbdcaa843af5 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Fri, 6 Dec 2024 12:36:35 -0500 Subject: [PATCH] doc: generate and edit comments for tools --- tools/check-translations.js | 27 ++++++++++-- tools/comment-parser/main.js | 57 ++++++++++++++++++++++++ tools/gen-release-notes.js | 7 +++ tools/license-headers/main.js | 46 ++++++++++++++++++++ tools/module-docgen/defs.js | 82 +++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 3 deletions(-) diff --git a/tools/check-translations.js b/tools/check-translations.js index 17e5361e..7cfc94f8 100644 --- a/tools/check-translations.js +++ b/tools/check-translations.js @@ -1,3 +1,4 @@ +// METADATA // {"ai-commented":{"service":"claude"}} /* * Copyright (C) 2024 Puter Technologies Inc. * @@ -25,7 +26,13 @@ function reportError(message) { process.stderr.write(`❌ ${message}\n`); } -// Check that each translation file is recorded in `translations` +/** +* Verifies that all translation files in the translations directory are properly registered +* in the translations object. Checks for required properties like name, code, and dictionary. +* Reports errors if translations are missing, improperly configured, or have mismatched codes. +* @async +* @returns {Promise} +*/ async function checkTranslationRegistrations() { const files = await fs.promises.readdir('./src/gui/src/i18n/translations'); for (const fileName of files) { @@ -53,7 +60,13 @@ async function checkTranslationRegistrations() { } } -// Ensure that translations only contain keys that exist in the en dictionary +/** +* Validates that translation dictionaries only contain keys present in en.js +* +* Iterates through all translations (except English) and checks that each key in their +* dictionary exists in the en.js dictionary. Reports errors for any keys that don't exist. +* Skips validation if the translation dictionary is missing or invalid. +*/ function checkTranslationKeys() { const enDictionary = translations.en.dictionary; @@ -72,7 +85,15 @@ function checkTranslationKeys() { } } -// Ensure that all keys passed to i18n() exist in the en dictionary +/** +* Checks for usage of i18n() calls in source files and verifies that all translation keys exist in en.js +* +* Scans JavaScript files in specified source directories for i18n() function calls using regex. +* Validates that each key used in these calls exists in the English translation dictionary. +* +* @async +* @returns {Promise} +*/ async function checkTranslationUsage() { const enDictionary = translations.en.dictionary; diff --git a/tools/comment-parser/main.js b/tools/comment-parser/main.js index 185cab09..ead8fc1c 100644 --- a/tools/comment-parser/main.js +++ b/tools/comment-parser/main.js @@ -1,3 +1,4 @@ +// METADATA // {"ai-commented":{"service":"claude"}} /* * Copyright (C) 2024 Puter Technologies Inc. * @@ -44,6 +45,14 @@ lib.dedent_lines = lines => { } }; + +/** +* Creates a StringStream object for parsing a string with position tracking +* @param {string} str - The string to parse +* @param {Object} [options] - Optional configuration object +* @param {Object} [options.state_] - Initial state with position +* @returns {Object} StringStream instance with parsing methods +*/ const StringStream = (str, { state_ } = {}) => { const state = state_ ?? { pos: 0 }; return { @@ -190,6 +199,13 @@ const BlockCommentParser = ({ }; }; + +/** +* Creates a writer for line-style comments with a specified prefix +* @param {Object} options - Configuration options +* @param {string} options.prefix - The prefix to use for each comment line +* @returns {Object} A comment writer object +*/ const LinesCommentWriter = ({ prefix }) => { return { write: (lines) => { @@ -202,6 +218,15 @@ const LinesCommentWriter = ({ prefix }) => { }; }; + +/** +* Creates a block comment writer with specified start/end markers and prefix +* @param {Object} options - Configuration options +* @param {string} options.start - Comment start marker (e.g. "/*") +* @param {string} options.end - Comment end marker (e.g. "* /") +* @param {string} options.prefix - Line prefix within comment (e.g. " * ") +* @returns {Object} Block comment writer object +*/ const BlockCommentWriter = ({ start, end, prefix }) => { return { write: (lines) => { @@ -217,6 +242,15 @@ const BlockCommentWriter = ({ start, end, prefix }) => { }; }; + +/** +* Creates a new CommentParser instance for parsing and handling source code comments +* +* @returns {Object} An object with methods: +* - supports: Checks if a file type is supported +* - extract_top_comments: Extracts comments from source code +* - output_comment: Formats and outputs comments in specified style +*/ const CommentParser = () => { const registry_ = { object: { @@ -263,6 +297,13 @@ const CommentParser = () => { }; + + /** + * Gets the language configuration for a given filename by extracting and validating its extension + * @param {Object} params - The parameters object + * @param {string} params.filename - The filename to get the language for + * @returns {Object} Object containing the language configuration + */ const get_language_by_filename = ({ filename }) => { const { language } = (({ filename }) => { const { language_id } = (({ filename }) => { @@ -293,6 +334,13 @@ const CommentParser = () => { return { language }; } + + /** + * Checks if a given filename is supported by the comment parser + * @param {Object} params - The parameters object + * @param {string} params.filename - The filename to check support for + * @returns {boolean} Whether the file type is supported + */ const supports = ({ filename }) => { try { get_language_by_filename({ filename }); @@ -338,6 +386,15 @@ const CommentParser = () => { return results; } + + /** + * Outputs a comment in the specified style for a given filename and text + * @param {Object} params - The parameters object + * @param {string} params.filename - The filename to determine comment style + * @param {string} params.style - The comment style to use ('lines' or 'block') + * @param {string} params.text - The text content of the comment + * @returns {string} The formatted comment string + */ const output_comment = ({ filename, style, text }) => { const { language } = get_language_by_filename({ filename }); diff --git a/tools/gen-release-notes.js b/tools/gen-release-notes.js index e2f1e027..93178eb8 100644 --- a/tools/gen-release-notes.js +++ b/tools/gen-release-notes.js @@ -1,3 +1,4 @@ +// METADATA // {"ai-commented":{"service":"claude"}} /* * Copyright (C) 2024 Puter Technologies Inc. * @@ -18,6 +19,7 @@ */ import { simpleGit } from 'simple-git'; +// GitHub repository URL for generating commit links in release notes const REPO_URL = 'https://github.com/HeyPuter/puter'; const params = { @@ -31,6 +33,7 @@ const git = simpleGit(); const log = await git.log({ from: params.from }); const commits = log.all; +// Array of all commits from git log between specified versions const CC_REGEX = /^([a-z0-9]+)(\([a-z0-9]+\))?:\s(.*)/; const parse_conventional_commit = message => { const parts = CC_REGEX.exec(message); @@ -84,6 +87,10 @@ const scope_aliases = { }; const complicated_cases = [ + /** + * Handles special cases for commit message transformations + * @type {Array} + */ function fix_i18n ({ commit, meta }) { if ( meta.type === 'fix' && meta.scope === 'i18n' ) { meta.type = 'i18n'; diff --git a/tools/license-headers/main.js b/tools/license-headers/main.js index 2a6a734e..704a8dc7 100644 --- a/tools/license-headers/main.js +++ b/tools/license-headers/main.js @@ -1,3 +1,4 @@ +// METADATA // {"ai-commented":{"service":"claude"}} /* * Copyright (C) 2024 Puter Technologies Inc. * @@ -29,6 +30,15 @@ const { CommentParser } = require('../comment-parser/main'); const fs = require('fs'); const path_ = require('path'); + +/** +* Compares two license headers and returns their Levenshtein distance and formatted diff +* @param {Object} params - The parameters object +* @param {string} params.header1 - First header text to compare +* @param {string} params.header2 - Second header text to compare +* @param {boolean} [params.distance_only=false] - If true, only return distance without diff +* @returns {Object} Object containing distance and formatted terminal diff +*/ const CompareFn = ({ header1, header2, distance_only = false }) => { // Calculate Levenshtein distance @@ -64,6 +74,13 @@ const CompareFn = ({ header1, header2, distance_only = false }) => { }; } +/** +* Creates a license checker instance that can compare and validate license headers +* @param {Object} params - Configuration parameters +* @param {Object} params.comment_parser - Comment parser instance to use +* @param {string} params.desired_header - The expected license header text +* @returns {Object} License checker instance with compare and supports methods +*/ const LicenseChecker = ({ comment_parser, desired_header, @@ -197,6 +214,15 @@ const license_check_test = async ({ options }) => { } }; + +/** +* Executes the main command line interface for the license header tool. +* Sets up Commander.js program with commands for checking and syncing license headers. +* Handles configuration file loading and command execution. +* +* @async +* @returns {Promise} Resolves when command execution is complete +*/ const cmd_check_fn = async () => { const comment_parser = CommentParser(); const license_checker = LicenseChecker({ @@ -335,6 +361,18 @@ const cmd_check_fn = async () => { t.printTable(); }; + +/** +* Synchronizes license headers in source files by adding missing headers and handling conflicts +* +* Walks through files, checks for license headers, and: +* - Adds headers to files missing them +* - Prompts user to resolve conflicts when headers don't match +* - Handles duplicate headers by allowing removal +* - Tracks counts of different header statuses (ok, missing, conflict, etc) +* +* @returns {Promise} Resolves when synchronization is complete +*/ const cmd_sync_fn = async () => { const comment_parser = CommentParser(); const desired_header = fs.readFileSync( @@ -547,6 +585,14 @@ const cmd_sync_fn = async () => { t.printTable(); }; + +/** +* Main entry point for the license header tool. +* Sets up command line interface using Commander and processes commands. +* Handles 'check' and 'sync' commands for managing license headers in files. +* +* @returns {Promise} Resolves when command processing is complete +*/ const main = async () => { const { program } = require('commander'); const helptext = dedent(` diff --git a/tools/module-docgen/defs.js b/tools/module-docgen/defs.js index d99ca827..23eb0f0c 100644 --- a/tools/module-docgen/defs.js +++ b/tools/module-docgen/defs.js @@ -1,6 +1,19 @@ +// METADATA // {"ai-commented":{"service":"claude"}} const dedent = require('dedent'); const doctrine = require('doctrine'); + +/** +* Out class - A utility class for generating formatted text output +* Provides methods for creating headings, line feeds, and text output +* +* ~~with a fluent interface.~~ +* ^ Nope, AI got this wrong but maybe it's a good idea to +* make this a fluent interface +* +* The constructor returns a bound function that +* maintains the output state and provides access to helper methods. +*/ class Out { constructor () { this.str = ''; @@ -15,13 +28,29 @@ class Out { this.str += '#'.repeat(n) + ' ' + text + '\n\n'; } + + /** + * Adds a line feed (newline) to the output string + * @returns {void} + */ lf () { this.str += '\n'; } + /** + * Append to the string + * @param {string} str + */ out (str) { this.str += str; } } + +/** +* Doc class serves as a base class for documentation generation. +* Provides core functionality for parsing and storing documentation comments +* using the doctrine parser. Contains methods for handling JSDoc-style +* comments and maintaining documentation state. +*/ class Doc { constructor () { this._construct(); @@ -32,25 +61,52 @@ class Doc { } } + +/** +* ModuleDoc class extends Doc to represent documentation for a module. +* Handles module-level documentation including services, libraries, and requirements. +* Provides methods for adding services/libraries and generating markdown documentation. +* Tracks external imports and generates notes about module dependencies. +*/ class ModuleDoc extends Doc { + /** + * Initializes the base properties for a ModuleDoc instance + * Sets up empty arrays for services, requires, and libs collections + * @private + */ _construct () { this.services = []; this.requires = []; this.libs = []; } + + /** + * Creates and adds a new service to this module's services array + * @returns {ServiceDoc} The newly created service document instance + */ add_service () { const service = new ServiceDoc(); this.services.push(service); return service; } + + /** + * Creates and adds a new LibDoc instance to the module's libs array + * @returns {LibDoc} The newly created LibDoc instance + */ add_lib () { const lib = new LibDoc(); this.libs.push(lib); return lib; } + + /** + * Populates a "notes" array for the module documentation + * based on findings about imports. + */ ready () { this.notes = []; const rel_requires = this.requires.filter(r => r.startsWith('../')); @@ -114,7 +170,19 @@ class ModuleDoc extends Doc { } } + +/** +* ServiceDoc class represents documentation for a service module. +* Handles parsing and formatting of service-related documentation including +* listeners, methods, and their associated parameters. Extends the base Doc class +* to provide specialized documentation capabilities for service components. +*/ class ServiceDoc extends Doc { + /** + * Represents documentation for a service + * Handles parsing and storing service documentation including listeners and methods + * Initializes with empty arrays for listeners and methods + */ _construct () { this.listeners = []; this.methods = []; @@ -206,7 +274,21 @@ class ServiceDoc extends Doc { } } + +/** +* LibDoc class for documenting library modules +* Handles documentation for library functions including their descriptions, +* parameters, and markdown generation. Extends the base Doc class to provide +* specialized documentation capabilities for library components. +*/ class LibDoc extends Doc { + /** + * Represents documentation for a library module + * + * Handles parsing and formatting documentation for library functions. + * Stores function definitions with their comments, parameters and descriptions. + * Can output formatted markdown documentation. + */ _construct () { this.functions = []; }