private async Task ExecuteInitScriptsAsync()
        {
            // Fix for Bug 1426 Disallow ExecuteInitScripts from being executed concurrently by multiple threads.
            using (await _initScriptsLock.EnterAsync())
            {
                if (!await _solutionManager.Value.IsSolutionOpenAsync())
                {
                    return;
                }

                Debug.Assert(_settings != null);
                if (_settings == null)
                {
                    return;
                }

                var latestRestore           = _latestRestore;
                var latestSolutionDirectory = await _solutionManager.Value.GetSolutionDirectoryAsync();

                if (ShouldNoOpDueToRestore(latestRestore) &&
                    ShouldNoOpDueToSolutionDirectory(latestSolutionDirectory))
                {
                    _currentRestore           = latestRestore;
                    _currentSolutionDirectory = latestSolutionDirectory;

                    return;
                }
                // We may be enumerating packages from disk here. Always do it from a background thread.
                await TaskScheduler.Default;

                var packageManager = new NuGetPackageManager(
                    _sourceRepositoryProvider,
                    _settings.Value,
                    _solutionManager.Value,
                    _deleteOnRestartManager.Value,
                    _restoreProgressReporter.Value);

                var enumerator        = new InstalledPackageEnumerator(_solutionManager.Value, _settings.Value);
                var installedPackages = await enumerator.EnumeratePackagesAsync(packageManager, CancellationToken.None);

                foreach (var installedPackage in installedPackages)
                {
                    await ExecuteInitPs1Async(installedPackage.InstallPath, installedPackage.Identity);
                }

                // We are done executing scripts, so record the restore and solution directory that we executed for.
                // This aids the no-op logic above.
                _currentRestore           = latestRestore;
                _currentSolutionDirectory = latestSolutionDirectory;
            }
        }
        public async Task EnumeratePackagesAsync_ForBuildIntegratedProject_ReturnsOrderedItems()
        {
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();

            using (var testDirectory = TestDirectory.Create())
            {
                var testSettings = PopulateSettingsWithSources(sourceRepositoryProvider, testDirectory);

                var solutionDirectory = Path.Combine(testDirectory.Path, "solutionA");
                Directory.CreateDirectory(solutionDirectory);
                var testSolutionManager = new TestSolutionManager(solutionDirectory);
                testSolutionManager.NuGetProjects.Add(Mock.Of <BuildIntegratedNuGetProject>());

                var userPackageFolder = Path.Combine(testDirectory.Path, "userPackages");
                Directory.CreateDirectory(userPackageFolder);

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(
                    userPackageFolder,
                    new PackageIdentity("Foo", NuGetVersion.Parse("1.0.1")));

                var fallbackPackageFolder = Path.Combine(testDirectory.Path, "fallbackPackages");
                Directory.CreateDirectory(fallbackPackageFolder);

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(
                    fallbackPackageFolder,
                    new PackageIdentity("Bar", NuGetVersion.Parse("1.0.2")));

                var target = new InstalledPackageEnumerator(
                    testSolutionManager,
                    testSettings,
                    getLockFileOrNullAsync: _ => Task.FromResult(
                        new LockFile
                {
                    PackageFolders = new[]
                    {
                        new LockFileItem(userPackageFolder),
                        new LockFileItem(fallbackPackageFolder)
                    },
                    Targets = new[]
                    {
                        new LockFileTarget
                        {
                            TargetFramework = NuGetFramework.Parse("netcoreapp2.0"),
                            Libraries       = new[]
                            {
                                new LockFileTargetLibrary
                                {
                                    Type         = LibraryType.Package,
                                    Name         = "Foo",
                                    Version      = NuGetVersion.Parse("1.0.1"),
                                    Dependencies = new[]
                                    {
                                        new PackageDependency("Bar")
                                    }
                                },
                                new LockFileTargetLibrary
                                {
                                    Type    = LibraryType.Package,
                                    Name    = "Bar",
                                    Version = NuGetVersion.Parse("1.0.2")
                                }
                            }
                        }
                    },
                    Libraries = new[]
                    {
                        new LockFileLibrary
                        {
                            Type    = LibraryType.Package,
                            Name    = "Foo",
                            Version = NuGetVersion.Parse("1.0.1")
                        },
                        new LockFileLibrary
                        {
                            Type    = LibraryType.Package,
                            Name    = "Bar",
                            Version = NuGetVersion.Parse("1.0.2")
                        }
                    }
                }));

                var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(
                    solutionDirectory, testSettings);

                var testPackageManager = new NuGetPackageManager(
                    sourceRepositoryProvider,
                    testSettings,
                    packagesFolderPath);

                // Act
                var installedPackages = await target.EnumeratePackagesAsync(
                    testPackageManager,
                    CancellationToken.None);

                // Assert: Order is important!
                installedPackages.Should().Equal(
                    new PackageItem(
                        new PackageIdentity("Bar", NuGetVersion.Parse("1.0.2")),
                        Path.Combine(fallbackPackageFolder, "bar", "1.0.2")),
                    new PackageItem(
                        new PackageIdentity("Foo", NuGetVersion.Parse("1.0.1")),
                        Path.Combine(userPackageFolder, "foo", "1.0.1")));
            }
        }
        public async Task EnumeratePackagesAsync_ForPackagesConfig_ReturnsOrderedItems()
        {
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();

            using (var testDirectory = TestDirectory.Create())
            {
                var testSettings = PopulateSettingsWithSources(sourceRepositoryProvider, testDirectory);

                var solutionDirectory = Path.Combine(testDirectory.Path, "solutionA");
                Directory.CreateDirectory(solutionDirectory);
                var testSolutionManager = new TestSolutionManager(solutionDirectory);

                var userPackageFolder = Path.Combine(testDirectory.Path, "packagesA");
                Directory.CreateDirectory(userPackageFolder);

                testSettings.SetValue("config", "repositoryPath", userPackageFolder);

                var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(
                    solutionDirectory, testSettings);

                var packageBar = new SimpleTestPackageContext
                {
                    Id      = "Bar",
                    Version = "1.0.2"
                };

                var packageFoo = new SimpleTestPackageContext
                {
                    Id           = "Foo",
                    Version      = "1.0.1",
                    Dependencies = new List <SimpleTestPackageContext> {
                        packageBar
                    }
                };

                await SimpleTestPackageUtility.CreateFolderFeedPackagesConfigAsync(
                    packagesFolderPath,
                    packageFoo,
                    packageBar);

                var target = new InstalledPackageEnumerator(
                    testSolutionManager,
                    testSettings,
                    getLockFileOrNullAsync: _ => Task.FromResult <LockFile>(null));

                var projectSystem = Mock.Of <IMSBuildProjectSystem>();
                Mock.Get(projectSystem)
                .SetupGet(x => x.TargetFramework)
                .Returns(NuGetFramework.Parse("net45"));

                var project = new Mock <MSBuildNuGetProject>(
                    projectSystem, packagesFolderPath, testDirectory.Path);

                project
                .Setup(x => x.GetInstalledPackagesAsync(It.IsAny <CancellationToken>()))
                .ReturnsAsync(new[]
                {
                    new PackageReference(
                        new PackageIdentity("Foo", NuGetVersion.Parse("1.0.1")),
                        NuGetFramework.Parse("net45")),
                    new PackageReference(
                        new PackageIdentity("Bar", NuGetVersion.Parse("1.0.2")),
                        NuGetFramework.Parse("net45"))
                })
                .Verifiable();

                testSolutionManager.NuGetProjects.Add(project.Object);

                var testPackageManager = new NuGetPackageManager(
                    sourceRepositoryProvider,
                    testSettings,
                    packagesFolderPath);

                // Act
                var installedPackages = await target.EnumeratePackagesAsync(
                    testPackageManager,
                    CancellationToken.None);

                // Assert: Order is important!
                installedPackages.Should().Equal(
                    new PackageItem(
                        new PackageIdentity("Bar", NuGetVersion.Parse("1.0.2")),
                        Path.Combine(packagesFolderPath, "Bar.1.0.2")),
                    new PackageItem(
                        new PackageIdentity("Foo", NuGetVersion.Parse("1.0.1")),
                        Path.Combine(packagesFolderPath, "Foo.1.0.1")));

                project.Verify();
            }
        }