Skip to content

Commit

Permalink
Preserve the files permissions (#753)
Browse files Browse the repository at this point in the history
Closes #463
  • Loading branch information
theofidry authored Nov 12, 2022
1 parent d2781db commit 8de23f9
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 12 deletions.
3 changes: 3 additions & 0 deletions fixtures/set002/original/executable-file.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

declare(strict_types=1);
3 changes: 3 additions & 0 deletions fixtures/set002/scoped/executable-file.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

declare (strict_types=1);
30 changes: 25 additions & 5 deletions src/Console/ConsoleScoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use function Humbug\PhpScoper\get_common_path;
use function preg_match as native_preg_match;
use function Safe\file_get_contents;
use function Safe\fileperms;
use function sprintf;
use function str_replace;
use function strlen;
Expand Down Expand Up @@ -99,7 +100,7 @@ private function scopeFiles(
// Creates output directory if does not already exist
$this->fileSystem->mkdir($outputDir);

[$files, $whitelistedFiles] = self::getFiles($config, $outputDir);
[$files, $excludedFilesWithContents] = self::getFiles($config, $outputDir);

$logger->outputFileCount(count($files));

Expand All @@ -121,14 +122,14 @@ private function scopeFiles(
);
}

foreach ($whitelistedFiles as [$inputFilePath, $inputContents, $outputFilePath]) {
$this->fileSystem->dumpFile($outputFilePath, $inputContents);
foreach ($excludedFilesWithContents as $excludedFileWithContent) {
$this->dumpFileWithPermissions(...$excludedFileWithContent);
}

$vendorDir = self::findVendorDir(
[
...array_column($files, 2),
...array_column($whitelistedFiles, 2),
...array_column($excludedFilesWithContents, 2),
],
);

Expand All @@ -142,6 +143,21 @@ private function scopeFiles(
}
}

private function dumpFileWithPermissions(
string $inputFilePath,
string $inputContents,
string $outputFilePath
): void {
$this->fileSystem->dumpFile($outputFilePath, $inputContents);

$originalFilePermissions = fileperms($inputFilePath) & 0o777;

if ($originalFilePermissions !== 420) {
// Only change the permissions if necessary
$this->fileSystem->chmod($outputFilePath, $originalFilePermissions);
}
}

/**
* @return array{array<array{string, string, string}>, array<array{string, string, string}>}
*/
Expand Down Expand Up @@ -228,7 +244,11 @@ private function scopeFile(
$scoppedContent = file_get_contents($inputFilePath);
}

$this->fileSystem->dumpFile($outputFilePath, $scoppedContent);
$this->dumpFileWithPermissions(
$inputFilePath,
$scoppedContent,
$outputFilePath,
);

if (!isset($exception)) {
$logger->outputSuccess($inputFilePath);
Expand Down
16 changes: 9 additions & 7 deletions tests/Console/Command/AddPrefixCommandIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use function iterator_to_array;
use function Safe\file_get_contents;
use function Safe\file_put_contents;
use function Safe\fileperms;
use function Safe\preg_replace;
use function Safe\realpath;
use function sprintf;
Expand All @@ -36,7 +37,6 @@
* @coversNothing
*
* @group integration
* @runTestsInSeparateProcesses
*
* @internal
*/
Expand Down Expand Up @@ -135,10 +135,10 @@ public function test_scope_in_normal_mode(): void
PhpScoper version TestVersion 28/01/2020
0/4 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
4/4 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
0/5 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
5/5 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
[OK] Successfully prefixed 4 files.
[OK] Successfully prefixed 5 files.
// Memory usage: 5.00MB (peak: 10.00MB), time: 0.00s

Expand Down Expand Up @@ -196,12 +196,13 @@ public function test_scope_in_verbose_mode(): void
PhpScoper version TestVersion 28/01/2020
* [NO] /path/to/composer/installed.json
* [OK] /path/to/executable-file.php
* [OK] /path/to/file.php
* [NO] /path/to/invalid-file.php
* [OK] /path/to/scoper.inc.php
[OK] Successfully prefixed 4 files.
[OK] Successfully prefixed 5 files.
// Memory usage: 5.00MB (peak: 10.00MB), time: 0.00s

Expand Down Expand Up @@ -257,6 +258,7 @@ public function test_scope_in_very_verbose_mode(): void
#7
#8
#9
* [OK] /path/to/executable-file.php
* [OK] /path/to/file.php
* [NO] /path/to/invalid-file.php
Could not parse the file "/path/to/invalid-file.php".: PhpParser
Expand All @@ -274,7 +276,7 @@ public function test_scope_in_very_verbose_mode(): void
* [OK] /path/to/scoper.inc.php
[OK] Successfully prefixed 4 files.
[OK] Successfully prefixed 5 files.
// Memory usage: 5.00MB (peak: 10.00MB), time: 0.00s

Expand Down Expand Up @@ -351,7 +353,7 @@ static function (array $collectedFiles, SplFileInfo $file) use ($dir): array {

$path = str_replace($dir, '', $realPath);

$collectedFiles[$path] = file_get_contents($realPath);
$collectedFiles[$path] = [file_get_contents($realPath), fileperms($realPath)];

return $collectedFiles;
},
Expand Down
41 changes: 41 additions & 0 deletions tests/Console/Command/AddPrefixCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,21 @@ public function test_scope_the_given_paths(): void

$expectedFiles = [
'composer/installed.json' => 'f1',
'executable-file.php' => 'f5',
'file.php' => 'f2',
'invalid-file.php' => 'f3',
'scoper.inc.php' => 'f4',
];

$root = realpath($root);

$this->fileSystemProphecy
->chmod(
$this->tmp.'/executable-file.php',
493,
)
->shouldBeCalled();

foreach ($expectedFiles as $expectedFile => $prefixedContents) {
$inputPath = escape_path($root.'/'.$expectedFile);
$outputPath = escape_path($this->tmp.'/'.$expectedFile);
Expand Down Expand Up @@ -159,13 +167,21 @@ public function test_let_the_file_unchanged_when_cannot_scope_a_file(): void

$expectedFiles = [
'composer/installed.json' => 'f1',
'executable-file.php' => 'f5',
'file.php' => 'f2',
'invalid-file.php' => 'f3',
'scoper.inc.php' => null,
];

$root = realpath($root);

$this->fileSystemProphecy
->chmod(
$this->tmp.'/executable-file.php',
493,
)
->shouldBeCalled();

foreach ($expectedFiles as $expectedFile => $prefixedContents) {
$inputPath = escape_path($root.'/'.$expectedFile);
$outputPath = escape_path($this->tmp.'/'.$expectedFile);
Expand Down Expand Up @@ -315,13 +331,21 @@ public function test_scope_the_current_working_directory_if_no_path_given(): voi

$expectedFiles = [
'composer/installed.json' => 'f1',
'executable-file.php' => 'f5',
'file.php' => 'f2',
'invalid-file.php' => 'f3',
'scoper.inc.php' => 'f4',
];

$root = realpath($root);

$this->fileSystemProphecy
->chmod(
$this->tmp.'/executable-file.php',
493,
)
->shouldBeCalled();

foreach ($expectedFiles as $expectedFile => $prefixedContents) {
$inputPath = escape_path($root.'/'.$expectedFile);
$outputPath = escape_path($this->tmp.'/'.$expectedFile);
Expand Down Expand Up @@ -365,13 +389,21 @@ public function test_an_output_directory_can_be_given(): void

$expectedFiles = [
'composer/installed.json' => 'f1',
'executable-file.php' => 'f5',
'file.php' => 'f2',
'invalid-file.php' => 'f3',
'scoper.inc.php' => 'f4',
];

$root = realpath($root);

$this->fileSystemProphecy
->chmod(
$outDir.'/executable-file.php',
493,
)
->shouldBeCalled();

foreach ($expectedFiles as $expectedFile => $prefixedContents) {
$inputPath = escape_path($root.'/'.$expectedFile);
$outputPath = escape_path($outDir.'/'.$expectedFile);
Expand Down Expand Up @@ -416,13 +448,21 @@ public function test_relative_output_directory_are_made_absolute(): void

$expectedFiles = [
'composer/installed.json' => 'f1',
'executable-file.php' => 'f5',
'file.php' => 'f2',
'invalid-file.php' => 'f3',
'scoper.inc.php' => 'f4',
];

$root = realpath($root);

$this->fileSystemProphecy
->chmod(
$this->tmp.DIRECTORY_SEPARATOR.$outDir.'/executable-file.php',
493,
)
->shouldBeCalled();

foreach ($expectedFiles as $expectedFile => $prefixedContents) {
$inputPath = escape_path($root.'/'.$expectedFile);
$outputPath = escape_path($this->tmp.DIRECTORY_SEPARATOR.$outDir.'/'.$expectedFile);
Expand Down Expand Up @@ -526,6 +566,7 @@ public function test_can_scope_projects_with_invalid_files(): void
$this->fileSystemProphecy->mkdir($this->tmp)->shouldBeCalled();
$this->fileSystemProphecy->exists(Argument::cetera())->willReturn(false);
$this->fileSystemProphecy->remove(Argument::cetera())->shouldNotBeCalled();
$this->fileSystemProphecy->chmod(Argument::cetera())->shouldNotBeCalled();

$expectedFiles = [
'invalid-json.json' => 'f1',
Expand Down

0 comments on commit 8de23f9

Please sign in to comment.