Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always treat stream wrappers as absolute paths #18

Merged
merged 9 commits into from
Feb 5, 2025

Conversation

BrianHenryIE
Copy link
Contributor

@BrianHenryIE BrianHenryIE commented Feb 1, 2025

I'm trying to add a --dry-run mode to BrianHenryIE/strauss. To achieve this I've written a FlySystem ReadOnlyFilesytem class which uses a couple of in-memory filesystems to emulate the process without ever writing to the true filesystem.

Obviously, I can't pass a Flysystem instance to third party libraries, such as this.

elazar/flystream to the rescue! Which allows registering myscheme:// to then use your Flysystem of choice during normal file_get_contents('myscheme://path/to/file.php') operations.

Currently, composer/class-map-generator does some operations, e.g. ::isAbsolutePath(), that mis-characterise myscheme://....

This PR adds a ::isStreamWrapper() function which is used in the ClassMapGenerator::scanPaths() function to enable using stream wrappers.

The test creates a stream wrapper that reads e.g. test://BackslashLineEndingString.php from file://path/to/class-map-generator/tests/Fixtures/BackslashLineEndingString.php.

}
}
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use tabs in files that use spaces for indentation..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I’ll open another PR with .php-cs-fixer.php copied from the main project

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or set your editor to autodetect what's in the file then you never have such issues.

@@ -142,18 +142,20 @@ public function scanPaths($path, ?string $excluded = null, string $autoloadType
continue;
}

if (!self::isAbsolutePath($filePath)) {
if (!self::isAbsolutePath($filePath) && !self::isStreamWrapper($filePath)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be done by checking for || Preg::isMatch('{^[a-z0-9]+://}', $path) in isAbsolutePath, then we don't need to iterate all stream wrappers for every single file, because that seems kinda wasteful..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, it’s certainly not efficient how I’ve written it, but it does at least confirm that it’s a valid streamwrapper.

I was considering putting a static variable inside the function, but I know that’s a nightmare made for testing. I could put a regular instance variable array map of path:bool. Or maybe add ~implode(‘|’, stream_get_wrappers()) into that regex, and move the definition out of the loop.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that sounds better for sure

Comment on lines 148 to 149
} elseif(!self::isStreamWrapper($filePath)) {
$filePath = Preg::replace('{[\\\\/]{2,}}', '/', $filePath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} elseif(!self::isStreamWrapper($filePath)) {
$filePath = Preg::replace('{[\\\\/]{2,}}', '/', $filePath);
} else {
$filePath = Preg::replace('{(?<!:)[\\\\/]{2,}}', '/', $filePath);

This should prevent foo:// from being replaced

Comment on lines 156 to 158
$realPath = !self::isStreamWrapper($filePath)
? realpath($filePath)
: $filePath;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one I'm not sure what to do about.. Is $file->getRealPath() also returning false for stream wrapper paths?

Anyway we could also do a check like I suggested above (Preg::isMatch('{^[a-z0-9]+://}', $filePath)) if needed..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BrianHenryIE BrianHenryIE requested a review from Seldaek February 5, 2025 08:01
@Seldaek
Copy link
Member

Seldaek commented Feb 5, 2025

Thanks, I think that looks fine now :)

@Seldaek Seldaek merged commit ffe442c into composer:main Feb 5, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants