From 57e5aabdd418b0abd56e0905d2fffaf4ceafd5b2 Mon Sep 17 00:00:00 2001 From: rsi-rohithmr Date: Wed, 15 Oct 2025 17:25:17 +0530 Subject: [PATCH 1/2] heeee --- docs/6-Image-Viewer/4_MoreOptionsToolbarMenu.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/6-Image-Viewer/4_MoreOptionsToolbarMenu.md b/docs/6-Image-Viewer/4_MoreOptionsToolbarMenu.md index 69a16fc..fedba5c 100644 --- a/docs/6-Image-Viewer/4_MoreOptionsToolbarMenu.md +++ b/docs/6-Image-Viewer/4_MoreOptionsToolbarMenu.md @@ -178,6 +178,7 @@ seen below). ![img-as-1](img/img-as-1.png) + **Popout in Window** Allows you to open the current image in a separate window. From cdc28f4d0e5f99ce9b3c6a238e334fe970b613ea Mon Sep 17 00:00:00 2001 From: rsi-rohithmr Date: Thu, 16 Oct 2025 13:15:40 +0530 Subject: [PATCH 2/2] haha --- AutoSnap/test-enhanced-flow-ci.js | 276 ++++++++++++++++++++++++++++-- existing-changes.diff | 0 2 files changed, 259 insertions(+), 17 deletions(-) delete mode 100644 existing-changes.diff diff --git a/AutoSnap/test-enhanced-flow-ci.js b/AutoSnap/test-enhanced-flow-ci.js index 838ab5b..c36585a 100644 --- a/AutoSnap/test-enhanced-flow-ci.js +++ b/AutoSnap/test-enhanced-flow-ci.js @@ -640,14 +640,23 @@ const processListMode = async (listFilePath, forcedMode = null) => { // Read and parse the list file const listContent = fs.readFileSync(listFilePath, 'utf8'); - const filePaths = listContent.split('\n') + + // Enhanced format: supports "filepath|mode" format + const fileEntries = listContent.split('\n') .map(line => line.trim()) - .filter(line => line.length > 0 && !line.startsWith('#')); // Filter empty lines and comments + .filter(line => line.length > 0 && !line.startsWith('#')) // Filter empty lines and comments + .map(line => { + // Check if line contains a mode specification (filepath|mode) + const parts = line.split('|'); + const filePath = parts[0].trim(); + const fileMode = parts.length > 1 ? parts[1].trim() : null; + return { filePath, fileMode }; + }); - console.log(`šŸ“„ Found ${filePaths.length} file paths in list`); + console.log(`šŸ“„ Found ${fileEntries.length} file entries in list`); - if (filePaths.length === 0) { - console.warn(`āš ļø No valid file paths found in list file: ${listFilePath}`); + if (fileEntries.length === 0) { + console.warn(`āš ļø No valid file entries found in list file: ${listFilePath}`); return []; } @@ -655,7 +664,9 @@ const processListMode = async (listFilePath, forcedMode = null) => { const validFiles = []; const invalidFiles = []; - for (const filePath of filePaths) { + for (const entry of fileEntries) { + const { filePath, fileMode } = entry; + // Handle both relative and absolute paths // Get workspace root (parent of AutoSnap directory) const workspaceRoot = path.dirname(__dirname); @@ -673,7 +684,15 @@ const processListMode = async (listFilePath, forcedMode = null) => { continue; } - validFiles.push(resolvedPath); + // Validate mode if specified + if (fileMode && !['new_feature', 'ui_change', 'default'].includes(fileMode)) { + console.warn(`āš ļø Invalid mode '${fileMode}' for file: ${filePath}. Using auto-classification.`); + } + + validFiles.push({ + path: resolvedPath, + mode: fileMode || null // null means auto-classify + }); } catch (error) { invalidFiles.push({ path: filePath, reason: error.message }); } @@ -695,15 +714,21 @@ const processListMode = async (listFilePath, forcedMode = null) => { // Process each file sequentially const results = []; for (let i = 0; i < validFiles.length; i++) { - const filePath = validFiles[i]; + const fileEntry = validFiles[i]; + const filePath = fileEntry.path; try { console.log(`\nšŸ”„ Processing file ${i + 1}/${validFiles.length}: ${filePath}`); let mode; + // Priority: 1. Global forced mode, 2. File-specific mode, 3. Auto-classify if (forcedMode && ['new_feature', 'ui_change', 'default'].includes(forcedMode)) { - // Use forced mode if provided + // Use global forced mode if provided (overrides file-specific mode) mode = forcedMode; - console.log(`šŸŽÆ Using forced mode: ${mode.toUpperCase()}`); + console.log(`šŸŽÆ Using global forced mode: ${mode.toUpperCase()}`); + } else if (fileEntry.mode && ['new_feature', 'ui_change', 'default'].includes(fileEntry.mode)) { + // Use file-specific mode if provided + mode = fileEntry.mode; + console.log(`šŸŽÆ Using file-specific mode: ${mode.toUpperCase()}`); } else { // Auto-classify based on content mode = await classifyFileMode(filePath); @@ -1145,13 +1170,20 @@ USAGE: MODES: Default/Translation Mode: Processes all .md/.mdx files in specified folder (default and translation are the same) Single File Mode: Processes a single specified .md/.mdx file with classification + Multi-File Mode: Processes multiple files specified directly on the command line List Mode: Processes multiple files from a list file with auto-classification for each +REQUIRED PARAMETERS: + - You must specify ONE of: --folder, --file, --files, or --list + - When using --file in CI mode, you must also specify --mode + - When using translation mode, you must specify --lang + OPTIONS: --folder Default/Translation mode: Process folder that mirrors docs structure (NOT docs itself) --file Single file mode: Process one specific .md/.mdx file + --files Multi-file mode: Process multiple files with modes (format: "file1.md|mode1,file2.md|mode2") --changed-files Use specific changed files list (overrides git diff) - --list List mode: Process multiple files from a list file (one path per line) + --list List mode: Process multiple files from a list file (format: filepath|mode) --mode, -m Scenario type: ui_change, new_feature, default/translation --lang, -l Language code or name to select in UI (overrides auto-detection) --help, -h Show this help message @@ -1162,13 +1194,28 @@ EXAMPLES: node test-enhanced-flow.js --folder ./docs-fr # Default/Translation mode on French docs (auto-detect French) node test-enhanced-flow.js --folder ./custom --lang es # Default/Translation mode with explicit Spanish language code node test-enhanced-flow.js --folder ./docs-es --lang Spanish # Default/Translation mode with explicit Spanish language name - node test-enhanced-flow.js --file ./docs/guide.md # Single file mode - node test-enhanced-flow.js --file ./docs/api.md --mode new_feature # Single file with specific mode + node test-enhanced-flow.js --file ./docs/guide.md --mode ui_change # Single file with specific mode (REQUIRED in CI) + node test-enhanced-flow.js --file ./docs/api.md --scenario new_feature # Single file with specific scenario node test-enhanced-flow.js --file ./spanish/guide.md --lang es # Single file with explicit language node test-enhanced-flow.js --changed-files list.txt # Use custom file list node test-enhanced-flow.js --list file-list.md # Process files from list with auto-classification - node test-enhanced-flow.js --list my-files.txt --mode ui_change # Process list with forced mode + node test-enhanced-flow.js --list my-files.txt --mode ui_change # Process list with forced mode for all files node test-enhanced-flow.js --list my-files.txt --lang pt # Process list with explicit Portuguese + + # Multi-file mode examples: + node test-enhanced-flow.js --files "docs/file1.md|ui_change,docs/file2.md|new_feature" # Multiple files with specific modes + node test-enhanced-flow.js --files "docs/file1.md,docs/file2.md" --mode ui_change # Multiple files with same mode + node test-enhanced-flow.js --files "docs/file1.md|ui_change,docs/file2.md" # Mixed modes (second file auto-classified) + + # List file format examples: + # Simple format (auto-classify each file): + # docs/file1.md + # docs/file2.md + # + # Enhanced format (specify mode for each file): + # docs/file1.md|ui_change + # docs/file2.md|new_feature + # docs/file3.md # This file will be auto-classified CONFIGURATION: Image Naming: The script uses simple, descriptive names for generated images based on @@ -1239,6 +1286,9 @@ if (args.includes('--help') || args.includes('-h')) { process.exit(0); } +// Variable to store multiple files with modes +let multipleFiles = []; + // Parse command-line arguments for (let i = 0; i < args.length; i++) { if (args[i] === '--changed-files' && args[i + 1]) { @@ -1252,6 +1302,24 @@ for (let i = 0; i < args.length; i++) { i++; } else if (args[i] === '--file' && args[i + 1]) { singleFilePath = args[i + 1]; + i++; + } else if (args[i] === '--files' && args[i + 1]) { + // New option for multiple files with modes + // Format: --files "file1.md|mode1,file2.md|mode2,file3.md|mode3" + const filesArg = args[i + 1]; + const fileSpecs = filesArg.split(','); + + fileSpecs.forEach(spec => { + const parts = spec.split('|'); + if (parts.length >= 1) { + const filePath = parts[0].trim(); + const fileMode = parts.length > 1 ? parts[1].trim() : null; + if (filePath) { + multipleFiles.push({ filePath, fileMode }); + } + } + }); + i++; } else if (args[i] === '--list' && args[i + 1]) { listFilePath = args[i + 1]; @@ -1262,6 +1330,18 @@ for (let i = 0; i < args.length; i++) { } else if (args[i] === '--scenario' && args[i + 1]) { scenarioArg = args[i + 1]; i++; + } else if (args[i] === '--senario' && args[i + 1]) { + // Handle common misspelling of scenario + console.warn('āš ļø Warning: "--senario" is misspelled. Please use "--scenario" instead.'); + scenarioArg = args[i + 1]; + i++; + } else if (args[i].startsWith('--') && !args[i].includes('=')) { + // Check for unrecognized arguments + const knownArgs = ['--help', '-h', '--changed-files', '--mode', '-m', '--folder', '--file', + '--files', '--list', '--lang', '-l', '--scenario']; + if (!knownArgs.includes(args[i])) { + console.warn(`āš ļø Warning: Unrecognized argument "${args[i]}". It will be ignored.`); + } } } @@ -1272,9 +1352,10 @@ if (scenarioArg && !modeArg) { } // Validate exclusive options -const exclusiveOptions = [folderPath, singleFilePath, changedFiles, listFilePath].filter(Boolean); +const hasMultipleFiles = multipleFiles.length > 0; +const exclusiveOptions = [folderPath, singleFilePath, changedFiles, listFilePath, hasMultipleFiles].filter(Boolean); if (exclusiveOptions.length > 1) { - console.error('āŒ Error: Only one of --folder, --file, --changed-files, or --list can be specified at a time.'); + console.error('āŒ Error: Only one of --folder, --file, --files, --changed-files, or --list can be specified at a time.'); showUsage(); process.exit(1); } @@ -1282,6 +1363,58 @@ if (exclusiveOptions.length > 1) { // Detect if running in GitHub Actions or CI environment const isCI = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true' || true; // Force CI mode to avoid interactive prompts +// Validate required parameters for CI mode +function validateRequiredParams() { + // In CI mode, we need stricter validation + if (isCI) { + // Check if we have a file source (one of these must be specified) + const hasFileSource = folderPath || singleFilePath || changedFiles || listFilePath || hasMultipleFiles; + if (!hasFileSource) { + console.error('āŒ Error: In CI mode, you must specify one of: --folder, --file, --files, --changed-files, or --list'); + showUsage(); + process.exit(1); + } + + // For single file mode, validate required parameters + if (singleFilePath) { + // For single file, we need a mode/scenario + if (!modeArg && !scenarioArg) { + console.error('āŒ Error: When using --file in CI mode, you must specify --mode'); + showUsage(); + process.exit(1); + } + } + + // For multiple files mode, validate each file has a mode + if (hasMultipleFiles) { + const filesWithoutMode = multipleFiles.filter(file => !file.fileMode && !modeArg); + if (filesWithoutMode.length > 0) { + if (!modeArg) { + console.warn(`āš ļø Warning: Some files in --files don't have a mode specified. They will be auto-classified.`); + filesWithoutMode.forEach(file => { + console.warn(` - ${file.filePath}`); + }); + } + } + } + + // For list mode, we don't need to validate mode because: + // 1. Global mode can be specified with --mode + // 2. Per-file modes can be specified in the list file + // 3. Auto-classification is used as a fallback + + // For translation mode, validate language code + if (modeArg === 'translation' && !languageCodeArg) { + console.error('āŒ Error: When using translation mode in CI mode, you must specify --lang'); + showUsage(); + process.exit(1); + } + } +} + +// Run validation for CI mode +validateRequiredParams(); + // Determine execution mode and process files accordingly let executionMode = 'default'; let filesToProcess = []; @@ -1505,10 +1638,119 @@ async function executeWorkflow() { console.log(`šŸ“‹ Created single file changed files list: ${singleFileChangedList}`); changedFiles = singleFileChangedList; executionMode = 'single_file'; + } else if (hasMultipleFiles) { + // Process multiple files specified with --files + const fs = require('node:fs'); + const path = require('node:path'); + + console.log(`šŸ” Processing ${multipleFiles.length} files from --files parameter`); + + // Validate and process each file + const validFiles = []; + const invalidFiles = []; + + for (const fileEntry of multipleFiles) { + const { filePath, fileMode } = fileEntry; + + // Handle both relative and absolute paths + const workspaceRoot = path.dirname(__dirname); + const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(workspaceRoot, filePath); + + try { + if (!fs.existsSync(resolvedPath)) { + invalidFiles.push({ path: filePath, reason: 'File does not exist' }); + continue; + } + + const isMarkdown = resolvedPath.endsWith('.md') || resolvedPath.endsWith('.mdx'); + if (!isMarkdown) { + invalidFiles.push({ path: filePath, reason: 'Not a .md or .mdx file' }); + continue; + } + + validFiles.push({ + path: resolvedPath, + mode: fileMode || null // null means use global mode or auto-classify + }); + } catch (error) { + invalidFiles.push({ path: filePath, reason: error.message }); + } + } + + console.log(`āœ… Valid files: ${validFiles.length}`); + console.log(`āŒ Invalid files: ${invalidFiles.length}`); + + if (invalidFiles.length > 0) { + console.log(`āš ļø Invalid files found:`); + invalidFiles.forEach(file => console.log(` - ${file.path}: ${file.reason}`)); + } + + if (validFiles.length === 0) { + console.warn(`āš ļø No valid markdown files found in --files parameter`); + process.exit(1); + } + + // Process each file sequentially + const results = []; + for (let i = 0; i < validFiles.length; i++) { + const fileEntry = validFiles[i]; + const filePath = fileEntry.path; + try { + console.log(`\nšŸ”„ Processing file ${i + 1}/${validFiles.length}: ${filePath}`); + + let mode; + // Priority: 1. Global forced mode, 2. File-specific mode, 3. Auto-classify + if (modeArg && ['new_feature', 'ui_change', 'default'].includes(modeArg.toLowerCase())) { + // Use global forced mode if provided (overrides file-specific mode) + mode = modeArg; + console.log(`šŸŽÆ Using global forced mode: ${mode.toUpperCase()}`); + } else if (fileEntry.mode && ['new_feature', 'ui_change', 'default'].includes(fileEntry.mode)) { + // Use file-specific mode if provided + mode = fileEntry.mode; + console.log(`šŸŽÆ Using file-specific mode: ${mode.toUpperCase()}`); + } else { + // Auto-classify based on content + mode = await classifyFileMode(filePath); + console.log(`šŸ” Auto-classified as: ${mode.toUpperCase()}`); + } + + // Process the file based on its mode + const result = await processFileByMode(filePath, mode); + results.push({ + ...result, + listIndex: i + 1, + totalFiles: validFiles.length + }); + + console.log(`āœ… Completed file ${i + 1}/${validFiles.length} in ${mode.toUpperCase()} mode`); + + } catch (error) { + console.error(`āŒ Error processing file ${filePath}: ${error.message}`); + results.push({ + filePath, + processed: false, + error: error.message, + listIndex: i + 1, + totalFiles: validFiles.length + }); + } + } + + processedFileResults = results; + + // Create a changed files list for the automation + const multiFilesChangedList = path.join(__dirname, 'changed-files-multi.txt'); + const normalizedPaths = validFiles + .map(file => file.path.replace(/\\/g, '/')); + + fs.writeFileSync(multiFilesChangedList, normalizedPaths.join('\n')); + console.log(`šŸ“‹ Created multi-file changed files list: ${multiFilesChangedList}`); + changedFiles = multiFilesChangedList; + executionMode = 'multi_file'; } else if (folderPath) { executionMode = 'translation'; // Note: The folder processing will be handled by the main code -} else if (listFilePath) { + } else if (listFilePath) { executionMode = 'list'; // Note: The list processing will be handled by the main code } diff --git a/existing-changes.diff b/existing-changes.diff deleted file mode 100644 index e69de29..0000000