@@ -29,6 +29,19 @@ public function describeConfiguration(PluginConfigurationBuilderInterface $confi
2929 )
3030 ->withDefaultValue ([])
3131 ->isRequired ();
32+
33+ $ configOptionsBuilder
34+ ->describeBoolOption ('coverage ' , 'Enable coverage collection by switching xdebug to coverage mode. ' )
35+ ->withDefaultValue (false )
36+ ->isRequired ();
37+
38+ $ configOptionsBuilder
39+ ->describeEnumOption (
40+ 'coverage ' ,
41+ 'Enable coverage collection by switching xdebug to coverage mode ' .
42+ ' and writing in the specified coverage format. '
43+ )
44+ ->ofStringValues ('clover ' , 'cobertura ' , 'crap4j ' /*, 'html'*/ , 'php ' , 'text ' , 'xml ' );
3245 }
3346
3447 public function createDiagnosticTasks (
@@ -47,33 +60,63 @@ public function createDiagnosticTasks(
4760 }
4861
4962 $ projectRoot = $ environment ->getProjectConfiguration ()->getProjectRootPath ();
63+
64+ $ coverageFile = null ;
65+ $ coverage = null ;
66+ $ envVariables = [];
67+ if ($ config ->has ('coverage ' )) {
68+ $ envVariables ['XDEBUG_MODE ' ] = 'coverage ' ;
69+ $ coverage = $ config ->getString ('coverage ' );
70+ $ args [] = '--coverage- ' . $ coverage ;
71+ $ args [] = $ coverageFile = $ environment ->getUniqueTempFile ($ this , 'coverage.tmp ' );
72+ }
73+
5074 yield $ environment
5175 ->getTaskFactory ()
5276 ->buildRunPhar ('phpunit ' , $ args )
77+ ->withEnv ($ envVariables )
5378 ->withWorkingDirectory ($ projectRoot )
54- ->withOutputTransformer ($ this ->createOutputTransformerFactory ($ logFile , $ projectRoot ))
79+ ->withOutputTransformer (
80+ $ this ->createOutputTransformerFactory ($ logFile , $ coverage , $ coverageFile , $ projectRoot )
81+ )
5582 ->build ();
5683 }
5784
5885 private function createOutputTransformerFactory (
5986 string $ logFile ,
87+ ?string $ coverage ,
88+ ?string $ coverageFile ,
6089 string $ rootDir
6190 ): OutputTransformerFactoryInterface {
62- return new class ($ logFile , $ rootDir ) implements OutputTransformerFactoryInterface {
91+ return new class ($ logFile , $ coverage , $ coverageFile , $ rootDir ) implements OutputTransformerFactoryInterface {
6392 private $ logFile ;
93+ private $ coverage ;
94+ private $ coverageFile ;
6495 private $ rootDir ;
6596
66- public function __construct (string $ logFile , string $ rootDir )
97+ public function __construct (string $ logFile , ? string $ coverage , ? string $ coverageFile , string $ rootDir )
6798 {
68- $ this ->logFile = $ logFile ;
69- $ this ->rootDir = $ rootDir ;
99+ $ this ->logFile = $ logFile ;
100+ $ this ->coverage = $ coverage ;
101+ $ this ->coverageFile = $ coverageFile ;
102+ $ this ->rootDir = $ rootDir ;
70103 }
71104
72105 public function createFor (TaskReportInterface $ report ): OutputTransformerInterface
73106 {
74- return new class ($ this ->logFile , $ this ->rootDir , $ report ) implements OutputTransformerInterface {
107+ return new class (
108+ $ this ->logFile ,
109+ $ this ->coverage ,
110+ $ this ->coverageFile ,
111+ $ this ->rootDir ,
112+ $ report
113+ ) implements OutputTransformerInterface {
75114 /** @var string */
76115 private $ logFile ;
116+ /** @var string|null */
117+ private $ coverage ;
118+ /** @var string|null */
119+ private $ coverageFile ;
77120 /** @var string */
78121 private $ rootDir ;
79122 /** @var TaskReportInterface */
@@ -83,13 +126,20 @@ public function createFor(TaskReportInterface $report): OutputTransformerInterfa
83126 /** @var BufferedLineReader */
84127 private $ stdErr ;
85128
86- public function __construct (string $ logFile , string $ rootDir , TaskReportInterface $ report )
87- {
88- $ this ->logFile = $ logFile ;
89- $ this ->rootDir = $ rootDir ;
90- $ this ->report = $ report ;
91- $ this ->stdOut = BufferedLineReader::create ();
92- $ this ->stdErr = BufferedLineReader::create ();
129+ public function __construct (
130+ string $ logFile ,
131+ ?string $ coverage ,
132+ ?string $ coverageFile ,
133+ string $ rootDir ,
134+ TaskReportInterface $ report
135+ ) {
136+ $ this ->logFile = $ logFile ;
137+ $ this ->coverage = $ coverage ;
138+ $ this ->coverageFile = $ coverageFile ;
139+ $ this ->rootDir = $ rootDir ;
140+ $ this ->report = $ report ;
141+ $ this ->stdOut = BufferedLineReader::create ();
142+ $ this ->stdErr = BufferedLineReader::create ();
93143 }
94144
95145 public function write (string $ data , int $ channel ): void
@@ -103,6 +153,28 @@ public function write(string $data, int $channel): void
103153
104154 public function finish (int $ exitCode ): void
105155 {
156+ switch ($ this ->coverage ) {
157+ case 'clover ' :
158+ case 'cobertura ' :
159+ case 'crap4j ' :
160+ case 'xml ' :
161+ $ this ->report
162+ ->addAttachment ('coverage- ' . $ this ->coverage . '.xml ' )
163+ ->fromFile ($ this ->coverageFile )
164+ ->end ();
165+ break ;
166+ // FIXME: this is a directory, we'll need to use a finder then or what to do?
167+ // case 'html':
168+ // $this->report->addAttachment('coverage.php')->fromDirectory($this->logFile)->end();
169+ // break;
170+ case 'php ' :
171+ $ this ->report ->addAttachment ('coverage.php ' )->fromFile ($ this ->logFile )->end ();
172+ break ;
173+ case 'text ' :
174+ $ this ->report ->addAttachment ('coverage.txt ' )->fromFile ($ this ->logFile )->end ();
175+ default :
176+ // Do nothing.
177+ }
106178 try {
107179 JUnitReportAppender::appendFileTo ($ this ->report , $ this ->logFile , $ this ->rootDir );
108180 $ this ->report ->addAttachment ('junit-log.xml ' )->fromFile ($ this ->logFile )->end ();
0 commit comments