Skip to content

Commit cf50510

Browse files
jbagsikcursoragent
andcommitted
Extract shared veraPDF install/env logic for thin commands
Closes mooxphp/verapdf#6. Centralize path resolution, Java/installed gating, and doctor health checks in VeraPdfService plus a command trait. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 653f822 commit cf50510

7 files changed

Lines changed: 220 additions & 85 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Moox\VeraPdf\Commands\Concerns;
6+
7+
use Moox\VeraPdf\DTOs\VeraPdfHealth;
8+
use Moox\VeraPdf\Services\VeraPdfService;
9+
10+
trait InteractsWithVeraPdfEnvironment
11+
{
12+
protected function requireJavaAvailable(VeraPdfService $veraPdf): ?int
13+
{
14+
if ($veraPdf->javaAvailable()) {
15+
return null;
16+
}
17+
18+
$this->components->error($veraPdf->javaMissingMessage());
19+
20+
return self::FAILURE;
21+
}
22+
23+
protected function requireVeraPdfInstalled(VeraPdfService $veraPdf): ?int
24+
{
25+
if ($veraPdf->isInstalled()) {
26+
return null;
27+
}
28+
29+
$this->components->error($veraPdf->notInstalledMessage());
30+
31+
return self::FAILURE;
32+
}
33+
34+
protected function renderVeraPdfHealth(VeraPdfHealth $health): int
35+
{
36+
if ($health->javaAvailable) {
37+
$this->components->info('Java: OK');
38+
} else {
39+
$this->components->error('Java: NOT FOUND');
40+
}
41+
42+
if ($health->launcherPath !== null) {
43+
$this->components->info("Launcher: {$health->launcherPath}");
44+
} else {
45+
$this->components->error('Launcher: '.($health->launcherError ?? 'unknown error'));
46+
}
47+
48+
if ($health->installed) {
49+
$this->components->info('Installed: yes');
50+
} else {
51+
$this->components->error('Installed: no');
52+
}
53+
54+
if ($health->cliBinariesPresent) {
55+
$this->components->info('CLI binaries: OK');
56+
} else {
57+
$this->components->error('CLI binaries: NOT FOUND (expected bin/*cli*.jar from the veraPDF CLI pack)');
58+
}
59+
60+
if ($health->guiArtefactsPresent) {
61+
$this->components->warn('GUI pack artefacts present; slim/headless installs use the CLI pack only.');
62+
}
63+
64+
if ($health->outputPathWritable) {
65+
$this->components->info("Report output: {$health->outputPath}");
66+
} else {
67+
$this->components->warn("Report output: {$health->outputPath} (not writable)");
68+
}
69+
70+
$this->newLine();
71+
72+
if ($health->isHealthy()) {
73+
$this->components->info('Everything looks good.');
74+
75+
return self::SUCCESS;
76+
}
77+
78+
$this->components->warn('Issues found. Run php artisan verapdf:install to fix.');
79+
80+
return self::FAILURE;
81+
}
82+
}

packages/verapdf/src/Commands/DoctorCommand.php

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,72 +5,19 @@
55
namespace Moox\VeraPdf\Commands;
66

77
use Illuminate\Console\Command;
8-
use Illuminate\Support\Facades\File;
8+
use Moox\VeraPdf\Commands\Concerns\InteractsWithVeraPdfEnvironment;
99
use Moox\VeraPdf\Services\VeraPdfService;
10-
use Moox\VeraPdf\Support\VeraPdfOutputPath;
11-
use RuntimeException;
1210

1311
class DoctorCommand extends Command
1412
{
13+
use InteractsWithVeraPdfEnvironment;
14+
1515
protected $signature = 'verapdf:doctor';
1616

1717
protected $description = 'Check veraPDF installation health';
1818

1919
public function handle(VeraPdfService $veraPdf): int
2020
{
21-
$allGood = true;
22-
23-
if ($veraPdf->javaAvailable()) {
24-
$this->components->info('Java: OK');
25-
} else {
26-
$this->components->error('Java: NOT FOUND');
27-
$allGood = false;
28-
}
29-
30-
try {
31-
$launcher = $veraPdf->launcherPath();
32-
$this->components->info("Launcher: {$launcher}");
33-
} catch (RuntimeException $e) {
34-
$this->components->error('Launcher: '.$e->getMessage());
35-
$allGood = false;
36-
}
37-
38-
if ($veraPdf->isInstalled()) {
39-
$this->components->info('Installed: yes');
40-
} else {
41-
$this->components->error('Installed: no');
42-
$allGood = false;
43-
}
44-
45-
if ($veraPdf->hasCliBinaries()) {
46-
$this->components->info('CLI binaries: OK');
47-
} else {
48-
$this->components->error('CLI binaries: NOT FOUND (expected bin/*cli*.jar from the veraPDF CLI pack)');
49-
$allGood = false;
50-
}
51-
52-
if ($veraPdf->hasGuiArtefacts()) {
53-
$this->components->warn('GUI pack artefacts present; slim/headless installs use the CLI pack only.');
54-
}
55-
56-
$outputPath = VeraPdfOutputPath::resolve();
57-
try {
58-
File::ensureDirectoryExists($outputPath);
59-
$this->components->info("Report output: {$outputPath}");
60-
} catch (\Throwable) {
61-
$this->components->warn("Report output: {$outputPath} (not writable)");
62-
}
63-
64-
$this->newLine();
65-
66-
if ($allGood) {
67-
$this->components->info('Everything looks good.');
68-
69-
return self::SUCCESS;
70-
}
71-
72-
$this->components->warn('Issues found. Run php artisan verapdf:install to fix.');
73-
74-
return self::FAILURE;
21+
return $this->renderVeraPdfHealth($veraPdf->inspectHealth());
7522
}
7623
}

packages/verapdf/src/Commands/InstallVeraPdfCommand.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Support\Facades\File;
99
use Illuminate\Support\Facades\Http;
1010
use Illuminate\Support\Facades\Process;
11+
use Moox\VeraPdf\Commands\Concerns\InteractsWithVeraPdfEnvironment;
1112
use Moox\VeraPdf\Services\VeraPdfService;
1213
use Moox\VeraPdf\Support\InstallerChecksum;
1314
use Moox\VeraPdf\Support\SafeZipExtractor;
@@ -18,6 +19,8 @@
1819

1920
class InstallVeraPdfCommand extends Command
2021
{
22+
use InteractsWithVeraPdfEnvironment;
23+
2124
protected $signature = 'verapdf:install
2225
{--force : Overwrite existing installation}';
2326

@@ -27,17 +30,13 @@ public function handle(VeraPdfService $veraPdf): int
2730
{
2831
$this->components->info('Checking Java ...');
2932

30-
if (! $veraPdf->javaAvailable()) {
31-
$this->components->error(
32-
'Java not found. Install a JRE/JDK on the server first (e.g. sudo apt install default-jre-headless).'
33-
);
34-
33+
if ($this->requireJavaAvailable($veraPdf) !== null) {
3534
return self::FAILURE;
3635
}
3736

3837
$this->components->info('Java found.');
3938

40-
$basePath = rtrim((string) config('verapdf.base_path'), '/\\');
39+
$basePath = $veraPdf->basePath();
4140

4241
if ($veraPdf->isInstalled() && ! $this->option('force')) {
4342
if ($veraPdf->hasCliBinaries()) {

packages/verapdf/src/Commands/ValidateCommand.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,26 @@
66

77
use Illuminate\Console\Command;
88
use Moox\VeraPdf\Actions\RecordVeraPdfValidation;
9+
use Moox\VeraPdf\Commands\Concerns\InteractsWithVeraPdfEnvironment;
910
use Moox\VeraPdf\Services\VeraPdfService;
1011
use RuntimeException;
1112

1213
class ValidateCommand extends Command
1314
{
15+
use InteractsWithVeraPdfEnvironment;
16+
1417
protected $signature = 'verapdf:validate
1518
{path : Absolute path to the PDF file to validate}';
1619

1720
protected $description = 'Validate a PDF for PDF/A-3 conformance using veraPDF';
1821

1922
public function handle(VeraPdfService $veraPdf, RecordVeraPdfValidation $recordVeraPdfValidation): int
2023
{
21-
if (! $veraPdf->javaAvailable()) {
22-
$this->components->error(
23-
'Java not found. Install a JRE/JDK on the server first (e.g. sudo apt install default-jre-headless).'
24-
);
25-
24+
if ($this->requireJavaAvailable($veraPdf) !== null) {
2625
return self::FAILURE;
2726
}
2827

29-
if (! $veraPdf->isInstalled()) {
30-
$this->components->error('veraPDF is not installed. Run php artisan verapdf:install first.');
31-
28+
if ($this->requireVeraPdfInstalled($veraPdf) !== null) {
3229
return self::FAILURE;
3330
}
3431

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Moox\VeraPdf\DTOs;
6+
7+
final readonly class VeraPdfHealth
8+
{
9+
public function __construct(
10+
public bool $javaAvailable,
11+
public ?string $launcherPath,
12+
public ?string $launcherError,
13+
public bool $installed,
14+
public bool $cliBinariesPresent,
15+
public bool $guiArtefactsPresent,
16+
public string $outputPath,
17+
public bool $outputPathWritable,
18+
) {}
19+
20+
public function isHealthy(): bool
21+
{
22+
return $this->javaAvailable
23+
&& $this->launcherPath !== null
24+
&& $this->installed
25+
&& $this->cliBinariesPresent;
26+
}
27+
}

packages/verapdf/src/Services/VeraPdfService.php

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,22 @@
66

77
use Illuminate\Support\Facades\File;
88
use Illuminate\Support\Facades\Process;
9+
use Moox\VeraPdf\DTOs\VeraPdfHealth;
910
use Moox\VeraPdf\DTOs\VeraPdfResult;
1011
use Moox\VeraPdf\Support\VeraPdfOutputPath;
1112
use RuntimeException;
13+
use Throwable;
1214

1315
class VeraPdfService
1416
{
17+
public function basePath(): string
18+
{
19+
return rtrim((string) config('verapdf.base_path'), '/\\');
20+
}
21+
1522
public function launcherPath(): string
1623
{
17-
$basePath = rtrim((string) config('verapdf.base_path'), '/\\');
24+
$basePath = $this->basePath();
1825
$launcher = (string) config('verapdf.paths.launcher', 'verapdf');
1926
$path = $basePath.'/'.$launcher;
2027

@@ -34,23 +41,74 @@ public function launcherPath(): string
3441
return $path;
3542
}
3643

44+
public function javaMissingMessage(): string
45+
{
46+
return 'Java not found. Install a JRE/JDK on the server first (e.g. sudo apt install default-jre-headless).';
47+
}
48+
49+
public function notInstalledMessage(): string
50+
{
51+
return 'veraPDF is not installed. Run php artisan verapdf:install first.';
52+
}
53+
54+
public function assertJavaAvailable(): void
55+
{
56+
if ($this->javaAvailable()) {
57+
return;
58+
}
59+
60+
throw new RuntimeException($this->javaMissingMessage());
61+
}
62+
63+
public function assertInstalled(): void
64+
{
65+
if ($this->isInstalled()) {
66+
return;
67+
}
68+
69+
throw new RuntimeException($this->notInstalledMessage());
70+
}
71+
72+
public function inspectHealth(): VeraPdfHealth
73+
{
74+
$launcherPath = null;
75+
$launcherError = null;
76+
77+
try {
78+
$launcherPath = $this->launcherPath();
79+
} catch (RuntimeException $e) {
80+
$launcherError = $e->getMessage();
81+
}
82+
83+
$outputPath = VeraPdfOutputPath::resolve();
84+
$outputPathWritable = true;
85+
86+
try {
87+
File::ensureDirectoryExists($outputPath);
88+
} catch (Throwable) {
89+
$outputPathWritable = false;
90+
}
91+
92+
return new VeraPdfHealth(
93+
javaAvailable: $this->javaAvailable(),
94+
launcherPath: $launcherPath,
95+
launcherError: $launcherError,
96+
installed: $this->isInstalled(),
97+
cliBinariesPresent: $this->hasCliBinaries(),
98+
guiArtefactsPresent: $this->hasGuiArtefacts(),
99+
outputPath: $outputPath,
100+
outputPathWritable: $outputPathWritable,
101+
);
102+
}
103+
37104
/**
38105
* @param string|null $reportDirectory Absolute filesystem directory for report output.
39106
* When null, uses `verapdf.output.path` config.
40107
*/
41108
public function validate(string $pdfPath, ?string $reportDirectory = null): VeraPdfResult
42109
{
43-
if (! $this->javaAvailable()) {
44-
throw new RuntimeException(
45-
'Java not found. Install a JRE/JDK on the server first (e.g. sudo apt install default-jre-headless).'
46-
);
47-
}
48-
49-
if (! $this->isInstalled()) {
50-
throw new RuntimeException(
51-
'veraPDF is not installed. Run php artisan verapdf:install first.'
52-
);
53-
}
110+
$this->assertJavaAvailable();
111+
$this->assertInstalled();
54112

55113
if (! file_exists($pdfPath)) {
56114
throw new RuntimeException("File not found: {$pdfPath}");
@@ -138,7 +196,7 @@ public function hasCliBinaries(): bool
138196
*/
139197
public function hasGuiArtefacts(): bool
140198
{
141-
$basePath = rtrim((string) config('verapdf.base_path'), '/\\');
199+
$basePath = $this->basePath();
142200

143201
if (is_file($basePath.'/verapdf-gui') || is_file($basePath.'/verapdf-gui.bat')) {
144202
return true;
@@ -162,7 +220,7 @@ public function findCliJar(): ?string
162220

163221
private function findJarInBin(string $needle): ?string
164222
{
165-
$binDir = rtrim((string) config('verapdf.base_path'), '/\\').'/bin';
223+
$binDir = $this->basePath().'/bin';
166224

167225
if (! is_dir($binDir)) {
168226
return null;

0 commit comments

Comments
 (0)