public string CreateReleasePackage(string outputFile, string packagesRootDir = null, Func <string, string> releaseNotesProcessor = null, Action <string> contentsPostProcessHook = null) { Contract.Requires(!String.IsNullOrEmpty(outputFile)); releaseNotesProcessor = releaseNotesProcessor ?? (x => (new Markdown()).Transform(x)); if (ReleasePackageFile != null) { return(ReleasePackageFile); } var package = new ZipPackage(InputPackageFile); var dontcare = default(SemanticVersion); // NB: Our test fixtures use packages that aren't SemVer compliant, // we don't really care that they aren't valid if (!ModeDetector.InUnitTestRunner() && !SemanticVersion.TryParseStrict(package.Version.ToString(), out dontcare)) { throw new Exception( String.Format( "Your package version is currently {0}, which is *not* SemVer-compatible, change this to be a SemVer version number", package.Version.ToString())); } // we can tell from here what platform(s) the package targets // but given this is a simple package we only // ever expect one entry here (crash hard otherwise) var frameworks = package.GetSupportedFrameworks(); if (frameworks.Count() > 1) { var platforms = frameworks .Aggregate(new StringBuilder(), (sb, f) => sb.Append(f.ToString() + "; ")); throw new InvalidOperationException(String.Format( "The input package file {0} targets multiple platforms - {1} - and cannot be transformed into a release package.", InputPackageFile, platforms)); } else if (!frameworks.Any()) { throw new InvalidOperationException(String.Format( "The input package file {0} targets no platform and cannot be transformed into a release package.", InputPackageFile)); } var targetFramework = frameworks.Single(); // Recursively walk the dependency tree and extract all of the // dependent packages into the a temporary directory this.Log().Info("Creating release package: {0} => {1}", InputPackageFile, outputFile); var dependencies = findAllDependentPackages( package, new LocalPackageRepository(packagesRootDir), frameworkName: targetFramework) .ToArray(); string tempPath = null; using (Utility.WithTempDirectory(out tempPath, null)) { var tempDir = new DirectoryInfo(tempPath); extractZipWithEscaping(InputPackageFile, tempPath).Wait(); this.Log().Info("Extracting dependent packages: [{0}]", String.Join(",", dependencies.Select(x => x.Id))); extractDependentPackages(dependencies, tempDir, targetFramework); var specPath = tempDir.GetFiles("*.nuspec").First().FullName; this.Log().Info("Removing unnecessary data"); removeDependenciesFromPackageSpec(specPath); removeDeveloperDocumentation(tempDir); if (releaseNotesProcessor != null) { renderReleaseNotesMarkdown(specPath, releaseNotesProcessor); } addDeltaFilesToContentTypes(tempDir.FullName); contentsPostProcessHook?.Invoke(tempPath); Utility.CreateZipFromDirectory(outputFile, tempPath).Wait(); ReleasePackageFile = outputFile; return(ReleasePackageFile); } }
public string CreateReleasePackage(string outputFile, string packagesRootDir = null, Func <string, string> releaseNotesProcessor = null) { Contract.Requires(!String.IsNullOrEmpty(outputFile)); releaseNotesProcessor = releaseNotesProcessor ?? (x => (new Markdown()).Transform(x)); if (ReleasePackageFile != null) { return(ReleasePackageFile); } var package = new ZipPackage(InputPackageFile); // we can tell from here what platform(s) the package targets // but given this is a simple package we only // ever expect one entry here (crash hard otherwise) var frameworks = package.GetSupportedFrameworks(); if (frameworks.Count() > 1) { var platforms = frameworks .Aggregate(new StringBuilder(), (sb, f) => sb.Append(f.ToString() + "; ")); throw new InvalidOperationException(String.Format( "The input package file {0} targets multiple platforms - {1} - and cannot be transformed into a release package.", InputPackageFile, platforms)); } else if (!frameworks.Any()) { throw new InvalidOperationException(String.Format( "The input package file {0} targets no platform and cannot be transformed into a release package.", InputPackageFile)); } var targetFramework = frameworks.Single(); // Recursively walk the dependency tree and extract all of the // dependent packages into the a temporary directory this.Log().Info("Creating release package: {0} => {1}", InputPackageFile, outputFile); var dependencies = findAllDependentPackages( package, new LocalPackageRepository(packagesRootDir), frameworkName: targetFramework); string tempPath = null; using (Utility.WithTempDirectory(out tempPath)) { var tempDir = new DirectoryInfo(tempPath); using (var zf = new ZipFile(InputPackageFile)) { zf.ExtractAll(tempPath); } this.Log().Info("Extracting dependent packages: [{0}]", String.Join(",", dependencies.Select(x => x.Id))); extractDependentPackages(dependencies, tempDir, targetFramework); var specPath = tempDir.GetFiles("*.nuspec").First().FullName; this.Log().Info("Removing unnecessary data"); removeDependenciesFromPackageSpec(specPath); removeDeveloperDocumentation(tempDir); if (releaseNotesProcessor != null) { renderReleaseNotesMarkdown(specPath, releaseNotesProcessor); } addDeltaFilesToContentTypes(tempDir.FullName); using (var zf = new ZipFile(outputFile)) { this.Log().Info("Succeeeded, saving to " + outputFile); zf.AddDirectory(tempPath); zf.Save(); } ReleasePackageFile = outputFile; return(ReleasePackageFile); } }
public IList <PackageIndexError> AddPackage(ZipPackage package, bool force = false) { if (package == null) { return(null); } // check if package exists in the index: // - if it does not, proceed and add it // - if it is, add to index only if new package has higher version var existingPackage = GetPackages(package.Id).FirstOrDefault(); if (existingPackage != null) { var existingPackageVersion = new SemanticVersion(existingPackage.Version); if (existingPackageVersion >= package.Version && !force) { Logger.WriteVerbose("More recent version {0} of package {1} {2} exists in the index. Skipping...", existingPackageVersion.ToString(), package.Id, package.Version); return(new List <PackageIndexError>()); } else { // Remove all old packages types. This is for the case if new package does not // contain some types (deprecated), in this case index would still keep them. Logger.WriteVerbose("Older version {0} of package {1} {2} exists in the index. Removing from index...", existingPackageVersion.ToString(), package.Id, package.Version); RemovePackage(package.Id); } } Logger.WriteInformation("Adding package {0} {1} to index.", package.Id, package.Version); var libFiles = package.GetLibFiles().Where(x => ".dll".Equals(Path.GetExtension(x.EffectivePath), StringComparison.OrdinalIgnoreCase)); var packageTargetFrameworks = package.GetSupportedFrameworks(); var packageTypes = new Dictionary <string, TypeModel>(StringComparer.OrdinalIgnoreCase); // get a list of all public types in all unique package assemblies foreach (IPackageFile dll in libFiles) { // if dll is a contracts dll it provides types accross all frameworks supported by package var dllTtargetFrameworks = packageTargetFrameworks; if (dll.TargetFramework != null && !dll.Path.ToLower().Contains(@"lib\contract")) { dllTtargetFrameworks = new[] { dll.TargetFramework }; } Logger.WriteVerbose("Processing assembly {0}.", dll.Path); var assemblyTypes = ProcessAssembly(package.Id, package.Version.ToString(), dllTtargetFrameworks, dll.GetStream()); if (assemblyTypes != null) { Logger.WriteVerbose("Found {0} public types.", assemblyTypes.Count()); MergeTypes(packageTypes, assemblyTypes); } } Logger.WriteVerbose("Storing package model to the index."); // add a pckage entry to index var result = Engine.AddEntry( new PackageModel { Name = package.Id, Version = package.Version.ToString() }); Logger.WriteVerbose("Storing type models to the index."); // add all types to index result.AddRange(Engine.AddEntries(packageTypes.Values, true)); Logger.WriteVerbose("Package indexing complete."); return(result); }