Skip to content

Commit

Permalink
Support environment variable for patch output path
Browse files Browse the repository at this point in the history
  • Loading branch information
siemova committed Aug 17, 2023
1 parent b4cbe14 commit 6653769
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 15 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,22 @@ Only `*.php` file is loaded, not the `*.php.old` one. This way you can **be sure
vendor/bin/vendor-patches generate
```

This tool will generate **patch files for all files created this** way in `/patches` directory:
This tool will generate **patch files for all vendor files modified this way**.

By default, they will be created in the `patches` subdirectory of your repository,
but you can override this using the environment variable `VENDOR_PATCHES_OUTPUT_PATH`.
If its value is an absolute path, it must describe a path within the repository.
If a relative path, it will be relative to the repository root.

```bash
/patches/nette-di-di-extensions-injectextension.php.patch
patches/nette-di-di-extensions-injectextension.php.patch
```

The patch path is based on original file path, so **the patch name is always unique**.
Each patch file name is based on the original file path, so **it is always unique**.

<br>

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

```json
{
Expand Down
5 changes: 3 additions & 2 deletions src/Command/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Symplify\VendorPatches\Composer\ComposerPatchesConfigurationUpdater;
use Symplify\VendorPatches\Console\GenerateCommandReporter;
use Symplify\VendorPatches\Differ\PatchDiffer;
use Symplify\VendorPatches\FileSystem\PathResolver;
use Symplify\VendorPatches\Finder\OldToNewFilesFinder;
use Symplify\VendorPatches\PatchFileFactory;
use Symplify\VendorPatches\VendorDirProvider;
Expand Down Expand Up @@ -77,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

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

private function resolveProjectVendorDirectory(): string
{
$projectVendorDirectory = getcwd() . '/vendor';
$projectVendorDirectory = PathResolver::getProjectRootPath() . 'vendor';
if (file_exists($projectVendorDirectory)) {
return $projectVendorDirectory;
}
Expand Down
10 changes: 10 additions & 0 deletions src/FileSystem/PathResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ final class PathResolver
*/
private const VENDOR_PACKAGE_DIRECTORY_REGEX = '#^(?<vendor_package_directory>.*?vendor\/(\w|\.|\-)+\/(\w|\.|\-)+)\/#si';

public static function getAbsoluteRootPath(): string
{
return getenv('SystemDrive', true) . DIRECTORY_SEPARATOR;
}

public static function getProjectRootPath(): string
{
return getcwd() . DIRECTORY_SEPARATOR;
}

public static function resolveVendorDirectory(string $filePath): string
{
$match = Strings::match($filePath, self::VENDOR_PACKAGE_DIRECTORY_REGEX);
Expand Down
24 changes: 23 additions & 1 deletion src/PatchFileFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
*/
final class PatchFileFactory
{
public const DEFAULT_OUTPUT_PATH = 'patches';

public const OUTPUT_PATH_ENV_VAR = 'VENDOR_PATCHES_OUTPUT_PATH';

public function createPatchFilePath(OldAndNewFile $oldAndNewFile, string $vendorDirectory): string
{
$inVendorRelativeFilePath = PathResolver::getRelativeFilePathFromDirectory(
Expand All @@ -23,6 +27,24 @@ public function createPatchFilePath(OldAndNewFile $oldAndNewFile, string $vendor
$relativeFilePathWithoutSuffix = Strings::lower($inVendorRelativeFilePath);
$pathFileName = Strings::webalize($relativeFilePathWithoutSuffix) . '.patch';

return 'patches' . DIRECTORY_SEPARATOR . $pathFileName;
return $this->getOutputPathRelativeToProjectRoot() . DIRECTORY_SEPARATOR . $pathFileName;
}

private function getOutputPathRelativeToProjectRoot(): string
{
$outputPath = getenv(self::OUTPUT_PATH_ENV_VAR);

if ($outputPath) {
if (!str_starts_with($outputPath, PathResolver::getAbsoluteRootPath())) {
return $outputPath;
}

$projectRootPath = PathResolver::getProjectRootPath();
if (str_starts_with($outputPath, $projectRootPath)) {
return PathResolver::getRelativeFilePathFromDirectory($outputPath, $projectRootPath);
}
}

return self::DEFAULT_OUTPUT_PATH;
}
}
7 changes: 4 additions & 3 deletions src/VendorDirProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@

use Composer\Autoload\ClassLoader;
use ReflectionClass;
use Symplify\VendorPatches\FileSystem\PathResolver;
use Webmozart\Assert\Assert;

final class VendorDirProvider
{
public static function provide(): string
{
$rootFolder = getenv('SystemDrive', true) . DIRECTORY_SEPARATOR;
$absoluteRootPath = PathResolver::getAbsoluteRootPath();

$path = __DIR__;
while (! \str_ends_with($path, 'vendor') && $path !== $rootFolder) {
while (! \str_ends_with($path, 'vendor') && $path !== $absoluteRootPath) {
$path = dirname($path);
}

if ($path !== $rootFolder) {
if ($path !== $absoluteRootPath) {
return $path;
}

Expand Down
50 changes: 45 additions & 5 deletions tests/PatchFileFactory/PatchFileFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,57 @@

final class PatchFileFactoryTest extends AbstractTestCase
{
public function test(): void
private const FIXTURE_PATH = __DIR__ . DIRECTORY_SEPARATOR . 'Fixture';

private const NESTED_OUTPUT_PATH = 'path' . DIRECTORY_SEPARATOR . 'to' . DIRECTORY_SEPARATOR . 'patches';

public function testDefaultOutputPath(): void
{
$patchFilePath = $this->makePatchFilePath();
$expectedPath = PatchFileFactory::DEFAULT_OUTPUT_PATH . DIRECTORY_SEPARATOR . 'some-new-file-php.patch';

$this->assertSame($expectedPath, $patchFilePath);
}

public function testRelativeEnvironmentOutputPath(): void
{
$relativeOutputPath = self::NESTED_OUTPUT_PATH;
$patchFilePath = $this->makePatchFilePathWithEnvironmentOutputPath($relativeOutputPath);
$expectedPath = self::NESTED_OUTPUT_PATH . DIRECTORY_SEPARATOR . 'some-new-file-php.patch';

$this->assertSame($expectedPath, $patchFilePath);
}

public function testAbsoluteEnvironmentOutputPath(): void
{
$absoluteOutputPath = dirname(__FILE__, 3) . DIRECTORY_SEPARATOR . self::NESTED_OUTPUT_PATH;
$patchFilePath = $this->makePatchFilePathWithEnvironmentOutputPath($absoluteOutputPath);
$expectedPath = self::NESTED_OUTPUT_PATH . DIRECTORY_SEPARATOR . 'some-new-file-php.patch';

$this->assertSame($expectedPath, $patchFilePath);
}

private function makePatchFilePath(): string
{
$patchFileFactory = $this->make(PatchFileFactory::class);

$oldAndNewFile = new OldAndNewFile(
__DIR__ . '/Fixture/some_old_file.php',
__DIR__ . '/Fixture/some_new_file.php',
self::FIXTURE_PATH . DIRECTORY_SEPARATOR . 'some_old_file.php',
self::FIXTURE_PATH . DIRECTORY_SEPARATOR . 'some_new_file.php',
'package/name'
);

$pathFilePath = $patchFileFactory->createPatchFilePath($oldAndNewFile, __DIR__ . '/Fixture');
$this->assertSame('patches/some-new-file-php.patch', $pathFilePath);
return $patchFileFactory->createPatchFilePath($oldAndNewFile, self::FIXTURE_PATH);
}

private function makePatchFilePathWithEnvironmentOutputPath(string $environmentOutputPath): string
{
putenv(PatchFileFactory::OUTPUT_PATH_ENV_VAR . '=' . $environmentOutputPath);

$patchFilePath = $this->makePatchFilePath();

putenv(PatchFileFactory::OUTPUT_PATH_ENV_VAR); // Unset

return $patchFilePath;
}
}

0 comments on commit 6653769

Please sign in to comment.