Skip to content

Commit 4141eff

Browse files
author
Greg Bowler
committed
Set errors to optional array instead of throwing exception
1 parent d7c18ce commit 4141eff

10 files changed

+129
-34
lines changed

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
"require": {
77
"php": ">=7.2",
8+
"ext-json": "*",
89
"phpgt/cli": "1.*",
910
"webmozart/glob": "4.*",
1011
"composer/semver": "1.*"

composer.lock

+3-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Build.php

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
namespace Gt\Build;
33

4+
use Webmozart\Glob\Glob;
5+
46
class Build {
57
/** @var TaskList */
68
protected $taskList;
@@ -16,11 +18,19 @@ public function __construct(
1618
);
1719
}
1820

19-
public function check():int {
21+
public function check(array &$errors = null):int {
2022
$count = 0;
2123

2224
foreach($this->taskList as $pathMatch => $task) {
23-
$task->check();
25+
$absolutePathMatch = implode(DIRECTORY_SEPARATOR, [
26+
getcwd(),
27+
$pathMatch,
28+
]);
29+
$fileList = Glob::glob($absolutePathMatch);
30+
if(!empty($fileList)) {
31+
$task->check($errors);
32+
}
33+
2434
$count ++;
2535
}
2636

@@ -30,10 +40,10 @@ public function check():int {
3040
/**
3141
* @return Task[]
3242
*/
33-
public function build():array {
43+
public function build(array &$errors = null):array {
3444
$updatedTasks = [];
3545
foreach($this->taskList as $pathMatch => $task) {
36-
if($task->build()) {
46+
if($task->build($errors)) {
3747
$updatedTasks []= $task;
3848
}
3949
}

src/BuildRunner.php

+30-6
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ public function setDefault(string $path):void {
2727
$this->defaultPath = $path;
2828
}
2929

30-
public function run(
31-
string $workingDirectory,
32-
bool $continue = true
33-
):void {
30+
public function run(bool $continue = true):void {
31+
$workingDirectory = $this->workingDirectory;
32+
3433
if(is_file($workingDirectory)) {
3534
$workingDirectory = dirname($workingDirectory);
3635
}
@@ -46,11 +45,23 @@ public function run(
4645
$jsonPath= $this->defaultPath;
4746
}
4847

48+
$startTime = microtime(true);
49+
50+
$errors = [];
4951
$build = new Build($jsonPath, $workingDirectory);
50-
$build->check();
52+
$build->check($errors);
53+
54+
if(!empty($errors)) {
55+
$this->stream->writeLine("The following errors occurred:", Stream::ERROR);
56+
57+
foreach($errors as $e) {
58+
$this->stream->writeLine("" . $e);
59+
}
60+
exit(1);
61+
}
5162

5263
do {
53-
$updates = $build->build();
64+
$updates = $build->build($errors);
5465

5566
foreach($updates as $update) {
5667
$this->stream->writeLine(
@@ -60,9 +71,22 @@ public function run(
6071
);
6172
}
6273

74+
foreach($errors as $error) {
75+
$this->stream->writeLine(
76+
$error,
77+
Stream::ERROR
78+
);
79+
}
80+
6381
// Quarter-second wait:
6482
usleep(250000);
6583
}
6684
while($continue);
85+
86+
$deltaTime = round(
87+
microtime(true) - $startTime,
88+
1
89+
);
90+
$this->stream->writeLine("Build script completed in $deltaTime seconds");
6791
}
6892
}

src/Command/RunCommand.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
<?php
22
namespace Gt\Build\Command;
33

4+
use Gt\Build\BuildRunner;
45
use Gt\Cli\Argument\ArgumentValueList;
56
use Gt\Cli\Command\Command;
67
use Gt\Cli\Parameter\NamedParameter;
78
use Gt\Cli\Parameter\Parameter;
9+
use Gt\Cli\Stream;
810

911
class RunCommand extends Command {
1012
public function run(ArgumentValueList $arguments = null):void {
11-
$this->writeLine("Run command");
13+
$stream = new Stream(
14+
"php://stdin",
15+
"php://stdout",
16+
"php://stderr"
17+
);
18+
$buildRunner = new BuildRunner(getcwd(), $stream);
19+
$buildRunner->run(false);
1220
}
1321

1422
public function getName():string {

src/Requirement.php

+25-6
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,41 @@ public function __toString():string {
2727
]);
2828
}
2929

30-
public function check():bool {
30+
public function check(array &$errors = null):bool {
3131
$arg = $this->getArgumentToCheckVersionOfCommand();
3232
$versionCommand = implode(" ", [
3333
$this->name,
3434
$arg,
3535
]);
3636

37-
exec($versionCommand, $output, $return);
37+
$descriptor = [
38+
0 => ["pipe", "r"],
39+
1 => ["pipe", "w"],
40+
2 => ["pipe", "w"],
41+
];
42+
$proc = proc_open($versionCommand, $descriptor, $pipes);
3843

39-
if($return !== 0) {
40-
throw new VersionCheckException($this->name);
44+
do {
45+
$status = proc_get_status($proc);
4146
}
47+
while($status["running"]);
48+
$return = $status["exitcode"];
49+
$output = "";
50+
51+
$output .= stream_get_contents($pipes[1]);
52+
$output .= stream_get_contents($pipes[2]);
53+
proc_close($proc);
4254

43-
$outputString = implode(" ", $output);
44-
$versionInstalled = $this->getVersionFromVersionString($outputString);
55+
if($return !== 0) {
56+
if(is_null($errors)) {
57+
throw new RequirementMissingException($this->name);
58+
}
59+
else {
60+
$errors []= "Requirement missing: " . $this->name;
61+
}
62+
}
4563

64+
$versionInstalled = $this->getVersionFromVersionString($output);
4665
return $this->isVersionStringValid($versionInstalled);
4766
}
4867

src/RequirementMissingException.php

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
namespace Gt\Build;
3+
4+
class RequirementMissingException extends BuildException {}

src/Task.php

+42-11
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ class Task {
1818

1919
protected $fileHashList = [];
2020

21-
// TODO: PHP 7.2 object typehint
2221
public function __construct(
23-
$details,
22+
object $details,
2423
string $pathMatch = self::MATCH_EVERYTHING,
2524
string $basePath = ""
2625
) {
@@ -38,24 +37,28 @@ public function __toString():string {
3837
return $this->name ?? $this->execute->command;
3938
}
4039

41-
public function check():void {
40+
public function check(array &$errors = null):void {
4241
foreach($this->requirements as $requirement) {
43-
if(!$requirement->check()) {
44-
throw new UnsatisfiedRequirementVersion($requirement);
42+
if(!$requirement->check($errors)) {
43+
if(is_null($errors)) {
44+
throw new UnsatisfiedRequirementVersion($requirement);
45+
}
46+
else {
47+
$errors []= "Unsatisfied version: " . $requirement;
48+
}
4549
}
4650
}
4751
}
4852

49-
public function build():bool {
53+
public function build(array &$errors = null):bool {
5054
$changes = false;
5155

5256
foreach(Glob::glob($this->absolutePath) as $matchedPath) {
5357
$hash = filemtime($matchedPath);
5458
$existingHash = $this->fileHashList[$matchedPath] ?? null;
5559

5660
if($hash !== $existingHash) {
57-
$this->execute();
58-
$changes = true;
61+
$changes = $this->execute($errors);
5962
}
6063

6164
$this->fileHashList[$matchedPath] = $hash;
@@ -86,7 +89,7 @@ protected function setDetails($details):void {
8689
}
8790
}
8891

89-
protected function execute():void {
92+
protected function execute(array &$errors = null):bool {
9093
$previousCwd = getcwd();
9194
chdir($this->basePath);
9295

@@ -95,12 +98,40 @@ protected function execute():void {
9598
$this->execute->arguments,
9699
]);
97100

98-
exec($fullCommand, $output, $return);
101+
$descriptor = [
102+
0 => ["pipe", "r"],
103+
1 => ["pipe", "w"],
104+
2 => ["pipe", "w"],
105+
];
106+
$proc = proc_open($fullCommand, $descriptor, $pipes);
107+
108+
do {
109+
$status = proc_get_status($proc);
110+
} while($status["running"]);
99111
chdir($previousCwd);
112+
$output = "";
113+
114+
$return = $status["exitcode"];
115+
$output .= stream_get_contents($pipes[1]);
116+
$output .= stream_get_contents($pipes[2]);
117+
proc_close($proc);
100118

101119
if($return !== 0) {
102-
throw new TaskExecutionFailureException($fullCommand);
120+
if(is_null($errors)) {
121+
throw new TaskExecutionFailureException($fullCommand);
122+
}
123+
else {
124+
$errors []= "ERROR executing "
125+
. $this->execute->command
126+
. ": "
127+
. PHP_EOL
128+
. $output;
129+
}
130+
131+
return false;
103132
}
133+
134+
return true;
104135
}
105136

106137
protected function expandRelativePath(string $basePath):string {

src/TaskList.php

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
class TaskList implements Iterator {
77
protected $pathMatches = [];
8+
/** @var array Task[] */
89
protected $tasks = [];
910

1011
protected $iteratorKey;

src/VersionCheckException.php

-4
This file was deleted.

0 commit comments

Comments
 (0)