mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
Co-authored-by: cocojojo5213 <cocojojo5213@users.noreply.github.com>
This commit is contained in:
parent
01183111dc
commit
049c75e7f3
4 changed files with 240 additions and 286 deletions
55
scripts/log-migration-helper.test.cjs
Normal file
55
scripts/log-migration-helper.test.cjs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
require('ts-node/register/transpile-only');
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const test = require('node:test');
|
||||
const { migrateLogContent } = require('./log-migration-helper.ts');
|
||||
|
||||
test('migrates Log calls and updates the import for the target logger', () => {
|
||||
const input = [
|
||||
"import { Log, OtherLog } from '../core/log';",
|
||||
'',
|
||||
"Log.log('a');",
|
||||
"Log.err('b');",
|
||||
'OtherLog.log();',
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
const result = migrateLogContent(input, 'PluginLog');
|
||||
|
||||
assert.equal(result.changes, 2);
|
||||
assert.equal(
|
||||
result.content,
|
||||
[
|
||||
"import { OtherLog, PluginLog } from '../core/log';",
|
||||
'',
|
||||
"PluginLog.log('a');",
|
||||
"PluginLog.err('b');",
|
||||
'OtherLog.log();',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
});
|
||||
|
||||
test('keeps the Log import when non-call Log references remain', () => {
|
||||
const input = [
|
||||
"import { Log } from '../core/log';",
|
||||
'',
|
||||
'const logger = Log;',
|
||||
"Log.info('a');",
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
const result = migrateLogContent(input, 'IssueLog');
|
||||
|
||||
assert.equal(result.changes, 1);
|
||||
assert.equal(
|
||||
result.content,
|
||||
[
|
||||
"import { Log, IssueLog } from '../core/log';",
|
||||
'',
|
||||
'const logger = Log;',
|
||||
"IssueLog.info('a');",
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
});
|
||||
171
scripts/log-migration-helper.ts
Normal file
171
scripts/log-migration-helper.ts
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as glob from 'glob';
|
||||
|
||||
interface Replacement {
|
||||
pattern: RegExp;
|
||||
replacement: string;
|
||||
}
|
||||
|
||||
export interface LogMigrationConfig {
|
||||
description: string;
|
||||
fileLabel: string;
|
||||
globPattern: string;
|
||||
targetLogName: string;
|
||||
ignore?: string[];
|
||||
}
|
||||
|
||||
export interface MigrationResult {
|
||||
content: string;
|
||||
changes: number;
|
||||
}
|
||||
|
||||
export interface FileMigrationResult {
|
||||
modified: boolean;
|
||||
changes: number;
|
||||
}
|
||||
|
||||
const DEFAULT_IGNORE = ['**/*.spec.ts', '**/node_modules/**'];
|
||||
const LOG_METHODS = ['log', 'err', 'info', 'debug', 'verbose', 'critical'];
|
||||
|
||||
const createReplacements = (targetLogName: string): Replacement[] =>
|
||||
LOG_METHODS.map((method) => ({
|
||||
pattern: new RegExp(`\\bLog\\.${method}\\(`, 'g'),
|
||||
replacement: `${targetLogName}.${method}(`,
|
||||
}));
|
||||
|
||||
const getTargetLogImportRegex = (targetLogName: string): RegExp =>
|
||||
new RegExp(
|
||||
`import\\s*{[^}]*\\b${targetLogName}\\b[^}]*}\\s*from\\s*['"][^'"]*\\/log['"]`,
|
||||
);
|
||||
|
||||
const LOG_IMPORT_REGEX = /import\s*{([^}]*\bLog\b[^}]*)}\s*from\s*(['"][^'"]*\/log['"])/;
|
||||
|
||||
const updateImports = (
|
||||
content: string,
|
||||
targetLogName: string,
|
||||
replacements: Replacement[],
|
||||
): string => {
|
||||
if (getTargetLogImportRegex(targetLogName).test(content)) {
|
||||
return content;
|
||||
}
|
||||
|
||||
const match = content.match(LOG_IMPORT_REGEX);
|
||||
if (!match) {
|
||||
return content;
|
||||
}
|
||||
|
||||
const [fullMatch, imports, importPath] = match;
|
||||
const importList = imports.split(',').map((s) => s.trim());
|
||||
|
||||
if (!importList.includes(targetLogName)) {
|
||||
importList.push(targetLogName);
|
||||
}
|
||||
|
||||
let tempContent = content;
|
||||
for (const { pattern, replacement } of replacements) {
|
||||
tempContent = tempContent.replace(pattern, replacement);
|
||||
}
|
||||
|
||||
tempContent = tempContent.replace(LOG_IMPORT_REGEX, '');
|
||||
|
||||
if (!/\bLog\b/.test(tempContent)) {
|
||||
const logIndex = importList.indexOf('Log');
|
||||
if (logIndex > -1) {
|
||||
importList.splice(logIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return content.replace(
|
||||
fullMatch,
|
||||
`import { ${importList.join(', ')} } from ${importPath}`,
|
||||
);
|
||||
};
|
||||
|
||||
export const migrateLogContent = (
|
||||
content: string,
|
||||
targetLogName: string,
|
||||
): MigrationResult => {
|
||||
const replacements = createReplacements(targetLogName);
|
||||
let nextContent = content;
|
||||
let changeCount = 0;
|
||||
|
||||
for (const { pattern, replacement } of replacements) {
|
||||
const matches = nextContent.match(pattern);
|
||||
if (matches) {
|
||||
changeCount += matches.length;
|
||||
nextContent = nextContent.replace(pattern, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (changeCount > 0) {
|
||||
nextContent = updateImports(nextContent, targetLogName, replacements);
|
||||
}
|
||||
|
||||
return {
|
||||
content: nextContent,
|
||||
changes: changeCount,
|
||||
};
|
||||
};
|
||||
|
||||
export const migrateLogFile = (
|
||||
filePath: string,
|
||||
targetLogName: string,
|
||||
dryRun: boolean = false,
|
||||
): FileMigrationResult => {
|
||||
try {
|
||||
const originalContent = fs.readFileSync(filePath, 'utf8');
|
||||
const { content, changes } = migrateLogContent(originalContent, targetLogName);
|
||||
const modified = content !== originalContent;
|
||||
|
||||
if (modified && !dryRun) {
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
}
|
||||
|
||||
return { modified, changes };
|
||||
} catch (error) {
|
||||
console.error(`Error processing ${filePath}:`, error);
|
||||
return { modified: false, changes: 0 };
|
||||
}
|
||||
};
|
||||
|
||||
export const runLogMigration = (config: LogMigrationConfig): void => {
|
||||
const dryRun = process.argv.includes('--dry-run');
|
||||
|
||||
console.log(`${config.description}\n`);
|
||||
if (dryRun) {
|
||||
console.log('Running in DRY RUN mode - no files will be modified\n');
|
||||
}
|
||||
|
||||
const files = glob.sync(config.globPattern, {
|
||||
ignore: config.ignore || DEFAULT_IGNORE,
|
||||
absolute: true,
|
||||
});
|
||||
|
||||
console.log(`Found ${files.length} ${config.fileLabel}\n`);
|
||||
|
||||
const modifiedFiles: { path: string; changes: number }[] = [];
|
||||
let totalChanges = 0;
|
||||
|
||||
for (const file of files) {
|
||||
const result = migrateLogFile(file, config.targetLogName, dryRun);
|
||||
if (result.modified) {
|
||||
modifiedFiles.push({ path: file, changes: result.changes });
|
||||
totalChanges += result.changes;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\nMigration complete!\n');
|
||||
console.log(`Total changes: ${totalChanges}`);
|
||||
console.log(`${dryRun ? 'Would modify' : 'Modified'} ${modifiedFiles.length} files:\n`);
|
||||
|
||||
modifiedFiles
|
||||
.sort((a, b) => b.changes - a.changes)
|
||||
.forEach(({ path: filePath, changes }) => {
|
||||
console.log(` - ${path.relative(process.cwd(), filePath)} (${changes} changes)`);
|
||||
});
|
||||
|
||||
if (modifiedFiles.length === 0) {
|
||||
console.log(' No files needed modification.');
|
||||
}
|
||||
};
|
||||
|
|
@ -1,146 +1,10 @@
|
|||
#!/usr/bin/env ts-node
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as glob from 'glob';
|
||||
import { runLogMigration } from './log-migration-helper';
|
||||
|
||||
interface Replacement {
|
||||
pattern: RegExp;
|
||||
replacement: string;
|
||||
}
|
||||
|
||||
const replacements: Replacement[] = [
|
||||
// Replace Log.log with IssueLog.log
|
||||
{ pattern: /\bLog\.log\(/g, replacement: 'IssueLog.log(' },
|
||||
// Replace Log.err with IssueLog.err
|
||||
{ pattern: /\bLog\.err\(/g, replacement: 'IssueLog.err(' },
|
||||
// Replace Log.info with IssueLog.info
|
||||
{ pattern: /\bLog\.info\(/g, replacement: 'IssueLog.info(' },
|
||||
// Replace Log.debug with IssueLog.debug
|
||||
{ pattern: /\bLog\.debug\(/g, replacement: 'IssueLog.debug(' },
|
||||
// Replace Log.verbose with IssueLog.verbose
|
||||
{ pattern: /\bLog\.verbose\(/g, replacement: 'IssueLog.verbose(' },
|
||||
// Replace Log.critical with IssueLog.critical
|
||||
{ pattern: /\bLog\.critical\(/g, replacement: 'IssueLog.critical(' },
|
||||
];
|
||||
|
||||
function updateImports(content: string): string {
|
||||
// Check if file already imports IssueLog
|
||||
const hasIssueLogImport =
|
||||
/import\s*{[^}]*\bIssueLog\b[^}]*}\s*from\s*['"][^'"]*\/log['"]/.test(content);
|
||||
|
||||
if (hasIssueLogImport) {
|
||||
// If IssueLog is already imported, just remove Log from the import if it's not used elsewhere
|
||||
return content;
|
||||
}
|
||||
|
||||
// Find existing Log import and add IssueLog to it
|
||||
const logImportRegex = /import\s*{([^}]*\bLog\b[^}]*)}\s*from\s*(['"][^'"]*\/log['"])/;
|
||||
const match = content.match(logImportRegex);
|
||||
|
||||
if (match) {
|
||||
const [fullMatch, imports, importPath] = match;
|
||||
const importList = imports.split(',').map((s) => s.trim());
|
||||
|
||||
// Add IssueLog if not already there
|
||||
if (!importList.includes('IssueLog')) {
|
||||
importList.push('IssueLog');
|
||||
}
|
||||
|
||||
// Check if Log is still used after replacements
|
||||
let tempContent = content;
|
||||
for (const { pattern, replacement } of replacements) {
|
||||
tempContent = tempContent.replace(pattern, replacement);
|
||||
}
|
||||
|
||||
// Remove the import statement from check
|
||||
tempContent = tempContent.replace(logImportRegex, '');
|
||||
|
||||
// If Log is no longer used, remove it from imports
|
||||
const logStillUsed = /\bLog\b/.test(tempContent);
|
||||
if (!logStillUsed) {
|
||||
const logIndex = importList.indexOf('Log');
|
||||
if (logIndex > -1) {
|
||||
importList.splice(logIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const newImports = importList.join(', ');
|
||||
const newImportStatement = `import { ${newImports} } from ${importPath}`;
|
||||
content = content.replace(fullMatch, newImportStatement);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
function processFile(filePath: string): { modified: boolean; changes: number } {
|
||||
try {
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
const originalContent = content;
|
||||
let changeCount = 0;
|
||||
|
||||
// Count and apply replacements
|
||||
for (const { pattern, replacement } of replacements) {
|
||||
const matches = content.match(pattern);
|
||||
if (matches) {
|
||||
changeCount += matches.length;
|
||||
content = content.replace(pattern, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
// Update imports if changes were made
|
||||
if (changeCount > 0) {
|
||||
content = updateImports(content);
|
||||
}
|
||||
|
||||
const modified = content !== originalContent;
|
||||
|
||||
if (modified) {
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
}
|
||||
|
||||
return { modified, changes: changeCount };
|
||||
} catch (error) {
|
||||
console.error(`Error processing ${filePath}:`, error);
|
||||
return { modified: false, changes: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log('Migrating Log to IssueLog in features/issue directory...\n');
|
||||
|
||||
// Find all TypeScript files in features/issue directory
|
||||
const files = glob.sync('src/app/features/issue/**/*.ts', {
|
||||
ignore: ['**/*.spec.ts', '**/node_modules/**'],
|
||||
absolute: true,
|
||||
});
|
||||
|
||||
console.log(`Found ${files.length} TypeScript files in features/issue directory\n`);
|
||||
|
||||
const modifiedFiles: { path: string; changes: number }[] = [];
|
||||
let totalChanges = 0;
|
||||
|
||||
for (const file of files) {
|
||||
const result = processFile(file);
|
||||
if (result.modified) {
|
||||
modifiedFiles.push({ path: file, changes: result.changes });
|
||||
totalChanges += result.changes;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\nMigration complete!\n');
|
||||
console.log(`Total changes: ${totalChanges}`);
|
||||
console.log(`Modified ${modifiedFiles.length} files:\n`);
|
||||
|
||||
modifiedFiles
|
||||
.sort((a, b) => b.changes - a.changes)
|
||||
.forEach(({ path: filePath, changes }) => {
|
||||
console.log(` - ${path.relative(process.cwd(), filePath)} (${changes} changes)`);
|
||||
});
|
||||
|
||||
if (modifiedFiles.length === 0) {
|
||||
console.log(' No files needed modification.');
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
runLogMigration({
|
||||
description: 'Migrating Log to IssueLog in features/issue directory...',
|
||||
fileLabel: 'TypeScript files in features/issue directory',
|
||||
globPattern: 'src/app/features/issue/**/*.ts',
|
||||
targetLogName: 'IssueLog',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,146 +1,10 @@
|
|||
#!/usr/bin/env ts-node
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as glob from 'glob';
|
||||
import { runLogMigration } from './log-migration-helper';
|
||||
|
||||
interface Replacement {
|
||||
pattern: RegExp;
|
||||
replacement: string;
|
||||
}
|
||||
|
||||
const replacements: Replacement[] = [
|
||||
// Replace Log.log with PluginLog.log
|
||||
{ pattern: /\bLog\.log\(/g, replacement: 'PluginLog.log(' },
|
||||
// Replace Log.err with PluginLog.err
|
||||
{ pattern: /\bLog\.err\(/g, replacement: 'PluginLog.err(' },
|
||||
// Replace Log.info with PluginLog.info
|
||||
{ pattern: /\bLog\.info\(/g, replacement: 'PluginLog.info(' },
|
||||
// Replace Log.debug with PluginLog.debug
|
||||
{ pattern: /\bLog\.debug\(/g, replacement: 'PluginLog.debug(' },
|
||||
// Replace Log.verbose with PluginLog.verbose
|
||||
{ pattern: /\bLog\.verbose\(/g, replacement: 'PluginLog.verbose(' },
|
||||
// Replace Log.critical with PluginLog.critical
|
||||
{ pattern: /\bLog\.critical\(/g, replacement: 'PluginLog.critical(' },
|
||||
];
|
||||
|
||||
function updateImports(content: string): string {
|
||||
// Check if file already imports PluginLog
|
||||
const hasPluginLogImport =
|
||||
/import\s*{[^}]*\bPluginLog\b[^}]*}\s*from\s*['"][^'"]*\/log['"]/.test(content);
|
||||
|
||||
if (hasPluginLogImport) {
|
||||
// If PluginLog is already imported, just remove Log from the import if it's not used elsewhere
|
||||
return content;
|
||||
}
|
||||
|
||||
// Find existing Log import and add PluginLog to it
|
||||
const logImportRegex = /import\s*{([^}]*\bLog\b[^}]*)}\s*from\s*(['"][^'"]*\/log['"])/;
|
||||
const match = content.match(logImportRegex);
|
||||
|
||||
if (match) {
|
||||
const [fullMatch, imports, importPath] = match;
|
||||
const importList = imports.split(',').map((s) => s.trim());
|
||||
|
||||
// Add PluginLog if not already there
|
||||
if (!importList.includes('PluginLog')) {
|
||||
importList.push('PluginLog');
|
||||
}
|
||||
|
||||
// Check if Log is still used after replacements
|
||||
let tempContent = content;
|
||||
for (const { pattern, replacement } of replacements) {
|
||||
tempContent = tempContent.replace(pattern, replacement);
|
||||
}
|
||||
|
||||
// Remove the import statement from check
|
||||
tempContent = tempContent.replace(logImportRegex, '');
|
||||
|
||||
// If Log is no longer used, remove it from imports
|
||||
const logStillUsed = /\bLog\b/.test(tempContent);
|
||||
if (!logStillUsed) {
|
||||
const logIndex = importList.indexOf('Log');
|
||||
if (logIndex > -1) {
|
||||
importList.splice(logIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const newImports = importList.join(', ');
|
||||
const newImportStatement = `import { ${newImports} } from ${importPath}`;
|
||||
content = content.replace(fullMatch, newImportStatement);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
function processFile(filePath: string): { modified: boolean; changes: number } {
|
||||
try {
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
const originalContent = content;
|
||||
let changeCount = 0;
|
||||
|
||||
// Count and apply replacements
|
||||
for (const { pattern, replacement } of replacements) {
|
||||
const matches = content.match(pattern);
|
||||
if (matches) {
|
||||
changeCount += matches.length;
|
||||
content = content.replace(pattern, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
// Update imports if changes were made
|
||||
if (changeCount > 0) {
|
||||
content = updateImports(content);
|
||||
}
|
||||
|
||||
const modified = content !== originalContent;
|
||||
|
||||
if (modified) {
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
}
|
||||
|
||||
return { modified, changes: changeCount };
|
||||
} catch (error) {
|
||||
console.error(`Error processing ${filePath}:`, error);
|
||||
return { modified: false, changes: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log('Migrating Log to PluginLog in plugins directory...\n');
|
||||
|
||||
// Find all TypeScript files in plugins directory
|
||||
const files = glob.sync('src/app/plugins/**/*.ts', {
|
||||
ignore: ['**/*.spec.ts', '**/node_modules/**'],
|
||||
absolute: true,
|
||||
});
|
||||
|
||||
console.log(`Found ${files.length} TypeScript files in plugins directory\n`);
|
||||
|
||||
const modifiedFiles: { path: string; changes: number }[] = [];
|
||||
let totalChanges = 0;
|
||||
|
||||
for (const file of files) {
|
||||
const result = processFile(file);
|
||||
if (result.modified) {
|
||||
modifiedFiles.push({ path: file, changes: result.changes });
|
||||
totalChanges += result.changes;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\nMigration complete!\n');
|
||||
console.log(`Total changes: ${totalChanges}`);
|
||||
console.log(`Modified ${modifiedFiles.length} files:\n`);
|
||||
|
||||
modifiedFiles
|
||||
.sort((a, b) => b.changes - a.changes)
|
||||
.forEach(({ path: filePath, changes }) => {
|
||||
console.log(` - ${path.relative(process.cwd(), filePath)} (${changes} changes)`);
|
||||
});
|
||||
|
||||
if (modifiedFiles.length === 0) {
|
||||
console.log(' No files needed modification.');
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
runLogMigration({
|
||||
description: 'Migrating Log to PluginLog in plugins directory...',
|
||||
fileLabel: 'TypeScript files in plugins directory',
|
||||
globPattern: 'src/app/plugins/**/*.ts',
|
||||
targetLogName: 'PluginLog',
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue