doctum: PHAR fails when relative cache || build path is used
With 5.2.1, the phar version fails to create directories within cache or build path, when relative cache/build paths are used in config. Here is an example run:
ptomulik@barakus:$ php bin/doctum.phar update --force -vvv docs/doctum-relative.conf.php
Updating project
Version main
-------------
In Filesystem.php line 105:
[Symfony\Component\Filesystem\Exception\IOException]
Failed to create "docs/cache/html": mkdir(): File exists
Exception trace:
at phar:///tmp/test/bin/doctum.phar/vendor/symfony/filesystem/Filesystem.php:105
Symfony\Component\Filesystem\Filesystem->mkdir() at phar:///tmp/test/bin/doctum.phar/src/Project.php:380
Doctum\Project->flushDir() at phar:///tmp/test/bin/doctum.phar/src/Project.php:431
Doctum\Project->prepareDir() at phar:///tmp/test/bin/doctum.phar/src/Project.php:374
Doctum\Project->getCacheDir() at phar:///tmp/test/bin/doctum.phar/src/Store/JsonStore.php:76
Doctum\Store\JsonStore->getStoreDir() at phar:///tmp/test/bin/doctum.phar/src/Store/JsonStore.php:64
Doctum\Store\JsonStore->flushProject() at phar:///tmp/test/bin/doctum.phar/src/Project.php:464
Doctum\Project->parseVersion() at phar:///tmp/test/bin/doctum.phar/src/Project.php:125
Doctum\Project->update() at phar:///tmp/test/bin/doctum.phar/src/Console/Command/Command.php:183
Doctum\Console\Command\Command->update() at phar:///tmp/test/bin/doctum.phar/src/Console/Command/UpdateCommand.php:54
Doctum\Console\Command\UpdateCommand->execute() at phar:///tmp/test/bin/doctum.phar/vendor/symfony/console/Command/Command.php:255
Symfony\Component\Console\Command\Command->run() at phar:///tmp/test/bin/doctum.phar/vendor/symfony/console/Application.php:1009
Symfony\Component\Console\Application->doRunCommand() at phar:///tmp/test/bin/doctum.phar/vendor/symfony/console/Application.php:273
Symfony\Component\Console\Application->doRun() at phar:///tmp/test/bin/doctum.phar/vendor/symfony/console/Application.php:149
Symfony\Component\Console\Application->run() at phar:///tmp/test/bin/doctum.phar/bin/doctum-binary.php:26
include() at /tmp/test/bin/doctum.phar:9
update [--only-version ONLY-VERSION] [--force] [--output-format OUTPUT-FORMAT] [--no-progress] [--ignore-parse-errors] [--] <config>
The problem does not appear with non-phar version. Absolute paths work well.
I attach an archive containing a minimal example. The issue looks very strange and may be related to Symfony\Filesystem.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 25 (25 by maintainers)
Commits related to this issue
- fix: #18 - warn if the Phar class is not loaded — committed to code-lts/doctum by williamdes 4 years ago
- attempt fixing #18 — committed to ptomulik/doctum by ptomulik 4 years ago
- Fix #18 - Phar relative paths — committed to ptomulik/doctum by ptomulik 4 years ago
- Merge #22 - Fix #18 Make releative paths work using phars — committed to code-lts/doctum by williamdes 4 years ago
I released the
5.3.1-devpharYes, this is related. Seems that #22 does the job finally. If
interceptFileFuncs()is called, the file functions look for relative files withinphar://filesystem (but we want it to work on real filesystem). The default stub, doctum used previosuly, calledinterceptFileFuncs()internally as stated in docs for createDefaultStub. Now, after removing the line withinterceptFileFuncs()everything seems to work as expected.I still can’t wrap my head around how did I came to completelly opposite conclusions previously (mean, that
interceptFileFuncs()should be presend, while it appears, it should be actually absent).Seems I messed up things. It’s something about
Phar::interceptFileFuncs()but I wonder why, during my previous experiments I found I need it foris_dir()to work. Now it looks completely opposite -is_dir()doesn’t work with relative paths wheninterceptFileFuncs()is present.Downloaded sami.phar and it works well with relative paths.
The issue is related to how certain filesystem-related functions work in phars, in this case
is_dir()does not work as we expect. TheinterceptFileFuncs()should do the job, but it looks like it didn’t. Maybe we should take a closer look, how and where it should be placed.Looks like it’s related to interceptFileFuncs().
If I addEDIT: looks it’s completely opposite (we need to remove all occurrences ofPhar::interceptFileFuncs()at the beginning of mybin/test.php, then it works as expected (checking for files in real filesystem).interceptFileFuncs()).Another solution, I found, was to use box to create PHAR. Sami seemed to use box. For my
bin/test.phpI’ve used the followingbox.jsonconfiguration for boxand just executed
box compile. I guess,boxprepends thePhar::interceptFileFuncs()call by default.I investigated it further, with the following script (call it
bin/test.php)First ran it normally providing relative name of an existing directory:
then made a phar out of
bin/test.phpusing your phar-generator-script.sh (with slight modification to usebin/test.phpinstead ofbin/doctum.php). Running the phar version results withIt looks, like
file_exists()&is_dir()do not work well with relative paths from phar.Some additional details:
The same happens with php 7.3.
The issue looks quite strange to me. The exception appears to be thrown from within symfony, from mkdir() function (not sure, this is exactly same version of symfony/filesystem you use to create phar). The check in line 92 should prevent the “File exists” exception, except there exists a file with the same name as
$dir(and it’s not a directory).No.
The config within the minimal example is the following