Compare commits
4 Commits
6f162102ef
...
18650ba7ad
Author | SHA1 | Date |
---|---|---|
|
18650ba7ad | |
|
8654d13e81 | |
|
5a5f1756e1 | |
|
6d88ccb8f1 |
|
@ -10,7 +10,14 @@ use Log;
|
||||||
|
|
||||||
abstract class BaseCompiler implements Responsable
|
abstract class BaseCompiler implements Responsable
|
||||||
{
|
{
|
||||||
protected File $file;
|
public function __construct(protected ?File $file = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromFile(string $file): static
|
||||||
|
{
|
||||||
|
return new static(new File($file, false));
|
||||||
|
}
|
||||||
|
|
||||||
public function compile(Document $document): self
|
public function compile(Document $document): self
|
||||||
{
|
{
|
||||||
|
@ -21,7 +28,7 @@ abstract class BaseCompiler implements Responsable
|
||||||
|
|
||||||
if ($document->template()) {
|
if ($document->template()) {
|
||||||
$templatePath = $document->template()->fullPath();
|
$templatePath = $document->template()->fullPath();
|
||||||
exec('rsync -av '.escapeshellarg($templatePath).'/ '.escapeshellarg($this->file->getPath()));
|
exec('rsync -av ' . escapeshellarg($templatePath) . '/ ' . escapeshellarg($this->file->getPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
exec($this->command($document), $output, $returnVar);
|
exec($this->command($document), $output, $returnVar);
|
||||||
|
@ -41,15 +48,41 @@ abstract class BaseCompiler implements Responsable
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, Documents> $documents
|
||||||
|
*/
|
||||||
|
public function merge(array $documents): self
|
||||||
|
{
|
||||||
|
$outfile = '/tmp/' . Str::uuid()->toString() . '.pdf';
|
||||||
|
$paths = array_map(fn ($document) => static::compile($document)->getPath(), $documents);
|
||||||
|
$command = collect([
|
||||||
|
'pdfjam --nup 1x1 --outfile ' . $outfile,
|
||||||
|
...array_map(fn ($path) => escapeshellarg($path), $paths),
|
||||||
|
])->implode(' ');
|
||||||
|
|
||||||
|
exec($command, $output, $returnVar);
|
||||||
|
|
||||||
|
foreach ($paths as $path) {
|
||||||
|
@unlink($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 !== $returnVar) {
|
||||||
|
Log::error('Merging failed', ['output' => $output]);
|
||||||
|
throw (new CompilerException('Compilation failed.'))->setOutput($output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::fromFile($outfile);
|
||||||
|
}
|
||||||
|
|
||||||
public function storeAs(string $directory, string $name, string $disk): string
|
public function storeAs(string $directory, string $name, string $disk): string
|
||||||
{
|
{
|
||||||
$contents = $this->file->getContent();
|
$contents = $this->file->getContent();
|
||||||
|
|
||||||
Storage::disk($disk)->put($directory.'/'.$name, $contents);
|
Storage::disk($disk)->put($directory . '/' . $name, $contents);
|
||||||
|
|
||||||
$this->cleanup();
|
$this->cleanup();
|
||||||
|
|
||||||
return $directory.'/'.$name;
|
return $directory . '/' . $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeIn(string $directory, string $disk): string
|
public function storeIn(string $directory, string $disk): string
|
||||||
|
@ -72,9 +105,9 @@ abstract class BaseCompiler implements Responsable
|
||||||
|
|
||||||
protected function prepareForCompilation(Document $document): void
|
protected function prepareForCompilation(Document $document): void
|
||||||
{
|
{
|
||||||
$workDir = '/tmp/'.Str::random(32);
|
$workDir = '/tmp/' . Str::uuid()->toString();
|
||||||
mkdir($workDir, 0777, true);
|
mkdir($workDir, 0777, true);
|
||||||
$this->file = new File($workDir.'/'.$document->compiledFilename(), false);
|
$this->file = new File($workDir . '/' . $document->compiledFilename(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function refreshFile(): void
|
private function refreshFile(): void
|
||||||
|
@ -85,14 +118,14 @@ abstract class BaseCompiler implements Responsable
|
||||||
private function command(Document $document): string
|
private function command(Document $document): string
|
||||||
{
|
{
|
||||||
return collect([
|
return collect([
|
||||||
'cd '.escapeshellarg($this->file->getPath()),
|
'cd ' . escapeshellarg($this->file->getPath()),
|
||||||
$document->getEngine()->binary().' --halt-on-error '.escapeshellarg($document->filename()),
|
$document->getEngine()->binary() . ' --halt-on-error ' . escapeshellarg($document->filename()),
|
||||||
$document->getEngine()->binary().' --halt-on-error '.escapeshellarg($document->filename()),
|
$document->getEngine()->binary() . ' --halt-on-error ' . escapeshellarg($document->filename()),
|
||||||
])->implode(' && ');
|
])->implode(' && ');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function cleanup(): void
|
private function cleanup(): void
|
||||||
{
|
{
|
||||||
exec('rm -R '.$this->file->getPath());
|
exec('rm -R ' . $this->file->getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,9 @@ use PHPUnit\Framework\Assert;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use ReflectionProperty;
|
use ReflectionProperty;
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
|
||||||
abstract class Document
|
abstract class Document extends Data
|
||||||
{
|
{
|
||||||
abstract public function basename(): string;
|
abstract public function basename(): string;
|
||||||
|
|
||||||
|
@ -35,6 +36,15 @@ abstract class Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function assertIsContent(string $content): void
|
||||||
|
{
|
||||||
|
Assert::assertEquals(
|
||||||
|
$content,
|
||||||
|
$this->renderBody(),
|
||||||
|
"Failed asserting that Content is {$content}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, string> $content
|
* @param array<int, string> $content
|
||||||
*/
|
*/
|
||||||
|
@ -80,12 +90,12 @@ abstract class Document
|
||||||
|
|
||||||
public function filename(): string
|
public function filename(): string
|
||||||
{
|
{
|
||||||
return $this->basename().'.tex';
|
return $this->basename() . '.tex';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function compiledFilename(): string
|
public function compiledFilename(): string
|
||||||
{
|
{
|
||||||
return $this->basename().'.pdf';
|
return $this->basename() . '.pdf';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,8 +154,8 @@ abstract class Document
|
||||||
protected function createVariableFromMethod(ReflectionMethod $method): Closure|InvokableComponentVariable
|
protected function createVariableFromMethod(ReflectionMethod $method): Closure|InvokableComponentVariable
|
||||||
{
|
{
|
||||||
return 0 === $method->getNumberOfParameters()
|
return 0 === $method->getNumberOfParameters()
|
||||||
? $this->createInvokableVariable($method->getName())
|
? $this->createInvokableVariable($method->getName())
|
||||||
: Closure::fromCallable([$this, $method->getName()]);
|
: Closure::fromCallable([$this, $method->getName()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createInvokableVariable(string $method): InvokableComponentVariable
|
protected function createInvokableVariable(string $method): InvokableComponentVariable
|
||||||
|
|
|
@ -22,12 +22,21 @@ trait FakesCompilation
|
||||||
|
|
||||||
Assert::assertFalse(
|
Assert::assertFalse(
|
||||||
$compilations->isEmpty(),
|
$compilations->isEmpty(),
|
||||||
'The TeX Document "'.$documentClass.'" has not been compiled.'
|
'The TeX Document "' . $documentClass . '" has not been compiled.'
|
||||||
);
|
);
|
||||||
|
|
||||||
$validDocuments = $compilations->filter(fn ($compilation) => $check($compilation));
|
$validDocuments = $compilations->filter(fn ($compilation) => $check($compilation));
|
||||||
|
|
||||||
Assert::assertNotEmpty($validDocuments, 'Failed that TeX Document "'.$documentClass.'" has been compiled with given check.');
|
Assert::assertNotEmpty($validDocuments, 'Failed that TeX Document "' . $documentClass . '" has been compiled with given check.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param class-string<Document> $documentClass
|
||||||
|
* @param callable(Document): bool $check
|
||||||
|
*/
|
||||||
|
public function assertCompiledContent(string $documentClass, string $content): void
|
||||||
|
{
|
||||||
|
$this->assertCompiled($documentClass, fn ($document) => $document->renderBody() === $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +48,7 @@ trait FakesCompilation
|
||||||
|
|
||||||
Assert::assertTrue(
|
Assert::assertTrue(
|
||||||
$compilations->isEmpty(),
|
$compilations->isEmpty(),
|
||||||
'The TeX Document "'.$documentClass.'" should not have been compiled.'
|
'The TeX Document "' . $documentClass . '" should not have been compiled.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue