@@ -23,64 +23,62 @@ class AddLinesConfigurator extends AbstractConfigurator
2323 self ::POSITION_AFTER_TARGET ,
2424 ];
2525
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+
2635 public function configure (Recipe $ recipe , $ config , Lock $ lock , array $ options = []): void
2736 {
28- $ changes = $ this ->getConfigureFileChanges ($ recipe , $ config );
37+ $ this ->fileContents = [];
38+ $ this ->executeConfigure ($ recipe , $ config );
2939
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 );
3343 }
3444 }
3545
3646 public function unconfigure (Recipe $ recipe , $ config , Lock $ lock ): void
3747 {
38- $ changes = $ this ->getUnconfigureFileChanges ($ recipe , $ config );
48+ $ this ->fileContents = [];
49+ $ this ->executeUnconfigure ($ recipe , $ config );
3950
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) ));
4253 file_put_contents ($ file , $ change );
4354 }
4455 }
4556
4657 public function update (RecipeUpdate $ recipeUpdate , array $ originalConfig , array $ newConfig ): void
4758 {
59+ // manually check for "requires", as unconfigure ignores it
4860 $ originalConfig = array_filter ($ originalConfig , function ($ item ) {
4961 return !isset ($ item ['requires ' ]) || $ this ->isPackageInstalled ($ item ['requires ' ]);
5062 });
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 );
7663
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 );
7978 }
8079
81- public function getConfigureFileChanges (Recipe $ recipe , $ config ): array
80+ public function executeConfigure (Recipe $ recipe , $ config ): void
8281 {
83- $ changes = [];
8482 foreach ($ config as $ patch ) {
8583 if (!isset ($ patch ['file ' ])) {
8684 $ 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
133131 $ target = isset ($ patch ['target ' ]) ? $ patch ['target ' ] : null ;
134132
135133 $ newContents = $ this ->getPatchedContents ($ file , $ content , $ position , $ target , $ warnIfMissing );
136- $ changes [$ file ] = $ newContents ;
134+ $ this -> fileContents [$ file ] = $ newContents ;
137135 }
138-
139- return $ changes ;
140136 }
141137
142- public function getUnconfigureFileChanges (Recipe $ recipe , $ config ): array
138+ public function executeUnconfigure (Recipe $ recipe , $ config ): void
143139 {
144- $ changes = [];
145140 foreach ($ config as $ patch ) {
146141 if (!isset ($ patch ['file ' ])) {
147142 $ 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
165160 $ value = $ patch ['content ' ];
166161
167162 $ newContents = $ this ->getUnPatchedContents ($ file , $ value );
168- $ changes [$ file ] = $ newContents ;
163+ $ this -> fileContents [$ file ] = $ newContents ;
169164 }
170-
171- return $ changes ;
172165 }
173166
174167 private function getPatchedContents (string $ file , string $ value , string $ position , ?string $ target , bool $ warnIfMissing ): string
175168 {
176- $ fileContents = file_get_contents ($ file );
169+ $ fileContents = $ this -> readFile ($ file );
177170
178171 if (false !== strpos ($ fileContents , $ value )) {
179172 return $ fileContents ; // already includes value, skip
@@ -219,7 +212,7 @@ private function getPatchedContents(string $file, string $value, string $positio
219212
220213 private function getUnPatchedContents (string $ file , $ value ): string
221214 {
222- $ fileContents = file_get_contents ($ file );
215+ $ fileContents = $ this -> readFile ($ file );
223216
224217 if (false === strpos ($ fileContents , $ value )) {
225218 return $ fileContents ; // value already gone!
@@ -232,9 +225,8 @@ private function getUnPatchedContents(string $file, $value): string
232225 }
233226
234227 $ position = strpos ($ fileContents , $ value );
235- $ fileContents = substr_replace ($ fileContents , '' , $ position , \strlen ($ value ));
236228
237- return $ fileContents ;
229+ return substr_replace ( $ fileContents, '' , $ position , \strlen ( $ value )) ;
238230 }
239231
240232 private function isPackageInstalled ($ packages ): bool
@@ -253,4 +245,26 @@ private function isPackageInstalled($packages): bool
253245
254246 return true ;
255247 }
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+ }
256270}
0 commit comments