Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ Create a ZIP archive containing a file from a GitHub repository:
$zipPath = GithubFile::zip('owner/repo', 'path/to/file.txt');
```

The ZIP file will be stored in the default disk's `zips` directory.
The ZIP file will be stored in the default disk's `zips` directory. Or zip multiple files at the same times.

```php
$zipPath = GithubFile::zip('owner/repo', ['path/to/file.txt', 'path/to/file2.txt']);
```

## Testing

Expand Down
2 changes: 1 addition & 1 deletion src/Facades/GithubFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* @method static string get(string $repository, string $filePath, string $branch = 'main')
* @method static string download(string $repository, string $filePath, string $disk = 'local', string $branch = 'main')
* @method static string zip(string $repository, string $filePath, string $disk = 'local', string $branch = 'main')
* @method static string zip(string $repository, string|array $filePath, string $disk = 'local', string $branch = 'main')
*
* @see \VeiligLanceren\GithubFile\Services\GithubFileService
*/
Expand Down
8 changes: 4 additions & 4 deletions src/Interfaces/IGithubFileService.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public function download(string $repository, string $filePath, string $disk = 'l
* Create a ZIP archive containing a file from a GitHub repository.
*
* @param string $repository The GitHub repository in the format 'owner/repo'.
* @param string $filePath The path to the file within the repository.
* @param string $disk The disk where the ZIP file should be stored.
* @param string $branch The branch name. Defaults to 'main'.
* @param string|array $filePaths
* @param string $disk The disk where the ZIP file should be stored.
* @param string $branch The branch name. Defaults to 'main'.
*
* @return string The path where the ZIP file was stored.
*/
public function zip(string $repository, string $filePath, string $disk = 'local', string $branch = 'main'): string;
public function zip(string $repository, string|array $filePaths, string $disk = 'local', string $branch = 'main'): string;
}
38 changes: 21 additions & 17 deletions src/Services/GithubFileService.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,34 +59,38 @@ public function download(
/**
* {@inheritDoc}
*/
public function zip(string $repository, string $filePath, string $disk = 'local', string $branch = 'main'): string
public function zip(string $repository, string|array $filePaths, string $disk = 'local', string $branch = 'main'): string
{
$files = [];
$filename = basename($filePath);
$filePaths = is_array($filePaths) ? $filePaths : [$filePaths];
$allFiles = [];

if (substr($filePath, -1) === '/') {
$filePath = rtrim($filePath, '/');
$url = "https://api.github.com/repos/{$repository}/contents/{$filePath}?ref={$branch}";
foreach ($filePaths as $filePath) {
$cleanPath = rtrim($filePath, '/');
$url = "https://api.github.com/repos/{$repository}/contents/{$cleanPath}?ref={$branch}";
$response = Http::get($url);

if ($response->successful()) {
$filesData = $response->json();
if (! $response->successful()) {
throw new RuntimeException("Failed to fetch file from GitHub: {$url}");
}

$data = $response->json();

foreach ($filesData as $file) {
if ($file['type'] === 'file') {
$fileContent = Http::get($file['download_url'])->body();
$files[] = ['name' => $file['name'], 'content' => $fileContent];
if (array_is_list($data)) {
foreach ($data as $item) {
if ($item['type'] === 'file') {
$fileContent = Http::get($item['download_url'])->body();
$allFiles[] = ['name' => $item['name'], 'content' => $fileContent];
}
}
} else {
throw new RuntimeException("Failed to fetch directory contents from GitHub: {$url}");
$content = base64_decode($data['content'] ?? '');
$allFiles[] = ['name' => basename($filePath), 'content' => $content];
}
} else {
$fileContent = $this->get($repository, $filePath, $branch);
$files[] = ['name' => $filename, 'content' => $fileContent];
}

return $this->fileZipService->createZip($filePath, $files, $disk);
$zipName = 'github-files';

return $this->fileZipService->createZip($zipName, $allFiles, $disk);
}

}
44 changes: 41 additions & 3 deletions tests/Unit/Services/GithubFileServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,49 @@
});

it('creates a zip archive containing the file', function () {
Http::fake([
'https://api.github.com/repos/owner/repo/contents/path/to/file.txt?ref=main' => Http::response([
'content' => base64_encode('file content'),
], 200),
]);

$service = new GithubFileService();
$zipPath = $service->zip('owner/repo', 'path/to/file.txt');
$relativePath = str_replace(Storage::disk('local')->path(''), '', $zipPath);

Storage::disk('local')->assertExists($relativePath);
expect($zipPath)->toBe(Storage::disk('local')->path($relativePath));
});

it('creates a zip archive from multiple GitHub file and folder paths', function () {
Http::fake([
'https://api.github.com/repos/owner/repo/contents/folder?ref=main' => Http::response([
[
'type' => 'file',
'name' => 'file1.txt',
'download_url' => 'https://raw.githubusercontent.com/owner/repo/main/folder/file1.txt',
],
[
'type' => 'file',
'name' => 'file2.txt',
'download_url' => 'https://raw.githubusercontent.com/owner/repo/main/folder/file2.txt',
],
]),

Storage::disk('local')->assertExists('zips/file.txt.zip');
'https://raw.githubusercontent.com/owner/repo/main/folder/file1.txt' => Http::response('content 1', 200),
'https://raw.githubusercontent.com/owner/repo/main/folder/file2.txt' => Http::response('content 2', 200),
'https://api.github.com/repos/owner/repo/contents/README.md?ref=main' => Http::response([
'content' => base64_encode('readme content'),
]),
]);

$service = new GithubFileService();
$zipPath = $service->zip('owner/repo', ['folder/', 'README.md']);

expect($zipPath)->toBe(Storage::disk('local')->path('zips/github-files.zip'));

expect($zipPath)
->toBe(Storage::disk('local')->path('zips/file.txt.zip'));
Storage::disk('local')->assertExists('zips/github-files.zip');
});