diff --git a/src/Rclone.php b/src/Rclone.php index 2c6820a..e4b1439 100644 --- a/src/Rclone.php +++ b/src/Rclone.php @@ -1272,6 +1272,41 @@ public function md5sum(?string $path = null, array $flags = []): array return $checksums; } + /** + * Gets checksums for files using the specified hash algorithm (rclone hashsum). + * + * @see https://rclone.org/commands/rclone_hashsum/ + * + * @param string $hashAlgorithm The hash algorithm to use (e.g., 'md5', 'sha1', 'dropbox'). + * @param string|null $path Path to checksum. + * @param array $flags Additional flags. + * + * @return array Associative array of [path => hash]. + */ + public function hashsum(string $hashAlgorithm, ?string $path = null, array $flags = []): array + { + $result = $this->simpleRun('hashsum', [$hashAlgorithm, $this->left_side->backend($path)], $flags); + + if ($result === '') { + return []; + } + + $checksums = []; + foreach (explode("\n", $result) as $line) { + $line = trim($line); + if ($line === '') { + continue; + } + // Format: "hash filename" (two spaces between) + // Note: Hash length varies by algorithm, so we use + instead of fixed length + if (preg_match('/^([a-fA-F0-9]+)\s+(.+)$/', $line, $matches)) { + $checksums[$matches[2]] = $matches[1]; + } + } + + return $checksums; + } + /** * Gets SHA1 checksums for files (rclone sha1sum). * diff --git a/tests/Unit/ExtraCommandsTest.php b/tests/Unit/ExtraCommandsTest.php index 5d9437f..b1869ab 100644 --- a/tests/Unit/ExtraCommandsTest.php +++ b/tests/Unit/ExtraCommandsTest.php @@ -277,4 +277,28 @@ public function test_copyto_command(Rclone $rclone): void // Source should still exist (copy, not move) self::assertFileExists($sourceFile); } + + #[Test] + #[Depends('instantiate_with_one_provider')] + public function test_hashsum_command(Rclone $rclone): void + { + $dir = $this->working_directory . '/hashsum_test'; + if (!is_dir($dir)) { + mkdir($dir, 0777, true); + } + file_put_contents($dir . '/file1.txt', 'hello world'); + + // Test with MD5 + $checksums = $rclone->hashsum('md5', $dir); + + self::assertIsArray($checksums); + self::assertArrayHasKey('file1.txt', $checksums); + // md5('hello world') = 5eb63bbbe01eeed093cb22bb8f5acdc3 + self::assertEquals('5eb63bbbe01eeed093cb22bb8f5acdc3', $checksums['file1.txt']); + + // Test with SHA1 + $checksums = $rclone->hashsum('sha1', $dir); + // sha1('hello world') = 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed + self::assertEquals('2aae6c35c94fcfb415dbe95f408b9ce91ee846ed', $checksums['file1.txt']); + } }