@@ -2,6 +2,7 @@ import path from 'path';
2
2
3
3
import fs from 'fs-extra' ;
4
4
5
+ import { buildPatternToFilepathMap , crawlDirectory } from '../../../utils/dir' ;
5
6
import { isErrorWithCode } from '../../../utils/error' ;
6
7
import { loadModules } from '../modules' ;
7
8
import { FileDiff , Files , Module , Options } from '../types' ;
@@ -25,30 +26,51 @@ export const createDestinationFileReader = (root: string) => async (
25
26
const loadModuleFiles = async ( modules : Module [ ] , destinationRoot : string ) => {
26
27
const readDestinationFile = createDestinationFileReader ( destinationRoot ) ;
27
28
28
- const allFilenames = modules . flatMap ( ( module ) => Object . keys ( module ) ) ;
29
+ const allFilepaths = await crawlDirectory ( destinationRoot ) ;
29
30
30
- const uniqueFilenames = [ ...new Set ( allFilenames ) ] ;
31
+ const patterns = [ ...new Set ( modules . flatMap ( ( m ) => Object . keys ( m ) ) ) ] ;
32
+
33
+ const patternToFilepaths = buildPatternToFilepathMap ( patterns , allFilepaths ) ;
34
+
35
+ const matchedFilepaths = [
36
+ ...new Set ( Object . values ( patternToFilepaths ) . flat ( ) ) ,
37
+ ] ;
31
38
32
39
const fileEntries = await Promise . all (
33
- uniqueFilenames . map (
34
- async ( filename ) =>
35
- [ filename , await readDestinationFile ( filename ) ] as const ,
40
+ matchedFilepaths . map (
41
+ async ( filepath ) =>
42
+ [ filepath , await readDestinationFile ( filepath ) ] as const ,
36
43
) ,
37
44
) ;
38
45
39
- return Object . fromEntries ( fileEntries ) ;
46
+ return {
47
+ inputFiles : Object . fromEntries ( fileEntries ) ,
48
+ patternToFilepaths,
49
+ } ;
40
50
} ;
41
51
42
- const processTextFiles = ( modules : Module [ ] , inputFiles : Readonly < Files > ) => {
52
+ const processTextFiles = (
53
+ modules : Module [ ] ,
54
+ inputFiles : Readonly < Files > ,
55
+ patternToFilepaths : Record < string , string [ ] > ,
56
+ ) => {
43
57
const outputFiles = { ...inputFiles } ;
44
58
45
59
const textProcessorEntries = modules . flatMap ( ( module ) =>
46
- Object . entries ( module ) ,
60
+ Object . entries ( module ) . flatMap ( ( [ pattern , processText ] ) => {
61
+ // Include the raw pattern along with any matched filepaths.
62
+ // Some modules create a new file at the specified pattern.
63
+ const filepaths = [ pattern , ...( patternToFilepaths [ pattern ] ?? [ ] ) ] ;
64
+
65
+ return [ ...new Set ( filepaths ) ] . map (
66
+ ( filepath ) => [ filepath , processText ] as const ,
67
+ ) ;
68
+ } ) ,
47
69
) ;
48
70
49
- for ( const [ filename , processText ] of textProcessorEntries ) {
50
- outputFiles [ filename ] = processText (
51
- outputFiles [ filename ] ,
71
+ for ( const [ filepath , processText ] of textProcessorEntries ) {
72
+ outputFiles [ filepath ] = processText (
73
+ outputFiles [ filepath ] ,
52
74
outputFiles ,
53
75
inputFiles ,
54
76
) ;
@@ -60,18 +82,18 @@ const processTextFiles = (modules: Module[], inputFiles: Readonly<Files>) => {
60
82
export const diffFiles = async ( opts : Options ) : Promise < FileDiff > => {
61
83
const modules = await loadModules ( opts ) ;
62
84
63
- const inputFiles = Object . freeze (
85
+ const { inputFiles, patternToFilepaths } = Object . freeze (
64
86
await loadModuleFiles ( modules , opts . destinationRoot ) ,
65
87
) ;
66
88
67
- const outputFiles = processTextFiles ( modules , inputFiles ) ;
89
+ const outputFiles = processTextFiles ( modules , inputFiles , patternToFilepaths ) ;
68
90
69
91
const diffEntries = Object . entries ( outputFiles )
70
- . filter ( ( [ filename , data ] ) => inputFiles [ filename ] !== data )
71
- . map ( ( [ filename , data ] ) => {
72
- const operation = determineOperation ( inputFiles [ filename ] , data ) ;
92
+ . filter ( ( [ filepath , data ] ) => inputFiles [ filepath ] !== data )
93
+ . map ( ( [ filepath , data ] ) => {
94
+ const operation = determineOperation ( inputFiles [ filepath ] , data ) ;
73
95
74
- return [ filename , { data, operation } ] as const ;
96
+ return [ filepath , { data, operation } ] as const ;
75
97
} ) ;
76
98
77
99
return Object . fromEntries ( diffEntries ) ;
0 commit comments