diff --git a/.gitattributes b/.gitattributes
index d6a434b..2b5ac9b 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,5 +3,8 @@
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
-CHANGELOG.md export-ignore
-phpunit.xml.dist export-ignore
+phpunit.xml export-ignore
+LICENSE export-ignore
+.php-cs-fixer.dist.php export-ignore
+package.json export-ignore
+webpack.mix.js export-ignore
diff --git a/.github/README.md b/.github/README.md
index 161d525..ed2185b 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -173,7 +173,7 @@ Special thanks to @codepotato for the logo! ❤️
## Security
-If you find any security related issues, please send me an email to import.lorises_0c@icloud.com.
+If you find any security related issues, please send an email to **29132017+Sammyjo20@users.noreply.github.com**
## And that's it! ✨
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index 0fe0b25..4c9663b 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -1,3 +1,3 @@
# Security Policy
-If you discover any security related issues, please email security@yeehaw.dev instead of using the issue tracker.
+If you discover any security related issues, please email **29132017+Sammyjo20@users.noreply.github.com** instead of using the issue tracker.
diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml
index 0180a90..08a497f 100644
--- a/.github/workflows/php-cs-fixer.yml
+++ b/.github/workflows/php-cs-fixer.yml
@@ -1,10 +1,15 @@
name: Code Style
on:
- pull_request:
- branches: [ 'master', 'v2.0', 'v3.0' ]
push:
- branches: [ 'master', 'v2.0', 'v3.0' ]
+ branches:
+ - 'v3.0'
+ pull_request:
+ branches:
+ - '*'
+
+permissions:
+ contents: write
jobs:
php-cs-fixer:
@@ -16,8 +21,8 @@ jobs:
- name: Run PHP CS Fixer
uses: docker://oskarstark/php-cs-fixer-ga
with:
- args: --config=.php-cs-fixer.dist.php
+ args: --config=.php-cs-fixer.dist.php --allow-risky=yes
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
- commit_message: Apply Code Style Fixes
+ commit_message: 🪄 Code Style Fixes
diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
new file mode 100644
index 0000000..512c212
--- /dev/null
+++ b/.github/workflows/phpstan.yml
@@ -0,0 +1,28 @@
+name: PHPStan
+
+on:
+ push:
+ branches:
+ - 'main'
+ pull_request:
+ branches:
+ - '*'
+
+jobs:
+ phpstan:
+ name: phpstan
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ coverage: none
+
+ - name: Install composer dependencies
+ uses: ramsey/composer-install@v2
+
+ - name: Run PHPStan
+ run: ./vendor/bin/phpstan analyse --error-format=github
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 1444365..8769290 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,42 +1,51 @@
-name: Tests
+name: tests
-on: [pull_request, push]
+on:
+ push:
+ branches:
+ - 'v3.0'
+ pull_request:
+ branches:
+ - '*'
+
+permissions:
+ contents: write
jobs:
tests:
- runs-on: ubuntu-latest
+ runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
- php: [8.1, 8.2]
- laravel: [^9.0, ^10.0]
- dependency-version: [prefer-lowest, prefer-stable]
- include:
- - laravel: ^9.0
- testbench: ^7.0
- - laravel: ^10.0
- testbench: ^8.0
+ os: [ ubuntu-latest, windows-latest ]
+ php: [ 8.1, 8.2, 8.3 ]
+ stability: [ prefer-lowest, prefer-stable ]
- name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.dependency-version }}
+ name: P${{ matrix.php }} - ${{ matrix.stability }} - ${{ matrix.os }}
steps:
- name: Checkout code
- uses: actions/checkout@v2
-
- - name: Cache dependencies
- uses: actions/cache@v2
- with:
- path: ~/.composer/cache/files
- key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
+ uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
+ extensions: mbstring, zip, fileinfo
coverage: none
- - name: Install composer dependencies
+ - name: Install Node Dependencies
+ run: |
+ npm install
+
+ - name: Setup problem matchers
+ run: |
+ echo "::add-matcher::${{ runner.tool_cache }}/php.json"
+ echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
+
+ - name: Install dependencies
run: |
- composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest
+ composer update --${{ matrix.stability }} --prefer-dist --no-interaction
+
- name: Execute tests
- run: composer test
+ run: ./vendor/bin/pest
diff --git a/.gitignore b/.gitignore
index 8ec15d1..09e6016 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,8 @@ composer.lock
node_modules
vendor
.php-cs-fixer.cache
+package-lock.json
+tests/Fixtures/Cloud
+tests/Fixtures/Public
+lasso-bundle.json
+.lasso
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index a603d96..110098c 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -37,4 +37,12 @@
'return_type_declaration' => [
'space_before' => 'none'
],
+ 'declare_strict_types' => true,
+ 'blank_line_after_opening_tag' => true,
+ 'single_import_per_statement' => true,
+ 'mb_str_functions' => true,
+ 'no_superfluous_phpdoc_tags' => true,
+ 'no_blank_lines_after_phpdoc' => true,
+ 'no_empty_phpdoc' => true,
+ 'phpdoc_trim' => true,
])->setFinder($finder);
diff --git a/LICENSE b/LICENSE
index 077d195..9f9905e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020 Sam Carré
+Copyright (c) 2023 Sam Carré
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/composer.json b/composer.json
index b00b01d..2834d4c 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,8 @@
"authors": [
{
"name": "Sam Carré",
- "email": "sam.carre2000@gmail.com"
+ "email": "29132017+Sammyjo20@users.noreply.github.com",
+ "role": "Developer"
}
],
"require": {
@@ -21,11 +22,11 @@
"league/flysystem": "^3.0"
},
"require-dev": {
- "phpunit/phpunit": "^9.3",
"orchestra/testbench": "^7.0 || ^8.0",
"friendsofphp/php-cs-fixer": "^3.1.0",
"spatie/ray": "^1.33",
- "pestphp/pest": "^1.21"
+ "pestphp/pest": "^2.25",
+ "phpstan/phpstan": "^1.10"
},
"extra": {
"laravel": {
@@ -45,7 +46,10 @@
"./vendor/bin/pest"
],
"fix-code": [
- "./vendor/bin/php-cs-fixer fix"
+ "./vendor/bin/php-cs-fixer fix --allow-risky=yes"
+ ],
+ "pstan": [
+ "./vendor/bin/phpstan analyse"
]
},
"minimum-stability": "stable",
diff --git a/config/lasso.php b/config/lasso.php
index 13390ab..bd65d32 100644
--- a/config/lasso.php
+++ b/config/lasso.php
@@ -1,7 +1,8 @@
[
/*
diff --git a/mix-manifest.json b/mix-manifest.json
new file mode 100644
index 0000000..c3ee70e
--- /dev/null
+++ b/mix-manifest.json
@@ -0,0 +1,4 @@
+{
+ "/tests/Fixtures/Public/app.css": "/tests/Fixtures/Public/app.css",
+ "/tests/Fixtures/Public/lasso-logo.png": "/tests/Fixtures/Public/lasso-logo.png"
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..ce915d9
--- /dev/null
+++ b/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "lasso",
+ "version": "1.0.0",
+ "description": "Yeehaw",
+ "scripts": {
+ "production": "echo \"Error: no test specified\" && exit 1"
+ },
+ "devDependencies": {
+ "laravel-mix": "^6.0.49"
+ }
+}
diff --git a/phpstan.dist.neon b/phpstan.dist.neon
new file mode 100644
index 0000000..074c0e6
--- /dev/null
+++ b/phpstan.dist.neon
@@ -0,0 +1,14 @@
+#############################################################################################
+# Don't edit this config file directly. #
+# For temporary, or local overrides, create a file named 'phpstan.neon' alongside this one. #
+#############################################################################################
+
+parameters:
+ # Add one of the editorUrl's in your phpstan.neon file for direct editor/IDE links in the terminal.
+ #editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
+ #editorUrl: 'vscode://file/%%file%%:%%line%%'
+
+ level: 7
+
+ paths:
+ - src
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..31b0dda
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ tests
+
+
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
deleted file mode 100644
index 82fb072..0000000
--- a/phpunit.xml.dist
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- tests
-
-
-
diff --git a/src/Commands/BaseCommand.php b/src/Commands/BaseCommand.php
index 56b5ba6..4ccaa22 100644
--- a/src/Commands/BaseCommand.php
+++ b/src/Commands/BaseCommand.php
@@ -1,33 +1,31 @@
option('silent') === true;
- $lassoEnvironment = config('lasso.storage.environment', null);
+ $silent = $this->option('silent') === true;
+ $environment = config('lasso.storage.environment');
$artisan->setCommand($this);
- if ($noPrompt) {
+ if ($silent) {
$artisan->silent();
}
- if ($checkFilesystem === true && $noPrompt === false && ! is_null($lassoEnvironment)) {
- $definedEnv = $this->ask('🐎 Which Lasso environment would you like to publish to?', $lassoEnvironment);
+ if ($checkFilesystem === true && $silent === false && ! is_null($environment)) {
+ $definedEnv = $this->ask('🐎 Which Lasso environment would you like to publish to?', $environment);
$filesystem->setLassoEnvironment($definedEnv);
}
diff --git a/src/Commands/PublishCommand.php b/src/Commands/PublishCommand.php
index cfe8eb5..6f1042c 100644
--- a/src/Commands/PublishCommand.php
+++ b/src/Commands/PublishCommand.php
@@ -1,5 +1,7 @@
validate();
+ (new ConfigValidator)->validate();
$this->configureApplication($artisan, $filesystem, true);
$dontUseGit = $this->option('no-git') === true;
$useCommit = $this->option('use-commit') === true;
$withCommit = $this->option('with-commit');
- $this->configureApplication($artisan, $filesystem);
$job = new PublishJob;
@@ -52,8 +50,8 @@ public function handle(Artisan $artisan, Filesystem $filesystem): int
$job->useCommit();
}
- if ($withCommit) {
- $job->withCommit($withCommit);
+ if (is_string($withCommit)) {
+ $job->withCommit(mb_substr($withCommit, 0, 12));
}
$artisan->note(sprintf(
@@ -68,6 +66,6 @@ public function handle(Artisan $artisan, Filesystem $filesystem): int
$filesystem->getCloudDisk()
));
- return 0;
+ return self::SUCCESS;
}
}
diff --git a/src/Commands/PullCommand.php b/src/Commands/PullCommand.php
index 2e47826..135f943 100644
--- a/src/Commands/PullCommand.php
+++ b/src/Commands/PullCommand.php
@@ -1,5 +1,7 @@
option('use-commit') === true;
$withCommit = $this->option('with-commit');
+
$this->configureApplication($artisan, $filesystem);
$artisan->setCommand($this);
@@ -50,21 +51,21 @@ public function handle(Artisan $artisan, Filesystem $filesystem): int
$filesystem->getCloudDisk()
));
- $job = new PullJob();
+ $job = new PullJob;
if ($useCommit) {
$job->useCommit();
}
- if ($withCommit) {
- $job->withCommit(substr($withCommit, 0, 12));
+ if (is_string($withCommit)) {
+ $job->withCommit(mb_substr((string)$withCommit, 0, 12));
}
$job->run();
$artisan->note('✅ Successfully downloaded the latest assets. Yee-haw!');
- $artisan->note('❤️ Thank you for using Lasso. https://getlasso.dev');
+ $artisan->note('❤️ Thank you for using Lasso.');
- return 0;
+ return self::SUCCESS;
}
}
diff --git a/src/Container/Artisan.php b/src/Container/Artisan.php
index 0d74f19..216e087 100644
--- a/src/Container/Artisan.php
+++ b/src/Container/Artisan.php
@@ -1,5 +1,7 @@
setCompilerOutputMode(config('lasso.compiler.output', 'progress'));
- }
+ private ?ProgressBar $progressBar = null;
/**
- * @param $name
- * @param $arguments
- * @return mixed|void
- * @throws ConsoleMethodException
+ * Constructor
*/
- public function __call($name, $arguments)
+ public function __construct()
{
- if (method_exists($this->command, $name)) {
- return call_user_func_array([$this->command, $name], $arguments);
- }
-
- throw new ConsoleMethodException(sprintf(
- 'Method %s::%s does not exist.',
- get_class($this->command),
- $name
- ));
+ $this->compilerOutputMode = config('lasso.compiler.output', 'progress');
}
/**
* Create a note for the front end, set the second parameter to true for an error.
*
- * @param string $message
- * @param bool $error
* @return $this
*/
public function note(string $message, bool $error = false): self
{
if (! $this->isSilent) {
$command = $error === true ? 'error' : 'info';
+
$this->$command($message);
}
return $this;
}
- public function compilerOutput(string $line): void
+ /**
+ * Show compiler output
+ */
+ public function showCompilerOutput(string $line): void
{
$mode = $this->compilerOutputMode;
@@ -89,14 +81,22 @@ public function compilerOutput(string $line): void
}
}
+ /**
+ * Mark compiler as complete
+ */
public function compilerComplete(): void
{
- if ($this->progressBar instanceof ProgressBar) {
- $this->progressBar->finish();
- $this->command->getOutput()->newLine();
+ if (! $this->progressBar instanceof ProgressBar) {
+ return;
}
+
+ $this->progressBar->finish();
+ $this->command->getOutput()->newLine();
}
+ /**
+ * Get the progress bar
+ */
private function getProgressBar(): ProgressBar
{
if ($bar = $this->progressBar) {
@@ -110,11 +110,14 @@ private function getProgressBar(): ProgressBar
$bar->setEmptyBarCharacter('-');
$bar->start();
- $this->setProgressBar($bar);
+ $this->progressBar = $bar;
return $bar;
}
+ /**
+ * Set the command being run
+ */
public function setCommand(Command $command): self
{
$this->command = $command;
@@ -122,6 +125,9 @@ public function setCommand(Command $command): self
return $this;
}
+ /**
+ * Run the artisan console in silent mode
+ */
public function silent(): self
{
$this->isSilent = true;
@@ -129,17 +135,18 @@ public function silent(): self
return $this;
}
- private function setCompilerOutputMode(string $mode): self
- {
- $this->compilerOutputMode = $mode;
-
- return $this;
- }
-
- private function setProgressBar(ProgressBar $bar): self
+ /**
+ * Handle a method call
+ *
+ * @param array $arguments
+ * @throws \Sammyjo20\Lasso\Exceptions\ConsoleMethodException
+ */
+ public function __call(string $name, array $arguments): mixed
{
- $this->progressBar = $bar;
+ if (method_exists($this->command, $name)) {
+ return $this->command->$name(...$arguments);
+ }
- return $this;
+ throw new ConsoleMethodException(sprintf('Method %s::%s does not exist.', get_class($this->command), $name));
}
}
diff --git a/src/Exceptions/BaseException.php b/src/Exceptions/BaseException.php
index 416a8e2..1cda26a 100644
--- a/src/Exceptions/BaseException.php
+++ b/src/Exceptions/BaseException.php
@@ -1,24 +1,32 @@
*/
public function create(): array
{
@@ -29,8 +36,7 @@ public function create(): array
}
/**
- * @param string $bundleId
- * @return $this
+ * Set the bundle ID
*/
public function setBundleId(string $bundleId): self
{
@@ -40,8 +46,7 @@ public function setBundleId(string $bundleId): self
}
/**
- * @param string $path
- * @return $this
+ * Set the ZIP path
*/
public function setZipPath(string $path): self
{
diff --git a/src/Helpers/BundleIntegrityHelper.php b/src/Helpers/BundleIntegrityHelper.php
index 96ba62f..218c472 100644
--- a/src/Helpers/BundleIntegrityHelper.php
+++ b/src/Helpers/BundleIntegrityHelper.php
@@ -1,24 +1,29 @@
setCloudDisk(config('lasso.storage.disk'));
-
- $this->initCloudFilesystem()
- ->initLocalFilesystem();
+ $this->cloudFilesystem = Storage::disk(config('lasso.storage.disk'));
+ $this->localFilesystem = resolve(Filesystem::class);
}
/**
- * @param $name
- * @param $arguments
- * @return mixed|void
- * @throws ConsoleMethodException
- */
- public function __call($name, $arguments)
- {
- if (method_exists($this->cloudFilesystem, $name)) {
- return call_user_func_array([$this->cloudFilesystem, $name], $arguments);
- }
-
- throw new ConsoleMethodException(sprintf(
- 'Method %s::%s does not exist.',
- get_class($this->cloudFilesystem),
- $name
- ));
- }
-
- /**
- * @param string $path
- * @param string $name
+ * Upload a file to the cloud filesystem
*/
public function uploadFile(string $path, string $name): void
{
- $upload_path = $this->getUploadPath($name);
+ $uploadPath = $this->getUploadPath($name);
$stream = fopen($path, 'rb');
- // Use the stream to write the bundle to the Filesystem.
- if ($this->cloudFilesystem->writeStream($upload_path, $stream) === false) {
- throw new UnableToWriteFile('Unable to write file at location ' . $upload_path);
+ if (! $stream) {
+ throw new LogicException('Unable to create a stream from the file path');
}
- // Close the Stream pointer because it's good practice.
- if (is_resource($stream)) {
- fclose($stream);
+ // Use the stream to write the bundle to the Filesystem.
+
+ if ($this->cloudFilesystem->writeStream($uploadPath, $stream) === false) {
+ throw new UnableToWriteFile(sprintf('Unable to write file at location [%s]', $uploadPath));
}
+
+ fclose($stream);
}
/**
- * Returns the Lasso upload directory. You can specify a file
- * to create a fully qualified URL.
+ * Returns the Lasso upload directory.
*
- * @param string|null $file
- * @return string
+ * You can specify a file to create a fully qualified URL.
*/
public function getUploadPath(string $file = null): string
{
$uploadPath = config('lasso.storage.upload_to');
- $dir = sprintf('%s/%s', $uploadPath, $this->localFilesystem->getLassoEnvironment());
+ $directory = sprintf('%s/%s', $uploadPath, $this->localFilesystem->getLassoEnvironment());
if (is_null($file)) {
- return $dir;
+ return $directory;
}
- return $dir . '/' . ltrim($file, '/');
+ return $directory . '/' . ltrim($file, '/');
}
/**
- * @return string
- */
- public function getCloudDisk(): string
- {
- return $this->cloudDisk;
- }
-
- /**
- * @param string $disk
- * @return $this
- */
- public function setCloudDisk(string $disk): self
- {
- $this->cloudDisk = $disk;
-
- return $this;
- }
-
- /**
- * @return $this
- */
- public function initCloudFilesystem(): self
- {
- $this->cloudFilesystem = Storage::disk($this->cloudDisk);
-
- return $this;
- }
-
- /**
- * @return $this
+ * Call a method on the base Filesystem
+ *
+ * @param array $arguments
+ * @throws \Sammyjo20\Lasso\Exceptions\ConsoleMethodException
*/
- public function initLocalFilesystem(): self
+ public function __call(string $name, array $arguments): mixed
{
- $this->localFilesystem = resolve(LocalFilesystem::class);
+ if (method_exists($this->cloudFilesystem, $name)) {
+ return $this->cloudFilesystem->$name(...$arguments);
+ }
- return $this;
+ throw new ConsoleMethodException(sprintf('Method %s::%s does not exist.', get_class($this->cloudFilesystem), $name));
}
}
diff --git a/src/Actions/Compiler.php b/src/Helpers/Compiler.php
similarity index 62%
rename from src/Actions/Compiler.php
rename to src/Helpers/Compiler.php
index dce149b..59e5850 100644
--- a/src/Actions/Compiler.php
+++ b/src/Helpers/Compiler.php
@@ -1,33 +1,35 @@
command)
->setTimeout($this->timeout)
->mustRun(function ($type, $line) use ($artisan) {
- $artisan->compilerOutput($line);
+ $artisan->showCompilerOutput($line);
});
$processTime = microtime(true) - $startTime;
$artisan->compilerComplete();
- $this->setCompilationTime($processTime);
+ $this->compilationTime = round($processTime, 2);
return $this;
}
- public function setCommand($command): self
+ /**
+ * Set the command for the compiler
+ */
+ public function setCommand(string $command): self
{
$this->command = $command;
return $this;
}
- public function setTimeout($timeout): self
+ /**
+ * Set the timeout for the compiler
+ */
+ public function setTimeout(int $timeout): self
{
$this->timeout = $timeout;
return $this;
}
- private function setCompilationTime(float $time): self
- {
- $this->compilationTime = round($time, 2);
-
- return $this;
- }
-
+ /**
+ * Get the compilation time
+ */
public function getCompilationTime(): float
{
return $this->compilationTime;
diff --git a/src/Helpers/CompilerOutputFormatter.php b/src/Helpers/CompilerOutputFormatter.php
index db5584c..db794d5 100644
--- a/src/Helpers/CompilerOutputFormatter.php
+++ b/src/Helpers/CompilerOutputFormatter.php
@@ -1,16 +1,18 @@
filesystem->exists($value) && $this->filesystem->isReadable($value) && $this->filesystem->isWritable($value);
}
/**
- * @param $value
- * @return bool
+ * Check disk exists
*/
- private function checkDiskExists($value): bool
+ private function checkDiskExists(mixed $value): bool
{
- return ! is_null(config('filesystems.disks.' . $value, null));
+ return ! is_null(config('filesystems.disks.' . $value));
}
/**
- * @param $value
- * @return bool
+ * Check bundle to keep count
*/
- private function checkBundleToKeepCount($value): bool
+ private function checkBundleToKeepCount(mixed $value): bool
{
return is_int($value) && $value > 0;
}
/**
- * @throws ConfigFailedValidation
- * @return void
+ * Validate config
+ *
+ * @throws ConfigFailedValidation|\Sammyjo20\Lasso\Exceptions\BaseException
*/
public function validate(): void
{
diff --git a/src/Helpers/FileLister.php b/src/Helpers/FileLister.php
index 5fba6bd..44c2746 100644
--- a/src/Helpers/FileLister.php
+++ b/src/Helpers/FileLister.php
@@ -1,24 +1,27 @@
finder = (new Finder())
+ $this->finder = (new Finder)
->in($directory)
->ignoreDotFiles(false)
->ignoreUnreadableDirs(true)
@@ -27,9 +30,9 @@ public function __construct(string $directory)
}
/**
- * @return Finder
+ * Return Finder
*/
- public function getFinder()
+ public function getFinder(): Finder
{
return $this->finder;
}
diff --git a/src/Helpers/Filesystem.php b/src/Helpers/Filesystem.php
index 0591978..255a931 100644
--- a/src/Helpers/Filesystem.php
+++ b/src/Helpers/Filesystem.php
@@ -1,48 +1,49 @@
setLassoEnvironment($lassoEnvironment)
- ->setCloudDisk($cloudDisk)
- ->setPublicPath($publicPath);
+ $this->lassoEnvironment = config('lasso.storage.environment') ?? 'global';
+ $this->cloudDisk = config('lasso.storage.disk', 'assets');
+ $this->publicPath = config('lasso.public_path', public_path());
}
/**
- * @param $resource
- * @param string $destination
- * @return bool
+ * Store a file as a stream
+ *
+ * @param resource $resource
*/
- public function putStream($resource, string $destination): bool
+ public function putStream(mixed $resource, string $destination): bool
{
- $stream = fopen($destination, 'w+b');
+ $stream = fopen($destination, 'wb+');
if (! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) {
return false;
@@ -52,17 +53,19 @@ public function putStream($resource, string $destination): bool
}
/**
- * @param array $bundle
+ * Create fresh from local bundle
+ *
+ * @param array $bundle
*/
public function createFreshLocalBundle(array $bundle): void
{
$this->deleteLocalBundle();
- $this->put(base_path('lasso-bundle.json'), json_encode($bundle));
+ $this->put(base_path('lasso-bundle.json'), (string)json_encode($bundle));
}
/**
- * @return bool
+ * Delete local bundle
*/
public function deleteLocalBundle(): bool
{
@@ -71,8 +74,6 @@ public function deleteLocalBundle(): bool
/**
* Delete Lasso's base directory (.lasso)
- *
- * @return bool
*/
public function deleteBaseLassoDirectory(): bool
{
@@ -80,16 +81,7 @@ public function deleteBaseLassoDirectory(): bool
}
/**
- * @return string
- */
- public function getLassoEnvironment(): string
- {
- return $this->lassoEnvironment;
- }
-
- /**
- * @param string $environment
- * @return $this
+ * Set the Lasso environment
*/
public function setLassoEnvironment(string $environment): self
{
@@ -99,40 +91,26 @@ public function setLassoEnvironment(string $environment): self
}
/**
- * @return string
+ * Get the Lasso environment
*/
- public function getPublicPath(): string
+ public function getLassoEnvironment(): string
{
- return $this->publicPath;
+ return $this->lassoEnvironment;
}
/**
- * @param string $publicPath
- * @return $this
+ * Get the public path
*/
- public function setPublicPath(string $publicPath): self
+ public function getPublicPath(): string
{
- $this->publicPath = $publicPath;
-
- return $this;
+ return $this->publicPath;
}
/**
- * @return string
+ * Get the cloud disk
*/
public function getCloudDisk(): string
{
return $this->cloudDisk;
}
-
- /**
- * @param string $disk
- * @return $this
- */
- public function setCloudDisk(string $disk): self
- {
- $this->cloudDisk = $disk;
-
- return $this;
- }
}
diff --git a/src/Helpers/Git.php b/src/Helpers/Git.php
index 6611389..13b38a3 100644
--- a/src/Helpers/Git.php
+++ b/src/Helpers/Git.php
@@ -1,28 +1,31 @@
getMessage(), $exception);
- }
-
- if ($hash) {
- return substr($hash, 0, 12);
+ } catch (Exception $exception) {
+ throw new GitHashException($exception->getMessage(), previous: $exception);
}
- return null;
+ return $hash ? mb_substr($hash, 0, 12) : null;
}
}
diff --git a/src/Helpers/Unzipper.php b/src/Helpers/Unzipper.php
index 844e0bc..c670303 100644
--- a/src/Helpers/Unzipper.php
+++ b/src/Helpers/Unzipper.php
@@ -1,93 +1,57 @@
setFilesystem()
- ->createBaseZip($source)
- ->setDestination($destination);
+ $this->filesystem = resolve(Filesystem::class);
+ $this->destination = $destination;
+
+ $this->createBaseZip($source);
}
/**
- * @return void
+ * Unzip the source into the destination
*/
public function run(): void
{
$this->filesystem->ensureDirectoryExists($this->destination);
- $this->zip->extractTo($this->destination);
- $this->closeZip();
- }
-
- /**
- * @return $this
- */
- private function setFilesystem(): self
- {
- $this->filesystem = resolve(Filesystem::class);
+ $this->zip->extractTo($this->destination);
- return $this;
+ $this->zip->close();
}
/**
- * @param string $destination
- * @return $this
+ * Create the base ZipArchive
*/
- private function createBaseZip(string $destination): self
+ private function createBaseZip(string $destination): void
{
- $this->zip = new ZipArchive();
+ $this->zip = new ZipArchive;
$this->zip->open($destination, ZipArchive::CREATE);
-
- return $this;
- }
-
- /**
- * @param string $destination
- * @return $this
- */
- private function setDestination(string $destination): self
- {
- $this->destination = $destination;
-
- return $this;
- }
-
- /**
- * @return void
- */
- public function closeZip(): void
- {
- $this->zip->close();
}
}
diff --git a/src/Helpers/Webhook.php b/src/Helpers/Webhook.php
new file mode 100644
index 0000000..a5a6432
--- /dev/null
+++ b/src/Helpers/Webhook.php
@@ -0,0 +1,29 @@
+ $data
+ */
+ public static function send(string $url, string $event, array $data = []): void
+ {
+ rescue(
+ callback: static function () use ($url, $event, $data) {
+ Http::post($url, array_merge(['event' => $event], $data));
+ },
+ rescue: false,
+ report: false
+ );
+ }
+}
diff --git a/src/Helpers/Zip.php b/src/Helpers/Zip.php
index b9f013b..28dbbbb 100644
--- a/src/Helpers/Zip.php
+++ b/src/Helpers/Zip.php
@@ -1,45 +1,47 @@
setFilesystem()
- ->createBaseZip($destinationPath);
+ $this->filesystem = resolve(Filesystem::class);
+
+ $this->createBaseZip($destinationPath);
}
/**
- * @param string $directory
- * @return $this
+ * Add files from a given directory
*/
public function addFilesFromDirectory(string $directory): self
{
- $files = (new FileLister($directory))
- ->getFinder();
+ $files = (new FileLister($directory))->getFinder();
foreach ($files as $file) {
$this->zip->addFile(str_replace('\\', '/', $file->getPathname()), str_replace('\\', '/', $file->getRelativePathname()));
@@ -49,29 +51,16 @@ public function addFilesFromDirectory(string $directory): self
}
/**
- * @return $this
- */
- private function setFilesystem(): self
- {
- $this->filesystem = resolve(Filesystem::class);
-
- return $this;
- }
-
- /**
- * @param string $destination
- * @return $this
+ * Create base ZipArchive
*/
- private function createBaseZip(string $destination): self
+ private function createBaseZip(string $destination): void
{
- $this->zip = new ZipArchive();
+ $this->zip = (new ZipArchive);
$this->zip->open($destination, ZipArchive::CREATE);
-
- return $this;
}
/**
- * @return void
+ * Close the Zip
*/
public function closeZip(): void
{
diff --git a/src/Interfaces/JobInterface.php b/src/Interfaces/JobInterface.php
deleted file mode 100644
index cc55c16..0000000
--- a/src/Interfaces/JobInterface.php
+++ /dev/null
@@ -1,11 +0,0 @@
-mergeConfigFrom(
- __DIR__ . '/../config/lasso.php',
- 'lasso'
- );
- }
-
- public function boot(): void
- {
- if ($this->app->runningInConsole()) {
- $this->registerCommands()
- ->offerPublishing()
- ->bindsServices();
- }
- }
-
/**
- * @return $this
+ * Register the Lasso service provider
*/
- protected function registerCommands(): self
+ public function register(): void
{
- $this->commands([
- PublishCommand::class,
- PullCommand::class,
- ]);
-
- return $this;
+ $this->mergeConfigFrom(__DIR__ . '/../config/lasso.php', 'lasso');
}
/**
- * @return $this
+ * Boot the Lasso service provider
*/
- protected function offerPublishing(): self
+ public function boot(): void
{
+ if (! $this->app->runningInConsole()) {
+ return;
+ }
+
+ // Publish the config
+
$this->publishes([
__DIR__ . '/../config/lasso.php' => config_path('lasso.php'),
], 'lasso-config');
- return $this;
- }
+ // Register Lasso's commands
- /**
- * @return $this
- */
- protected function bindsServices(): self
- {
- $this->app->singleton(Artisan::class, function () {
- return new Artisan;
- });
+ $this->commands([
+ PublishCommand::class,
+ PullCommand::class,
+ ]);
- $this->app->singleton(Filesystem::class, function () {
- return new Filesystem;
- });
+ // Bind Artisan and Filesystem to the container
- return $this;
+ $this->app->singleton(Artisan::class, static fn () => new Artisan);
+ $this->app->singleton(Filesystem::class, static fn () => new Filesystem);
}
}
diff --git a/src/Services/ArchiveService.php b/src/Services/ArchiveService.php
index 6b33cb7..92753f0 100644
--- a/src/Services/ArchiveService.php
+++ b/src/Services/ArchiveService.php
@@ -1,5 +1,7 @@
run();
+ (new Unzipper($source, $destination))->run();
}
}
diff --git a/src/Services/BackupService.php b/src/Services/BackupService.php
index f57c00d..2fa6c24 100644
--- a/src/Services/BackupService.php
+++ b/src/Services/BackupService.php
@@ -1,5 +1,7 @@
setFilesystem($filesystem);
+ $this->filesystem = $filesystem;
}
/**
* Copy a directory to a given location.
- *
- * @param string $sourceDirectory
- * @param string $destinationDirectory
- * @return bool
*/
public function createBackup(string $sourceDirectory, string $destinationDirectory): bool
{
@@ -49,8 +45,8 @@ public function createBackup(string $sourceDirectory, string $destinationDirecto
}
/**
- * @param string $destinationDirectory
- * @return bool
+ * Restore a backup
+ *
* @throws \Sammyjo20\Lasso\Exceptions\BaseException
*/
public function restoreBackup(string $destinationDirectory): bool
@@ -67,27 +63,7 @@ public function restoreBackup(string $destinationDirectory): bool
}
/**
- * @param Filesystem $filesystem
- * @return $this
- */
- public function setFilesystem(Filesystem $filesystem): self
- {
- $this->filesystem = $filesystem;
-
- return $this;
- }
-
- /**
- * @return bool
- */
- public function hasBackup(): bool
- {
- return ! is_null($this->backupPath);
- }
-
- /**
- * @param string $path
- * @return $this
+ * Set a backup path
*/
public function setBackupPath(string $path): self
{
diff --git a/src/Services/VersioningService.php b/src/Services/VersioningService.php
index a2e1044..98ebafb 100644
--- a/src/Services/VersioningService.php
+++ b/src/Services/VersioningService.php
@@ -1,25 +1,32 @@
* @throws \Sammyjo20\Lasso\Exceptions\BaseException
*/
private static function getHistoryFromDisk(): array
{
$disk = self::getDisk();
- $path = self::getFileDirectory('history.json');
+ $path = self::getFileDirectory();
// If there is no history to be found in the Filesystem,
// that's completely fine. Let's just return an empty
@@ -60,7 +67,7 @@ private static function getHistoryFromDisk(): array
ksort($history);
return $history;
- } catch (\Exception $ex) {
+ } catch (Exception $ex) {
throw VersioningFailed::because(
'Lasso could not retrieve the history.json file from the Filesystem.'
);
@@ -68,46 +75,49 @@ private static function getHistoryFromDisk(): array
}
/**
- * @param array $bundles
- * @return array
+ * Delete expired bundles
+ *
+ * @param array $bundles
+ * @return array
*/
private static function deleteExpiredBundles(array $bundles): array
{
- $bundle_limit = self::getMaxBundlesAllowed();
+ $bundleLimit = config('lasso.storage.max_bundles');
- // If we haven't exceeded our bundle Limit,
- // let's just return the bundles. There's nothing
- // more we can do here.
+ // If we haven't exceeded our bundle Limit, let's just return the bundles.
+ // There's nothing more we can do here.
- if (count($bundles) <= $bundle_limit) {
+ if (count($bundles) <= $bundleLimit) {
return $bundles;
}
- // However, if there's a bundle to be removed
- // we need to go Ghostbuster on that bundle.
- $deletable_count = count($bundles) - $bundle_limit;
+ // However, if there's a bundle to be removed we need to go Ghostbuster on that bundle.
+
+ $deletable_count = count($bundles) - $bundleLimit;
$deletable = array_slice($bundles, 0, $deletable_count, true);
// Now let's delete those bundles!
+
$deleted = self::deleteBundles(array_values($deletable));
- // Finally, we want to return a new array, with
- // the bundles that have been deleted removed.
+ // Finally, we want to return a new array, with the bundles that have been deleted removed.
+
return array_diff($bundles, $deleted);
}
/**
- * @param array $deletable
- * @return array
+ * Delete bundles
+ *
+ * @param array $deletable
+ * @return array
*/
private static function deleteBundles(array $deletable): array
{
$disk = self::getDisk();
$deleted = [];
- // Attempt to delete the bundle. If something
- // goes wrong, Lasso isn't precious about it.
- // we will simply try to delete the next directory and move on.
+ // Attempt to delete the bundle. If something goes wrong, Lasso isn't precious about it.
+ // We will simply try to delete the next directory and move on.
foreach ($deletable as $bundle_key => $bundle) {
try {
@@ -116,7 +126,7 @@ private static function deleteBundles(array $deletable): array
if ($success) {
$deleted[$bundle_key] = $bundle;
}
- } catch (\Exception $ex) {
+ } catch (Exception) {
continue;
}
}
@@ -125,20 +135,16 @@ private static function deleteBundles(array $deletable): array
}
/**
- * @param array $history
- * @return bool
+ * Update history file
+ *
+ * @param array $history
* @throws \Sammyjo20\Lasso\Exceptions\BaseException
*/
- private static function updateHistory(array $history): bool
+ private static function updateHistory(array $history): void
{
- $disk = self::getDisk();
- $path = self::getFileDirectory('history.json');
-
try {
- $encoded = json_encode($history);
-
- return Storage::disk($disk)->put($path, $encoded);
- } catch (\Exception $ex) {
+ Storage::disk(self::getDisk())->put(self::getFileDirectory(), json_encode($history, JSON_THROW_ON_ERROR));
+ } catch (Exception) {
throw VersioningFailed::because(
'Lasso could not update the history.json on the Filesystem.'
);
@@ -146,27 +152,18 @@ private static function updateHistory(array $history): bool
}
/**
- * @param string $path
- * @return string
+ * Get the file directory
*/
- private static function getFileDirectory(string $path): string
+ private static function getFileDirectory(): string
{
- return (new Cloud())->getUploadPath($path);
+ return (new Cloud)->getUploadPath('history.json');
}
/**
- * @return string
+ * Get the disk
*/
private static function getDisk(): string
{
return config('lasso.storage.disk');
}
-
- /**
- * @return int
- */
- private static function getMaxBundlesAllowed(): int
- {
- return config('lasso.storage.max_bundles');
- }
}
diff --git a/src/Tasks/BaseJob.php b/src/Tasks/BaseJob.php
index 71ddcb0..ee78194 100644
--- a/src/Tasks/BaseJob.php
+++ b/src/Tasks/BaseJob.php
@@ -1,70 +1,37 @@
setArtisan()
- ->setFilesystem();
-
- // The Cloud class should be defined after the Filesystem as
- // it depends on the Filesystem.
-
- $this->setCloud();
- }
-
- /**
- * @return $this
- */
- private function setArtisan(): self
{
$this->artisan = resolve(Artisan::class);
-
- return $this;
- }
-
- /**
- * @return $this
- */
- private function setFilesystem(): self
- {
$this->filesystem = resolve(Filesystem::class);
-
- return $this;
- }
-
- /**
- * @return $this
- */
- private function setCloud(): self
- {
$this->cloud = new Cloud;
-
- return $this;
}
}
diff --git a/src/Tasks/Command.php b/src/Tasks/Command.php
deleted file mode 100644
index e951991..0000000
--- a/src/Tasks/Command.php
+++ /dev/null
@@ -1,63 +0,0 @@
-script);
-
- $process->setTimeout($this->timeout)
- ->run();
-
- if (! $process->isSuccessful()) {
- throw new ProcessFailedException($process);
- }
- }
-
- /**
- * @param $script
- * @return $this
- */
- public function setScript($script): self
- {
- if (! is_array($script)) {
- $script = explode(' ', $script);
- }
-
- $this->script = $script;
-
- return $this;
- }
-
- /**
- * @param int $timeout
- * @return $this
- */
- public function setTimeout(int $timeout = 600): self
- {
- $this->timeout = $timeout;
-
- return $this;
- }
-}
diff --git a/src/Tasks/Publish/BundleJob.php b/src/Tasks/Publish/BundleJob.php
index d3a3193..97a5ba9 100644
--- a/src/Tasks/Publish/BundleJob.php
+++ b/src/Tasks/Publish/BundleJob.php
@@ -1,5 +1,7 @@
*/
- protected $forbiddenFiles = [
+ protected array $forbiddenFiles = [
'.htaccess',
'web.config',
'index.php',
@@ -25,9 +29,11 @@ final class BundleJob extends BaseJob
];
/**
- * @var array
+ * Forbidden Directories
+ *
+ * @var array
*/
- protected $forbiddenDirectories = [
+ protected array $forbiddenDirectories = [
'storage',
'hot',
];
@@ -42,15 +48,13 @@ public function __construct()
$userForbiddenFiles = config('lasso.compiler.excluded_files', []);
$userForbiddenDirs = config('lasso.compiler.excluded_directories', []);
- $this->setForbiddenFiles(
- array_merge($this->forbiddenFiles, $userForbiddenFiles)
- );
-
- $this->setForbiddenDirectories(
- array_merge($this->forbiddenDirectories, $userForbiddenDirs)
- );
+ $this->forbiddenFiles = array_merge($this->forbiddenFiles, $userForbiddenFiles);
+ $this->forbiddenDirectories = array_merge($this->forbiddenDirectories, $userForbiddenDirs);
}
+ /**
+ * Run the bundle job
+ */
public function run(): void
{
$filesystem = $this->filesystem;
@@ -105,8 +109,7 @@ public function run(): void
}
/**
- * @param string $bundleId
- * @return $this
+ * Set the Bundle ID
*/
public function setBundleId(string $bundleId): self
{
@@ -114,26 +117,4 @@ public function setBundleId(string $bundleId): self
return $this;
}
-
- /**
- * @param array $files
- * @return $this
- */
- private function setForbiddenFiles(array $files): self
- {
- $this->forbiddenFiles = $files;
-
- return $this;
- }
-
- /**
- * @param array $directories
- * @return $this
- */
- private function setForbiddenDirectories(array $directories): self
- {
- $this->forbiddenDirectories = $directories;
-
- return $this;
- }
}
diff --git a/src/Tasks/Publish/PublishJob.php b/src/Tasks/Publish/PublishJob.php
index 8a43a9c..1ac5e49 100644
--- a/src/Tasks/Publish/PublishJob.php
+++ b/src/Tasks/Publish/PublishJob.php
@@ -1,37 +1,39 @@
artisan;
+ $filesystem = $this->filesystem;
+ $cloud = $this->cloud;
+
try {
$this->generateBundleId();
- $this->artisan->note('⏳ Compiling assets...');
+ $artisan->note('⏳ Compiling assets...');
// Start with the compiler. This will run the "script" which
// has been defined in the config file (e.g. npm run production).
- $compiler = (new Compiler())
+ $compiler = (new Compiler)
->setCommand(config('lasso.compiler.script'))
->setTimeout(config('lasso.compiler.timeout', 600))
->execute();
- $this->artisan->note(sprintf(
+ $artisan->note(sprintf(
'✅ Compiled assets in %s seconds.',
$compiler->getCompilationTime()
));
- $this->artisan->note('⏳ Copying and zipping compiled assets...');
+ $artisan->note('⏳ Copying and zipping compiled assets...');
// Once we have compiled all of our assets, we need to "bundle"
- // them up. Todo: Remove this step in the future.
+ // them up.
- (new BundleJob())
+ (new BundleJob)
->setBundleId($this->bundleId)
->run();
$zipBundlePath = base_path('.lasso/dist/' . $this->bundleId . '.zip');
- $this->artisan->note('✅ Successfully copied and zipped assets.');
+ $artisan->note('✅ Successfully copied and zipped assets.');
// Now we want to create the data which will go inside the
// "lasso-bundle.json" file. After that, we will create a Zip file
// with all the assets inside.
- $bundle = (new Bundle())
+ $bundle = (new Bundle)
->setBundleId($this->bundleId)
->setZipPath($zipBundlePath)
->create();
- $this->artisan->note(
- sprintf('⏳ Uploading asset bundle to "%s" filesystem...', $this->filesystem->getCloudDisk())
+ $artisan->note(
+ sprintf('⏳ Uploading asset bundle to "%s" filesystem...', $filesystem->getCloudDisk())
);
$bundlePath = base_path('.lasso/dist/lasso-bundle.json');
@@ -99,20 +104,20 @@ public function run(): void
// this uses stream to ensure we don't run out of memory
// while uploading the file.
- $this->cloud->uploadFile($zipBundlePath, $bundle['file']);
+ $cloud->uploadFile($zipBundlePath, $bundle['file']);
// Has the user requested to use/not use Git? Here
// we will create the lasso-bundle.json in the right
// place.
if ($this->usesGit) {
- $this->filesystem->createFreshLocalBundle($bundle);
+ $filesystem->createFreshLocalBundle($bundle);
} else {
- $this->filesystem->deleteLocalBundle();
+ $filesystem->deleteLocalBundle();
- $this->filesystem->put($bundlePath, json_encode($bundle));
+ $filesystem->put($bundlePath, (string)json_encode($bundle));
- $this->cloud->uploadFile($bundlePath, config('lasso.storage.prefix') . 'lasso-bundle.json');
+ $cloud->uploadFile($bundlePath, config('lasso.storage.prefix') . 'lasso-bundle.json');
}
// Done! Let's run some cleanup, and dispatch all the
@@ -126,8 +131,9 @@ public function run(): void
}
}
+
/**
- * @return void
+ * Clean up the publish
*/
public function cleanUp(): void
{
@@ -135,10 +141,11 @@ public function cleanUp(): void
}
/**
- * @param Exception $exception
+ * Roll back the publish
+ *
* @throws Exception
*/
- private function rollBack(Exception $exception)
+ private function rollBack(Exception $exception): void
{
$this->deleteLassoDirectory();
@@ -146,7 +153,9 @@ private function rollBack(Exception $exception)
}
/**
- * @param array $webhooks
+ * Dispatch the webhooks
+ *
+ * @param array $webhooks
*/
public function dispatchWebhooks(array $webhooks = []): void
{
@@ -164,10 +173,11 @@ public function dispatchWebhooks(array $webhooks = []): void
}
/**
- * @return $this
+ * Generate the Bundle ID
+ *
* @throws GitHashException
*/
- private function generateBundleId(): self
+ private function generateBundleId(): void
{
$id = Str::random(20);
@@ -180,21 +190,19 @@ private function generateBundleId(): self
}
$this->bundleId = $id;
-
- return $this;
}
/**
- * @return $this
+ * Delete the Lasso directory
*/
- private function deleteLassoDirectory(): self
+ private function deleteLassoDirectory(): void
{
$this->filesystem->deleteBaseLassoDirectory();
-
- return $this;
}
/**
+ * Disable Git with Lasso
+ *
* @return $this
*/
public function dontUseGit(): self
@@ -205,6 +213,8 @@ public function dontUseGit(): self
}
/**
+ * Should Lasso use the latest commit from Git?
+ *
* @return $this
*/
public function useCommit(): self
@@ -214,6 +224,11 @@ public function useCommit(): self
return $this;
}
+ /**
+ * Specify a commit that is used for the bundle
+ *
+ * @return $this
+ */
public function withCommit(string $commitHash): self
{
$this->commit = $commitHash;
diff --git a/src/Tasks/Pull/PullJob.php b/src/Tasks/Pull/PullJob.php
index 5d63aaa..69bbb88 100644
--- a/src/Tasks/Pull/PullJob.php
+++ b/src/Tasks/Pull/PullJob.php
@@ -1,10 +1,13 @@
setBackup();
+ $this->backup = new BackupService($this->filesystem);
}
/**
- * @return void
+ * Run the "pull" job
+ *
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
* @throws \Sammyjo20\Lasso\Exceptions\BaseException
- * @throws PullJobFailed
*/
public function run(): void
{
@@ -85,7 +90,7 @@ public function run(): void
$this->filesystem
->copy($source, $destination);
}
- } catch (\Exception $ex) {
+ } catch (Exception $ex) {
// If anything goes wrong inside this try block,
// we will "roll back" which means we will restore
// our backup.
@@ -100,11 +105,12 @@ public function run(): void
$this->cleanUp();
$webhooks = config('lasso.webhooks.pull', []);
+
$this->dispatchWebhooks($webhooks);
}
/**
- * @return void
+ * Cleanup the command
*/
public function cleanUp(): void
{
@@ -112,7 +118,9 @@ public function cleanUp(): void
}
/**
- * @param array $webhooks
+ * Dispatch the webhooks
+ *
+ * @param array $webhooks
*/
public function dispatchWebhooks(array $webhooks = []): void
{
@@ -130,16 +138,19 @@ public function dispatchWebhooks(array $webhooks = []): void
}
/**
- * @return array
+ * Get the latest bundle info
+ *
+ * @return array
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
*/
private function getLatestBundleInfo(): array
{
$localPath = base_path('lasso-bundle.json');
$cloudPath = $this->cloud->getUploadPath(config('lasso.storage.prefix') . 'lasso-bundle.json');
- // Firstly, let's check if the local filesystem has a "lasso-bundle.json"
- // file in it's root directory.
+ // Firstly, let's check if the local filesystem has a "lasso-bundle.json" file in its root directory.
if ($this->filesystem->exists($localPath)) {
$file = $this->filesystem->get($localPath);
@@ -150,10 +161,9 @@ private function getLatestBundleInfo(): array
return $bundle;
}
- // If there isn't a "lasso-bundle.json" file in the root directory,
- // that's okay - this means that the commit is in "non-git" mode. So
- // let's just grab that file. If we don't have a file on the server
- // however; we need to throw an exception.
+ // If there isn't a "lasso-bundle.json" file in the root directory, that's okay - this means
+ // that the commit is in "non-git" mode. So let's just grab that file. If we don't have a
+ // file on the server however; we need to throw an exception.
if (! $this->cloud->exists($cloudPath)) {
$this->rollBack(
@@ -170,13 +180,14 @@ private function getLatestBundleInfo(): array
}
/**
- * @param array $bundle
- * @return bool
+ * Validate the bundle checksum
+ *
+ * @param array $bundle
* @throws \Exception
*/
private function validateBundle(array $bundle): bool
{
- if (! isset($bundle['file']) || ! isset($bundle['checksum'])) {
+ if (! isset($bundle['file'], $bundle['checksum'])) {
$this->rollBack(
PullJobFailed::because('The bundle info was missing the required data.')
);
@@ -186,10 +197,7 @@ private function validateBundle(array $bundle): bool
}
/**
- * @param string $file
- * @param string $checksum
- * @return string
- * @throws PullJobFailed|\Exception
+ * Download Zip bundle file
*/
private function downloadBundleZip(string $file, string $checksum): string
{
@@ -212,7 +220,7 @@ private function downloadBundleZip(string $file, string $checksum): string
if (is_resource($bundleZip)) {
fclose($bundleZip);
}
- } catch (\Exception $ex) {
+ } catch (Exception $ex) {
$this->rollBack($ex);
}
@@ -236,18 +244,17 @@ private function downloadBundleZip(string $file, string $checksum): string
}
/**
- * @param \Exception $exception
+ * Roll back and throw an exception
+ *
* @throws \Exception
*/
- private function rollBack(\Exception $exception)
+ private function rollBack(Exception $exception): Exception
{
- if ($this->backup->hasBackup()) {
- $this->artisan->note('⏳ Restoring backup...');
+ $this->artisan->note('⏳ Restoring backup...');
- $this->backup->restoreBackup($this->filesystem->getPublicPath());
+ $this->backup->restoreBackup($this->filesystem->getPublicPath());
- $this->artisan->note('✅ Successfully restored backup.');
- }
+ $this->artisan->note('✅ Successfully restored backup.');
$this->filesystem->deleteBaseLassoDirectory();
@@ -255,30 +262,15 @@ private function rollBack(\Exception $exception)
}
/**
- * @return $this
+ * Backup the source data
*/
- private function runBackup(): self
+ private function runBackup(): void
{
- $this->backup->createBackup(
- $this->filesystem->getPublicPath(),
- base_path('.lasso/backup')
- );
-
- return $this;
- }
-
- /**
- * @return $this
- */
- private function setBackup(): self
- {
- $this->backup = new BackupService($this->filesystem);
-
- return $this;
+ $this->backup->createBackup($this->filesystem->getPublicPath(), base_path('.lasso/backup'));
}
/**
- * @return void
+ * Cleanup the Lasso directory
*/
private function cleanLassoDirectory(): void
{
@@ -288,8 +280,7 @@ private function cleanLassoDirectory(): void
}
/**
- * @param string $file
- * @return string
+ * Get the Lasso bundle path
*/
private function getBundlePath(string $file): string
{
@@ -305,7 +296,7 @@ private function getBundlePath(string $file): string
}
/**
- * @return $this
+ * Should Lasso use the latest commit from Git?
*/
public function useCommit(): self
{
@@ -315,7 +306,7 @@ public function useCommit(): self
}
/**
- * @return $this
+ * Specify a custom commit hash
*/
public function withCommit(string $commitHash): self
{
diff --git a/src/Tasks/Webhook.php b/src/Tasks/Webhook.php
deleted file mode 100644
index a6f7795..0000000
--- a/src/Tasks/Webhook.php
+++ /dev/null
@@ -1,23 +0,0 @@
- $event], $data));
- }, false, false);
-
- return true;
- }
-}
diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php
deleted file mode 100644
index 19eb2cf..0000000
--- a/tests/ExampleTest.php
+++ /dev/null
@@ -1,12 +0,0 @@
-assertTrue(true);
- }
-}
diff --git a/tests/Feature/LassoTest.php b/tests/Feature/LassoTest.php
new file mode 100644
index 0000000..fe17d8c
--- /dev/null
+++ b/tests/Feature/LassoTest.php
@@ -0,0 +1,45 @@
+toBeFalse();
+ expect(File::isEmptyDirectory('./tests/Fixtures/Cloud'))->toBeTrue();
+
+ Config::set('lasso', defaultConfig());
+
+ // Kick off the publish which will compile the asset
+
+ $this->artisan('lasso:publish');
+
+ expect(File::exists('./lasso-bundle.json'))->toBeTrue();
+
+ $bundleName = json_decode(File::get('./lasso-bundle.json'), true, 512, JSON_THROW_ON_ERROR)['file'];
+
+ // Check the bundle exists
+
+ expect(File::exists('./tests/Fixtures/Cloud/lasso/global/' . $bundleName))->toBeTrue();
+
+ File::cleanDirectory('./tests/Fixtures/Public');
+
+ expect(File::isEmptyDirectory('./tests/Fixtures/Public'))->toBeTrue();
+
+ $this->artisan('lasso:pull');
+
+ // Now we'll ensure that the public directory has contents!
+
+ expect(File::isEmptyDirectory('./tests/Fixtures/Public'))->toBeFalse();
+ expect(File::exists('./tests/Fixtures/Public/app.css'))->toBeTrue();
+ expect(File::exists('./tests/Fixtures/Public/lasso-logo.png'))->toBeTrue();
+});
diff --git a/tests/Fixtures/Local/app.css b/tests/Fixtures/Local/app.css
new file mode 100644
index 0000000..7bb2d46
--- /dev/null
+++ b/tests/Fixtures/Local/app.css
@@ -0,0 +1,3 @@
+/*! tailwindcss v2.2.4 | MIT License | https://tailwindcss.com*/
+
+/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */html{-webkit-text-size-adjust:100%;line-height:1.15;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;margin:0}hr{color:inherit;height:0}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{border:0 solid;box-sizing:border-box}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{color:inherit;line-height:inherit;padding:0}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}*,:after,:before{--tw-border-opacity:1;border-color:rgba(229,231,235,var(--tw-border-opacity))}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.left-0{left:0}.z-0{z-index:0}.z-10{z-index:10}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-2{margin-top:.5rem}.mt-6{margin-top:1.5rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.mb-12{margin-bottom:3rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.hidden{display:none}.h-full{height:100%}.w-8{width:2rem}.w-12{width:3rem}.w-full{width:100%}.transform{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100,.transform{--tw-scale-x:1;--tw-scale-y:1}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}@-webkit-keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}@keyframes bounce{0%,to{-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}.cursor-pointer{cursor:pointer}.flex-row{flex-direction:row}.items-center{align-items:center}.overflow-y-hidden{overflow-y:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-lg{border-radius:.5rem}.bg-primary{--tw-bg-opacity:1;background-color:rgba(249,199,46,var(--tw-bg-opacity))}.bg-faded-leather{--tw-bg-opacity:1;background-color:rgba(130,95,77,var(--tw-bg-opacity))}.bg-burned-leather{--tw-bg-opacity:1;background-color:rgba(74,53,43,var(--tw-bg-opacity))}.p-4{padding:1rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-16{padding-left:4rem;padding-right:4rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-8{padding-bottom:2rem;padding-top:2rem}.py-16{padding-bottom:4rem;padding-top:4rem}.pt-24{padding-top:6rem}.pb-16{padding-bottom:4rem}.text-center{text-align:center}.font-roboto{font-family:Roboto,sans-serif}.font-jetbrains-mono{font-family:JetBrains Mono,sans-serif}.text-sm{font-size:.875rem;line-height:1.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-primary{--tw-text-opacity:1;color:rgba(249,199,46,var(--tw-text-opacity))}.text-leather{--tw-text-opacity:1;color:rgba(99,71,57,var(--tw-text-opacity))}.opacity-25{opacity:.25}.opacity-75{opacity:.75}*,:after,:before{--tw-shadow:0 0 #0000}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus,.outline-none{outline:2px solid transparent;outline-offset:2px}*,:after,:before{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000}.duration-200{transition-duration:.2s}@font-face{font-family:JetBrains Mono;font-style:normal;font-weight:400;src:url(../fonts/JetBrainsMono-Regular.eot) format("embedded-opentype"),url(../fonts/JetBrainsMono-Regular.woff2) format("woff2"),url(../fonts/JetBrainsMono-Regular.woff) format("woff"),url(../fonts/JetBrainsMono-Regular.ttf) format("truetype")}*{font-family:Yeseva One,sans-serif}body{--tw-bg-opacity:1;background-color:rgba(99,71,57,var(--tw-bg-opacity))}.github-icon{box-sizing:border-box;display:block;height:4rem;padding:1rem;position:absolute;right:0;top:0;width:4rem}.github-icon.docs{position:relative}@media (min-width:768px){.github-icon{height:5rem;width:5rem}}.kendrick-lamar{margin-left:auto;margin-right:auto;max-width:700px;width:100%}.svg-bg{background-color:#634739;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='28'%3E%3Cpath fill='%23825f4d' fill-opacity='.4' d='M56 26v2h-7.75c2.3-1.27 4.94-2 7.75-2zm-26 2a2 2 0 1 0-4 0h-4.09A25.98 25.98 0 0 0 0 16v-2c.67 0 1.34.02 2 .07V14a2 2 0 0 0-2-2v-2a4 4 0 0 1 3.98 3.6 28.09 28.09 0 0 1 2.8-3.86A8 8 0 0 0 0 6V4a9.99 9.99 0 0 1 8.17 4.23c.94-.95 1.96-1.83 3.03-2.63A13.98 13.98 0 0 0 0 0h7.75c2 1.1 3.73 2.63 5.1 4.45 1.12-.72 2.3-1.37 3.53-1.93A20.1 20.1 0 0 0 14.28 0h2.7c.45.56.88 1.14 1.29 1.74 1.3-.48 2.63-.87 4-1.15-.11-.2-.23-.4-.36-.59H26v.07a28.4 28.4 0 0 1 4 0V0h4.09l-.37.59c1.38.28 2.72.67 4.01 1.15.4-.6.84-1.18 1.3-1.74h2.69a20.1 20.1 0 0 0-2.1 2.52c1.23.56 2.41 1.2 3.54 1.93A16.08 16.08 0 0 1 48.25 0H56c-4.58 0-8.65 2.2-11.2 5.6 1.07.8 2.09 1.68 3.03 2.63A9.99 9.99 0 0 1 56 4v2a8 8 0 0 0-6.77 3.74c1.03 1.2 1.97 2.5 2.79 3.86A4 4 0 0 1 56 10v2a2 2 0 0 0-2 2.07 28.4 28.4 0 0 1 2-.07v2c-9.2 0-17.3 4.78-21.91 12H30zM7.75 28H0v-2c2.81 0 5.46.73 7.75 2zM56 20v2c-5.6 0-10.65 2.3-14.28 6h-2.7c4.04-4.89 10.15-8 16.98-8zm-39.03 8h-2.69C10.65 24.3 5.6 22 0 22v-2c6.83 0 12.94 3.11 16.97 8zm15.01-.4a28.09 28.09 0 0 1 2.8-3.86 8 8 0 0 0-13.55 0c1.03 1.2 1.97 2.5 2.79 3.86a4 4 0 0 1 7.96 0zm14.29-11.86c1.3-.48 2.63-.87 4-1.15a25.99 25.99 0 0 0-44.55 0c1.38.28 2.72.67 4.01 1.15a21.98 21.98 0 0 1 36.54 0zm-5.43 2.71c1.13-.72 2.3-1.37 3.54-1.93a19.98 19.98 0 0 0-32.76 0c1.23.56 2.41 1.2 3.54 1.93a15.98 15.98 0 0 1 25.68 0zm-4.67 3.78c.94-.95 1.96-1.83 3.03-2.63a13.98 13.98 0 0 0-22.4 0c1.07.8 2.09 1.68 3.03 2.63a9.99 9.99 0 0 1 16.34 0z'/%3E%3C/svg%3E")}.header-bg .logo{display:block;margin-left:auto;margin-right:auto;pointer-events:none}.header-bg .logo,.header-bg .strapline{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%}.header-bg .strapline{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity));font-size:1.25rem;line-height:1.75rem;margin-top:1.5rem;text-align:center}@media (min-width:640px){.header-bg .strapline{font-size:1.5rem;line-height:2rem}}@media (min-width:768px){.header-bg .strapline{bottom:16px;margin-top:0;position:absolute;right:-64px;width:auto}}.content{max-width:1000px}.flow{flex-direction:row;width:100%}.flow,.flow .step .circle{display:flex;justify-content:center}.flow .step .circle{--tw-bg-opacity:1;background-color:rgba(74,53,43,var(--tw-bg-opacity));border-radius:9999px;flex-direction:column;height:90px;text-align:center;width:90px}@media (min-width:768px){.flow .step .circle{height:140px;width:140px}}.flow .step .circle .icon{height:48px;margin-left:auto;margin-right:auto;width:48px}@media (min-width:768px){.flow .step .circle .icon{height:64px;width:64px}}.flow .breadcrumbs{align-items:center;display:flex;flex-direction:row;margin-left:.5rem;margin-right:.5rem}@media (min-width:768px){.flow .breadcrumbs{margin-left:1.5rem;margin-right:1.5rem}}.flow .breadcrumbs .arrow{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity));font-size:1.875rem;line-height:2.25rem}@media (min-width:768px){.flow .breadcrumbs .arrow{display:none}}.flow .breadcrumbs .crumb{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity));border-radius:9999px;display:none;height:16px;margin-left:.25rem;margin-right:.25rem;width:16px}@media (min-width:768px){.flow .breadcrumbs .crumb{display:block;margin-left:.75rem;margin-right:.75rem}}.flow .breadcrumbs .crumb:first-child{margin-left:0}.flow .breadcrumbs .crumb:last-child{margin-right:0}.cactus{bottom:0;display:none;opacity:.75;position:absolute;z-index:0}.cactus.cactus-one{left:0;margin-bottom:-5px;padding-left:8rem}.cactus.cactus-two{margin-bottom:-10px;padding-right:8rem;right:0}@media (min-width:1280px){.cactus{display:block}}.docs-font *{font-family:Lato,sans-serif}.check,.times{height:28px;width:28px}@media (min-width:768px){.md\:mx-12{margin-left:3rem;margin-right:3rem}.md\:mb-0{margin-bottom:0}.md\:mb-12{margin-bottom:3rem}.md\:mb-16{margin-bottom:4rem}.md\:ml-12{margin-left:3rem}.md\:flex{display:flex}.md\:grid{display:grid}.md\:hidden{display:none}.md\:w-1\/2{width:50%}.md\:grid-flow-col{grid-auto-flow:column}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-col{flex-direction:column}.md\:justify-center{justify-content:center}.md\:gap-6{gap:1.5rem}.md\:bg-burned-leather{--tw-bg-opacity:1;background-color:rgba(74,53,43,var(--tw-bg-opacity))}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:px-12{padding-left:3rem;padding-right:3rem}.md\:py-2{padding-bottom:.5rem;padding-top:.5rem}.md\:py-3{padding-bottom:.75rem;padding-top:.75rem}.md\:py-4{padding-bottom:1rem;padding-top:1rem}.md\:py-24{padding-bottom:6rem;padding-top:6rem}.md\:py-32{padding-bottom:8rem;padding-top:8rem}.md\:text-center{text-align:center}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}.md\:text-2xl{font-size:1.5rem;line-height:2rem}.md\:text-5xl{font-size:3rem;line-height:1}}
diff --git a/tests/Fixtures/Local/lasso-logo.png b/tests/Fixtures/Local/lasso-logo.png
new file mode 100644
index 0000000..83bf8ca
Binary files /dev/null and b/tests/Fixtures/Local/lasso-logo.png differ
diff --git a/tests/Helpers/ConfigValidatorTest.php b/tests/Helpers/ConfigValidatorTest.php
deleted file mode 100644
index 5b94056..0000000
--- a/tests/Helpers/ConfigValidatorTest.php
+++ /dev/null
@@ -1,97 +0,0 @@
-set([
- 'filesystems.disks' => [
- 'assets' => [
- 'driver' => 's3',
- ],
- ],
- ]);
- }
-
- /** @test */
- public function it_throws_exception_when_storage_push_to_git_is_set()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessageMatches('/push_to_git/');
- config()->set(['lasso.storage.push_to_git' => true]);
- (new ConfigValidator())->validate();
- }
-
- /** @test */
- public function it_throws_exception_when_compile_script_is_not_set()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessageMatches('/npm run production/');
-
- config()->set(['lasso.compiler.script' => null]);
-
- (new ConfigValidator())->validate();
- }
-
- /** @test */
- public function it_throws_exception_when_invalid_compiler_output_is_provided()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessage('You must specify a valid output setting. Available options: all, progress, disable.');
-
- config()->set(['lasso.compiler.output' => 'abc']);
-
- (new ConfigValidator())->validate();
- }
-
- /** @test */
- public function it_throws_exception_when_disk_does_not_exist()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessageMatches('/not a valid disk/');
-
- config()->set(['filesystems.disks' => null]);
-
- (new ConfigValidator())->validate();
- }
-
- /** @test */
- public function it_throws_exception_when_bundle_count_is_missing()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessageMatches('/how many bundles/');
-
- config()->set(['lasso.storage.max_bundles' => null]);
-
- (new ConfigValidator())->validate();
- }
-
- /** @test */
- public function it_throws_exception_when_bundle_count_is_less_than_one()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessageMatches('/how many bundles/');
-
- config()->set(['lasso.storage.max_bundles' => 0]);
-
- (new ConfigValidator())->validate();
- }
-
- /** @test */
- public function it_throws_exception_when_public_path_is_inaccessible()
- {
- $this->expectException(ConfigFailedValidation::class);
- $this->expectExceptionMessageMatches('/accessible directory/');
-
- config()->set(['lasso.public_path' => 'a_non_existing_path']);
-
- (new ConfigValidator())->validate();
- }
-}
diff --git a/tests/Helpers/ZipTest.php b/tests/Helpers/ZipTest.php
deleted file mode 100644
index 364f593..0000000
--- a/tests/Helpers/ZipTest.php
+++ /dev/null
@@ -1,130 +0,0 @@
-sourceDirectory = __DIR__ . '/Support/Zip/Source';
- $this->destinationDirectory = __DIR__ . '/Support/Zip/Destination';
-
- $this->cleanUpPreviousArtifacts();
- }
-
- /** @test */
- public function it_can_add_a_single_file_from_a_source_directory_to_a_zip_file(): void
- {
- $sourceFile = ['SingleFile/logo.png'];
- $zipFile = $this->destinationDirectory . '/SingleFile.zip';
-
- $this->assertFileDoesNotExist($zipFile);
-
- (new Zip($zipFile))
- ->addFilesFromDirectory($this->sourceDirectory .'/SingleFile')
- ->closeZip();
-
- $this->assertFileExists($zipFile);
-
- $this->assertZipFileContains($sourceFile, $zipFile);
- }
-
- /** @test */
- public function it_adds_all_files_within_a_source_directory_to_a_zip_file(): void
- {
- $sourceFiles = [
- 'MultipleFiles/1.txt',
- 'MultipleFiles/2.txt',
- 'MultipleFiles/3.txt',
- ];
-
- $zipFile = $this->destinationDirectory . '/MultiFile.zip';
-
- $this->assertFileDoesNotExist($zipFile);
-
- (new Zip($zipFile))
- ->addFilesFromDirectory($this->sourceDirectory .'/MultipleFiles')
- ->closeZip();
-
- $this->assertFileExists($zipFile);
-
- $this->assertZipFileContains($sourceFiles, $zipFile);
- }
-
- /** @test */
- public function it_adds_all_files_within_a_source_directory_including_sub_folders_to_a_zip_file(): void
- {
- $sourceFiles = [
- 'FilesWithSubFolder/SubFolder/in_sub_folder.txt',
- 'FilesWithSubFolder/SubFolder/logo_in_sub_folder.png',
- 'FilesWithSubFolder/logo_in_root_folder.png',
- 'FilesWithSubFolder/in_root_folder.txt',
- ];
-
- $zipFile = $this->destinationDirectory . '/WithSubFolder.zip';
-
- $this->assertFileDoesNotExist($zipFile);
-
- (new Zip($zipFile))
- ->addFilesFromDirectory($this->sourceDirectory .'/FilesWithSubFolder')
- ->closeZip();
-
- $this->assertFileExists($zipFile);
-
- $this->assertZipFileContains($sourceFiles, $zipFile);
- }
-
- private function assertZipFileContains(array $sourceFiles, string $destinationZipFile): void
- {
- $inspectZipFile = new ZipArchive();
- $inspectZipFile->open($destinationZipFile);
-
- collect($sourceFiles)->each(function (string $filePath) use ($inspectZipFile) {
- $relativePath = $this->getRelativePath($filePath);
-
- $this->assertSame(
- file_get_contents($this->sourceDirectory . '/' . $filePath),
- $inspectZipFile->getFromName($relativePath)
- );
- });
- }
-
- /**
- * Clean working directory at the start by purging files generated in previous tests,
- * to be able to inspect the files manually if needed after a specific test has run.
- */
- private function cleanUpPreviousArtifacts(): void
- {
- File::cleanDirectory($this->destinationDirectory);
- }
-
- /**
- * @param string $filePath
- * @return false|string
- *
- * Returns the relative path of source files, to be located in the zip file.
- */
- private function getRelativePath(string $filePath): string
- {
- // Find the root directory (first directory listed)
- $rootDirectory = explode('/', $filePath)[0];
-
- // Remove the root directory from the given path
- $normalizedPath = str_replace($rootDirectory, '', $filePath);
-
- // Remove preliminary forward slash "/Dir" -> "Dir"
- $relativePath = substr($normalizedPath, 1);
-
- return $relativePath;
- }
-}
diff --git a/tests/Pest.php b/tests/Pest.php
index 7183e93..7c8afb0 100644
--- a/tests/Pest.php
+++ b/tests/Pest.php
@@ -1,5 +1,7 @@
in('Feature');
+uses(TestCase::class)->in(__DIR__);
-/*
-|--------------------------------------------------------------------------
-| Expectations
-|--------------------------------------------------------------------------
-|
-| When you're writing tests, you often need to check that values meet certain conditions. The
-| "expect()" function gives you access to a set of "expectations" methods that you can use
-| to assert different things. Of course, you may extend the Expectation API at any time.
-|
-*/
-
-expect()->extend('toBeOne', function () {
- return $this->toBe(1);
-});
+function sourceDirectory(): string
+{
+ return __DIR__ . '/Unit/Support/Zip/Source';
+}
-/*
-|--------------------------------------------------------------------------
-| Functions
-|--------------------------------------------------------------------------
-|
-| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
-| project that you don't want to repeat in every file. Here you can also expose helpers as
-| global functions to help you to reduce the number of lines of code in your test files.
-|
-*/
+function destinationDirectory(): string
+{
+ return __DIR__ . '/Unit/Support/Zip/Destination';
+}
-function something()
+function defaultConfig(): array
{
- // ..
+ return [
+ 'compiler' => [
+
+ /*
+ * Configure which command Lasso should run in its deployment
+ * phase. This will most likely be "npm run production" but
+ * you may choose what you would like to execute.
+ */
+ 'script' => 'npx mix --production',
+
+ /*
+ * Configure the amount of time (in seconds) the compiler
+ * should run before it times out. By default, this is set
+ * to 600 seconds (10 minutes).
+ */
+ 'timeout' => 600,
+
+ /*
+ * Lasso will attempt to display the compilation progress
+ * from webpack. If your progress bar isn't incrementing, it's
+ * likely you have the `--no-progress` flag on your script
+ * (e.g npm run production). Change it to `--progress`.
+ *
+ * Available progress options are:
+ *
+ * - 'all': Display everything from the compiler.
+ * - 'progress': Display compilation progress.
+ * - 'disable': Disable the progress.
+ */
+ 'output' => 'progress',
+
+ /*
+ * If there are any directories/files you would like to Lasso to
+ * exclude when uploading to the Filesystem, specify them below.
+ */
+ 'excluded_files' => [],
+
+ 'excluded_directories' => [],
+
+ ],
+
+ 'storage' => [
+
+ /*
+ * Specify the filesystem Lasso should use to store
+ * and retrieve its files.
+ */
+ 'disk' => 'assets',
+
+ /*
+ * Specify the directory Lasso should store all of its
+ * files within.
+ *
+ * WARNING: If you have multiple projects all using Lasso,
+ * make sure this is unique for each project.
+ */
+ 'upload_to' => 'lasso',
+
+ /*
+ * Lasso can also create a separate directory containing
+ * the environment the files will be stored in. Specify this
+ * here.
+ */
+ 'environment' => null,
+
+ /*
+ * Lasso can add a prefix to the bundle file, in order to store
+ * multiple bundle files in the same filesystem for different
+ * environments
+ */
+ 'prefix' => '',
+
+ /*
+ * Lasso will automatically version the assets. This is useful if you
+ * suddenly need to roll back a deployment and use an older version
+ * of built files. You can set the maximum amount of files stored here.
+ */
+ 'max_bundles' => 5,
+
+ ],
+
+ /*
+ * Lasso can also trigger Webhooks after its commands have been
+ * successfully executed. You may specify URLs that Lasso will POST
+ * to, for each of the commands.
+ */
+ 'webhooks' => [
+
+ /*
+ * Specify which webhooks should be triggered after a successful
+ * "php artisan lasso:publish" command execution.
+ */
+ 'publish' => [
+ //
+ ],
+
+ /*
+ * Specify which webhooks should be triggered after a successful
+ * "php artisan lasso:pull" command execution.
+ */
+ 'pull' => [
+ //
+ ],
+
+ ],
+
+ /*
+ * Where are your assets stored? Most of the time, they will
+ * be stored within the /public directory in Laravel - but if
+ * you have changed this - please specify it below.
+ */
+ 'public_path' => __DIR__ . '/Fixtures/Public',
+ ];
}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index aeb7399..298fd35 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -1,5 +1,7 @@
setBasePath(__DIR__ . '/../');
+
+ $app['config']->set('filesystems.disks.assets', [
+ 'driver' => 'local',
+ 'root' => __DIR__ . '/Fixtures/Cloud',
+ 'throw' => false,
+ ]);
+ }
}
diff --git a/tests/Unit/ConfigValidatorPestTest.php b/tests/Unit/ConfigValidatorPestTest.php
new file mode 100644
index 0000000..43a2e5c
--- /dev/null
+++ b/tests/Unit/ConfigValidatorPestTest.php
@@ -0,0 +1,79 @@
+set([
+ 'filesystems.disks' => [
+ 'assets' => [
+ 'driver' => 's3',
+ ],
+ ],
+ ]);
+});
+
+test('it throws exception when storage push to git is set', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessageMatches('/push_to_git/');
+
+ config()->set(['lasso.storage.push_to_git' => true]);
+
+ (new ConfigValidator)->validate();
+});
+
+test('it throws an exception when the compile script is not set', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessageMatches('/npm run production/');
+
+ config()->set(['lasso.compiler.script' => null]);
+
+ (new ConfigValidator)->validate();
+});
+
+test('it throws an exception when an invalid compiler output is provided', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessage('You must specify a valid output setting. Available options: all, progress, disable.');
+
+ config()->set(['lasso.compiler.output' => 'abc']);
+
+ (new ConfigValidator)->validate();
+});
+
+test('it throws exception when disk does not exist', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessageMatches('/not a valid disk/');
+
+ config()->set(['filesystems.disks' => null]);
+
+ (new ConfigValidator)->validate();
+});
+
+test('it throws exception when bundle count is missing', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessageMatches('/how many bundles/');
+
+ config()->set(['lasso.storage.max_bundles' => null]);
+
+ (new ConfigValidator)->validate();
+});
+
+test('it throws exception when bundle count is less than one', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessageMatches('/how many bundles/');
+
+ config()->set(['lasso.storage.max_bundles' => 0]);
+
+ (new ConfigValidator)->validate();
+});
+
+test('it throws exception when public path is inaccessible', function () {
+ $this->expectException(ConfigFailedValidation::class);
+ $this->expectExceptionMessageMatches('/accessible directory/');
+
+ config()->set(['lasso.public_path' => 'a_non_existing_path']);
+
+ (new ConfigValidator)->validate();
+});
diff --git a/tests/Helpers/Support/Zip/Destination/WithSubFolder.zip b/tests/Unit/Support/Zip/Destination/WithSubFolder.zip
similarity index 100%
rename from tests/Helpers/Support/Zip/Destination/WithSubFolder.zip
rename to tests/Unit/Support/Zip/Destination/WithSubFolder.zip
diff --git a/tests/Helpers/Support/Zip/Source/FilesWithSubFolder/SubFolder/in_sub_folder.txt b/tests/Unit/Support/Zip/Source/FilesWithSubFolder/SubFolder/in_sub_folder.txt
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/FilesWithSubFolder/SubFolder/in_sub_folder.txt
rename to tests/Unit/Support/Zip/Source/FilesWithSubFolder/SubFolder/in_sub_folder.txt
diff --git a/tests/Helpers/Support/Zip/Source/FilesWithSubFolder/SubFolder/logo_in_sub_folder.png b/tests/Unit/Support/Zip/Source/FilesWithSubFolder/SubFolder/logo_in_sub_folder.png
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/FilesWithSubFolder/SubFolder/logo_in_sub_folder.png
rename to tests/Unit/Support/Zip/Source/FilesWithSubFolder/SubFolder/logo_in_sub_folder.png
diff --git a/tests/Helpers/Support/Zip/Source/FilesWithSubFolder/in_root_folder.txt b/tests/Unit/Support/Zip/Source/FilesWithSubFolder/in_root_folder.txt
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/FilesWithSubFolder/in_root_folder.txt
rename to tests/Unit/Support/Zip/Source/FilesWithSubFolder/in_root_folder.txt
diff --git a/tests/Helpers/Support/Zip/Source/FilesWithSubFolder/logo_in_root_folder.png b/tests/Unit/Support/Zip/Source/FilesWithSubFolder/logo_in_root_folder.png
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/FilesWithSubFolder/logo_in_root_folder.png
rename to tests/Unit/Support/Zip/Source/FilesWithSubFolder/logo_in_root_folder.png
diff --git a/tests/Helpers/Support/Zip/Source/MultipleFiles/1.txt b/tests/Unit/Support/Zip/Source/MultipleFiles/1.txt
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/MultipleFiles/1.txt
rename to tests/Unit/Support/Zip/Source/MultipleFiles/1.txt
diff --git a/tests/Helpers/Support/Zip/Source/MultipleFiles/2.txt b/tests/Unit/Support/Zip/Source/MultipleFiles/2.txt
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/MultipleFiles/2.txt
rename to tests/Unit/Support/Zip/Source/MultipleFiles/2.txt
diff --git a/tests/Helpers/Support/Zip/Source/MultipleFiles/3.txt b/tests/Unit/Support/Zip/Source/MultipleFiles/3.txt
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/MultipleFiles/3.txt
rename to tests/Unit/Support/Zip/Source/MultipleFiles/3.txt
diff --git a/tests/Helpers/Support/Zip/Source/SingleFile/logo.png b/tests/Unit/Support/Zip/Source/SingleFile/logo.png
similarity index 100%
rename from tests/Helpers/Support/Zip/Source/SingleFile/logo.png
rename to tests/Unit/Support/Zip/Source/SingleFile/logo.png
diff --git a/tests/Unit/ZipPestTest.php b/tests/Unit/ZipPestTest.php
new file mode 100644
index 0000000..e6d6216
--- /dev/null
+++ b/tests/Unit/ZipPestTest.php
@@ -0,0 +1,95 @@
+addFilesFromDirectory(sourceDirectory() . '/SingleFile')
+ ->closeZip();
+
+ assertFileExists($zipFile);
+ assertZipFileContains($sourceFile, $zipFile);
+});
+
+test('it adds all files within a source directory to a zip file', function () {
+ $sourceFiles = [
+ 'MultipleFiles/1.txt',
+ 'MultipleFiles/2.txt',
+ 'MultipleFiles/3.txt',
+ ];
+
+ $zipFile = destinationDirectory() . '/MultiFile.zip';
+
+ assertFileDoesNotExist($zipFile);
+
+ (new Zip($zipFile))
+ ->addFilesFromDirectory(sourceDirectory() .'/MultipleFiles')
+ ->closeZip();
+
+ assertFileExists($zipFile);
+
+ assertZipFileContains($sourceFiles, $zipFile);
+});
+
+test('it adds all files within a source directory including sub folders to a zip file', function () {
+ $sourceFiles = [
+ 'FilesWithSubFolder/SubFolder/in_sub_folder.txt',
+ 'FilesWithSubFolder/SubFolder/logo_in_sub_folder.png',
+ 'FilesWithSubFolder/logo_in_root_folder.png',
+ 'FilesWithSubFolder/in_root_folder.txt',
+ ];
+
+ $zipFile = destinationDirectory() . '/WithSubFolder.zip';
+
+ assertFileDoesNotExist($zipFile);
+
+ (new Zip($zipFile))
+ ->addFilesFromDirectory(sourceDirectory() .'/FilesWithSubFolder')
+ ->closeZip();
+
+ assertFileExists($zipFile);
+
+ assertZipFileContains($sourceFiles, $zipFile);
+});
+
+function assertZipFileContains(array $sourceFiles, string $destinationZipFile): void
+{
+ $inspectZipFile = new ZipArchive();
+ $inspectZipFile->open($destinationZipFile);
+
+ collect($sourceFiles)->each(function (string $filePath) use ($inspectZipFile) {
+ $relativePath = getRelativePath($filePath);
+
+ assertStringEqualsFile(
+ sourceDirectory() . '/' . $filePath,
+ $inspectZipFile->getFromName($relativePath)
+ );
+ });
+}
+
+function getRelativePath(string $filePath): string
+{
+ // Find the root directory (first directory listed)
+ $rootDirectory = explode('/', $filePath)[0];
+
+ // Remove the root directory from the given path
+ $normalizedPath = str_replace($rootDirectory, '', $filePath);
+
+ // Remove preliminary forward slash "/Dir" -> "Dir"
+ return mb_substr($normalizedPath, 1);
+}
diff --git a/webpack.mix.js b/webpack.mix.js
new file mode 100644
index 0000000..e94772e
--- /dev/null
+++ b/webpack.mix.js
@@ -0,0 +1,3 @@
+let mix = require('laravel-mix');
+
+mix.copyDirectory('tests/Fixtures/Local', './tests/Fixtures/Public');