@@ -23,64 +23,62 @@ class AddLinesConfigurator extends AbstractConfigurator
23
23
self ::POSITION_AFTER_TARGET ,
24
24
];
25
25
26
+ /**
27
+ * Holds file contents for files that have been loaded.
28
+ * This allows us to "change" the contents of a file multiple
29
+ * times before we actually write it out.
30
+ *
31
+ * @var string[]
32
+ */
33
+ private $ fileContents = [];
34
+
26
35
public function configure (Recipe $ recipe , $ config , Lock $ lock , array $ options = []): void
27
36
{
28
- $ changes = $ this ->getConfigureFileChanges ($ recipe , $ config );
37
+ $ this ->fileContents = [];
38
+ $ this ->executeConfigure ($ recipe , $ config );
29
39
30
- foreach ($ changes as $ file => $ change ) {
31
- $ this ->write (sprintf ('[add-lines] Patching file "%s" ' , $ file ));
32
- file_put_contents ($ file , $ change );
40
+ foreach ($ this -> fileContents as $ file => $ contents ) {
41
+ $ this ->write (sprintf ('[add-lines] Patching file "%s" ' , $ this -> relativize ( $ file) ));
42
+ file_put_contents ($ file , $ contents );
33
43
}
34
44
}
35
45
36
46
public function unconfigure (Recipe $ recipe , $ config , Lock $ lock ): void
37
47
{
38
- $ changes = $ this ->getUnconfigureFileChanges ($ recipe , $ config );
48
+ $ this ->fileContents = [];
49
+ $ this ->executeUnconfigure ($ recipe , $ config );
39
50
40
- foreach ($ changes as $ file => $ change ) {
41
- $ this ->write (sprintf ('[add-lines] Reverting file "%s" ' , $ file ));
51
+ foreach ($ this -> fileContents as $ file => $ change ) {
52
+ $ this ->write (sprintf ('[add-lines] Reverting file "%s" ' , $ this -> relativize ( $ file) ));
42
53
file_put_contents ($ file , $ change );
43
54
}
44
55
}
45
56
46
57
public function update (RecipeUpdate $ recipeUpdate , array $ originalConfig , array $ newConfig ): void
47
58
{
59
+ // manually check for "requires", as unconfigure ignores it
48
60
$ originalConfig = array_filter ($ originalConfig , function ($ item ) {
49
61
return !isset ($ item ['requires ' ]) || $ this ->isPackageInstalled ($ item ['requires ' ]);
50
62
});
51
- $ newConfig = array_filter ($ newConfig , function ($ item ) {
52
- return !isset ($ item ['requires ' ]) || $ this ->isPackageInstalled ($ item ['requires ' ]);
53
- });
54
-
55
- $ filterDuplicates = function (array $ sourceConfig , array $ comparisonConfig ) {
56
- $ filtered = [];
57
- foreach ($ sourceConfig as $ sourceItem ) {
58
- $ found = false ;
59
- foreach ($ comparisonConfig as $ comparisonItem ) {
60
- if ($ sourceItem ['file ' ] === $ comparisonItem ['file ' ] && $ sourceItem ['content ' ] === $ comparisonItem ['content ' ]) {
61
- $ found = true ;
62
- break ;
63
- }
64
- }
65
- if (!$ found ) {
66
- $ filtered [] = $ sourceItem ;
67
- }
68
- }
69
-
70
- return $ filtered ;
71
- };
72
-
73
- // remove any config where the file+value is the same before & after
74
- $ filteredOriginalConfig = $ filterDuplicates ($ originalConfig , $ newConfig );
75
- $ filteredNewConfig = $ filterDuplicates ($ newConfig , $ originalConfig );
76
63
77
- $ this ->unconfigure ($ recipeUpdate ->getOriginalRecipe (), $ filteredOriginalConfig , $ recipeUpdate ->getLock ());
78
- $ this ->configure ($ recipeUpdate ->getNewRecipe (), $ filteredNewConfig , $ recipeUpdate ->getLock ());
64
+ // reset the file content cache
65
+ $ this ->fileContents = [];
66
+ $ this ->executeUnconfigure ($ recipeUpdate ->getOriginalRecipe (), $ originalConfig );
67
+ $ this ->executeConfigure ($ recipeUpdate ->getNewRecipe (), $ newConfig );
68
+ $ newFiles = [];
69
+ $ originalFiles = [];
70
+ foreach ($ this ->fileContents as $ file => $ contents ) {
71
+ // set the original file to the current contents
72
+ $ originalFiles [$ this ->relativize ($ file )] = file_get_contents ($ file );
73
+ // and the new file where the old recipe was unconfigured, and the new configured
74
+ $ newFiles [$ this ->relativize ($ file )] = $ contents ;
75
+ }
76
+ $ recipeUpdate ->addOriginalFiles ($ originalFiles );
77
+ $ recipeUpdate ->addNewFiles ($ newFiles );
79
78
}
80
79
81
- public function getConfigureFileChanges (Recipe $ recipe , $ config ): array
80
+ public function executeConfigure (Recipe $ recipe , $ config ): void
82
81
{
83
- $ changes = [];
84
82
foreach ($ config as $ patch ) {
85
83
if (!isset ($ patch ['file ' ])) {
86
84
$ this ->write (sprintf ('The "file" key is required for the "add-lines" configurator for recipe "%s". Skipping ' , $ recipe ->getName ()));
@@ -133,15 +131,12 @@ public function getConfigureFileChanges(Recipe $recipe, $config): array
133
131
$ target = isset ($ patch ['target ' ]) ? $ patch ['target ' ] : null ;
134
132
135
133
$ newContents = $ this ->getPatchedContents ($ file , $ content , $ position , $ target , $ warnIfMissing );
136
- $ changes [$ file ] = $ newContents ;
134
+ $ this -> fileContents [$ file ] = $ newContents ;
137
135
}
138
-
139
- return $ changes ;
140
136
}
141
137
142
- public function getUnconfigureFileChanges (Recipe $ recipe , $ config ): array
138
+ public function executeUnconfigure (Recipe $ recipe , $ config ): void
143
139
{
144
- $ changes = [];
145
140
foreach ($ config as $ patch ) {
146
141
if (!isset ($ patch ['file ' ])) {
147
142
$ this ->write (sprintf ('The "file" key is required for the "add-lines" configurator for recipe "%s". Skipping ' , $ recipe ->getName ()));
@@ -165,15 +160,13 @@ public function getUnconfigureFileChanges(Recipe $recipe, $config): array
165
160
$ value = $ patch ['content ' ];
166
161
167
162
$ newContents = $ this ->getUnPatchedContents ($ file , $ value );
168
- $ changes [$ file ] = $ newContents ;
163
+ $ this -> fileContents [$ file ] = $ newContents ;
169
164
}
170
-
171
- return $ changes ;
172
165
}
173
166
174
167
private function getPatchedContents (string $ file , string $ value , string $ position , ?string $ target , bool $ warnIfMissing ): string
175
168
{
176
- $ fileContents = file_get_contents ($ file );
169
+ $ fileContents = $ this -> readFile ($ file );
177
170
178
171
if (false !== strpos ($ fileContents , $ value )) {
179
172
return $ fileContents ; // already includes value, skip
@@ -219,7 +212,7 @@ private function getPatchedContents(string $file, string $value, string $positio
219
212
220
213
private function getUnPatchedContents (string $ file , $ value ): string
221
214
{
222
- $ fileContents = file_get_contents ($ file );
215
+ $ fileContents = $ this -> readFile ($ file );
223
216
224
217
if (false === strpos ($ fileContents , $ value )) {
225
218
return $ fileContents ; // value already gone!
@@ -232,9 +225,8 @@ private function getUnPatchedContents(string $file, $value): string
232
225
}
233
226
234
227
$ position = strpos ($ fileContents , $ value );
235
- $ fileContents = substr_replace ($ fileContents , '' , $ position , \strlen ($ value ));
236
228
237
- return $ fileContents ;
229
+ return substr_replace ( $ fileContents, '' , $ position , \strlen ( $ value )) ;
238
230
}
239
231
240
232
private function isPackageInstalled ($ packages ): bool
@@ -253,4 +245,26 @@ private function isPackageInstalled($packages): bool
253
245
254
246
return true ;
255
247
}
248
+
249
+ private function relativize (string $ path ): string
250
+ {
251
+ $ rootDir = $ this ->options ->get ('root-dir ' );
252
+ if (0 === strpos ($ path , $ rootDir )) {
253
+ $ path = substr ($ path , \strlen ($ rootDir ) + 1 );
254
+ }
255
+
256
+ return ltrim ($ path , '/ \\' );
257
+ }
258
+
259
+ private function readFile (string $ file ): string
260
+ {
261
+ if (isset ($ this ->fileContents [$ file ])) {
262
+ return $ this ->fileContents [$ file ];
263
+ }
264
+
265
+ $ fileContents = file_get_contents ($ file );
266
+ $ this ->fileContents [$ file ] = $ fileContents ;
267
+
268
+ return $ fileContents ;
269
+ }
256
270
}
0 commit comments