public static void GenerateNupkgMetadataFile(string nupkgPath, string installPath, string hashPath, string nupkgMetadataPath) { ConcurrencyUtilities.ExecuteWithFileLocked(nupkgPath, action: () => { // make sure new hash file doesn't exists within File lock before actually creating it. if (!File.Exists(nupkgMetadataPath)) { var tempNupkgMetadataFilePath = Path.Combine(installPath, Path.GetRandomFileName()); using (var stream = File.Open(nupkgPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var packageReader = new PackageArchiveReader(stream)) { // get hash of unsigned content of signed package var packageHash = packageReader.GetContentHashForSignedPackage(CancellationToken.None); // if null, then it's unsigned package so just read the existing sha512 file if (string.IsNullOrEmpty(packageHash)) { packageHash = File.ReadAllText(hashPath); } // write the new hash file var hashFile = new NupkgMetadataFile() { ContentHash = packageHash }; NupkgMetadataFileFormat.Write(tempNupkgMetadataFilePath, hashFile); File.Move(tempNupkgMetadataFilePath, nupkgMetadataPath); } } }); }
/// <summary> /// Read the .metadata.json file from disk. /// </summary> /// <remarks>Throws if the file is not found or corrupted.</remarks> public virtual Lazy <string> GetOrAddSha512(string sha512Path) { return(_sha512Cache.GetOrAdd(sha512Path, e => new Lazy <string>(() => { var metadataFile = NupkgMetadataFileFormat.Read(e); return metadataFile.ContentHash; }))); }
public async Task MsbuildRestore_PackageReferenceDependencyCsProjAsync() { // Arrange using (var pathContext = new SimpleTestPathContext()) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var net461 = NuGetFramework.Parse("net461"); var projectA = new SimpleTestProjectContext( "a", ProjectStyle.PackageReference, pathContext.SolutionRoot); projectA.Frameworks.Add(new SimpleTestProjectFrameworkContext(net461)); var packageX = new SimpleTestPackageContext() { Id = "x", Version = "1.0.0" }; packageX.Files.Clear(); projectA.AddPackageToAllFrameworks(packageX); packageX.AddFile("lib/net461/a.dll"); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); var configAPath = Path.Combine(Path.GetDirectoryName(projectA.ProjectPath), "NuGet.Config"); var configText = $@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <packageSources> <add key=""LocalSource"" value=""{pathContext.PackageSource}"" /> </packageSources> </configuration>"; using (var writer = new StreamWriter(configAPath)) { writer.Write(configText); } await SimpleTestPackageUtility.CreateFolderFeedV3Async( pathContext.PackageSource, packageX); // Act var result = _msbuildFixture.RunMsBuild(pathContext.WorkingDirectory, $"/t:restore {projectA.ProjectPath}", ignoreExitCode: true); // Assert Assert.True(result.ExitCode == 0, result.AllOutput); var resolver = new VersionFolderPathResolver(pathContext.UserPackagesFolder); var nupkg = NupkgMetadataFileFormat.Read(resolver.GetNupkgMetadataPath(packageX.Id, NuGetVersion.Parse(packageX.Version)), NullLogger.Instance); Assert.Contains($"Installed x 1.0.0 from {pathContext.PackageSource} with content hash {nupkg.ContentHash}.", result.AllOutput); Assert.Contains(configAPath, result.AllOutput); } }
private void WriteNupkgMetadata(string nupkgPath, string contentHash) { var metadataPath = GetNupkgMetadataPath(nupkgPath); var metadata = new NupkgMetadataFile() { ContentHash = contentHash }; NupkgMetadataFileFormat.Write(metadataPath, metadata); }
private Result TryGetNupkgMetadata(string nupkgPath) { var metadataPath = Path.Combine(Path.GetDirectoryName(nupkgPath), PackagingCoreConstants.NupkgMetadataFileExtension); if (File.Exists(metadataPath)) { var metadata = NupkgMetadataFileFormat.Read(metadataPath); return(new Result(found: true, contentHash: metadata.ContentHash)); } return(Result.NotFound); }
public void Read_ContentsNotAnObject_ThrowsException(string contents) { // Arrange var logger = new TestLogger(); // Act using (var stringReader = new StringReader(contents)) { Assert.Throws <InvalidDataException>(() => NupkgMetadataFileFormat.Read(stringReader, logger, "from memory")); } // Assert Assert.Equal(1, logger.Messages.Count); }
public void Read_ContentsInvalidJson_ThrowsJsonReaderException() { // Arrange var logger = new TestLogger(); // Act using (var stringReader = new StringReader(@"{""version"":")) { Assert.Throws <JsonReaderException>(() => NupkgMetadataFileFormat.Read(stringReader, logger, "from memory")); } // Assert Assert.Equal(1, logger.Messages.Count); }
public void NupkgMetadataFileFormat_Read() { var nupkgMetadataFileContent = @"{ ""version"": 1, ""contentHash"": ""NhfNp80eWq5ms7fMrjuRqpwhL1H56IVzXF9d+OIDcEfQ92m1DyE0c+ufUE1ogB09+sYLd58IO4eJ8jyn7AifbA=="" }"; using (var reader = new StringReader(nupkgMetadataFileContent)) { var file = NupkgMetadataFileFormat.Read(reader, NullLogger.Instance, string.Empty); Assert.NotNull(file); Assert.Equal(1, file.Version); Assert.Equal("NhfNp80eWq5ms7fMrjuRqpwhL1H56IVzXF9d+OIDcEfQ92m1DyE0c+ufUE1ogB09+sYLd58IO4eJ8jyn7AifbA==", file.ContentHash); } }
public void Read_V1FileContents_ReturnsCorrectObject() { // Arrange var nupkgMetadataFileContent = @"{ ""version"": 1, ""contentHash"": ""NhfNp80eWq5ms7fMrjuRqpwhL1H56IVzXF9d+OIDcEfQ92m1DyE0c+ufUE1ogB09+sYLd58IO4eJ8jyn7AifbA=="" }"; // Act NupkgMetadataFile file; using (var reader = new StringReader(nupkgMetadataFileContent)) { file = NupkgMetadataFileFormat.Read(reader, NullLogger.Instance, string.Empty); } // Assert Assert.NotNull(file); Assert.Equal(1, file.Version); Assert.Equal("NhfNp80eWq5ms7fMrjuRqpwhL1H56IVzXF9d+OIDcEfQ92m1DyE0c+ufUE1ogB09+sYLd58IO4eJ8jyn7AifbA==", file.ContentHash); Assert.Null(file.Source); }
public void Read_ContentsWithUnexpectedValues_IgnoresUnexpectedValues() { // Arrange var logger = new TestLogger(); var nupkgMetadataFileContent = @"{ ""version"": 2, ""contentHash"": ""NhfNp80eWq5ms7fMrjuRqpwhL1H56IVzXF9d+OIDcEfQ92m1DyE0c+ufUE1ogB09+sYLd58IO4eJ8jyn7AifbA=="", ""source"": ""https://source/v3/index.json"", ""number"": 1, ""array"": [], ""object"": {} }"; // Act using (var stringReader = new StringReader(nupkgMetadataFileContent)) { NupkgMetadataFileFormat.Read(stringReader, logger, "from memory"); } // Assert Assert.Equal(0, logger.Messages.Count); }
public void NupkgMetadataFileFormat_Write() { var nupkgMetadataFileContent = @"{ ""version"": 1, ""contentHash"": ""NhfNp80eWq5ms7fMrjuRqpwhL1H56IVzXF9d+OIDcEfQ92m1DyE0c+ufUE1ogB09+sYLd58IO4eJ8jyn7AifbA=="" }"; NupkgMetadataFile metadataFile = null; using (var reader = new StringReader(nupkgMetadataFileContent)) { metadataFile = NupkgMetadataFileFormat.Read(reader, NullLogger.Instance, string.Empty); } using (var writer = new StringWriter()) { NupkgMetadataFileFormat.Write(writer, metadataFile); var output = JObject.Parse(writer.ToString()); var expected = JObject.Parse(nupkgMetadataFileContent); Assert.Equal(expected.ToString(), output.ToString()); } }
public async Task MsbuildRestore_PR_PackageSourceMapping_WithAllRestoreSourceProperies_Succeed() { // Arrange using var pathContext = new SimpleTestPathContext(); // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var workingPath = pathContext.WorkingDirectory; var opensourceRepositoryPath = Path.Combine(workingPath, "PublicRepository"); Directory.CreateDirectory(opensourceRepositoryPath); var privateRepositoryPath = Path.Combine(workingPath, "PrivateRepository"); Directory.CreateDirectory(privateRepositoryPath); var net461 = NuGetFramework.Parse("net461"); var projectA = new SimpleTestProjectContext( "a", ProjectStyle.PackageReference, pathContext.SolutionRoot); projectA.Frameworks.Add(new SimpleTestProjectFrameworkContext(net461)); // Add both repositories as RestoreSources projectA.Properties.Add("RestoreSources", $"{opensourceRepositoryPath};{privateRepositoryPath}"); var packageOpenSourceA = new SimpleTestPackageContext("Contoso.Opensource.A", "1.0.0"); packageOpenSourceA.AddFile("lib/net461/openA.dll"); var packageOpenSourceContosoMvc = new SimpleTestPackageContext("Contoso.MVC.ASP", "1.0.0"); // Package Id conflict with internally created package packageOpenSourceContosoMvc.AddFile("lib/net461/openA.dll"); var packageContosoMvcReal = new SimpleTestPackageContext("Contoso.MVC.ASP", "1.0.0"); packageContosoMvcReal.AddFile("lib/net461/realA.dll"); projectA.AddPackageToAllFrameworks(packageOpenSourceA); projectA.AddPackageToAllFrameworks(packageOpenSourceContosoMvc); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); // SimpleTestPathContext adds a NuGet.Config with a repositoryPath, // so we go ahead and replace that config before running MSBuild. var configAPath = Path.Combine(Path.GetDirectoryName(projectA.ProjectPath), "NuGet.Config"); var configText = $@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <packageSources> <!--To inherit the global NuGet package sources remove the <clear/> line below --> <clear /> <add key=""PublicRepository"" value=""{opensourceRepositoryPath}"" /> <add key=""PrivateRepository"" value=""{privateRepositoryPath}"" /> </packageSources> <packageSourceMapping> <packageSource key=""PublicRepository""> <package pattern=""Contoso.Opensource.*"" /> </packageSource> <packageSource key=""PrivateRepository""> <package pattern=""Contoso.MVC.*"" /> <!--Contoso.MVC.ASP package exist in both repository but it'll restore from this one --> </packageSource> </packageSourceMapping> </configuration>"; using (var writer = new StreamWriter(configAPath)) { writer.Write(configText); } await SimpleTestPackageUtility.CreateFolderFeedV3Async( opensourceRepositoryPath, packageOpenSourceA, packageOpenSourceContosoMvc); await SimpleTestPackageUtility.CreateFolderFeedV3Async( privateRepositoryPath, packageContosoMvcReal); // Act var r = _msbuildFixture.RunMsBuild(pathContext.WorkingDirectory, $"/t:restore -v:d {pathContext.SolutionRoot}", ignoreExitCode: true); // Assert Assert.True(r.ExitCode == 0); Assert.Contains($"Package source mapping matches found for package ID 'Contoso.MVC.ASP' are: 'PrivateRepository'", r.Output); Assert.Contains($"Package source mapping matches found for package ID 'Contoso.Opensource.A' are: 'PublicRepository'", r.Output); var localResolver = new VersionFolderPathResolver(pathContext.UserPackagesFolder); var contosoMvcMetadataPath = localResolver.GetNupkgMetadataPath(packageContosoMvcReal.Identity.Id, packageContosoMvcReal.Identity.Version); NupkgMetadataFile contosoMvcmetadata = NupkgMetadataFileFormat.Read(contosoMvcMetadataPath); Assert.Equal(privateRepositoryPath, contosoMvcmetadata.Source); }
/// <summary> /// Initializes a new instance of the <see cref="PackageManifest"/> class. /// </summary> /// <param name="fullPath">The full path to the manifest file.</param> /// <param name="name">The name or ID of the package.</param> /// <param name="version">The semantic version of the package.</param> /// <param name="authors">An optional semicolon delimited list of authors of the package. The default value is "UserA"</param> /// <param name="description">An optional description of the package. The default value is "Description"</param> /// <param name="copyright">An optional copyright of the package.</param> /// <param name="developmentDependency">An optional value indicating whether or not the package is a development dependency. The default value is <code>false</code>.</param> /// <param name="iconUrl">An optional URL to the icon of the package.</param> /// <param name="language">An optional language of the package.</param> /// <param name="licenseUrl">An optional URL to the license of the package.</param> /// <param name="licenseMetadata">An optional <see cref="LicenseMetadata" /> of the package.</param> /// <param name="owners">An optional semicolon delimited list of owners of the package.</param> /// <param name="packageTypes">An optional <see cref="IEnumerable{PackageType}" /> containing the package types of the package.</param> /// <param name="projectUrl">An optional URL to the project of the package.</param> /// <param name="releaseNotes">An optional value specifying release notes of the package.</param> /// <param name="repositoryType">An optional value specifying the type of source code repository of the package.</param> /// <param name="repositoryUrl">An optional value specifying the URL of the source code repository of the package.</param> /// <param name="repositoryBranch">An optional value specifying the branch of the source code repository of the package.</param> /// <param name="repositoryCommit">An optional value specifying the commit of the source code repository of the package.</param> /// <param name="requireLicenseAcceptance">An optional value indicating whether or not the package requires license acceptance The default value is <code>false</code>.</param> /// <param name="serviceable">An option value indicating whether or not the package is serviceable. The default value is <code>false</code>.</param> /// <param name="summary">An optional summary of the package.</param> /// <param name="tags">An optional set of tags of the package.</param> /// <param name="title">An optional title of the package.</param> #else /// <summary> /// Initializes a new instance of the <see cref="PackageManifest"/> class. /// </summary> /// <param name="fullPath">The full path to the manifest file.</param> /// <param name="name">The name or ID of the package.</param> /// <param name="version">The semantic version of the package.</param> /// <param name="authors">An optional semicolon delimited list of authors of the package. The default value is "UserA"</param> /// <param name="description">An optional description of the package. The default value is "Description"</param> /// <param name="copyright">An optional copyright of the package.</param> /// <param name="developmentDependency">An optional value indicating whether or not the package is a development dependency. The default value is <code>false</code>.</param> /// <param name="icon">An optional path in the package that should be used for the icon of the package.</param> /// <param name="iconUrl">An optional URL to the icon of the package.</param> /// <param name="language">An optional language of the package.</param> /// <param name="licenseUrl">An optional URL to the license of the package.</param> /// <param name="licenseMetadata">An optional <see cref="LicenseMetadata" /> of the package.</param> /// <param name="owners">An optional semicolon delimited list of owners of the package.</param> /// <param name="packageTypes">An optional <see cref="IEnumerable{PackageType}" /> containing the package types of the package.</param> /// <param name="projectUrl">An optional URL to the project of the package.</param> /// <param name="releaseNotes">An optional value specifying release notes of the package.</param> /// <param name="repositoryType">An optional value specifying the type of source code repository of the package.</param> /// <param name="repositoryUrl">An optional value specifying the URL of the source code repository of the package.</param> /// <param name="repositoryBranch">An optional value specifying the branch of the source code repository of the package.</param> /// <param name="repositoryCommit">An optional value specifying the commit of the source code repository of the package.</param> /// <param name="requireLicenseAcceptance">An optional value indicating whether or not the package requires license acceptance The default value is <code>false</code>.</param> /// <param name="serviceable">An option value indicating whether or not the package is serviceable. The default value is <code>false</code>.</param> /// <param name="summary">An optional summary of the package.</param> /// <param name="tags">An optional set of tags of the package.</param> /// <param name="title">An optional title of the package.</param> #endif public PackageManifest( string fullPath, string name, string version, string authors = null, string description = null, string copyright = null, bool developmentDependency = false, #if !NET46 string icon = null, #endif string iconUrl = null, string language = null, string licenseUrl = null, LicenseMetadata licenseMetadata = null, string owners = null, IEnumerable <PackageType> packageTypes = null, string projectUrl = null, string releaseNotes = null, string repositoryType = null, string repositoryUrl = null, string repositoryBranch = null, string repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string summary = null, string tags = null, string title = null) : base( GetManifestMetadata( name, version, authors, description, copyright, developmentDependency, #if !NET46 icon, #endif iconUrl, language, licenseUrl, licenseMetadata, owners, packageTypes, projectUrl, releaseNotes, repositoryType, repositoryUrl, repositoryBranch, repositoryCommit, requireLicenseAcceptance, serviceable, summary, tags, title)) { if (string.IsNullOrWhiteSpace(fullPath)) { throw new ArgumentNullException(nameof(fullPath)); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException(nameof(name)); } if (string.IsNullOrWhiteSpace(version)) { throw new ArgumentNullException(nameof(version)); } FullPath = fullPath; Directory = Path.GetDirectoryName(fullPath); Save(); NupkgMetadataFileFormat.Write( Path.Combine(Directory, PackagingCoreConstants.NupkgMetadataFileExtension), new NupkgMetadataFile { ContentHash = string.Empty, Version = NupkgMetadataFileFormat.Version, }); }