mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 06:00:21 +08:00
doc: generate and edit comments for tools
This commit is contained in:
parent
c6455d53e4
commit
9aeecb650a
@ -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<void>}
|
||||
*/
|
||||
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<void>}
|
||||
*/
|
||||
async function checkTranslationUsage() {
|
||||
const enDictionary = translations.en.dictionary;
|
||||
|
||||
|
@ -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 });
|
||||
|
||||
|
@ -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>}
|
||||
*/
|
||||
function fix_i18n ({ commit, meta }) {
|
||||
if ( meta.type === 'fix' && meta.scope === 'i18n' ) {
|
||||
meta.type = 'i18n';
|
||||
|
@ -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<void>} 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<void>} 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<void>} Resolves when command processing is complete
|
||||
*/
|
||||
const main = async () => {
|
||||
const { program } = require('commander');
|
||||
const helptext = dedent(`
|
||||
|
@ -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 = [];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user