private void ManuallyGetChildNames(ContainerCmdletProvider provider, string providerPath, string relativePath, ReturnContainers returnContainers, bool recurse, IncludeExcludeFilter filter, ProviderRuntime runtime) { // Affected by #trailingSeparatorAmbiguity // Sometimes, PS removes or appends a trailing slash to the providerPath // E.g. when the recurse == true, there is a trailing slash, but not when recurse == false. // As it calls the method with the slash being appended and not appended, PS doesn't seem to make // promises to the provider implementation whether or not the path has a trailing slash var childNames = GetValidChildNames(provider, providerPath, returnContainers, runtime); foreach (var childName in childNames) { // add the child only if the filter accepts it if (!filter.Accepts(childName)) { continue; } var path = Path.Combine(provider, relativePath, childName, runtime); runtime.WriteObject(path); } // check if we need to handle this recursively if (!recurse) { return; } // okay, we should use recursion, so get all child containers and call this function again childNames = GetValidChildNames(provider, providerPath, ReturnContainers.ReturnAllContainers, runtime); foreach (var childName in childNames) { var providerChildPath = Path.Combine(provider, providerPath, childName, runtime); if (Item.IsContainer(providerChildPath, runtime)) { // recursive call wirth child's provider path and relative path var relativeChildPath = Path.Combine(provider, relativePath, childName, runtime); ManuallyGetChildNames(provider, providerChildPath, relativeChildPath, returnContainers, true, filter, runtime); } } }
internal void GetNames(string[] path, ReturnContainers returnContainers, bool recurse, ProviderRuntime runtime) { // the include/exclude filters apply to the results, not to the globbing process. Make this sure runtime.IgnoreFiltersForGlobbing = true; // compile here, not in every recursive iteration var filter = new IncludeExcludeFilter(runtime.Include, runtime.Exclude, false); // do the globbing manually, because the behavior depends on it... foreach (var p in path) { CmdletProvider provider; var doGlob = Globber.ShouldGlob(p, runtime); // even if we don't actually glob, the next method will return the resolved path & provider var resolved = Globber.GetGlobbedProviderPaths(p, runtime, out provider); var contProvider = CmdletProvider.As<ContainerCmdletProvider>(provider); foreach (var curPath in resolved) { if (!doGlob && filter.CanBeIgnored && !recurse) { contProvider.GetChildNames(curPath, returnContainers, runtime); continue; } if ((recurse || !doGlob) && Item.IsContainer(contProvider, curPath, runtime)) { ManuallyGetChildNames(contProvider, curPath, "", returnContainers, recurse, filter, runtime); continue; } var cn = Path.ParseChildName(contProvider, curPath, runtime); if (filter.Accepts(cn)) { runtime.WriteObject(cn); } } } }