/// <summary> /// Determines if a package is installed based on the provided package save mode. /// </summary> /// <param name="packageIdentity">A package identity.</param> /// <param name="packageSaveMode">A package save mode.</param> /// <returns>A flag indicating whether or not the package is installed.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" /> /// is <c>null</c>.</exception> public bool PackageExists(PackageIdentity packageIdentity, PackageSaveMode packageSaveMode) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } var nupkgPath = GetInstalledPackageFilePath(packageIdentity); var nuspecPath = GetInstalledManifestFilePath(packageIdentity); var packageExists = !string.IsNullOrEmpty(nupkgPath); var manifestExists = !string.IsNullOrEmpty(nuspecPath); // When using -ExcludeVersion check that the actual package version matches. if (!PackagePathResolver.UseSideBySidePaths) { if (packageExists) { using (var reader = new PackageArchiveReader(nupkgPath)) { packageExists = packageIdentity.Equals(reader.NuspecReader.GetIdentity()); } } if (manifestExists) { var reader = new NuspecReader(nuspecPath); packageExists = packageIdentity.Equals(reader.GetIdentity()); } } if (!packageExists) { packageExists |= !string.IsNullOrEmpty(GetPackageDownloadMarkerFilePath(packageIdentity)); } // A package must have either a nupkg or a nuspec to be valid var result = packageExists || manifestExists; // Verify nupkg present if specified if ((packageSaveMode & PackageSaveMode.Nupkg) == PackageSaveMode.Nupkg) { result &= packageExists; } // Verify nuspec present if specified if ((packageSaveMode & PackageSaveMode.Nuspec) == PackageSaveMode.Nuspec) { result &= manifestExists; } return(result); }
/// <summary> /// Retrieve all packages of an id from a v2 folder. /// </summary> /// <param name="root">Nupkg folder directory path.</param> /// <param name="identity">Package id and version.</param> public static LocalPackageInfo GetPackageV2(string root, PackageIdentity identity, ILogger log) { if (root == null) { throw new ArgumentNullException(nameof(root)); } if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (log == null) { throw new ArgumentNullException(nameof(log)); } // Verify the root path is a valid path. var rootDirInfo = GetAndVerifyRootDirectory(root); // Search directories starting with the top directory for any package matching the identity // If multiple packages are found in the same directory that match (ex: 1.0, 1.0.0.0) // then favor the exact non-normalized match. If no exact match is found take the first // using the file system sort order. This is to match the legacy nuget 2.8.x behavior. foreach (var directoryList in GetNupkgsFromFlatFolderChunked(rootDirInfo, log)) { LocalPackageInfo fallbackMatch = null; // Check for any files that are in the form packageId.version.nupkg foreach (var file in directoryList.Where(file => IsPossiblePackageMatch(file, identity))) { var package = GetPackageFromNupkg(file); if (identity.Equals(package.Identity)) { if (StringComparer.OrdinalIgnoreCase.Equals( identity.Version.ToString(), package.Identity.Version.ToString())) { // Take an exact match immediately return(package); } else if (fallbackMatch == null) { // This matches the identity, but there may be an exact match still fallbackMatch = package; } } } if (fallbackMatch != null) { // Use the fallback match if an exact match was not found return(fallbackMatch); } } // Not found return(null); }
public bool Equals(PackageIdentity packageIdentity, bool matchVersion = true) { var packageReference = CreatePackageReference(); var currentPackageIdentity = packageReference.PackageIdentity; if (matchVersion) { return(packageIdentity.Equals(currentPackageIdentity)); } return(StringComparer.OrdinalIgnoreCase.Equals(packageIdentity.Id, currentPackageIdentity.Id)); }
/// <summary> /// True if the file name matches the identity. This is could be incorrect if /// the package name ends with numbers. The result should be checked against the nuspec. /// </summary> public static bool IsPossiblePackageMatch(FileInfo file, PackageIdentity identity) { if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (file == null) { throw new ArgumentNullException(nameof(file)); } return(identity.Equals(GetIdentityFromNupkgPath(file, identity.Id))); }
/// <summary> /// Gets the package .nupkg file path if it exists; otherwise, <c>null</c>. /// </summary> /// <param name="packageIdentity">A package identity.</param> /// <returns>The package .nupkg file path if it exists; otherwise, <c>null</c>.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" /> /// is <c>null</c>.</exception> public string GetInstalledPackageFilePath(PackageIdentity packageIdentity) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } // Check the expected location before searching all directories var packageDirectory = PackagePathResolver.GetInstallPath(packageIdentity); var packageName = PackagePathResolver.GetPackageFileName(packageIdentity); var installPath = Path.GetFullPath(Path.Combine(packageDirectory, packageName)); // Keep the previous optimization of just going by the existance of the file if we find it. if (File.Exists(installPath)) { return(installPath); } // If the file was not found check for non-normalized paths and verify the id/version LocalPackageInfo package = null; if (PackagePathResolver.UseSideBySidePaths) { // Search for a folder with the id and version package = LocalFolderUtility.GetPackagesConfigFolderPackage( Root, packageIdentity, NullLogger.Instance); } else { // Search for just the id package = LocalFolderUtility.GetPackageV2( Root, packageIdentity, NullLogger.Instance, CancellationToken.None); } if (package != null && packageIdentity.Equals(package.Identity)) { return(package.Path); } // Default to empty return(string.Empty); }
public bool Equals(ImplicitProjectAction other) { if (other == null) { return(false); } if (ReferenceEquals(this, other)) { return(true); } return(StringComparer.Ordinal.Equals(Id, other.Id) && PackageIdentity.Equals(other.PackageIdentity) && ProjectActionType == other.ProjectActionType); }
/// <summary> /// Determines if a manifest is installed. /// </summary> /// <param name="packageIdentity">A package identity.</param> /// <returns>A flag indicating whether or not the package is installed.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" /> /// is <c>null</c>.</exception> public bool ManifestExists(PackageIdentity packageIdentity) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } var path = GetInstalledManifestFilePath(packageIdentity); var exists = !string.IsNullOrEmpty(path); if (exists && !PackagePathResolver.UseSideBySidePaths) { var reader = new NuspecReader(path); exists = packageIdentity.Equals(reader.GetIdentity()); } return(exists); }
/// <summary> /// Retrieve an exact version of a package /// </summary> public GatherCacheResult GetPackage( Configuration.PackageSource source, PackageIdentity package, NuGetFramework framework) { var key = new GatherSingleCacheKey(package, source, framework); var hasEntry = false; SourcePackageDependencyInfo result; hasEntry = _singleVersion.TryGetValue(key, out result); if (!hasEntry) { // Try finding the packages from cached all packages results var allPackagesResult = GetPackages(source, package.Id, framework); if (allPackagesResult.HasEntry) { hasEntry = true; // Find the exact package version in the list. The result may be null // if that version does not exist. result = allPackagesResult.Packages .Where(p => package.Equals(p)) .FirstOrDefault(); } } var packages = new List <SourcePackageDependencyInfo>(1); if (result != null) { packages.Add(result); } return(new GatherCacheResult(hasEntry, packages)); }
/// <summary> /// Retrieve a package with an id and version from a packages.config packages folder. /// </summary> /// <param name="root">Nupkg folder directory path.</param> /// <param name="identity">Package id and version.</param> public static LocalPackageInfo GetPackagesConfigFolderPackage(string root, PackageIdentity identity, ILogger log) { if (root == null) { throw new ArgumentNullException(nameof(root)); } if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (log == null) { throw new ArgumentNullException(nameof(log)); } var rootDirInfo = GetAndVerifyRootDirectory(root); // Try matching the exact version format var idVersion = $"{identity.Id}.{identity.Version.ToString()}"; var expectedPath = Path.Combine(rootDirInfo.FullName, idVersion, $"{idVersion}{PackagingCoreConstants.NupkgExtension}"); var expectedFile = new FileInfo(expectedPath); if (expectedFile.Exists) { var localPackage = GetPackageFromNupkg(expectedFile); // Verify that the nuspec matches the expected id/version. if (localPackage != null && identity.Equals(localPackage.Identity)) { return(localPackage); } } // Search all sub folders if (rootDirInfo.Exists) { var searchPattern = GetPackagesConfigFolderSearchPattern(identity.Id); foreach (var dir in rootDirInfo.GetDirectories(searchPattern, SearchOption.TopDirectoryOnly)) { // Check the id and version of the path, if the id matches and the version // is valid this will be non-null; var dirVersion = GetVersionFromIdVersionString(dir.Name, identity.Id); if (identity.Version == dirVersion) { var localPackage = GetPackagesConfigFolderPackage(dir); // Verify that the nuspec matches the expected id/version. if (localPackage != null && identity.Equals(localPackage.Identity)) { return(localPackage); } } } } return(null); }
static void AnalyzePackage( string packageId, string version, string framework, //ILogger logger, PackageSourceEnvironment packageSourceEnvironment) { var rootPackageIdentity = new PackageIdentity(packageId, NuGetVersion.Parse(version)); var rootNuGetFramework = NuGetFramework.ParseFolder(framework); // If configFileName is null, the user specific settings file is %AppData%\NuGet\NuGet.config. // After that, the machine wide settings files are added (c:\programdata\NuGet\Config\*.config). //var settings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null); //var sourceRepositoryProvider = new SourceRepositoryProvider(settings, Repository.Provider.GetCoreV3()); // TODO: Configure packageSources from external config // TODO: Use environment variables for MyGet username/password!!!!!! // TODO: Make 3 different environments // 1. MyGetCi // 2. MyGet // 3. Brf string username = null, password = null; if (packageSourceEnvironment == PackageSourceEnvironment.MyGetCi || packageSourceEnvironment == PackageSourceEnvironment.MyGet) { username = Environment.GetEnvironmentVariable("MYGET_USERNAME"); if (string.IsNullOrEmpty(username)) { username = "******"; } password = Environment.GetEnvironmentVariable("MYGET_PASSWORD"); if (string.IsNullOrEmpty(password)) { throw new InvalidOperationException("Missing MYGET_PASSWORD environment variable."); } } PackageSourceProvider packageSourceProvider; switch (packageSourceEnvironment) { case PackageSourceEnvironment.MyGetCi: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3"), CreatePackageSource("https://www.myget.org/F/maxfire-ci/api/v3/index.json", "MaxfireCi"), CreateAuthenticatedPackageSource("https://www.myget.org/F/brf-ci/api/v3/index.json", "BrfCiMyGet", username, password) }); break; case PackageSourceEnvironment.MyGet: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3"), CreateAuthenticatedPackageSource("https://www.myget.org/F/brf/api/v3/index.json", "BrfMyGet", username, password) }); break; case PackageSourceEnvironment.Brf: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3"), CreatePackageSource("http://pr-nuget/nuget", "Brf", protocolVersion: 2) }); break; case PackageSourceEnvironment.NugetOrg: default: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3") }); break; } var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, Repository.Provider.GetCoreV3()); Console.WriteLine("Feeds used:"); foreach (var packageSource in packageSourceProvider.LoadPackageSources()) { Console.WriteLine($" {packageSource}"); } Console.WriteLine(); //var nugetLogger = logger.AsNuGetLogger(); var nugetLogger = NullLogger.Instance; var tmpDirToRestoreTo = Path.Combine(Path.GetTempPath(), "packages"); using (var cacheContext = new SourceCacheContext { NoCache = true }) { var repositories = sourceRepositoryProvider.GetRepositories(); var resolvedPackages = new ConcurrentDictionary <PackageIdentity, SourcePackageDependencyInfo>(PackageIdentityComparer.Default); // Builds transitive closure // TODO: is Wait okay? ResolvePackageDependencies(rootPackageIdentity, rootNuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, targetIds: new[] { packageId }, availablePackages: new HashSet <SourcePackageDependencyInfo>(resolvedPackages.Values), packageSources: sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), log: nugetLogger, requiredPackageIds: Enumerable.Empty <string>(), packagesConfig: Enumerable.Empty <PackageReference>(), preferredVersions: Enumerable.Empty <PackageIdentity>()); var resolver = new PackageResolver(); List <SourcePackageDependencyInfo> prunedPackages; //try //{ prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) .Select(id => resolvedPackages[id]).ToList(); //} //catch (Exception ex) //{ // Console.WriteLine($"ERROR: {ex.Message}"); // return; //} Console.WriteLine($"root package identity: {rootPackageIdentity}"); Console.WriteLine($"root target framework: {rootNuGetFramework.DotNetFrameworkName} ({rootNuGetFramework.GetShortFolderName()})"); Console.WriteLine(); var packageNodes = new Dictionary <string, PackageReferenceNode>(StringComparer.OrdinalIgnoreCase); //var builder = new DependencyGraph.Builder(rootNode); // TODO: problem that the graph is flattened!!!!! // TODO: Should we inspect the items (assemblies of each package). remember meta-packages contain other packages // TODO: dependencies are important Console.WriteLine("Vertices of dependency package graph:"); Console.WriteLine(); PackageReferenceNode rootPackage = null; // resolve contained assemblies of packages foreach (SourcePackageDependencyInfo target in prunedPackages) { //target.Id //target.Version //target.Dependencies // TODO: --no-cache, --packages $tmpDirToRestoreTo var downloadResource = target.Source.GetResource <DownloadResource>(); // TODO: .Result of Async var downloadResult = downloadResource.GetDownloadResourceResultAsync( new PackageIdentity(target.Id, target.Version), new PackageDownloadContext(cacheContext, directDownloadDirectory: tmpDirToRestoreTo, directDownload: true), SettingsUtility.GetGlobalPackagesFolder(NullSettings.Instance), nugetLogger, CancellationToken.None).Result; // items in lib folder of target (a package is a collection of assemblies) var packageReader = downloadResult.PackageReader; if (packageReader == null) { downloadResult.PackageStream.Seek(0, SeekOrigin.Begin); packageReader = new PackageArchiveReader(downloadResult.PackageStream); } var libItems = packageReader.GetLibItems(); NuGetFramework nearest = libItems.Select(x => x.TargetFramework).GetNearestFrameworkMatching(rootNuGetFramework); // assembly references is a sequence of assembly names (file name including the extension) var assemblyReferences = libItems .Where(group => group.TargetFramework.Equals(nearest)) .SelectMany(group => group.Items) .Where(itemRelativePath => Path.GetExtension(itemRelativePath).Equals(".dll", StringComparison.OrdinalIgnoreCase)) .Select(Path.GetFileName); //.Select(assemblyName => new AssemblyReferenceNode(assemblyName)); // we do not include assembly references in the graph // TODO we ignore framework references in nuspec (only used by MS) //var frameworkItems = packageReader.GetFrameworkItems(); //nearest = reducer.GetNearest(nugetFramework, frameworkItems.Select(x => x.TargetFramework)); //// TODO: Why not use Path.GetFileName here? //var frameworkAssemblyReferences = frameworkItems // .Where(@group => @group.TargetFramework.Equals(nearest)) // .SelectMany(@group => @group.Items) // .Select(Path.GetFileName); // Why // //.Select(assemblyName => new AssemblyReferenceNode(assemblyName)); // we do not include assembly references in the graph //assemblyReferences = assemblyReferences.Concat(frameworkAssemblyReferences); var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString(), nearest.DotNetFrameworkName, nearest.GetShortFolderName(), assemblyReferences); if (rootPackageIdentity.Equals(new PackageIdentity(target.Id, target.Version))) { if (rootPackage != null) { throw new InvalidOperationException("UNEXPECTED: Root package should be unique."); } rootPackage = packageReferenceNode; } Console.WriteLine($" {packageReferenceNode}"); //builder.WithNode(packageReferenceNode); //builder.WithNodes(assemblyReferences); // TODO: Target package has edges to assembly nodes //builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); // TODO: Pack2Pack reference (directed vertex) packageNodes.Add(target.Id, packageReferenceNode); } Console.WriteLine(); // NOTE: We have transitive closure so all references are resolved!!!! // NOTE: The relation is A 'depends on' B shown like A ---> B // NOTE: The inverse relation is 'used by'.... // TODO: How to represent digraph (DAG) // TODO: How to represent the topological order (evaluation order, traversal order) // TODO: A directed acyclic graph (DAG) with a single root is not a tree!!!!! // NOTE: Both trees and DAGs are connected, directed, rooted, and have no cycles // so this means that starting from any node and going up the parents you will // eventually work your way up to the top (root). // However, since DAG nodes have multiple parents, there will be multiple paths // on the way up (that eventually merge). This is like GIT history (DAG) // Another way to see it is Tree is like single class inheritance, and DAG is like multiple class inheritance. // A (successor, downstream, core) package can be depended on by many (predecessor, upstream) packages Console.WriteLine("Edges of dependency package graph:"); Console.WriteLine(); // resolve dependencies of packages foreach (SourcePackageDependencyInfo target in prunedPackages) { // TODO: predecessor node in dependency package graph PackageReferenceNode sourceNode = packageNodes[target.Id]; // traverse all dependencies of nuspec foreach (PackageDependency dependency in target.Dependencies) { //dependency.Id //dependency.VersionRange // resolved dependency of sourceNode PackageReferenceNode targetNode = packageNodes[dependency.Id]; //targetNode.PackageId //targetNode.Type (package) //targetNode.Version // labeled edge //new Edge(sourceNode, targetNode, x.VersionRange.ToString()) Console.WriteLine($" {sourceNode}---{dependency.VersionRange}---->{targetNode}"); } // TODO: directed edge with label of version range for each successor node (successor node carries resolved version) //builder.WithEdges(target.Dependencies.Select(x => // new Edge(sourceNode, packageNodes[x.Id], x.VersionRange.ToString()))); } Console.WriteLine(); Console.WriteLine($"root package: {rootPackage}"); //return builder.Build(); } }
public async Task TestPacManPreviewUpdatePackagesSimple() { // Arrange var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV2OnlySourceRepositoryProvider(); var testSolutionManager = new TestSolutionManager(); var testSettings = new NullSettings(); var token = CancellationToken.None; var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, testSettings, testSolutionManager); var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(testSolutionManager, testSettings); var randomPackagesConfigFolderPath = TestFilesystemUtility.CreateRandomTestFolder(); var randomPackagesConfigPath = Path.Combine(randomPackagesConfigFolderPath, "packages.config"); var projectTargetFramework = NuGetFramework.Parse("net45"); var msBuildNuGetProjectSystem = new TestMSBuildNuGetProjectSystem(projectTargetFramework, new TestNuGetProjectContext()); var msBuildNuGetProject = new MSBuildNuGetProject(msBuildNuGetProjectSystem, packagesFolderPath, randomPackagesConfigPath); var packageIdentity0 = PackageWithDependents[0]; // jQuery.1.4.4 var resolutionContext = new ResolutionContext(); var latestVersion = await NuGetPackageManager.GetLatestVersionAsync(packageIdentity0.Id, new ResolutionContext(), sourceRepositoryProvider.GetRepositories().First(), token); var packageLatest = new PackageIdentity(packageIdentity0.Id, latestVersion); // Pre-Assert // Check that the packages.config file does not exist Assert.False(File.Exists(randomPackagesConfigPath)); // Check that there are no packages returned by PackagesConfigProject var packagesInPackagesConfig = (await msBuildNuGetProject.PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).ToList(); Assert.Equal(0, packagesInPackagesConfig.Count); Assert.Equal(0, msBuildNuGetProjectSystem.References.Count); // Act await nuGetPackageManager.InstallPackageAsync(msBuildNuGetProject, packageIdentity0, resolutionContext, new TestNuGetProjectContext(), sourceRepositoryProvider.GetRepositories().First(), null, token); // Assert // Check that the packages.config file exists after the installation Assert.True(File.Exists(randomPackagesConfigPath)); // Check the number of packages and packages returned by PackagesConfigProject after the installation packagesInPackagesConfig = (await msBuildNuGetProject.PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).ToList(); Assert.Equal(1, packagesInPackagesConfig.Count); Assert.Equal(packageIdentity0, packagesInPackagesConfig[0].PackageIdentity); Assert.Equal(projectTargetFramework, packagesInPackagesConfig[0].TargetFramework); var installedPackageIds = (await msBuildNuGetProject.GetInstalledPackagesAsync(token)) .Select(pr => pr.PackageIdentity.Id); // Main Act var packageActions = (await nuGetPackageManager.PreviewUpdatePackagesAsync(installedPackageIds, msBuildNuGetProject, new ResolutionContext(DependencyBehavior.Highest), new TestNuGetProjectContext(), sourceRepositoryProvider.GetRepositories().First(), null, token)).ToList(); // Assert Assert.Equal(2, packageActions.Count); Assert.True(packageIdentity0.Equals(packageActions[0].PackageIdentity)); Assert.Equal(NuGetProjectActionType.Uninstall, packageActions[0].NuGetProjectActionType); Assert.True(packageLatest.Equals(packageActions[1].PackageIdentity)); Assert.Equal(NuGetProjectActionType.Install, packageActions[1].NuGetProjectActionType); Assert.Equal(sourceRepositoryProvider.GetRepositories().Single().PackageSource.Source, packageActions[1].SourceRepository.PackageSource.Source); // Clean-up TestFilesystemUtility.DeleteRandomTestFolders(testSolutionManager.SolutionDirectory, randomPackagesConfigFolderPath); }