Skip to content

Commit

Permalink
some fixes and added method download_to_local (tests included)
Browse files Browse the repository at this point in the history
  • Loading branch information
insign committed Apr 14, 2024
1 parent bc7d74c commit 06fa705
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 106 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.env
ai.txt
/vendor
composer.phar
composer.lock
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"scripts" : {
"test" : "phpunit",
"test-local" : "phpunit --testsuite offline_no_docker",
"test-offline" : "phpunit --testsuite offline",
"security-check" : "security-checker security:check composer.lock",
"post-install-cmd" : [
"exit 0 || [ $COMPOSER_DEV_MODE -eq 0 ] || composer run security-check"
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ x-commons: &commons
env_file: .env
volumes :
- ".:/app"
- "./tests/Unit/sandbox:/tmp"

networks :
internal:
Expand Down
23 changes: 13 additions & 10 deletions Makefile → makefile
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
#!/usr/bin/make

.DEFAULT_GOAL := test

init: ## Start a new develop environment
make cin
test: ## Start containers detached
CMD="run-script test-local" make composer
test_offline:
CMD="run-script test" make composer
init: ## Start a new develop environment
make cin
test-offline:
docker compose run --rm test_sftp_to_s3
docker compose run --rm test_s3_to_sftp
logs: ## Show the output logs
docker-compose logs
docker compose logs
log: ## Open the logs and follow the news
docker-compose logs --follow
docker compose logs --follow
restart: ## Restart the app container
docker-compose restart
docker compose restart
composer:
docker-compose run --rm composer $(CMD)
composer $(CMD)
composer-docker:
docker compose run --rm composer $(CMD)
cin:
CMD=install make composer
cup:
CMD=update make composer
ai:
tog --output=ai.txt --folder-recursive=./src --ignore-folders=src/Exception
35 changes: 30 additions & 5 deletions src/Rclone.php
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ public function exists ( string $path, string $type ): object
$ls = $this->ls($dirname);
$found = array_filter($ls, static fn( $i ) => $i->Name === $basename && $i->IsDir === ($type === 'dir'));

return (object) [ 'exists' => count($found) === 1, 'details' => $found[ 0 ] ?? [], 'error' => '' ];
return (object) [ 'exists' => count($found) === 1, 'details' => reset($found) ?? [], 'error' => '' ];
} catch (\Exception $e) {
return (object) [ 'exists' => FALSE, 'error' => $e, ];
}
Expand Down Expand Up @@ -605,14 +605,39 @@ public function rcat ( string $path, string $input, array $flags = [], callable

public function upload_file ( string $local_path, string $remote_path, array $flags = [], callable $onProgress = NULL ): bool
{
$left_local = new LocalProvider('local');
$right_mix = $this->left_side;

$rclone = new self($left_local, $right_mix);
$rclone = new self(left_side: new LocalProvider('local'), right_side: $this->left_side);

return $rclone->moveto($local_path, $remote_path, $flags, $onProgress);
}

/**
* Downloads a file from a remote path to local storage.
*
* @param string $remote_path The path of the file on the remote server.
* @param ?string $local_path The local path where the file should be saved. If not provided, a temporary directory will be used.
* @param array $flags Additional flags for the download operation.
* @param ?callable $onProgress A callback function to track download progress.
*
* @return string|false The local path where the file is saved, or false if the download fails.
*/
public function download_to_local(string $remote_path, ?string $local_path = null, array $flags = [], ?callable $onProgress = null): string|false
{
if ($local_path === null) {
$local_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('flyclone_download_');
mkdir($local_path, 0777, true);
}

$rclone = new self(left_side: $this->left_side, right_side: new LocalProvider('local'));

$success = $rclone->copy($remote_path, $local_path, $flags, $onProgress);

if (!$success) {
return false;
}

return $local_path;
}

public function copy ( string $source_path, string $dest_DIR_path, array $flags = [], callable $onProgress = NULL ): bool
{
return $this->directTwinRun('copy', $source_path, $dest_DIR_path, $flags, $onProgress);
Expand Down
203 changes: 112 additions & 91 deletions tests/Unit/AbstractTwoProvidersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
namespace Verseles\Flyclone\Test\Unit;


use Verseles\Flyclone\Providers\Provider;
use Verseles\Flyclone\Rclone;
use PHPUnit\Framework\Exception;
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use SebastianBergmann\RecursionContext\InvalidArgumentException;
use Verseles\Flyclone\Providers\LocalProvider;
use Verseles\Flyclone\Providers\Provider;
use Verseles\Flyclone\Rclone;

abstract class AbstractTwoProvidersTest extends TestCase
{
Expand All @@ -20,160 +21,180 @@ abstract class AbstractTwoProvidersTest extends TestCase
protected string $left_working_directory = '/tmp';
protected string $right_working_directory = '/tmp';

final public function setLeftProviderName ( string $leftProviderName ): void
final public function setLeftProviderName(string $leftProviderName): void
{
$this->leftProviderName = $leftProviderName;
$this->leftProviderName = $leftProviderName;
}

final public function getLeftProviderName (): string
final public function getLeftProviderName(): string
{
return $this->leftProviderName;
return $this->leftProviderName;
}

final public function getRightProviderName (): string
final public function getRightProviderName(): string
{
return $this->rightProviderName;
return $this->rightProviderName;
}

final public function setRightProviderName ( string $rightProviderName ): void
final public function setRightProviderName(string $rightProviderName): void
{
$this->rightProviderName = $rightProviderName;
$this->rightProviderName = $rightProviderName;
}

final public function getLeftWorkingDirectory (): string
final public function getLeftWorkingDirectory(): string
{
return $this->left_working_directory;
return $this->left_working_directory;
}

final public function setLeftWorkingDirectory ( string $left_working_directory ): void
final public function setLeftWorkingDirectory(string $left_working_directory): void
{
$this->left_working_directory = $left_working_directory;
$this->left_working_directory = $left_working_directory;
}

final public function getRightWorkingDirectory (): string
final public function getRightWorkingDirectory(): string
{
return $this->right_working_directory;
return $this->right_working_directory;
}

final public function setRightWorkingDirectory ( string $right_working_directory ): void
final public function setRightWorkingDirectory(string $right_working_directory): void
{
$this->right_working_directory = $right_working_directory;
$this->right_working_directory = $right_working_directory;
}


abstract public function instantiate_left_provider (): Provider;
abstract public function instantiate_left_provider(): Provider;

abstract public function instantiate_right_provider (): Provider;
abstract public function instantiate_right_provider(): Provider;

/**
* @test
* @depends instantiate_left_provider
* @depends instantiate_right_provider
* @noinspection PhpUnitTestsInspection
* @throws ExpectationFailedException|InvalidArgumentException|Exception
*/
public function instantiate_with_two_providers ( $left_side, $right_side ): Rclone
* @test
* @depends instantiate_left_provider
* @depends instantiate_right_provider
* @noinspection PhpUnitTestsInspection
* @throws ExpectationFailedException|InvalidArgumentException|Exception
*/
public function instantiate_with_two_providers($left_side, $right_side): Rclone
{
$two_sides = new Rclone($left_side, $right_side);
$two_sides = new Rclone($left_side, $right_side);

self::assertInstanceOf(Rclone::class, $two_sides);
self::assertInstanceOf(Rclone::class, $two_sides);

return $two_sides;
return $two_sides;
}

/**
* @test
* @depends instantiate_with_two_providers
*
* @param Rclone $two_sides
*
* @return array
* @throws ExpectationFailedException|InvalidArgumentException
*/
public function touch_a_file_on_left_side ( Rclone $two_sides ): array
* @test
* @depends instantiate_with_two_providers
*
* @param Rclone $two_sides
*
* @return array
* @throws ExpectationFailedException|InvalidArgumentException
*/
public function touch_a_file_on_left_side(Rclone $two_sides): array
{
$temp_filepath = $this->getLeftWorkingDirectory() . '/flyclone_' . $this->random_string();
$temp_filepath = $this->getLeftWorkingDirectory() . '/flyclone_' . $this->random_string();

$result = $two_sides->touch($temp_filepath);
$result = $two_sides->touch($temp_filepath);

self::assertTrue($result);
self::assertTrue($result);

$file = $two_sides->is_file($temp_filepath);
$file = $two_sides->is_file($temp_filepath);

self::assertTrue($file->exists, 'File not created');
self::assertTrue($file->exists, 'File not created');

self::assertEquals(0, $file->details->Size ?? 9999, 'File should be empty by now');
self::assertIsObject($file->details);
self::assertObjectHasProperty('Size', $file->details);

return [ $two_sides, $temp_filepath ];
self::assertEquals(0, $file->details->Size ?? 9999, 'File should be empty for now');

return [$two_sides, $temp_filepath];
}

/**
* @test
* @depends touch_a_file_on_left_side
* @throws ExpectationFailedException|InvalidArgumentException
*/
public function write_to_a_file_on_left_side ( $params ): array
* @test
* @depends touch_a_file_on_left_side
* @throws ExpectationFailedException|InvalidArgumentException
*/
public function write_to_a_file_on_left_side($params): array
{
$content = 'But my father lives at https://helio.me :)';
$content = 'But my father lives at https://helio.me :)';

/** @var Rclone $two_sides */
[ $two_sides, $temp_filepath ] = $params;
/** @var Rclone $two_sides */
[$two_sides, $temp_filepath] = $params;

$two_sides->rcat($temp_filepath, $content);
$two_sides->rcat($temp_filepath, $content);

$file_content = $two_sides->cat($temp_filepath);
self::assertEquals($file_content, $content, 'File content are different');
$file_content = $two_sides->cat($temp_filepath);
self::assertEquals($file_content, $content, 'File content are different');

return [ $two_sides, $temp_filepath ];
return [$two_sides, $temp_filepath, $content];
}

/**
* @test
*
* @depends write_to_a_file_on_left_side
* @throws ExpectationFailedException|InvalidArgumentException
*/
public function move_file_to_right_side ( array $params ): array
* @test
*
* @depends write_to_a_file_on_left_side
* @throws ExpectationFailedException|InvalidArgumentException
*/
public function move_file_to_right_side(array $params): array
{
/** @var $two_sides Rclone */
[ $two_sides, $file_on_left_side ] = $params;
/** @var $two_sides Rclone */
[$two_sides, $file_on_left_side, $content] = $params;

$new_place = $this->getRightWorkingDirectory() . '/' . basename($file_on_left_side);
$two_sides->moveto($file_on_left_side, $new_place);
$new_place = $this->getRightWorkingDirectory() . '/' . basename($file_on_left_side);
$two_sides->moveto($file_on_left_side, $new_place);

$right_side = new Rclone($two_sides->getRightSide());
$check_new_place = $right_side->is_file($new_place);
self::assertTrue($check_new_place->exists, 'File not moved');
if (!$two_sides->isRightSideDirAgnostic()) {
self::assertGreaterThan(0, $check_new_place->details->Size, 'File not moved correctly');
}
$right_side = new Rclone($two_sides->getRightSide());
$check_new_place = $right_side->is_file($new_place);
self::assertTrue($check_new_place->exists, 'File not moved');
if (!$two_sides->isRightSideDirAgnostic()) {
self::assertGreaterThan(0, $check_new_place->details->Size, 'File not moved correctly');
}

return [ $two_sides, $right_side, $new_place ];
return [$two_sides, $right_side, $new_place, $content];
}

/**
* @test
* @depends move_file_to_right_side
*
*/
public function delete_file_on_right_side($params)
: array
* @test
* @depends move_file_to_right_side
*/
public function download_to_local(array $params)
{
/** @var Rclone $two_sides */
/** @var Rclone $right_side */
[ $two_sides, $right_side, $filepath ] = $params;

$file = $right_side->is_file($filepath);
self::assertTrue($file->exists, 'File should exist at this point');
/** @var $right_side Rclone */
[$two_sides, $right_side, $filepath, $content] = $params;

$right_side->delete($filepath);
$downloaded_path = $right_side->download_to_local($filepath);

$file = $right_side->is_file($filepath);
self::assertFileExists($downloaded_path, 'File not downloaded');

self::assertFalse($file->exists, 'This file should not exist anymore');
$local = new Rclone(new LocalProvider('local'));
$local_content = $local->cat($downloaded_path);
self::assertEquals($local_content, $content, 'File content are different');

return [ $two_sides, $right_side ];
return [$two_sides, $downloaded_path, $content];
}

/**
* @test
* @depends move_file_to_right_side
*
*/
public function delete_file_on_right_side($params): array
{
/** @var Rclone $two_sides */
/** @var Rclone $right_side */
[$two_sides, $right_side, $filepath] = $params;

$file = $right_side->is_file($filepath);
self::assertTrue($file->exists, 'File should exist at this point');

$right_side->delete($filepath);

$file = $right_side->is_file($filepath);

self::assertFalse($file->exists, 'This file should not exist anymore');

return [$two_sides, $right_side];
}
}
Loading

0 comments on commit 06fa705

Please sign in to comment.