Skip to content

Commit 6653769

Browse files
committed
Support environment variable for patch output path
1 parent b4cbe14 commit 6653769

File tree

6 files changed

+94
-15
lines changed

6 files changed

+94
-15
lines changed

README.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,22 @@ Only `*.php` file is loaded, not the `*.php.old` one. This way you can **be sure
4242
vendor/bin/vendor-patches generate
4343
```
4444

45-
This tool will generate **patch files for all files created this** way in `/patches` directory:
45+
This tool will generate **patch files for all vendor files modified this way**.
46+
47+
By default, they will be created in the `patches` subdirectory of your repository,
48+
but you can override this using the environment variable `VENDOR_PATCHES_OUTPUT_PATH`.
49+
If its value is an absolute path, it must describe a path within the repository.
50+
If a relative path, it will be relative to the repository root.
4651

4752
```bash
48-
/patches/nette-di-di-extensions-injectextension.php.patch
53+
patches/nette-di-di-extensions-injectextension.php.patch
4954
```
5055

51-
The patch path is based on original file path, so **the patch name is always unique**.
56+
Each patch file name is based on the original file path, so **it is always unique**.
5257

5358
<br>
5459

55-
Also, it will add configuration for `cweagans/composer-patches` to your `composer.json`:
60+
Also, `generate` will add configuration for `cweagans/composer-patches` to your `composer.json`:
5661

5762
```json
5863
{

src/Command/GenerateCommand.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Symplify\VendorPatches\Composer\ComposerPatchesConfigurationUpdater;
1313
use Symplify\VendorPatches\Console\GenerateCommandReporter;
1414
use Symplify\VendorPatches\Differ\PatchDiffer;
15+
use Symplify\VendorPatches\FileSystem\PathResolver;
1516
use Symplify\VendorPatches\Finder\OldToNewFilesFinder;
1617
use Symplify\VendorPatches\PatchFileFactory;
1718
use Symplify\VendorPatches\VendorDirProvider;
@@ -77,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7778

7879
if ($composerExtraPatches !== []) {
7980
$this->composerPatchesConfigurationUpdater->updateComposerJsonAndPrint(
80-
getcwd() . '/composer.json',
81+
PathResolver::getProjectRootPath() . 'composer.json',
8182
$composerExtraPatches
8283
);
8384
}
@@ -94,7 +95,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9495

9596
private function resolveProjectVendorDirectory(): string
9697
{
97-
$projectVendorDirectory = getcwd() . '/vendor';
98+
$projectVendorDirectory = PathResolver::getProjectRootPath() . 'vendor';
9899
if (file_exists($projectVendorDirectory)) {
99100
return $projectVendorDirectory;
100101
}

src/FileSystem/PathResolver.php

+10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ final class PathResolver
1616
*/
1717
private const VENDOR_PACKAGE_DIRECTORY_REGEX = '#^(?<vendor_package_directory>.*?vendor\/(\w|\.|\-)+\/(\w|\.|\-)+)\/#si';
1818

19+
public static function getAbsoluteRootPath(): string
20+
{
21+
return getenv('SystemDrive', true) . DIRECTORY_SEPARATOR;
22+
}
23+
24+
public static function getProjectRootPath(): string
25+
{
26+
return getcwd() . DIRECTORY_SEPARATOR;
27+
}
28+
1929
public static function resolveVendorDirectory(string $filePath): string
2030
{
2131
$match = Strings::match($filePath, self::VENDOR_PACKAGE_DIRECTORY_REGEX);

src/PatchFileFactory.php

+23-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
*/
1414
final class PatchFileFactory
1515
{
16+
public const DEFAULT_OUTPUT_PATH = 'patches';
17+
18+
public const OUTPUT_PATH_ENV_VAR = 'VENDOR_PATCHES_OUTPUT_PATH';
19+
1620
public function createPatchFilePath(OldAndNewFile $oldAndNewFile, string $vendorDirectory): string
1721
{
1822
$inVendorRelativeFilePath = PathResolver::getRelativeFilePathFromDirectory(
@@ -23,6 +27,24 @@ public function createPatchFilePath(OldAndNewFile $oldAndNewFile, string $vendor
2327
$relativeFilePathWithoutSuffix = Strings::lower($inVendorRelativeFilePath);
2428
$pathFileName = Strings::webalize($relativeFilePathWithoutSuffix) . '.patch';
2529

26-
return 'patches' . DIRECTORY_SEPARATOR . $pathFileName;
30+
return $this->getOutputPathRelativeToProjectRoot() . DIRECTORY_SEPARATOR . $pathFileName;
31+
}
32+
33+
private function getOutputPathRelativeToProjectRoot(): string
34+
{
35+
$outputPath = getenv(self::OUTPUT_PATH_ENV_VAR);
36+
37+
if ($outputPath) {
38+
if (!str_starts_with($outputPath, PathResolver::getAbsoluteRootPath())) {
39+
return $outputPath;
40+
}
41+
42+
$projectRootPath = PathResolver::getProjectRootPath();
43+
if (str_starts_with($outputPath, $projectRootPath)) {
44+
return PathResolver::getRelativeFilePathFromDirectory($outputPath, $projectRootPath);
45+
}
46+
}
47+
48+
return self::DEFAULT_OUTPUT_PATH;
2749
}
2850
}

src/VendorDirProvider.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@
66

77
use Composer\Autoload\ClassLoader;
88
use ReflectionClass;
9+
use Symplify\VendorPatches\FileSystem\PathResolver;
910
use Webmozart\Assert\Assert;
1011

1112
final class VendorDirProvider
1213
{
1314
public static function provide(): string
1415
{
15-
$rootFolder = getenv('SystemDrive', true) . DIRECTORY_SEPARATOR;
16+
$absoluteRootPath = PathResolver::getAbsoluteRootPath();
1617

1718
$path = __DIR__;
18-
while (! \str_ends_with($path, 'vendor') && $path !== $rootFolder) {
19+
while (! \str_ends_with($path, 'vendor') && $path !== $absoluteRootPath) {
1920
$path = dirname($path);
2021
}
2122

22-
if ($path !== $rootFolder) {
23+
if ($path !== $absoluteRootPath) {
2324
return $path;
2425
}
2526

tests/PatchFileFactory/PatchFileFactoryTest.php

+45-5
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,57 @@
1010

1111
final class PatchFileFactoryTest extends AbstractTestCase
1212
{
13-
public function test(): void
13+
private const FIXTURE_PATH = __DIR__ . DIRECTORY_SEPARATOR . 'Fixture';
14+
15+
private const NESTED_OUTPUT_PATH = 'path' . DIRECTORY_SEPARATOR . 'to' . DIRECTORY_SEPARATOR . 'patches';
16+
17+
public function testDefaultOutputPath(): void
18+
{
19+
$patchFilePath = $this->makePatchFilePath();
20+
$expectedPath = PatchFileFactory::DEFAULT_OUTPUT_PATH . DIRECTORY_SEPARATOR . 'some-new-file-php.patch';
21+
22+
$this->assertSame($expectedPath, $patchFilePath);
23+
}
24+
25+
public function testRelativeEnvironmentOutputPath(): void
26+
{
27+
$relativeOutputPath = self::NESTED_OUTPUT_PATH;
28+
$patchFilePath = $this->makePatchFilePathWithEnvironmentOutputPath($relativeOutputPath);
29+
$expectedPath = self::NESTED_OUTPUT_PATH . DIRECTORY_SEPARATOR . 'some-new-file-php.patch';
30+
31+
$this->assertSame($expectedPath, $patchFilePath);
32+
}
33+
34+
public function testAbsoluteEnvironmentOutputPath(): void
35+
{
36+
$absoluteOutputPath = dirname(__FILE__, 3) . DIRECTORY_SEPARATOR . self::NESTED_OUTPUT_PATH;
37+
$patchFilePath = $this->makePatchFilePathWithEnvironmentOutputPath($absoluteOutputPath);
38+
$expectedPath = self::NESTED_OUTPUT_PATH . DIRECTORY_SEPARATOR . 'some-new-file-php.patch';
39+
40+
$this->assertSame($expectedPath, $patchFilePath);
41+
}
42+
43+
private function makePatchFilePath(): string
1444
{
1545
$patchFileFactory = $this->make(PatchFileFactory::class);
1646

1747
$oldAndNewFile = new OldAndNewFile(
18-
__DIR__ . '/Fixture/some_old_file.php',
19-
__DIR__ . '/Fixture/some_new_file.php',
48+
self::FIXTURE_PATH . DIRECTORY_SEPARATOR . 'some_old_file.php',
49+
self::FIXTURE_PATH . DIRECTORY_SEPARATOR . 'some_new_file.php',
2050
'package/name'
2151
);
2252

23-
$pathFilePath = $patchFileFactory->createPatchFilePath($oldAndNewFile, __DIR__ . '/Fixture');
24-
$this->assertSame('patches/some-new-file-php.patch', $pathFilePath);
53+
return $patchFileFactory->createPatchFilePath($oldAndNewFile, self::FIXTURE_PATH);
54+
}
55+
56+
private function makePatchFilePathWithEnvironmentOutputPath(string $environmentOutputPath): string
57+
{
58+
putenv(PatchFileFactory::OUTPUT_PATH_ENV_VAR . '=' . $environmentOutputPath);
59+
60+
$patchFilePath = $this->makePatchFilePath();
61+
62+
putenv(PatchFileFactory::OUTPUT_PATH_ENV_VAR); // Unset
63+
64+
return $patchFilePath;
2565
}
2666
}

0 commit comments

Comments
 (0)