Retrieve/refresh mapping local file paths incorrectly

Issue #742 resolved
Scott Wells repo owner created an issue

I've seen this with a few folks now and it's time to get the root cause identified and resolved. Basically in some rare instances (and so far always on Windows), when retrieve/refresh is matching the retrieved metadata files to the local source files, it builds a bizarre hybrid absolute/relative path that's just incorrect, e.g.:

C:\Users\username\projects\projectName\..\..\..\..\..\..\path\to\temp\dir\classes\ClassName.cls

The number of ..s is always higher than the number of preceding path components leading to a broken path.

I have a user in this state now who is going to help produce debug logs that should yield all the info needed to resolve this. I'm using this ticket both to track the issue and to attach test builds while we triage the issue.

Comments (8)

  1. Scott Wells reporter

    Okay, here's a test build with significantly more debug logging around how retrieved files are matched to local files (which is where this odd path is being produced). Please install it using Settings>Plugins>Install plugin from disk, then reproduce the issue with the following in Help>Debug Log Settings:

    #com.illuminatedcloud.intellij.builder.ForceComMetadataRetriever
    

    Once that's done, send the latest idea.log and hopefully it'll contain the smoking gun for this issue.

  2. Scott Wells reporter

    And that last build addressed the issue. So the true nature of this issue was very surprising. Ever since Windows 95 (yes...22 years ago!), entries in the Windows filesystem have had two names, a short name that's 8.3 and a long name that's...well...the real name. For example, C:\Program Files is also C:\PROGRA~1. This bug occurs when a component in one of the paths on Windows ends up also having an 8.3 counterpart that's different than the component's actual name, then IC tries to create a relative path from it using another path that uses the actual name. For example, consider the following:

    File rootDir = new File("C:\\Users\\VeryLong Username\\Projects\\projectName");
    File sourceFile = new File("C:\\Users\\VeryLong Username\\Projects\\projectName\\src\\classes\\ClassName.cls");
    String relativePath = FileUtil.getRelativePath(rootDir, sourceFile, "/");
    

    That should return the string /src/classes/ClassName.cls, but in certain situations on Windows, the value for rootDir.getAbsolutePath() might return C:\\Users\\VERYLO~1\\Projects\\projectName. When that occurs, `FileUtil.getRelativePath() doesn't work very well because there's not really much overlap between the two paths at a glance. The fix is to canonicalize both paths before extracting the relative path.

    I never would've guessed this one without some detailed debug logs showing the exact issue. MASSIVE thanks to the user who worked with me to figure it out! In the resolution for this issue I'll ensure that all places where IC is computing relative paths against I/O files on Windows takes this possible situation into account.

  3. Log in to comment