Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
        }