示例#1
0
        private bool AddModuleIfNotExists(IRootPackage parent, string moduleDir, bool showMissingDevOptionalSubPackages, int depth, int maxDepth, IDependency dependency = null)
        {
            depth++;

            this.allModules.TryGetValue(moduleDir, out var moduleInfo);

            if (moduleInfo != null)
            {
                // Update module information if the module already exists.
                if (moduleInfo.Depth > depth)
                {
                    moduleInfo.Depth = depth;
                }

                if (dependency != null)
                {
                    var existingPackage = this[dependency.Name] as Package;
                    if (existingPackage != null)
                    {
                        existingPackage.RequestedVersionRange = dependency.VersionRangeText;
                    }
                }
            }
            else if (Directory.Exists(moduleDir) || depth == 1)
            {
                // Top-level modules are always added so we can include missing modules.
                moduleInfo = new ModuleInfo(depth);
                this.allModules.Add(moduleDir, moduleInfo);
            }
            else
            {
                // The module directory wasn't found.
                return(false);
            }

            IPackage package = moduleInfo.Package;

            if (package == null || depth == 1 || !moduleInfo.RequiredBy.Contains(parent.Path))
            {
                // Create a dummy value for the current package to prevent infinite loops
                moduleInfo.Package = new PackageProxy();

                moduleInfo.RequiredBy.Add(parent.Path);

                var pkg = new Package(parent, moduleDir, showMissingDevOptionalSubPackages, this.allModules, depth, maxDepth);
                if (dependency != null)
                {
                    pkg.RequestedVersionRange = dependency.VersionRangeText;
                }

                package = moduleInfo.Package = pkg;
            }

            if (parent as IPackage == null || !package.IsMissing || showMissingDevOptionalSubPackages)
            {
                AddModule(package);
            }

            return(true);
        }
示例#2
0
        public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages) {
            var modulesBase = Path.Combine(parent.Path, "node_modules");
            if (Directory.Exists(modulesBase)) {
                var bin = string.Format("{0}.bin", Path.DirectorySeparatorChar);
                foreach (var moduleDir in Directory.EnumerateDirectories(modulesBase)) {
                    if (!moduleDir.EndsWith(bin)) {
                        AddModule(new Package(parent, moduleDir, showMissingDevOptionalSubPackages));
                    }
                }
            }

            var parentPackageJson = parent.PackageJson;
            if (null != parentPackageJson) {
                foreach (var dependency in parentPackageJson.AllDependencies) {
                    Package module = null;
                    if (!Contains(dependency.Name)) {
                        module = new Package(
                            parent,
                            Path.Combine(modulesBase, dependency.Name),
                            showMissingDevOptionalSubPackages);
                        if (parent as IPackage == null || !module.IsMissing || showMissingDevOptionalSubPackages) {
                            AddModule(module);
                        }
                    } else {
                        module = this[dependency.Name] as Package;
                    }

                    if (null != module) {
                        module.RequestedVersionRange = dependency.VersionRangeText;
                    }
                }
            }

            _packagesSorted.Sort(new PackageComparer());
        }
示例#3
0
 public Package(
     IRootPackage parent,
     string fullPathToRootDirectory,
     bool showMissingDevOptionalSubPackages)
     : base(fullPathToRootDirectory, showMissingDevOptionalSubPackages) {
     _parent = parent;
 }
示例#4
0
 public Package(
     IRootPackage parent,
     string fullPathToRootDirectory,
     bool showMissingDevOptionalSubPackages)
     : base(fullPathToRootDirectory, showMissingDevOptionalSubPackages)
 {
     _parent = parent;
 }
示例#5
0
        public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages, Dictionary<string, ModuleInfo> allModulesToDepth = null, int depth = 0, int maxDepth = 1) {
            if (depth >= maxDepth) {
                return;
            }

            var modulesBase = Path.Combine(parent.Path, NodejsConstants.NodeModulesFolder);

            _allModules = allModulesToDepth ?? new Dictionary<string, ModuleInfo>();

            // This is the first time NodeModules is being created.
            // Iterate through directories to add everything that's known to be top-level.
            if (depth == 0) {
                Debug.Assert(_allModules.Count == 0, "Depth is 0, but top-level modules have already been added.");

                // Go through every directory in node_modules, and see if it's required as a top-level dependency
                foreach (var topLevelDependency in GetTopLevelPackageDirectories(modulesBase)) {
                    var moduleDir = topLevelDependency.Key;
                    var packageJson = topLevelDependency.Value;
                    if (packageJson.RequiredBy.Any()) {
                        // All dependencies in npm v3 will have at least one element present in _requiredBy.
                        // _requiredBy dependencies that begin with hash characters represent top-level dependencies
                        foreach (var requiredBy in packageJson.RequiredBy) {
                            if (requiredBy.StartsWith("#", StringComparison.Ordinal) || requiredBy == "/") {
                                AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth, maxDepth);
                                break;
                            }
                        }
                    } else {
                        // This dependency is a top-level dependency not added by npm v3
                        AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth, maxDepth);
                    }
                }
            }

            if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && parent.HasPackageJson) {
                // Iterate through all dependencies in the root package.json
                // Otherwise, only iterate through "dependencies" because iterating through optional, bundle, etc. dependencies
                // becomes unmanageable when they are already installed at the root of the project, and the performance impact
                // typically isn't worth the value add. 
                var dependencies = depth == 0 ? parent.PackageJson.AllDependencies : parent.PackageJson.Dependencies;
                foreach (var dependency in dependencies) {
                    var moduleDir = modulesBase;

                    // try to find folder by recursing up tree
                    do {
                        moduleDir = Path.Combine(moduleDir, dependency.Name);
                        if (AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, maxDepth, dependency)) {
                            break;
                        }

                        var parentNodeModulesIndex = moduleDir.LastIndexOf(NodejsConstants.NodeModulesFolder, Math.Max(0, moduleDir.Length - NodejsConstants.NodeModulesFolder.Length - dependency.Name.Length - 1), StringComparison.Ordinal);
                        moduleDir = moduleDir.Substring(0, parentNodeModulesIndex + NodejsConstants.NodeModulesFolder.Length);
                    } while (moduleDir.Contains(NodejsConstants.NodeModulesFolder));
                }
            }

            _packagesSorted.Sort(new PackageComparer());
        }
 public Package(
     IRootPackage parent,
     string fullPathToRootDirectory,
     bool showMissingDevOptionalSubPackages,
     Dictionary<string, ModuleInfo> allModules = null,
     int depth = 0)
     : base(fullPathToRootDirectory, showMissingDevOptionalSubPackages, allModules, depth) {
     _parent = parent;
 }
示例#7
0
 public Package(
     IRootPackage parent,
     string fullPathToRootDirectory,
     bool showMissingDevOptionalSubPackages,
     Dictionary <string, ModuleInfo> allModules = null,
     int depth = 0)
     : base(fullPathToRootDirectory, showMissingDevOptionalSubPackages, allModules, depth)
 {
     _parent = parent;
 }
示例#8
0
        private bool AddModuleIfNotExists(IRootPackage parent, string moduleDir, bool showMissingDevOptionalSubPackages, int depth, IDependency dependency = null)
        {
            depth++;

            ModuleInfo moduleInfo;

            _allModules.TryGetValue(moduleDir, out moduleInfo);

            if (moduleInfo != null)
            {
                // Update module information if the module already exists.
                if (moduleInfo.Depth > depth)
                {
                    moduleInfo.Depth = depth;
                }

                if (dependency != null)
                {
                    var existingPackage = this[dependency.Name] as Package;
                    if (existingPackage != null)
                    {
                        existingPackage.RequestedVersionRange = dependency.VersionRangeText;
                    }
                }
            }
            else if (Directory.Exists(moduleDir) || depth == 1)
            {
                // Top-level modules are always added so we can include missing modules.
                moduleInfo = new ModuleInfo(depth);
                _allModules.Add(moduleDir, moduleInfo);
            }
            else
            {
                // The module directory wasn't found.
                return(false);
            }

            if (moduleInfo.RequiredBy.Contains(parent.Name))
            {
                return(true);
            }

            moduleInfo.RequiredBy.Add(parent.Name);
            var package = new Package(parent, moduleDir, showMissingDevOptionalSubPackages, _allModules, depth);

            if (dependency != null)
            {
                package.RequestedVersionRange = dependency.VersionRangeText;
            }
            AddModule(package);

            return(true);
        }
示例#9
0
        public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages)
        {
            var modulesBase = Path.Combine(parent.Path, "node_modules");

            if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && Directory.Exists(modulesBase))
            {
                var bin = string.Format("{0}.bin", Path.DirectorySeparatorChar);
                foreach (var moduleDir in Directory.EnumerateDirectories(modulesBase))
                {
                    if (moduleDir.Length < NativeMethods.MAX_FOLDER_PATH && !moduleDir.EndsWith(bin))
                    {
                        AddModule(new Package(parent, moduleDir, showMissingDevOptionalSubPackages));
                    }
                }
            }

            var parentPackageJson = parent.PackageJson;

            if (null != parentPackageJson)
            {
                foreach (var dependency in parentPackageJson.AllDependencies)
                {
                    Package module = null;
                    if (!Contains(dependency.Name))
                    {
                        var dependencyPath = Path.Combine(modulesBase, dependency.Name);
                        if (dependencyPath.Length < NativeMethods.MAX_FOLDER_PATH)
                        {
                            module = new Package(
                                parent,
                                dependencyPath,
                                showMissingDevOptionalSubPackages);
                            if (parent as IPackage == null || !module.IsMissing || showMissingDevOptionalSubPackages)
                            {
                                AddModule(module);
                            }
                        }
                    }
                    else
                    {
                        module = this[dependency.Name] as Package;
                    }

                    if (null != module)
                    {
                        module.RequestedVersionRange = dependency.VersionRangeText;
                    }
                }
            }

            _packagesSorted.Sort(new PackageComparer());
        }
示例#10
0
        public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages, Dictionary <string, ModuleInfo> allModulesToDepth = null, int depth = 0, int maxDepth = 1)
        {
            if (depth >= maxDepth)
            {
                return;
            }

            var modulesBase = Path.Combine(parent.Path, NodejsConstants.NodeModulesFolder);

            this._allModules = allModulesToDepth ?? new Dictionary <string, ModuleInfo>();

            // This is the first time NodeModules is being created.
            // Iterate through directories to add everything that's known to be top-level.
            if (depth == 0)
            {
                Debug.Assert(this._allModules.Count == 0, "Depth is 0, but top-level modules have already been added.");

                // Go through every directory in node_modules, and see if it's required as a top-level dependency
                foreach (var topLevelDependency in GetTopLevelPackageDirectories(modulesBase))
                {
                    var moduleDir   = topLevelDependency.Key;
                    var packageJson = topLevelDependency.Value;
                    if (packageJson.RequiredBy.Any())
                    {
                        // All dependencies in npm v3 will have at least one element present in _requiredBy.
                        // _requiredBy dependencies that begin with hash characters represent top-level dependencies
                        foreach (var requiredBy in packageJson.RequiredBy)
                        {
                            if (requiredBy.StartsWith("#", StringComparison.Ordinal) || requiredBy == "/")
                            {
                                AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth, maxDepth);
                                break;
                            }
                        }
                    }
                    else
                    {
                        // This dependency is a top-level dependency not added by npm v3
                        AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth, maxDepth);
                    }
                }
            }

            if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && parent.HasPackageJson)
            {
                // Iterate through all dependencies in the root package.json
                // Otherwise, only iterate through "dependencies" because iterating through optional, bundle, etc. dependencies
                // becomes unmanageable when they are already installed at the root of the project, and the performance impact
                // typically isn't worth the value add.
                var dependencies = depth == 0 ? parent.PackageJson.AllDependencies : parent.PackageJson.Dependencies;
                foreach (var dependency in dependencies)
                {
                    var moduleDir = modulesBase;

                    // try to find folder by recursing up tree
                    do
                    {
                        moduleDir = Path.Combine(moduleDir, dependency.Name);
                        if (AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, maxDepth, dependency))
                        {
                            break;
                        }

                        var parentNodeModulesIndex = moduleDir.LastIndexOf(NodejsConstants.NodeModulesFolder, Math.Max(0, moduleDir.Length - NodejsConstants.NodeModulesFolder.Length - dependency.Name.Length - 1), StringComparison.Ordinal);
                        moduleDir = moduleDir.Substring(0, parentNodeModulesIndex + NodejsConstants.NodeModulesFolder.Length);
                    } while (moduleDir.Contains(NodejsConstants.NodeModulesFolder));
                }
            }

            this._packagesSorted.Sort(new PackageComparer());
        }
示例#11
0
        private async void FilterTimer_Elapsed(object state)
        {
            if (_allPackages == null)
            {
                LastRefreshedMessage = LastRefreshedMessageProvider.RefreshFailed;
                IsFiltering          = false;
                return;
            }

            var filterText = GetTrimmedTextSafe(_filterText);

            IEnumerable <IPackage> filtered;

            if (string.IsNullOrWhiteSpace(filterText))
            {
                filtered = Enumerable.Empty <IPackage>();
            }
            else
            {
                try {
                    filtered = await _allPackages.GetCatalogPackagesAsync(filterText);
                } catch (Exception ex) {
                    LastRefreshedMessage = LastRefreshedMessageProvider.RefreshFailed;
                    if (IsCriticalException(ex))
                    {
                        throw;
                    }
                    StartFilter();
                    return;
                }
            }

            if (filtered == null)
            {
                // The database file must be in use. Display current results, but try again later.
                LastRefreshedMessage = LastRefreshedMessageProvider.RefreshInProgress;
                StartFilter();
                return;
            }

            var newItems = new List <PackageCatalogEntryViewModel>();

            if (filterText != GetTrimmedTextSafe(_filterText))
            {
                return;
            }

            if (filtered.Any())
            {
                IRootPackage rootPackage = null;
                var          controller  = _npmController;
                if (controller != null)
                {
                    rootPackage = controller.RootPackage;
                }

                newItems.AddRange(filtered.Select(package => new ReadOnlyPackageCatalogEntryViewModel(
                                                      package,
                                                      rootPackage != null ? rootPackage.Modules[package.Name] : null)));
            }

            await _dispatcher.BeginInvoke((Action)(() => {
                if (filterText != GetTrimmedTextSafe(_filterText))
                {
                    return;
                }

                var originalSelectedPackage = SelectedPackage;
                FilteredPackages = newItems;

                // Reassign originalSelectedPackage to the original selected package in the new list of filtered packages.
                if (originalSelectedPackage != null)
                {
                    originalSelectedPackage = FilteredPackages.FirstOrDefault(package => package.Name == originalSelectedPackage.Name);
                }

                // Maintain selection when the filter list refreshes (e.g. due to an installation running in the background)
                SelectedPackage = originalSelectedPackage ?? FilteredPackages.FirstOrDefault();

                LastRefreshedMessage = IsCatalogEmpty
                    ? LastRefreshedMessageProvider.RefreshFailed
                    : new LastRefreshedMessageProvider(_allPackages.LastRefreshed);
                CatalogControlVisibility = Visibility.Visible;
            }));

            IsFiltering = false;

            // The catalog refresh operation spawns many long-lived Gen 2 objects,
            // so the garbage collector will take a while to get to them otherwise.
            GC.Collect();
        }
示例#12
0
        private bool AddModuleIfNotExists(IRootPackage parent, string moduleDir, bool showMissingDevOptionalSubPackages, int depth, int maxDepth, IDependency dependency = null) {
            depth++;

            ModuleInfo moduleInfo;
            _allModules.TryGetValue(moduleDir, out moduleInfo);

            if (moduleInfo != null) {
                // Update module information if the module already exists.
                if (moduleInfo.Depth > depth) {
                    moduleInfo.Depth = depth;
                }

                if (dependency != null) {
                    var existingPackage = this[dependency.Name] as Package;
                    if (existingPackage != null) {
                        existingPackage.RequestedVersionRange = dependency.VersionRangeText;
                    }
                }
            } else if (Directory.Exists(moduleDir) || depth == 1) {
                // Top-level modules are always added so we can include missing modules.
                moduleInfo = new ModuleInfo(depth);
                _allModules.Add(moduleDir, moduleInfo);
            } else {
                // The module directory wasn't found.
                return false;
            }

            IPackage package = moduleInfo.Package;
                        
            if (package == null || depth == 1 || !moduleInfo.RequiredBy.Contains(parent.Path)) {
                // Create a dummy value for the current package to prevent infinite loops
                moduleInfo.Package = new PackageProxy();

                moduleInfo.RequiredBy.Add(parent.Path);

                var pkg = new Package(parent, moduleDir, showMissingDevOptionalSubPackages, _allModules, depth, maxDepth);
                if (dependency != null) {
                    pkg.RequestedVersionRange = dependency.VersionRangeText;
                }

                package = moduleInfo.Package = pkg;
            }

            if (parent as IPackage == null || !package.IsMissing || showMissingDevOptionalSubPackages) {
                AddModule(package);
            }

            return true;
        }
示例#13
0
 private void AddTopLevelModule(IRootPackage parent, bool showMissingDevOptionalSubPackages, string moduleDir, int depth, int maxDepth) {
     Debug.Assert(depth == 0, "Depth should be 0 when adding a top level dependency");
     AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, maxDepth);
 }
示例#14
0
        private bool AddModuleIfNotExists(IRootPackage parent, string moduleDir, bool showMissingDevOptionalSubPackages, int depth, IDependency dependency = null) {
            depth++;

            ModuleInfo moduleInfo;
            _allModules.TryGetValue(moduleDir, out moduleInfo);

            if (moduleInfo != null) {
                // Update module information if the module already exists.
                if (moduleInfo.Depth > depth) {
                    moduleInfo.Depth = depth;
                }

                if (dependency != null) {
                    var existingPackage = this[dependency.Name] as Package;
                    if (existingPackage != null) {
                        existingPackage.RequestedVersionRange = dependency.VersionRangeText;
                    }
                }
            } else if (Directory.Exists(moduleDir) || depth == 1) {
                // Top-level modules are always added so we can include missing modules.
                moduleInfo = new ModuleInfo(depth);
                _allModules.Add(moduleDir, moduleInfo);
            } else {
                // The module directory wasn't found.
                return false;
            }

            if (moduleInfo.RequiredBy.Contains(parent.Name)) {
                return true;
            }

            moduleInfo.RequiredBy.Add(parent.Name);
            var package = new Package(parent, moduleDir, showMissingDevOptionalSubPackages, _allModules, depth);
            if (dependency != null) {
                package.RequestedVersionRange = dependency.VersionRangeText;
            }
            AddModule(package);

            return true;
        }
示例#15
0
        public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages, Dictionary<string, ModuleInfo> allModulesToDepth = null, int depth = 0) {
            var modulesBase = Path.Combine(parent.Path, NodejsConstants.NodeModulesFolder);

            _allModules = allModulesToDepth ?? new Dictionary<string, ModuleInfo>();

            // This is the first time NodeModules is being created.
            // Iterate through directories to add everything that's known to be top-level.
            if (depth == 0) {
                Debug.Assert(_allModules.Count == 0, "Depth is 0, but top-level modules have already been added.");

                IEnumerable<string> topLevelDirectories = Enumerable.Empty<string>();
                try {
                    topLevelDirectories = Directory.EnumerateDirectories(modulesBase);
                } catch (IOException) {
                    // We want to handle DirectoryNotFound, DriveNotFound, PathTooLong
                } catch (UnauthorizedAccessException) {
                }

                // Go through every directory in node_modules, and see if it's required as a top-level dependency
                foreach (var moduleDir in topLevelDirectories) {
                    if (moduleDir.Length < NativeMethods.MAX_FOLDER_PATH && !_ignoredDirectories.Any(toIgnore => moduleDir.EndsWith(toIgnore))) {
                        var packageJson = PackageJsonFactory.Create(new DirectoryPackageJsonSource(moduleDir));

                        if (packageJson != null) {
                            if (packageJson.RequiredBy.Count() > 0) {
                                // All dependencies in npm v3 will have at least one element present in _requiredBy.
                                // _requiredBy dependencies that begin with hash characters represent top-level dependencies
                                foreach (var requiredBy in packageJson.RequiredBy) {
                                    if (requiredBy.StartsWith("#") || requiredBy == "/") {
                                        AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth);
                                        break;
                                    }
                                }
                            } else {
                                // This dependency is a top-level dependency not added by npm v3
                                AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth);
                            }
                        }
                    }
                }
            }

            if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && parent.HasPackageJson) {
                // Iterate through all dependencies in package.json
                foreach (var dependency in parent.PackageJson.AllDependencies) {
                    var moduleDir = modulesBase;
                    
                    // try to find folder by recursing up tree
                    do {
                        moduleDir = Path.Combine(moduleDir, dependency.Name);
                        if (AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, dependency)) {
                            break;
                        }

                        var parentNodeModulesIndex = moduleDir.LastIndexOf(NodejsConstants.NodeModulesFolder, Math.Max(0, moduleDir.Length - NodejsConstants.NodeModulesFolder.Length - dependency.Name.Length - 1));
                        moduleDir = moduleDir.Substring(0, parentNodeModulesIndex + NodejsConstants.NodeModulesFolder.Length);
                    } while (moduleDir.Contains(NodejsConstants.NodeModulesFolder));
                }
            }

            _packagesSorted.Sort(new PackageComparer());
        }
示例#16
0
 private void AddTopLevelModule(IRootPackage parent, bool showMissingDevOptionalSubPackages, string moduleDir, int depth, int maxDepth)
 {
     Debug.Assert(depth == 0, "Depth should be 0 when adding a top level dependency");
     AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, maxDepth);
 }
        private async void FilterTimer_Elapsed(object state)
        {
            var filterText = GetTrimmedTextSafe(this.filterText);

            IEnumerable <IPackage> filtered;

            if (string.IsNullOrWhiteSpace(filterText))
            {
                filtered = Enumerable.Empty <IPackage>();
            }
            else
            {
                try
                {
                    filtered = await this.npmWorker.GetCatalogPackagesAsync(filterText);
                }
                catch (Exception ex)
                {
                    if (IsCriticalException(ex))
                    {
                        throw;
                    }
                    StartFilter();
                    return;
                }
            }

            var newItems = new List <PackageCatalogEntryViewModel>();

            if (filterText != GetTrimmedTextSafe(this.filterText))
            {
                return;
            }

            if (filtered.Any())
            {
                IRootPackage rootPackage = null;
                var          controller  = this.npmController;
                if (controller != null)
                {
                    rootPackage = controller.RootPackage;
                }

                newItems.AddRange(filtered.Select(package => new ReadOnlyPackageCatalogEntryViewModel(
                                                      package,
                                                      rootPackage != null ? rootPackage.Modules[package.Name] : null)));
            }

            await this.dispatcher.BeginInvoke((Action)(() =>
            {
                if (filterText != GetTrimmedTextSafe(this.filterText))
                {
                    return;
                }

                var originalSelectedPackage = this.SelectedPackage;
                this.FilteredPackages = newItems;

                // Reassign originalSelectedPackage to the original selected package in the new list of filtered packages.
                if (originalSelectedPackage != null)
                {
                    originalSelectedPackage = this.FilteredPackages.FirstOrDefault(package => package.Name == originalSelectedPackage.Name);
                }

                // Maintain selection when the filter list refreshes (e.g. due to an installation running in the background)
                this.SelectedPackage = originalSelectedPackage ?? this.FilteredPackages.FirstOrDefault();
            }));

            this.IsFiltering = false;

            // The catalog refresh operation spawns many long-lived Gen 2 objects,
            // so the garbage collector will take a while to get to them otherwise.
            GC.Collect();
        }
示例#18
0
        public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages, Dictionary <string, ModuleInfo> allModulesToDepth = null, int depth = 0)
        {
            var modulesBase = Path.Combine(parent.Path, NodejsConstants.NodeModulesFolder);

            _allModules = allModulesToDepth ?? new Dictionary <string, ModuleInfo>();

            // This is the first time NodeModules is being created.
            // Iterate through directories to add everything that's known to be top-level.
            if (depth == 0)
            {
                Debug.Assert(_allModules.Count == 0, "Depth is 0, but top-level modules have already been added.");

                IEnumerable <string> topLevelDirectories = Enumerable.Empty <string>();
                try {
                    topLevelDirectories = Directory.EnumerateDirectories(modulesBase);
                } catch (IOException) {
                    // We want to handle DirectoryNotFound, DriveNotFound, PathTooLong
                } catch (UnauthorizedAccessException) {
                }

                // Go through every directory in node_modules, and see if it's required as a top-level dependency
                foreach (var moduleDir in topLevelDirectories)
                {
                    if (moduleDir.Length < NativeMethods.MAX_FOLDER_PATH && !_ignoredDirectories.Any(toIgnore => moduleDir.EndsWith(toIgnore)))
                    {
                        var packageJson = PackageJsonFactory.Create(new DirectoryPackageJsonSource(moduleDir));

                        if (packageJson != null)
                        {
                            if (packageJson.RequiredBy.Count() > 0)
                            {
                                // All dependencies in npm v3 will have at least one element present in _requiredBy.
                                // _requiredBy dependencies that begin with hash characters represent top-level dependencies
                                foreach (var requiredBy in packageJson.RequiredBy)
                                {
                                    if (requiredBy.StartsWith("#") || requiredBy == "/")
                                    {
                                        AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth);
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                // This dependency is a top-level dependency not added by npm v3
                                AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth);
                            }
                        }
                    }
                }
            }

            if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && parent.HasPackageJson)
            {
                // Iterate through all dependencies in package.json
                foreach (var dependency in parent.PackageJson.AllDependencies)
                {
                    var moduleDir = modulesBase;

                    // try to find folder by recursing up tree
                    do
                    {
                        moduleDir = Path.Combine(moduleDir, dependency.Name);
                        if (AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, dependency))
                        {
                            break;
                        }

                        var parentNodeModulesIndex = moduleDir.LastIndexOf(NodejsConstants.NodeModulesFolder, Math.Max(0, moduleDir.Length - NodejsConstants.NodeModulesFolder.Length - dependency.Name.Length - 1));
                        moduleDir = moduleDir.Substring(0, parentNodeModulesIndex + NodejsConstants.NodeModulesFolder.Length);
                    } while (moduleDir.Contains(NodejsConstants.NodeModulesFolder));
                }
            }

            _packagesSorted.Sort(new PackageComparer());
        }