@@ -16,30 +16,33 @@ export async function searchAndReplace(
16
16
17
17
async function processFile ( filePath : string ) : Promise < void > {
18
18
try {
19
- const content = await readFile ( filePath , 'utf8' )
20
- let newContent = content
19
+ let newContent = await readFile ( filePath , 'utf8' )
20
+ let changesMade = false
21
21
22
22
for ( const [ i , fromString ] of fromStrings . entries ( ) ) {
23
23
const regex = new RegExp ( fromString , 'g' )
24
- newContent = newContent . replace ( regex , toStrings [ i ] )
24
+ if ( regex . test ( newContent ) ) {
25
+ newContent = newContent . replace ( regex , toStrings [ i ] )
26
+ changesMade = true
27
+ }
25
28
}
26
29
27
- if ( content !== newContent ) {
30
+ if ( changesMade ) {
28
31
if ( ! isDryRun ) {
29
32
await writeFile ( filePath , newContent , 'utf8' )
30
33
}
31
34
if ( isVerbose ) {
32
35
console . log ( `${ isDryRun ? '[Dry Run] ' : '' } File modified: ${ filePath } ` )
33
- }
34
- for ( const [ index , fromStr ] of fromStrings . entries ( ) ) {
35
- const count = ( newContent . match ( new RegExp ( toStrings [ index ] , 'g' ) ) || [ ] ) . length
36
- if ( count > 0 && isVerbose ) {
37
- console . log ( ` Replaced " ${ fromStr } " with " ${ toStrings [ index ] } " ${ count } time(s)` )
36
+ for ( const [ index , fromStr ] of fromStrings . entries ( ) ) {
37
+ const count = ( newContent . match ( new RegExp ( toStrings [ index ] , 'g' ) ) || [ ] ) . length
38
+ if ( count > 0 ) {
39
+ console . log ( ` Replaced " ${ fromStr } " with " ${ toStrings [ index ] } " ${ count } time(s)` )
40
+ }
38
41
}
39
42
}
40
43
}
41
44
} catch ( error ) {
42
- console . error ( `Error processing file ${ filePath } : ` , error )
45
+ console . error ( `Error processing file: ${ filePath } ` , error )
43
46
}
44
47
}
45
48
@@ -79,6 +82,7 @@ export async function searchAndReplace(
79
82
async function renamePaths ( directoryPath : string ) : Promise < void > {
80
83
try {
81
84
const entries = await readdir ( directoryPath , { withFileTypes : true } )
85
+ const renameQueue : { oldPath : string ; newPath : string } [ ] = [ ]
82
86
83
87
for ( const entry of entries ) {
84
88
if ( EXCLUDED_DIRECTORIES . has ( entry . name ) ) {
@@ -96,16 +100,23 @@ export async function searchAndReplace(
96
100
}
97
101
98
102
if ( oldPath !== newPath ) {
99
- if ( ! isDryRun ) {
100
- await rename ( oldPath , newPath )
101
- }
102
- if ( isVerbose ) {
103
- console . log ( `${ isDryRun ? '[Dry Run] ' : '' } Renamed: ${ oldPath } -> ${ newPath } ` )
104
- }
103
+ renameQueue . push ( { oldPath, newPath } )
105
104
}
106
105
107
106
if ( entry . isDirectory ( ) ) {
108
- await renamePaths ( entry . isDirectory ( ) ? newPath : oldPath )
107
+ await renamePaths ( oldPath ) // Process subdirectories first
108
+ }
109
+ }
110
+
111
+ // Sort by descending path length to rename deepest paths first
112
+ renameQueue . sort ( ( a , b ) => b . oldPath . length - a . oldPath . length )
113
+
114
+ for ( const { oldPath, newPath } of renameQueue ) {
115
+ if ( ! isDryRun ) {
116
+ await rename ( oldPath , newPath )
117
+ }
118
+ if ( isVerbose ) {
119
+ console . log ( `${ isDryRun ? '[Dry Run] ' : '' } Renamed: ${ oldPath } -> ${ newPath } ` )
109
120
}
110
121
}
111
122
} catch ( error ) {
0 commit comments