@@ -26,8 +26,8 @@ abstract class AbstractGenerator
2626 /** @var array */
2727 protected $ data ;
2828
29- /** @var string */
30- protected $ source ;
29+ /** @var array */
30+ protected $ sources ;
3131
3232 /** @var int */
3333 protected $ totalSum = 0 ;
@@ -38,9 +38,9 @@ abstract class AbstractGenerator
3838
3939 /**
4040 * @param string $file path to coverage.dat file
41- * @param string $source path to covered source file or directory
41+ * @param array $sources paths to covered source files or directories
4242 */
43- public function __construct (string $ file , string $ source = null )
43+ public function __construct (string $ file , array $ sources = [] )
4444 {
4545 if (!is_file ($ file )) {
4646 throw new \Exception ("File ' $ file' is missing. " );
@@ -55,23 +55,18 @@ public function __construct(string $file, string $source = null)
5555 return @is_file ($ path ); // @ some files or wrappers may not exist, i.e. mock://
5656 }, ARRAY_FILTER_USE_KEY );
5757
58- if (!$ source ) {
59- $ source = key ($ this ->data );
60- for ($ i = 0 ; $ i < strlen ($ source ); $ i ++) {
61- foreach ($ this ->data as $ s => $ foo ) {
62- if (!isset ($ s [$ i ]) || $ source [$ i ] !== $ s [$ i ]) {
63- $ source = substr ($ source , 0 , $ i );
64- break 2 ;
65- }
58+ if (!$ sources ) {
59+ $ sources = [self ::getCommonFilesPath (array_keys ($ this ->data ))];
60+
61+ } else {
62+ foreach ($ sources as $ source ) {
63+ if (!file_exists ($ source )) {
64+ throw new \Exception ("File or directory ' $ source' is missing. " );
6665 }
6766 }
68- $ source = dirname ($ source . 'x ' );
69-
70- } elseif (!file_exists ($ source )) {
71- throw new \Exception ("File or directory ' $ source' is missing. " );
7267 }
7368
74- $ this ->source = realpath ( $ source );
69+ $ this ->sources = array_map ( ' realpath ' , $ sources );
7570 }
7671
7772
@@ -107,9 +102,14 @@ public function getCoveredPercent(): float
107102
108103 protected function getSourceIterator (): \Iterator
109104 {
110- $ iterator = is_dir ($ this ->source )
111- ? new \RecursiveIteratorIterator (new \RecursiveDirectoryIterator ($ this ->source ))
112- : new \ArrayIterator ([new \SplFileInfo ($ this ->source )]);
105+ $ iterator = new \AppendIterator ;
106+ foreach ($ this ->sources as $ source ) {
107+ $ iterator ->append (
108+ is_dir ($ source )
109+ ? new \RecursiveIteratorIterator (new \RecursiveDirectoryIterator ($ source ))
110+ : new \ArrayIterator ([new \SplFileInfo ($ source )])
111+ );
112+ }
113113
114114 return new \CallbackFilterIterator ($ iterator , function (\SplFileInfo $ file ): bool {
115115 return $ file ->getBasename ()[0 ] !== '. ' // . or .. or .gitignore
@@ -118,5 +118,21 @@ protected function getSourceIterator(): \Iterator
118118 }
119119
120120
121+ protected static function getCommonFilesPath (array $ files ): string
122+ {
123+ $ path = reset ($ files );
124+ for ($ i = 0 ; $ i < strlen ($ path ); $ i ++) {
125+ foreach ($ files as $ file ) {
126+ if (!isset ($ file [$ i ]) || $ path [$ i ] !== $ file [$ i ]) {
127+ $ path = substr ($ path , 0 , $ i );
128+ break 2 ;
129+ }
130+ }
131+ }
132+
133+ return rtrim (is_dir ($ path ) ? $ path : dirname ($ path ), DIRECTORY_SEPARATOR );
134+ }
135+
136+
121137 abstract protected function renderSelf ();
122138}
0 commit comments