diff --git a/.gitignore b/.gitignore index 364e9e35424..a16a68976bb 100644 --- a/.gitignore +++ b/.gitignore @@ -97,4 +97,52 @@ ton_nft_metadata/ ton_nft_metadata/* ton_nft_images/ -ton_nft_images/* \ No newline at end of file +ton_nft_images/*# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + diff --git a/scripts/jsdoc-automation/package.json b/scripts/jsdoc-automation/package.json index 7c174e3221b..4ea9f15200b 100644 --- a/scripts/jsdoc-automation/package.json +++ b/scripts/jsdoc-automation/package.json @@ -13,7 +13,7 @@ "dbg": "node --inspect-brk --loader ts-node/esm src/index.ts", "dbg2": "node --inspect --loader ts-node/esm src/index.ts", "dbg3": "npx --node-options=--inspect-brk tsx ./src/index", - "ts": "NODE_ENV=development VERBOSE=true DEFAULT_LOG_LEVEL=debug DEBUG=eliza:* npx tsx src/index", + "ts": "npx tsx src/index", "clean": "rm -rf node_modules dist" }, "keywords": [], diff --git a/scripts/jsdoc-automation/src/DirectoryTraversal.ts b/scripts/jsdoc-automation/src/DirectoryTraversal.ts index 7b80e400714..2898c23bb84 100644 --- a/scripts/jsdoc-automation/src/DirectoryTraversal.ts +++ b/scripts/jsdoc-automation/src/DirectoryTraversal.ts @@ -1,7 +1,16 @@ -import * as fs from "fs"; +//import { promises as fs } from "fs"; import * as path from "path"; import type { Configuration } from "./Configuration.js"; +export interface FileChange { + filename: string; + status: string; + additions: number; + deletions: number; + changes: number; + contents_url?: string; +} + /** * DirectoryTraversal class for traversing through directories and files. * @class DirectoryTraversal @@ -30,15 +39,19 @@ export class DirectoryTraversal { "static", ]; + private fileChanges: Map; + /** * Constructor for directory traversal * @param {Configuration} config - Configuration object containing paths and exclusions - * @param {string[]} [prFiles=[]] - PR files to process + * @param {FileChange[]} [changes=[]] - Array of file changes from git diff */ constructor( private config: Configuration, - public prFiles: string[] = [] - ) {} + changes: FileChange[] = [] + ) { + this.fileChanges = new Map(changes.map(change => [change.filename, change])); + } /** * Gets the absolute path for a file @@ -55,62 +68,76 @@ export class DirectoryTraversal { } /** - * Traverses the directory based on PRFiles or all files in the root directory. - * If PRFiles are detected, processes only files from the PR. + * Gets the file change information for a given file + * @param {string} filePath - The path to the file + * @returns {FileChange | undefined} The file change information if available + */ + public getFileChange(filePath: string): FileChange | undefined { + const relativePath = this.getRelativePath(filePath); + return this.fileChanges.get(relativePath); + } + + /** + * Traverses the directory based on file changes from git diff. + * If changes are detected, processes only changed files. * Otherwise, scans all files in the root directory for TypeScript files. * - * * @returns An array of string containing the files to process. */ public traverse(): string[] { - if (this.prFiles.length > 0) { - console.log("Detected PR Files:", this.prFiles); + if (this.fileChanges.size > 0) { + console.log("Detected Changes:", Array.from(this.fileChanges.values())); + + // Changes are already relative to repo root, filter and convert to absolute paths + const files = Array.from(this.fileChanges.entries()) + .filter(([file, change]: [string, FileChange]) => { + // Skip deleted files + if (change.status === 'deleted') { + return false; + } - // PR files are already relative to repo root, filter and convert to absolute paths - const files = this.prFiles - .filter((file) => { - // Convert PR file (repo-relative) to absolute path + // Convert file (repo-relative) to absolute path const absolutePath = this.config.toAbsolutePath(file); - // Check if the file is within our target directory - const isInTargetDir = absolutePath.startsWith( - this.config.absolutePath - ); - - return ( - isInTargetDir && - fs.existsSync(absolutePath) && - !this.isExcluded(absolutePath) && - path.extname(file) === ".ts" - ); + // // Check if the file is within our target directory + // const isInTargetDir = absolutePath.startsWith( + // this.config.absolutePath + // ); + + // return ( + // isInTargetDir && + // fs.existsSync(absolutePath) && + // !this.isExcluded(absolutePath) && + // path.extname(file) === ".ts" + // ); }) - .map((file) => this.config.toAbsolutePath(file)); + .map(([file]) => this.config.toAbsolutePath(file)); console.log("Files to process:", files); return files; } else { console.log( - "No PR Files Detected, Scanning all files in root directory" + "No Changes Detected, Scanning all files in root directory" ); const typeScriptFiles: string[] = []; const traverseDirectory = (currentDirectory: string) => { - const files = fs.readdirSync(currentDirectory); - - files.forEach((file) => { - const filePath = path.join(currentDirectory, file); - const stats = fs.statSync(filePath); - - if (stats.isDirectory()) { - if (!this.isExcluded(filePath)) { - traverseDirectory(filePath); - } - } else if (stats.isFile() && !this.isExcluded(filePath)) { - if (path.extname(file) === ".ts") { - typeScriptFiles.push(filePath); - } - } - }); + // const files = fs.readdirSync(currentDirectory); + + // files.forEach((file) => { + // const filePath = path.join(currentDirectory, file); + // const stats = fs.statSync(filePath); + + // if (stats.isDirectory()) { + // if (!this.isExcluded(filePath)) { + // traverseDirectory(filePath); + // } + // } else if (stats.isFile() && !this.isExcluded(filePath)) { + // if (path.extname(file) === ".ts") { + // typeScriptFiles.push(filePath); + // } + // } + // }); }; traverseDirectory(this.config.absolutePath); diff --git a/scripts/jsdoc-automation/src/index.ts b/scripts/jsdoc-automation/src/index.ts index f9af8713a0b..9107f81b8a9 100644 --- a/scripts/jsdoc-automation/src/index.ts +++ b/scripts/jsdoc-automation/src/index.ts @@ -46,99 +46,190 @@ async function main() { const files = await gitManager.getFilesInPullRequest( configuration.repository.pullNumber ); - prFiles = files.map((file: { filename: any; }) => file.filename); - } catch (prError) { - console.error("Error fetching PR files:", { - error: prError, - pullNumber: configuration.repository.pullNumber, - repository: `${configuration.repository.owner}/${configuration.repository.name}`, - }); - throw prError; - } - } + // Log the changes for debugging + console.log("Files changed in PR:", files.map(f => ({ + file: f.filename, + changes: f.changes, + additions: f.additions, + deletions: f.deletions, + status: f.status + }))); + + try { + const directoryTraversal = new DirectoryTraversal( + configuration, + files + ); + const typeScriptParser = new TypeScriptParser(); + const jsDocAnalyzer = new JsDocAnalyzer(typeScriptParser); + const aiService = new AIService(configuration); + const jsDocGenerator = new JsDocGenerator(aiService); - try { - const directoryTraversal = new DirectoryTraversal( - configuration, - prFiles - ); - const typeScriptParser = new TypeScriptParser(); - const jsDocAnalyzer = new JsDocAnalyzer(typeScriptParser); - const aiService = new AIService(configuration); - const jsDocGenerator = new JsDocGenerator(aiService); - - const documentationGenerator = new DocumentationGenerator( - directoryTraversal, - typeScriptParser, - jsDocAnalyzer, - jsDocGenerator, - gitManager, - configuration, - aiService - ); + const documentationGenerator = new DocumentationGenerator( + directoryTraversal, + typeScriptParser, + jsDocAnalyzer, + jsDocGenerator, + gitManager, + configuration, + aiService + ); - const pluginDocGenerator = new PluginDocumentationGenerator( - aiService, - gitManager, - configuration - ); + const pluginDocGenerator = new PluginDocumentationGenerator( + aiService, + gitManager, + configuration + ); - const { todoItems, envUsages } = - await documentationGenerator.analyzeCodebase(); + const { todoItems, envUsages } = + await documentationGenerator.analyzeCodebase(); - // Generate JSDoc documentation first - const { documentedItems, branchName } = - await documentationGenerator.generate( - configuration.repository.pullNumber - ); + // Generate JSDoc documentation first + const { documentedItems, branchName } = + await documentationGenerator.generate( + configuration.repository.pullNumber + ); + + // If both are true, use JSDoc branch for README + // If only README is true, create new branch + if (configuration.generateReadme) { + const targetBranch = + configuration.generateJsDoc && branchName + ? branchName + : `docs-update-readme-${Date.now()}`; + + if (!configuration.generateJsDoc) { + await gitManager.createBranch( + targetBranch, + configuration.branch + ); + } + + await pluginDocGenerator.generate( + documentedItems, + targetBranch, + todoItems, + envUsages + ); + + // Only create PR if we're not also generating JSDoc (otherwise changes go in JSDoc PR) + if (!configuration.generateJsDoc) { + const prContent = { + title: "docs: Update plugin documentation", + body: "Updates plugin documentation with latest changes", + }; + + await gitManager.createPullRequest({ + title: prContent.title, + body: prContent.body, + head: targetBranch, + base: configuration.branch, + labels: ["documentation", "automated-pr"], + reviewers: configuration.pullRequestReviewers || [], + }); + } + } - // If both are true, use JSDoc branch for README - // If only README is true, create new branch - if (configuration.generateReadme) { - const targetBranch = - configuration.generateJsDoc && branchName - ? branchName - : `docs-update-readme-${Date.now()}`; - - if (!configuration.generateJsDoc) { - await gitManager.createBranch( - targetBranch, - configuration.branch - ); - } - await pluginDocGenerator.generate( - documentedItems, - targetBranch, - todoItems, - envUsages - ); - // Only create PR if we're not also generating JSDoc (otherwise changes go in JSDoc PR) - if (!configuration.generateJsDoc) { - const prContent = { - title: "docs: Update plugin documentation", - body: "Updates plugin documentation with latest changes", - }; - - await gitManager.createPullRequest({ - title: prContent.title, - body: prContent.body, - head: targetBranch, - base: configuration.branch, - labels: ["documentation", "automated-pr"], - reviewers: configuration.pullRequestReviewers || [], + try { + const typeScriptParser = new TypeScriptParser(); + const jsDocAnalyzer = new JsDocAnalyzer(typeScriptParser); + const aiService = new AIService(configuration); + const jsDocGenerator = new JsDocGenerator(aiService); + + const documentationGenerator = new DocumentationGenerator( + directoryTraversal, + typeScriptParser, + jsDocAnalyzer, + jsDocGenerator, + gitManager, + configuration, + aiService + ); + + const pluginDocGenerator = new PluginDocumentationGenerator( + aiService, + gitManager, + configuration + ); + + const { todoItems, envUsages } = + await documentationGenerator.analyzeCodebase(); + + // Generate JSDoc documentation first + const { documentedItems, branchName } = + await documentationGenerator.generate( + configuration.repository.pullNumber + ); + + // If both are true, use JSDoc branch for README + // If only README is true, create new branch + if (configuration.generateReadme) { + const targetBranch = + configuration.generateJsDoc && branchName + ? branchName + : `docs-update-readme-${Date.now()}`; + + if (!configuration.generateJsDoc) { + await gitManager.createBranch( + targetBranch, + configuration.branch + ); + } + + await pluginDocGenerator.generate( + documentedItems, + targetBranch, + todoItems, + envUsages + ); + + // Only create PR if we're not also generating JSDoc (otherwise changes go in JSDoc PR) + if (!configuration.generateJsDoc) { + const prContent = { + title: "docs: Update plugin documentation", + body: "Updates plugin documentation with latest changes", + }; + + await gitManager.createPullRequest({ + title: prContent.title, + body: prContent.body, + head: targetBranch, + base: configuration.branch, + labels: ["documentation", "automated-pr"], + reviewers: configuration.pullRequestReviewers || [], + }); + } + } + } catch (error) { + console.error("Error during documentation generation:", { + message: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + timestamp: new Date().toISOString(), + }); + process.exit(2); + } + + } catch (error) { + console.error("Error during documentation generation:", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + timestamp: new Date().toISOString(), }); + process.exit(2); } + } catch (prError) { + console.error("Error fetching PR files:", { + error: prError, + pullNumber: configuration.repository.pullNumber, + repository: `${configuration.repository.owner}/${configuration.repository.name}`, + }); + throw prError; } - } catch (error) { - console.error("Error during documentation generation:", { - message: error instanceof Error ? error.message : String(error), - stack: error instanceof Error ? error.stack : undefined, - timestamp: new Date().toISOString(), - }); - process.exit(2); } + + } catch (error) { console.error("Critical error during documentation generation:", { error: