GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Enable import-module to be case insensitive by SteveL-MSFT · Pull Request #5097 · PowerShell/PowerShell Conversation
|
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
If it is only for Linux maybe use "#if UNIX"?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
it's technically any filesystem that's case sensitive and technically (although unlikely), it seems you can make NTFS case sensitive. for practical cases, it's probably fine to #ifdef this and if a customer has an issue on Windows, we can revisit
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
fixed and added comment
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
The cyclomatic complexity of this function is pretty high. Can this be refactored into a smaller function?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I could simplify it a bit if we can make the assumption that the psd1 or psm1 file always has the same casing as the folder name. It's not clear to me if that is a safe assumption or not. The current code is conservative in that you could have: "...\Modules\FOO\foo.psd1"
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'll check with the PSGet folks
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
per PSGet, it is safe to assume the folder and file names have the same casing. So I'll simplify this code.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Please redirect to null.
New-Item -ItemType Directory -Path "$modulesPath/$modulePath" -Force > $null
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
will add
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Maybe -Force to ensure you are not loading a cached version.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
will add
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
actually, as part of this test, I'm removing the module with a different casing, so I don't want to -force loading
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ok
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
> $null
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
will add
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
> $null
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
will add
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Aditya Patwardhan (@adityapatwardhan) feedback addressed |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
In line 294 the same cycle? Can we remove it and replace with the new one on all platforms?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
We still need both as the first one will find an exact match and fall through to this if it doesn't find it. Also the above loop also handles a file path to the module which I think should be case sensitive since it's a literal file path. The lower code only handles the module name which we can treat as case insensitive. The code is similar, but I don't think it's worth combining which will make it more complex.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Why we should use different logic for module folder names and module file names?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
If someone uses: Import-module /users/steve/dev/MyModule/MyModule.psd1 then that should be treated as a case-sensitive path. If they use Import-module mymodule, then that's case-insensitive as that's a module name and not a filepath.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ah, I meant folder and file names not paths.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I don't see an easy way to have a single loop between the two without incurring a cost of enumerating the folders for the purpose of case-insensitive comparison in the "normal" case where either the case matches or the filesystem is case-insensitive. If there's two modules "Foo" and "foo", and the user does import-module foo we want the first loop to match foo and not Foo as that is an exact match.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
We have the same problem in #4699 - can you review the idea to use here?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
In the tab completion case, I think you have to cover more cases as ab might match ABc, abc, or aBcdefg, etc... so creating a case-insenstive match pattern makes sense. In this case, we have a specific name (wildcard is not accepted) and just need a case-insensitive match if we haven't already matched the exact casing (which is preferred). And we don't need to return all matches, the first one wins.
If we want just the first match to win even if there is an exact match, it would be easy to merge the two loops. However, I think we want to get an exact match if it exists, then fallback on case-sensitive search. For example, if the user typed ipmo AAA which exists in the last modulepath, but aaa exists in the first, I would have to enumerate all module folder names in every modulepath part every time just to make sure AAA wasn't found after my first case-insensitive match.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
We could have solved this situation on the other hand. Do we want all the modules to be portable? If so, we must document this and exclude the case-sensitivity in this code.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
That's a good point on portable scripts being able to rely on module names being case insensitive. It would make sense to just say module names are case insensitive everywhere and have it enforced by install-module and publish-module.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we could exclude #if here and leave one line.
Or maybe create helper functions - It will be easier to read and understand.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I think this line isn't needed as I have qualifiedPath = folder above, was probably thinking this, but didn't put it together. Will fix.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
d00ab71 to
43e45cf
Compare
There was an error while loading. Please reload this page.
|
Should we add negative tests too (to reflect the situations we have decided to exclude)? What errors should appear (throw)? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Ilya (@iSazonov) test was originally skipped due to the previous code for an exact match since it wasn't possible to create two modules that differ only by casing on Windows. With the new change, no reason not to run it on Windows. I also noticed a bug in the test where I wasn't removing the test module between runs. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I don't see still that tests reflect to "StringComparison.OrdinalIgnoreCase". |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Ilya (@iSazonov) the new test creates a module called TESTMODULE and imports it using testMODULE, this is where the case-insensitive comparison occurs. In the UNIX code path, if it enumerates the module folders in the module path and sees if it matches the name of the given module. Not clear to me if you were expecting a different test? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@SteveL-MSFT My thoughts was that we should do `Import-Module testMODULE` and `Import-Module TESTMODULE` and check that we load the same module. Although I'm not sure it's necessary.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Ilya (@iSazonov) I don't think that's necessary |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
simplify search loops with assumption that module file casing matches module folder name which is appropriate per PSGet
cefbc40 to
fd7dcfb
Compare
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| { | ||
| qualifiedPath = Path.Combine(qualifiedPath, fileBaseName); | ||
| } | ||
| else if (Directory.Exists(qualifiedPath)) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Please use Utils.NativeDirectoryExists()
https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/Utils.cs#L912
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Will change
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| if (!found) | ||
| #if UNIX | ||
| foreach (string folder in Directory.EnumerateDirectories(path)) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Please use Utils.NativeEnumerateDirectory()
https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/Utils.cs#L926
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Will change
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This method appears to be only implemented for Win32. Since this path is only for UNIX, I'll leave it as-is.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
ok
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ok
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Fix PowerShell#1621 Enable import-module to be case insensitive as macOS is case insensitive.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.