Beispiel #1
0
        private void ExtractTo(string format, byte[] data, string path)
        {
            Console.WriteLine("Unpacking binary package from " + format + " archive");
            switch (format)
            {
            case PackageManager.ARCHIVE_FORMAT_TAR_GZIP:
            {
                using (var memory = new MemoryStream(data))
                {
                    using (var decompress = new GZipStream(memory, CompressionMode.Decompress))
                    {
                        using (var memory2 = new MemoryStream())
                        {
                            decompress.CopyTo(memory2);
                            memory2.Seek(0, SeekOrigin.Begin);
                            var reader       = new tar_cs.TarReader(memory2);
                            var reduplicator = new Reduplicator();
                            reduplicator.UnpackTarToFolder(reader, path);
                        }
                    }
                }
                break;
            }

            case PackageManager.ARCHIVE_FORMAT_TAR_LZMA:
            {
                using (var inMemory = new MemoryStream(data))
                {
                    using (var outMemory = new MemoryStream())
                    {
                        LZMA.LzmaHelper.Decompress(inMemory, outMemory);
                        outMemory.Seek(0, SeekOrigin.Begin);
                        var reader       = new tar_cs.TarReader(outMemory);
                        var reduplicator = new Reduplicator();
                        reduplicator.UnpackTarToFolder(reader, path);
                    }
                }
                break;
            }

            default:
                throw new InvalidOperationException(
                          "This version of Protobuild does not support the " +
                          format + " package format.");
            }
        }
 public void ExtractTo(string path)
 {
     Console.WriteLine("Unpacking binary package from " + this.Format + " archive");
     switch (this.Format)
     {
         case PackageManager.ARCHIVE_FORMAT_TAR_GZIP:
             {
                 using (var memory = new MemoryStream(this.PackageData))
                 {
                     using (var decompress = new GZipStream(memory, CompressionMode.Decompress))
                     {
                         using (var memory2 = new MemoryStream())
                         {
                             decompress.CopyTo(memory2);
                             memory2.Seek(0, SeekOrigin.Begin);
                             var reader = new tar_cs.TarReader(memory2);
                             var reduplicator = new Reduplicator();
                             reduplicator.UnpackTarToFolder(reader, path);
                         }
                     }
                 }
                 break;
             }
         case PackageManager.ARCHIVE_FORMAT_TAR_LZMA:
             {
                 using (var inMemory = new MemoryStream(this.PackageData))
                 {
                     using (var outMemory = new MemoryStream())
                     {
                         LZMA.LzmaHelper.Decompress(inMemory, outMemory);
                         outMemory.Seek(0, SeekOrigin.Begin);
                         var reader = new tar_cs.TarReader(outMemory);
                         var reduplicator = new Reduplicator();
                         reduplicator.UnpackTarToFolder(reader, path);
                     }
                 }
                 break;
             }
         default:
             throw new InvalidOperationException(
                 "This version of Protobuild does not support the " +
                 this.Format + " package format.");
     }
 }
Beispiel #3
0
        private void ConvertNuGetOnlyPackage(Reduplicator reduplicator, ZipStorer zipStorer, string path, string packageName, string workingDirectory, string platform)
        {
            var folder = Path.GetTempFileName();

            File.Delete(folder);
            Directory.CreateDirectory(folder);

            try
            {
                reduplicator.UnpackZipToFolder(
                    zipStorer,
                    folder,
                    candidatePath => true,
                    outputPath => outputPath);

                var references          = new List <string>();
                var libraryReferences   = new Dictionary <string, string>();
                var packageDependencies = new Dictionary <string, string>();

                // Load NuGet specification file.
                var specFile = Directory.GetFiles(folder, "*.nuspec").FirstOrDefault();
                if (specFile != null)
                {
                    specFile = Path.Combine(folder, specFile);
                    if (File.Exists(specFile))
                    {
                        var packageDoc = new XmlDocument();
                        packageDoc.Load(specFile);

                        if (packageDoc?.DocumentElement != null)
                        {
                            // If we have an id in the package, that forms the package name.
                            if (packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                                .Count(x => x.Name == "id") > 0)
                            {
                                var newName = packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                                              .First(x => x.Name == "id").InnerText.Trim();
                                if (!string.IsNullOrWhiteSpace(newName))
                                {
                                    packageName = newName;
                                }
                            }

                            // If the references are explicitly provided in the nuspec, use
                            // those as to what files should be referenced by the projects.
                            if (packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                                .Count(x => x.Name == "references") > 0)
                            {
                                references =
                                    packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                                    .First(x => x.Name == "references")
                                    .ChildNodes.OfType <XmlElement>()
                                    .Where(x => x.Name == "reference")
                                    .Select(x => x.Attributes["file"].Value)
                                    .ToList();
                            }

                            // If there are dependencies specified, store them and convert them to
                            // Protobuild references, and reference them in the Module.xml file.
                            if (packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                                .Count(x => x.Name == "dependencies") > 0)
                            {
                                packageDependencies =
                                    packageDoc.DocumentElement.FirstChild.ChildNodes.OfType <XmlElement>()
                                    .First(x => x.Name == "dependencies")
                                    .ChildNodes.OfType <XmlElement>()
                                    .Where(x => x.Name == "dependency")
                                    .ToDictionarySafe(
                                        k => k.Attributes["id"].Value,
                                        v => v.Attributes["version"].Value,
                                        (dict, c) =>
                                        RedirectableConsole.WriteLine("WARNING: More than one dependency on " +
                                                                      c +
                                                                      " in NuGet package."));
                            }
                        }
                    }
                }

                if (string.IsNullOrWhiteSpace(packageName))
                {
                    throw new InvalidOperationException("Expected package name when converting NuGet-only package!");
                }

                // Determine the priority of the frameworks that we want to target
                // out of the available versions.
                string[] clrNames = _nugetPlatformMapping.GetFrameworkNamesForRead(workingDirectory, platform);

                var referenceDirectories = new string[] { "ref", "lib" };

                foreach (var directory in referenceDirectories)
                {
                    // Determine the base path for all references; that is, the lib/ folder.
                    var referenceBasePath = Path.Combine(
                        folder,
                        directory);

                    if (Directory.Exists(referenceBasePath))
                    {
                        // If no references are in nuspec, reference all of the libraries that
                        // are on disk.
                        if (references.Count == 0)
                        {
                            // Search through all of the target frameworks until we find one that
                            // has at least one file in it.
                            foreach (var clrNameOriginal in clrNames)
                            {
                                var clrName  = clrNameOriginal;
                                var foundClr = false;

                                if (clrName[0] == '=')
                                {
                                    // Exact match (strip the equals).
                                    clrName = clrName.Substring(1);

                                    // If this target framework doesn't exist for this library, skip it.
                                    var dirPath = Path.Combine(
                                        referenceBasePath,
                                        clrName);
                                    if (!Directory.Exists(dirPath))
                                    {
                                        continue;
                                    }
                                }
                                else if (clrName[0] == '?')
                                {
                                    // Substring, search the reference base path for any folders
                                    // with a matching substring.
                                    clrName = clrName.Substring(1);

                                    var baseDirPath = referenceBasePath;
                                    var found       = false;
                                    foreach (var subdir in new DirectoryInfo(baseDirPath).GetDirectories())
                                    {
                                        if (subdir.Name.Contains(clrName))
                                        {
                                            clrName = subdir.Name;
                                            found   = true;
                                            break;
                                        }
                                    }

                                    if (!found)
                                    {
                                        continue;
                                    }
                                }
                                else
                                {
                                    throw new InvalidOperationException("Unknown CLR name match type with '" + clrName +
                                                                        "'");
                                }

                                // Otherwise enumerate through all of the libraries in this folder.
                                foreach (var dll in Directory.EnumerateFiles(
                                             Path.Combine(
                                                 referenceBasePath, clrName),
                                             "*.dll"))
                                {
                                    // Determine the relative path to the library.
                                    var packageDll = Path.Combine(
                                        referenceBasePath,
                                        clrName,
                                        Path.GetFileName(dll));

                                    // Confirm again that the file actually exists on disk when
                                    // combined with the root path.
                                    if (File.Exists(
                                            Path.Combine(
                                                packageDll)))
                                    {
                                        // Create the library reference.
                                        if (!libraryReferences.ContainsKey(Path.GetFileNameWithoutExtension(dll)))
                                        {
                                            libraryReferences.Add(
                                                Path.GetFileNameWithoutExtension(dll),
                                                packageDll);
                                        }

                                        // Mark this target framework as having provided at least
                                        // one reference.
                                        foundClr = true;
                                    }
                                }

                                // Break if we have found at least one reference.
                                if (foundClr)
                                {
                                    break;
                                }
                            }
                        }

                        // For all of the references that were found in the original nuspec file,
                        // add those references.
                        foreach (var reference in references)
                        {
                            // Search through all of the target frameworks until we find the one
                            // that has the reference in it.
                            foreach (var clrName in clrNames)
                            {
                                // If this target framework doesn't exist for this library, skip it.
                                var packageDll = Path.Combine(
                                    referenceBasePath,
                                    clrName,
                                    reference);

                                if (File.Exists(
                                        Path.Combine(
                                            packageDll)))
                                {
                                    if (!libraryReferences.ContainsKey(Path.GetFileNameWithoutExtension(packageDll)))
                                    {
                                        libraryReferences.Add(
                                            Path.GetFileNameWithoutExtension(packageDll),
                                            packageDll);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                foreach (var kv in libraryReferences)
                {
                    RedirectableConsole.WriteLine("Found library to reference: " + kv.Key + " (at " + kv.Value + ")");
                }

                RedirectableConsole.WriteLine("Generating external project reference...");
                var document        = new XmlDocument();
                var externalProject = document.CreateElement("ExternalProject");
                externalProject.SetAttribute("Name", packageName);
                document.AppendChild(externalProject);
                foreach (var kv in libraryReferences)
                {
                    var binaryReference = document.CreateElement("Binary");
                    binaryReference.SetAttribute("Name", kv.Key);
                    binaryReference.SetAttribute("Path",
                                                 kv.Value.Substring(folder.Length).TrimStart(new[] { '/', '\\' }).Replace("%2B", "-"));
                    externalProject.AppendChild(binaryReference);
                }
                foreach (var package in packageDependencies)
                {
                    var externalReference = document.CreateElement("Reference");
                    externalReference.SetAttribute("Include", package.Key);
                    externalProject.AppendChild(externalReference);
                }
                Directory.CreateDirectory(Path.Combine(path, "Build", "Projects"));
                document.Save(Path.Combine(path, "Build", "Projects", packageName + ".definition"));

                RedirectableConsole.WriteLine("Generating module...");
                var generatedModule = new ModuleInfo();
                generatedModule.Name     = packageName;
                generatedModule.Packages = new List <PackageRef>();

                foreach (var package in packageDependencies)
                {
                    generatedModule.Packages.Add(new PackageRef
                    {
                        Uri    = "https-nuget-v3://api.nuget.org/v3/index.json|" + package.Key,
                        GitRef = package.Value.TrimStart('[').TrimEnd(']'),
                        Folder = package.Key
                    });
                }

                generatedModule.Save(Path.Combine(path, "Build", "Module.xml"));

                foreach (var kv in libraryReferences)
                {
                    var targetFile =
                        new FileInfo(Path.Combine(path,
                                                  kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/').Replace("%2B", "-")));
                    targetFile.Directory.Create();
                    File.Copy(kv.Value, targetFile.FullName);
                }
            }
            finally
            {
                PathUtils.AggressiveDirectoryDelete(folder);
            }
        }
Beispiel #4
0
        private void ExtractTo(string workingDirectory, string packageName, string format, byte[] data, string path, string platform)
        {
            RedirectableConsole.WriteLine("Unpacking binary package from " + format + " archive");
            switch (format)
            {
            case PackageManager.ARCHIVE_FORMAT_TAR_GZIP:
            {
                using (var memory = new MemoryStream(data))
                {
                    using (var decompress = new GZipStream(memory, CompressionMode.Decompress))
                    {
                        using (var memory2 = new MemoryStream())
                        {
                            decompress.CopyTo(memory2);
                            memory2.Seek(0, SeekOrigin.Begin);
                            var reader       = new tar_cs.TarReader(memory2);
                            var reduplicator = new Reduplicator();
                            reduplicator.UnpackTarToFolder(reader, path);
                        }
                    }
                }
                break;
            }

            case PackageManager.ARCHIVE_FORMAT_TAR_LZMA:
            {
                using (var inMemory = new MemoryStream(data))
                {
                    using (var outMemory = new MemoryStream())
                    {
                        LZMA.LzmaHelper.Decompress(inMemory, outMemory);
                        outMemory.Seek(0, SeekOrigin.Begin);
                        var reader       = new tar_cs.TarReader(outMemory);
                        var reduplicator = new Reduplicator();
                        reduplicator.UnpackTarToFolder(reader, path);
                    }
                }
                break;
            }

            case PackageManager.ARCHIVE_FORMAT_NUGET_ZIP:
            {
                using (var inMemory = new MemoryStream(data))
                {
                    using (var zipStorer = ZipStorer.Open(inMemory, FileAccess.Read, true))
                    {
                        var reduplicator   = new Reduplicator();
                        var extractedFiles = reduplicator.UnpackZipToFolder(
                            zipStorer,
                            path,
                            candidatePath => candidatePath.Replace('\\', '/').StartsWith("protobuild/" + platform + "/"),
                            outputPath => outputPath.Replace('\\', '/').Substring(("protobuild/" + platform + "/").Length));

                        if (extractedFiles.Count == 0)
                        {
                            // There were no files that matched protobuild/ which means this is
                            // not a Protobuild-aware NuGet package.  We need to convert it on-the-fly
                            // to a compatible Protobuild format.
                            ConvertNuGetOnlyPackage(reduplicator, zipStorer, path, packageName, workingDirectory, platform);
                        }
                    }
                }
                break;
            }

            default:
                throw new InvalidOperationException(
                          "This version of Protobuild does not support the " +
                          format + " package format.");
            }
        }