This commit is contained in:
20
Makefile
20
Makefile
@ -1,18 +1,24 @@
|
|||||||
analyze: analyze-phpmd analyze-phpstan analyze-psalm analyze-phpcs
|
analyze: analyze-yaml analyze-phpmd analyze-phpstan analyze-psalm analyze-phpcs
|
||||||
|
|
||||||
|
analyze-yaml:
|
||||||
|
vendor/bin/yaml-lint config.yml
|
||||||
analyze-phpmd:
|
analyze-phpmd:
|
||||||
./vendor/bin/phpmd src text cleancode,codesize,controversial,design,naming,unusedcode
|
vendor/bin/phpmd src text cleancode,codesize,controversial,design,naming,unusedcode
|
||||||
analyze-phpstan:
|
analyze-phpstan:
|
||||||
./vendor/bin/phpstan analyze --level=7 --error-format=raw src/ backup
|
vendor/bin/phpstan analyze --level=7 --error-format=raw src/ backup
|
||||||
analyze-psalm:
|
analyze-psalm:
|
||||||
./vendor/bin/psalm
|
vendor/bin/psalm
|
||||||
analyze-phpcs:
|
analyze-phpcs:
|
||||||
./vendor/bin/phpcs src backup --report=emacs --standard=PSR12
|
vendor/bin/phpcs src backup --report=emacs --standard=PSR12
|
||||||
|
|
||||||
install:
|
install:
|
||||||
php composer.phar install --no-dev
|
php composer.phar install --no-dev
|
||||||
install-dev:
|
install-dev:
|
||||||
php composer.phar install
|
php composer.phar install
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install rclone
|
||||||
test:
|
test:
|
||||||
./vendor/bin/phpunit tests --testdox --coverage-filter src --coverage-html output/coverage
|
vendor/bin/phpunit tests
|
||||||
|
test-coverage:
|
||||||
|
vendor/bin/phpunit tests --testdox --coverage-filter src --coverage-html output/coverage --coverage-text
|
||||||
|
|
10
composer.lock
generated
10
composer.lock
generated
@ -2922,16 +2922,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan",
|
"name": "phpstan/phpstan",
|
||||||
"version": "1.10.18",
|
"version": "1.10.19",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan.git",
|
"url": "https://github.com/phpstan/phpstan.git",
|
||||||
"reference": "52b6416c579663eebdd2f1d97df21971daf3b43f"
|
"reference": "af5a296ff02610c1bfb4ddfac9fd4a08657b9046"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/52b6416c579663eebdd2f1d97df21971daf3b43f",
|
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/af5a296ff02610c1bfb4ddfac9fd4a08657b9046",
|
||||||
"reference": "52b6416c579663eebdd2f1d97df21971daf3b43f",
|
"reference": "af5a296ff02610c1bfb4ddfac9fd4a08657b9046",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2980,7 +2980,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-06-07T22:00:43+00:00"
|
"time": "2023-06-14T15:26:58+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
|
@ -62,17 +62,13 @@ class CommandBackup extends Command
|
|||||||
$template['rclone_version'] = $rclone->getVersion();
|
$template['rclone_version'] = $rclone->getVersion();
|
||||||
$template['destination_size_before'] = $rclone->getSize($conf['destination']);
|
$template['destination_size_before'] = $rclone->getSize($conf['destination']);
|
||||||
|
|
||||||
$template['stdout'] = $rclone->copy(
|
$rclone->copy($conf['source'], $conf['destination'], $app->getConfig()['rclone']['options']);
|
||||||
$conf['source'],
|
|
||||||
$conf['destination'],
|
|
||||||
$app->getConfig()['rclone']['options']
|
|
||||||
);
|
|
||||||
|
|
||||||
$template['destination_size_after'] = $rclone->getSize($conf['destination']);
|
$template['destination_size_after'] = $rclone->getSize($conf['destination']);
|
||||||
$template['end'] = new DateTime();
|
$template['end'] = new DateTime();
|
||||||
|
|
||||||
$message = $twig->render('notify', $template);
|
$message = $twig->render('notify', $template);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Exception $e) {
|
||||||
$message = $e->getMessage();
|
$message = $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,13 +43,13 @@ class Rclone
|
|||||||
$this->rclonePath = $rclonePath;
|
$this->rclonePath = $rclonePath;
|
||||||
$this->setLogger(new NullLogger());
|
$this->setLogger(new NullLogger());
|
||||||
|
|
||||||
try {
|
$process = $this->exec('--version');
|
||||||
$version = $this->exec('--version');
|
if (!$process->isSuccessful()) {
|
||||||
$this->version = explode("\n", $version)[0];
|
|
||||||
} catch (ProcessFailedException $e) {
|
|
||||||
throw new Exception("Check installation of rclone");
|
throw new Exception("Check installation of rclone");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->version = explode("\n", $process->getOutput())[0];
|
||||||
|
|
||||||
if (!\str_contains($this->version, 'rclone')) {
|
if (!\str_contains($this->version, 'rclone')) {
|
||||||
throw new Exception("Rclone not recognized");
|
throw new Exception("Rclone not recognized");
|
||||||
}
|
}
|
||||||
@ -74,8 +74,12 @@ class Rclone
|
|||||||
*/
|
*/
|
||||||
public function getSize(string $path): int
|
public function getSize(string $path): int
|
||||||
{
|
{
|
||||||
$output = $this->exec('size', ['--json', $path]);
|
$process = $this->exec('size', ['--json', $path]);
|
||||||
return (int)json_decode($output)->bytes;
|
|
||||||
|
if (!$process->isSuccessful()) {
|
||||||
|
throw new Exception($process->getErrorOutput());
|
||||||
|
}
|
||||||
|
return (int)json_decode($process->getOutput())->bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,10 +88,8 @@ class Rclone
|
|||||||
* @param $src Source mount and path
|
* @param $src Source mount and path
|
||||||
* @param $dest Destination mount and path
|
* @param $dest Destination mount and path
|
||||||
* @param string[] $additionalOptions Additional options
|
* @param string[] $additionalOptions Additional options
|
||||||
*
|
|
||||||
* @return string Stdout from command
|
|
||||||
*/
|
*/
|
||||||
public function copy(string $src, string $dest, array $additionalOptions = array()): string
|
public function copy(string $src, string $dest, array $additionalOptions = array()): void
|
||||||
{
|
{
|
||||||
$options = array();
|
$options = array();
|
||||||
|
|
||||||
@ -95,16 +97,14 @@ class Rclone
|
|||||||
$options[] = $dest;
|
$options[] = $dest;
|
||||||
|
|
||||||
foreach ($additionalOptions as $key => $value) {
|
foreach ($additionalOptions as $key => $value) {
|
||||||
if (strlen($key) == 1) {
|
$options[] = '--' . $key;
|
||||||
$options[] = '-' . $key;
|
$options[] = $value;
|
||||||
$options[] = $value;
|
|
||||||
} elseif (strlen($key) > 2) {
|
|
||||||
$options[] = '--' . $key;
|
|
||||||
$options[] = $value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->exec('copy', $options);
|
$process = $this->exec('copy', $options);
|
||||||
|
if (!$process->isSuccessful()) {
|
||||||
|
throw new Exception($process->getErrorOutput());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,9 +113,9 @@ class Rclone
|
|||||||
* @param string $command Top level Rclone command
|
* @param string $command Top level Rclone command
|
||||||
* @param array<String> $options Array of additional options
|
* @param array<String> $options Array of additional options
|
||||||
*
|
*
|
||||||
* @return string stdout data.
|
* @return Process Instance.
|
||||||
*/
|
*/
|
||||||
protected function exec(string $command, array $options = array()): string
|
protected function exec(string $command, array $options = array()): Process
|
||||||
{
|
{
|
||||||
$process = new Process(
|
$process = new Process(
|
||||||
array_merge(
|
array_merge(
|
||||||
@ -137,11 +137,10 @@ class Rclone
|
|||||||
if ($this->logger instanceof LoggerInterface) {
|
if ($this->logger instanceof LoggerInterface) {
|
||||||
$this->logger->error("Failed execution");
|
$this->logger->error("Failed execution");
|
||||||
}
|
}
|
||||||
throw new ProcessFailedException($process);
|
|
||||||
}
|
}
|
||||||
if ($this->logger instanceof LoggerInterface) {
|
if ($this->logger instanceof LoggerInterface) {
|
||||||
$this->logger->info("Return code", [$process->getExitCode()]);
|
$this->logger->info("Return code", [$process->getExitCode()]);
|
||||||
}
|
}
|
||||||
return $process->getOutput();
|
return $process;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
tests/CommandBackupTest.php
Normal file
29
tests/CommandBackupTest.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Console\Application;
|
||||||
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
use App\CommandBackup;
|
||||||
|
|
||||||
|
class CommandBackupTest extends \PHPUnit\Framework\TestCase
|
||||||
|
{
|
||||||
|
public function testExecute()
|
||||||
|
{
|
||||||
|
|
||||||
|
$applicationd = new Application('backup', "1.1.1");
|
||||||
|
|
||||||
|
$applicationd->add(new CommandBackup());
|
||||||
|
|
||||||
|
|
||||||
|
$command = $applicationd->find('backup');
|
||||||
|
$commandTester = new CommandTester($command);
|
||||||
|
$commandTester->execute([]);
|
||||||
|
|
||||||
|
$commandTester->assertCommandIsSuccessful();
|
||||||
|
|
||||||
|
// the output of the command in the console
|
||||||
|
$output = $commandTester->getDisplay();
|
||||||
|
$this->assertStringContainsString('backup', $output);
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +1,65 @@
|
|||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
final class RcloneTest extends TestCase
|
final class RcloneTest extends TestCase
|
||||||
{
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
shell_exec('rclone test makefiles temp/source 2>&1');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
exec('rclone purge temp 2>&1', $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testRclonePath(): void
|
public function testRclonePath(): void
|
||||||
{
|
{
|
||||||
$this->expectException(\Exception::class);
|
$this->expectException(\Exception::class);
|
||||||
$rclone = new \App\Rclone\Rclone('invalid');
|
$rclone = new \App\Rclone\Rclone('invalid');
|
||||||
|
$this->assertString('', $rclone->getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRcloneInvalidVersion(): void
|
public function testRcloneInvalidVersion(): void
|
||||||
{
|
{
|
||||||
$this->expectException(\Exception::class);
|
$this->expectException(\Exception::class);
|
||||||
$rclone = new \App\Rclone\Rclone('uname');
|
$rclone = new \App\Rclone\Rclone('uname');
|
||||||
|
$this->assertString('', $rclone->getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRcloneValidVersion(): void
|
public function testRcloneValidVersion(): void
|
||||||
{
|
{
|
||||||
$rclone = new \App\Rclone\Rclone('./tests/mock-rclone');
|
$rclone = new \App\Rclone\Rclone();
|
||||||
$this->assertStringContainsString('rclone', $rclone->getVersion());
|
$this->assertStringContainsString('rclone', $rclone->getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRcloneSize(): void
|
||||||
|
{
|
||||||
|
$rclone = new \App\Rclone\Rclone();
|
||||||
|
$size = $rclone->getSize('temp/source');
|
||||||
|
$this->assertGreaterThan(10000, $size);
|
||||||
|
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage("ERROR");
|
||||||
|
$size = $rclone->getSize('temp/bogus-source');
|
||||||
|
$this->assertEquals(0, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRcloneCopy(): void
|
||||||
|
{
|
||||||
|
$rclone = new \App\Rclone\Rclone();
|
||||||
|
$result = $rclone->copy('temp/source','temp/destination');
|
||||||
|
$this->assertDirectoryExists('temp/destination');
|
||||||
|
|
||||||
|
$rclone = new \App\Rclone\Rclone();
|
||||||
|
$result = $rclone->copy('temp/source','temp/destination',['bwlimit'=>'6M']);
|
||||||
|
$this->assertDirectoryExists('temp/destination');
|
||||||
|
|
||||||
|
$this->expectException(\Exception::class);
|
||||||
|
$this->expectExceptionMessage("ERROR");
|
||||||
|
$result = $rclone->copy('temp/bogus-source','temp/bogus-destination');
|
||||||
|
$this->assertDirectoryDoesNotExist('temp/bogus-destination');
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
echo rclone v1.53.3-DEV
|
|
Reference in New Issue
Block a user