ramsey / conventional-commits

:yo_yo: A PHP library for creating and validating commit messages according to the Conventional Commits specification. Includes a CaptainHook plugin!
MIT License
184 stars 21 forks source link

realpath fails when run from within a Phar file #37

Closed hussainweb closed 2 years ago

hussainweb commented 2 years ago

Description

This is related to #25.

The PHP function realpath does not work when trying to resolve relative paths within the Phar file. This is mentioned in the documentation as well.

The function realpath() will not work for a file which is inside a Phar as such path would be a virtual path, not a real one.

There are three places I could find where this function is used. Two of them are in the path of FinderTool::findComposerJson but this is already addressed by changes in #29. The second place is in FinderTool::validateConfig in finding schema.json.

Steps to reproduce

This is reproducible after the changes in #29 and a box configuration file that includes schema.json. When run on a project which contains a configuration file (such as this very package (https://github.com/ramsey/conventional-commits)), the script crashes with an error:

PHP Fatal error:  Uncaught ValueError: Path cannot be empty in phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php:173

This is because realpath returns false and it gets cast to an empty string.

Expected behavior

The script should not crash.

Screenshots or output

Stack trace ``` PHP Fatal error: Uncaught ValueError: Path cannot be empty in phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php:173 Stack trace: #0 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php(173): file_get_contents('') #1 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php(127): Ramsey\ConventionalCommits\Console\Command\BaseCommand->validateConfig(Object(stdClass)) #2 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php(160): Ramsey\ConventionalCommits\Console\Command\BaseCommand->loadConfigFromFile('conventional-co...') #3 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php(84): Ramsey\ConventionalCommits\Console\Command\BaseCommand->loadConfigFromComposer(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #4 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Console/Command/BaseCommand.php(56): Ramsey\ConventionalCommits\Console\Command\BaseCommand->findConfiguration(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput), NULL) #5 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/vendor/symfony/console/Command/Command.php(299): Ramsey\ConventionalCommits\Console\Command\BaseCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #6 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/vendor/symfony/console/Application.php(978): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #7 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/vendor/symfony/console/Application.php(295): Symfony\Component\Console\Application->doRunCommand(Object(Ramsey\ConventionalCommits\Console\Command\PrepareCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #8 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/vendor/symfony/console/Application.php(167): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #9 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/bin/conventional-commits(68): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput)) #10 phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/bin/conventional-commits(69): {closure}(Array) #11 /Users/hw/work/php/conventional-commits/bin/conventional-commits.phar(14): require('phar:///Users/h...') #12 {main} thrown in phar:///Users/hw/work/php/conventional-commits/bin/conventional-commits.phar/src/ConventionalCommits/Configuration/FinderTool.php on line 173 ```

Environment details

hussainweb commented 2 years ago

@ramsey, if you prefer, I can include this fix in #29 as well or another PR. Please let me know which you prefer.

The fix I am planning is to use dirname thrice instead of using realpath. I have already tested it and it reads the schema.json properly.

ramsey commented 2 years ago

Go ahead and include it in #29. Thanks!

hussainweb commented 2 years ago

Thanks, @ramsey. I did that and it now needs your approval to run the workflow.