FireFS icon indicating copy to clipboard operation
FireFS copied to clipboard

FileFS::toInternalPath() prepends working directory to absolute path

Open j-j-banks opened this issue 1 year ago • 4 comments

FireFS::toInternalPath prepends working directory (which is confusingly referred to as $this->rootPath) to absolute path.

Example: Current working directory is /Users/dennis/bin/ FileFS::toIntenralPath('/Users/dennis/Docs') Result: /Users/dennis/bin/Users/dennis/Docs

To circumvent this, I have modified from line 368 as follows: // Prepend the root path if (substr($internalPath, 0, 1) !== DIRECTORY_SEPARATOR) { // Added - Lovelady, 7-Feb-2024 (process was prepending "root path" to absolute path) $rootPath = $this->rootPath(); if (!empty($rootPath)) { $internalPath = $this->makePath($rootPath, $internalPath); } } // Added - Lovelady, 7-Feb-2024 (process was prepending "root path" to absolute path)

But since I don't necessarily understand all the conditions that this routine might be trying to address, I am not certain this is a fix for all conditions. It would be better to have the source fixed in the official distribution. It was very tempting, for example, to test for (substr($internalPath, 0, 1) !== DIRECTORY_SEPARATOR) and return unchanges on true, right at the top of toInternalPath(), which is where I suspect it actually belongs.

j-j-banks avatar Feb 07 '24 13:02 j-j-banks

Hey @j-j-banks

I think there is some misunderstood from your side for the purpose of toInternalPath.

First of all, there is a difference between what you call working directory (which is actually the root path of a FireFS instance), and what FireFS calls a working directory. As FireFS works like a virtual filesystem, it manages its own working directories internally, to make a difference between absolute and relative paths (take a look at the README for example).

When you mount a filesystem instance on a directory, FireFS will consider the absolute path to that directory as the internal root path. Since FireFS works as a virtual filesystem, every absolute path you feed to him will be considered absolute from the virtual filesystem, so they will be prepended with the real filesystem absolute path (which is the absolute path to where you created the FireFS instance, a.k.a the internal root path) for internal usage. That's where the toInternalPath method is useful. It is supposed to convert an external path (a path from the virtual filesystem) to an internal path (a path from the real filesystem).

For this path conversion thing there are 02 other methods:

  • toExternalPath: Takes an internal path as parameter and converts it to an external path (a path from the virtual filesystem). This method take into account the current working directory.
  • toFileSystemPath: Takes an internal path as parameter and converts it to an absolute external path (a path which is absolute from the virtual filesystem).

Maybe the terms used here are misleading, but this is how to think:

  • internal is what FireFS use internally to work properly.
  • external is what is exposed to the user, and also feed by the user to FireFS (every path you specify is then considered external)

Now coming back to your issue, I don't know the use case which leads you to the usage of that method, but if it's really needed, you should tell FireFS how to reach your directory using an external path, by taking your example (with current working directory /Users/dennis/bin/), to access the directory /Users/dennis/Docs, you should do:

FileFS::toIntenralPath('../Docs');
// Result: /Users/dennis/Docs

na2axl avatar Feb 07 '24 23:02 na2axl

Thank you so much for the quick reply; I really appreciate it.

In this case, I had the following code:

$fs = new FireFS();

// Check if the directory to watch exists define('WATCH_FOLDER', '/home/dennis/watchme') ; if (!$fs->exists(WATCH_FOLDER)) { // If not, create the directory $fs->mkdir(WATCH_FOLDER); }

The folder /home/dennis/watchme existed. When I ran this code, the process failed with error: Cannot create directory.

So in debug mode, I traced the process, and found that although I was passing an absolute path (starting with a directory separator) the value I passed was altered by prepending the current path. Here's a video showing the problem clearly and step-by-step: https://youtu.be/pAV30NxXWpQ

What I think you're telling me, is that this does not support truly absolute paths in the same manner as the rest of the world does. That would be a sad shame. For example, if my interpretation is correct, and if I want to watch /home/dennis/a and /usr/local/b, then there's no way to do that within one script, lther than cd / before beginning.

j-j-banks avatar Feb 08 '24 04:02 j-j-banks

Hey @j-j-banks,

With your example I have now an idea of what you want. Have you tried to use toExternalPath first ?

$fs = new FireFS();

// Check if the directory to watch exists
define('WATCH_FOLDER', $fs->toExternalPath('/home/dennis/watchme'));
if (!$fs->exists(WATCH_FOLDER)) {
// If not, create the directory
$fs->mkdir(WATCH_FOLDER);
}

This should be able to transform that path to a relative path from the one you created the filesystem (I'm not sure, it's been a while I didn't worked on this 😅)

If that method doesn't work I should need to fix it, since it's built for that purpose.

na2axl avatar Feb 09 '24 11:02 na2axl

Sounds perfect. I will check when I return home tomorrow or Monday! Thank you!

j-j-banks avatar Feb 10 '24 17:02 j-j-banks