Quality of life improvements all around.
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				ci/woodpecker/push/woodpecker Pipeline failed
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	ci/woodpecker/push/woodpecker Pipeline failed
				
			This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "furyfire/backupscript",
 | 
			
		||||
    "description": "Wrapper for Rclone based backup",
 | 
			
		||||
    "description": "Wrapper for Rclone based backup with push notifications",
 | 
			
		||||
    "homepage": "https://jcktrue.dk",
 | 
			
		||||
    "version": "0.1.0",
 | 
			
		||||
    "require": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
			
		||||
        "This file is @generated automatically"
 | 
			
		||||
    ],
 | 
			
		||||
    "content-hash": "7c0718c0e4c6eabc3fec9cc0dbf816e2",
 | 
			
		||||
    "content-hash": "545ed8a092dd0e7cb6c11837968dafc7",
 | 
			
		||||
    "packages": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "dflydev/dot-access-data",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/App.php
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/App.php
									
									
									
									
									
								
							@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Yaml\Yaml;
 | 
			
		||||
@@ -11,21 +13,17 @@ use League\Config\Configuration;
 | 
			
		||||
use Nette\Schema\Expect;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Application class
 | 
			
		||||
 *
 | 
			
		||||
 * Mostly working as a register pattern for the logging and configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * @author  Jens True <jens.chr.true@gmail.com>
 | 
			
		||||
 * @license https://opensource.org/licenses/gpl-license.php GNU Public License
 | 
			
		||||
 * @link    https://jcktrue.dk
 | 
			
		||||
 */
 | 
			
		||||
class App
 | 
			
		||||
{
 | 
			
		||||
    /// Logging instance
 | 
			
		||||
    protected Logger $logger;
 | 
			
		||||
    /// Configuration singleton
 | 
			
		||||
    protected Configuration $config;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new instance providing a config file
 | 
			
		||||
     * Create a new instance providing a config file.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $configFile Relative or full path to YML config.
 | 
			
		||||
     * @SuppressWarnings(PHPMD.StaticAccess)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Console\Attribute\AsCommand;
 | 
			
		||||
@@ -28,6 +30,18 @@ class CommandBackup extends Command
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start the backup process.
 | 
			
		||||
     *
 | 
			
		||||
     * 1. Read the configuration file.
 | 
			
		||||
     * 2. For each configured backup entry
 | 
			
		||||
     *    1. Get the size of the source
 | 
			
		||||
     *    2. Get the size of the destination
 | 
			
		||||
     *    3. Perform the backup
 | 
			
		||||
     *    4. Get the new size of the destination
 | 
			
		||||
     *    5. Send push notifications.
 | 
			
		||||
     * 3. Report final success
 | 
			
		||||
     */
 | 
			
		||||
    protected function execute(InputInterface $input, OutputInterface $output): int
 | 
			
		||||
    {
 | 
			
		||||
        $sio = new SymfonyStyle($input, $output);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Console\Attribute\AsCommand;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Notification;
 | 
			
		||||
 | 
			
		||||
use App\Notification\Ntfy;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Notification;
 | 
			
		||||
 | 
			
		||||
interface NotificationInterface
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Notification;
 | 
			
		||||
 | 
			
		||||
use Ntfy\Server;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Rclone;
 | 
			
		||||
 | 
			
		||||
use Psr\Log\LoggerAwareTrait;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Template;
 | 
			
		||||
 | 
			
		||||
use Twig\Environment;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Template;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\DependencyInjection\ContainerInterface;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								tests/AppTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tests/AppTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Tests;
 | 
			
		||||
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
use PHPUnit\Framework\Attributes\CoversClass;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
use App\App;
 | 
			
		||||
 | 
			
		||||
#[CoversClass(App::class)]
 | 
			
		||||
final class AppTest extends \PHPUnit\Framework\TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testNonexistentConfigFile(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->expectException(\Exception::class);
 | 
			
		||||
        new App('no_file');
 | 
			
		||||
        $this->fail('Exception was not thrown');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testGoodConfig(): void
 | 
			
		||||
    {
 | 
			
		||||
        $app = new App('config.example.yml');
 | 
			
		||||
        $this->assertEquals('output.log', $app->getConfig('log'));
 | 
			
		||||
        $this->assertInstanceOf(LoggerInterface::class, $app->getLogger());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -23,15 +23,15 @@ final class RcloneTest extends TestCase
 | 
			
		||||
    public function testRclonePath(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->expectException(\Exception::class);
 | 
			
		||||
        $rclone = new Rclone('invalid');
 | 
			
		||||
        $this->assertEquals('', $rclone->getVersion());
 | 
			
		||||
        new Rclone('invalid');
 | 
			
		||||
        $this->fail('Exception was not thrown');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRcloneInvalidVersion(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->expectException(\Exception::class);
 | 
			
		||||
        $rclone = new Rclone('uname');
 | 
			
		||||
        $this->assertEquals('', $rclone->getVersion());
 | 
			
		||||
        new Rclone('uname');
 | 
			
		||||
        $this->fail('Exception was not thrown');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRcloneValidVersion(): void
 | 
			
		||||
@@ -49,7 +49,7 @@ final class RcloneTest extends TestCase
 | 
			
		||||
        $this->expectException(\Exception::class);
 | 
			
		||||
        $this->expectExceptionMessage("ERROR");
 | 
			
		||||
        $size = $rclone->getSize('temp/bogus-source');
 | 
			
		||||
        $this->assertEquals(0, $size);
 | 
			
		||||
        $this->fail('Exception was not thrown');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRcloneCopy(): void
 | 
			
		||||
@@ -65,6 +65,6 @@ final class RcloneTest extends TestCase
 | 
			
		||||
        $this->expectException(\Exception::class);
 | 
			
		||||
        $this->expectExceptionMessage("ERROR");
 | 
			
		||||
        $rclone->copy('temp/bogus-source', 'temp/bogus-destination');
 | 
			
		||||
        $this->assertDirectoryDoesNotExist('temp/bogus-destination');
 | 
			
		||||
        $this->fail('Exception was not thrown');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								tests/Template/TwigExtensionTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								tests/Template/TwigExtensionTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace App\Tests;
 | 
			
		||||
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
use PHPUnit\Framework\Attributes\DataProvider;
 | 
			
		||||
use App\Template\TwigExtension;
 | 
			
		||||
use Twig\TwigFilter;
 | 
			
		||||
 | 
			
		||||
final class TwigExtensionTest extends \PHPUnit\Framework\TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testGetFilters(): void
 | 
			
		||||
    {
 | 
			
		||||
        $obj = new TwigExtension();
 | 
			
		||||
        $filters = $obj->getFilters();
 | 
			
		||||
        $this->assertContainsOnlyInstancesOf(TwigFilter::class, $filters);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function testformatBytes(): void
 | 
			
		||||
    {
 | 
			
		||||
        $obj = new TwigExtension();
 | 
			
		||||
        $this->assertEquals('1.00B', $obj->formatBytes(1, 2));
 | 
			
		||||
        $this->assertEquals('2.00B', $obj->formatBytes(2, 2));
 | 
			
		||||
        $this->assertEquals('10.00B', $obj->formatBytes(10, 2));
 | 
			
		||||
        $this->assertEquals('0.98kB', $obj->formatBytes(1000, 2));
 | 
			
		||||
        $this->assertEquals('1.00kB', $obj->formatBytes(1024, 2));
 | 
			
		||||
        $this->assertEquals('512.00MB', $obj->formatBytes(1024 ** 3 / 2, 2));
 | 
			
		||||
        $this->assertEquals('1.00GB', $obj->formatBytes(1024 ** 3 - 1, 2));
 | 
			
		||||
        $this->assertEquals('1.00GB', $obj->formatBytes(1024 ** 3, 2));
 | 
			
		||||
        $this->assertEquals('512.00GB', $obj->formatBytes(1024 ** 4 / 2, 2));
 | 
			
		||||
        $this->assertEquals('1.00TB', $obj->formatBytes(1024 ** 4, 2));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user