private void ResolveTemplateBinary(PackageRef reference, string templateName, string platform, string sourceUri) { if (reference.Folder != string.Empty) { throw new InvalidOperationException("Reference folder must be empty for template type."); } if (Directory.Exists(".staging")) { PathUtils.AggressiveDirectoryDelete(".staging"); } Directory.CreateDirectory(".staging"); var package = m_PackageCache.GetBinaryPackage(reference.Uri, reference.GitRef, platform); if (package == null) { this.ResolveTemplateSource(reference, templateName, sourceUri); return; } package.ExtractTo(".staging"); ApplyProjectTemplateFromStaging(templateName); }
private void ResolveTemplateBinary(string workingDirectory, ICachableBinaryPackageMetadata protobuildMetadata, string folder, string templateName, bool forceUpgrade) { if (folder != string.Empty) { throw new InvalidOperationException("Reference folder must be empty for template type."); } // The template is a reference to a Git repository. if (Directory.Exists(Path.Combine(workingDirectory, ".staging"))) { PathUtils.AggressiveDirectoryDelete(Path.Combine(workingDirectory, ".staging")); } Directory.CreateDirectory(Path.Combine(workingDirectory, ".staging")); var package = GetBinaryPackage(protobuildMetadata); if (package == null) { _sourcePackageResolve.Resolve(workingDirectory, protobuildMetadata, folder, templateName, forceUpgrade); return; } ExtractTo(workingDirectory, protobuildMetadata.PackageName, protobuildMetadata.BinaryFormat, package, Path.Combine(workingDirectory, ".staging"), "Template"); _projectTemplateApplier.Apply(Path.Combine(workingDirectory, ".staging"), templateName); PathUtils.AggressiveDirectoryDelete(Path.Combine(workingDirectory, ".staging")); }
public int Execute(Execution execution) { var url = execution.PackageUrl; var module = ModuleInfo.Load(Path.Combine(execution.WorkingDirectory, "Build", "Module.xml")); if (module.Packages == null) { module.Packages = new List <PackageRef>(); } var packageRef = _packageUrlParser.Parse(url); foreach (var package in module.Packages.ToArray()) { if (package.Uri == packageRef.Uri) { RedirectableConsole.WriteLine("Removing " + package.Uri + "..."); module.Packages.Remove(package); // Save after each package remove in case something goes wrong deleting // the directory. module.Save(Path.Combine(execution.WorkingDirectory, "Build", "Module.xml")); if (Directory.Exists(Path.Combine(module.Path, package.Folder))) { RedirectableConsole.WriteLine("Deleting folder '" + package.Folder + "'..."); PathUtils.AggressiveDirectoryDelete(Path.Combine(module.Path, package.Folder)); } } } return(0); }
private void ResolveTemplateSource(PackageRef reference, string templateName, string source) { if (reference.Folder != string.Empty) { throw new InvalidOperationException("Reference folder must be empty for template type."); } if (Directory.Exists(".staging")) { PathUtils.AggressiveDirectoryDelete(".staging"); } var package = m_PackageCache.GetSourcePackage(source, reference.GitRef); package.ExtractTo(".staging"); this.ApplyProjectTemplateFromStaging(templateName); }
private void ApplyProjectTemplateFromStaging(string name) { foreach (var pathToFile in GetFilesFromStaging()) { var path = pathToFile.Key; var file = pathToFile.Value; var replacedPath = path.Replace("{PROJECT_NAME}", name); var dirSeperator = replacedPath.LastIndexOfAny(new[] { '/', '\\' }); if (dirSeperator != -1) { var replacedDir = replacedPath.Substring(0, dirSeperator); if (!Directory.Exists(replacedDir)) { Directory.CreateDirectory(replacedDir); } } string contents; using (var reader = new StreamReader(file.FullName)) { contents = reader.ReadToEnd(); } if (contents.Contains("{PROJECT_NAME}") || contents.Contains("{PROJECT_XML_NAME}")) { contents = contents.Replace("{PROJECT_NAME}", name); contents = contents.Replace("{PROJECT_XML_NAME}", System.Security.SecurityElement.Escape(name)); using (var writer = new StreamWriter(replacedPath)) { writer.Write(contents); } } else { // If we don't see {PROJECT_NAME} or {PROJECT_XML_NAME}, use a straight // file copy so that we don't break binary files. File.Copy(file.FullName, replacedPath, true); } } PathUtils.AggressiveDirectoryDelete(".staging"); }
private void ResolveGlobalToolBinary(string workingDirectory, ICachableBinaryPackageMetadata protobuildMetadata, bool forceUpgrade) { var toolFolder = _packageGlobalTool.GetGlobalToolInstallationPath(protobuildMetadata.CanonicalURI); if (File.Exists(Path.Combine(toolFolder, ".pkg"))) { if (!forceUpgrade) { RedirectableConsole.WriteLine("Protobuild binary package already present at " + toolFolder); return; } } RedirectableConsole.WriteLine("Creating and emptying " + toolFolder); PathUtils.AggressiveDirectoryDelete(toolFolder); Directory.CreateDirectory(toolFolder); RedirectableConsole.WriteLine("Installing " + protobuildMetadata.CanonicalURI + " at version " + protobuildMetadata.GitCommitOrRef); var package = GetBinaryPackage(protobuildMetadata); if (package == null) { RedirectableConsole.WriteLine("The specified global tool package is not available for this platform."); return; } ExtractTo(workingDirectory, protobuildMetadata.PackageName, protobuildMetadata.BinaryFormat, package, toolFolder, protobuildMetadata.Platform); var file = File.Create(Path.Combine(toolFolder, ".pkg")); file.Close(); if (_knownToolProvider == null) { // We must delay load this because of a circular dependency :( _knownToolProvider = _lightweightKernel.Get <IKnownToolProvider>(); } _packageGlobalTool.ScanPackageForToolsAndInstall(toolFolder, _knownToolProvider); RedirectableConsole.WriteLine("Binary resolution complete"); }
private string GetSourcePackage(string workingDirectory, string url) { var sourcePath = Path.Combine( _packageCacheConfiguration.GetCacheDirectory(), this.GetPackageName(url)); if (this.HasSourcePackage(url)) { if (Directory.Exists(Path.Combine(sourcePath, "objects")) && File.Exists(Path.Combine(sourcePath, "config"))) { try { GitUtils.RunGitAbsolute(sourcePath, "fetch origin +refs/heads/*:refs/heads/*"); } catch (InvalidOperationException) { // Ignore exceptions here in case the user is offline. } return(sourcePath); } else { RedirectableConsole.ErrorWriteLine("WARNING: Source package cache is corrupt, removing and cloning again..."); try { PathUtils.AggressiveDirectoryDelete(sourcePath); } catch (Exception) { RedirectableConsole.ErrorWriteLine("WARNING: Unable to delete invalid source package from cache!"); } } } Directory.CreateDirectory(sourcePath); GitUtils.RunGit(workingDirectory, null, "clone --progress --bare " + url + " \"" + sourcePath + "\""); return(sourcePath); }
private void ResolveGit(string workingDirectory, GitPackageMetadata gitMetadata, string folder, string templateName, bool forceUpgrade) { switch (gitMetadata.PackageType) { case PackageManager.PACKAGE_TYPE_LIBRARY: if (File.Exists(Path.Combine(workingDirectory, folder, ".git")) || Directory.Exists(Path.Combine(workingDirectory, folder, ".git"))) { if (!forceUpgrade) { RedirectableConsole.WriteLine("Git submodule / repository already present at " + folder); return; } } PathUtils.AggressiveDirectoryDelete(Path.Combine(workingDirectory, folder)); var packageLibrary = GetSourcePackage(workingDirectory, gitMetadata.CloneURI); ExtractGitSourceTo(workingDirectory, packageLibrary, gitMetadata.GitRef, folder); break; case PackageManager.PACKAGE_TYPE_TEMPLATE: if (Directory.Exists(".staging")) { PathUtils.AggressiveDirectoryDelete(Path.Combine(workingDirectory, ".staging")); } var packageTemplate = GetSourcePackage(workingDirectory, gitMetadata.CloneURI); ExtractGitSourceTo(workingDirectory, packageTemplate, gitMetadata.GitRef, Path.Combine(workingDirectory, ".staging")); _projectTemplateApplier.Apply(Path.Combine(workingDirectory, ".staging"), templateName); PathUtils.AggressiveDirectoryDelete(Path.Combine(workingDirectory, ".staging")); break; default: throw new InvalidOperationException("Unable to resolve source package with type '" + gitMetadata.PackageType + "' using Git-based package."); } }
public int Execute(Execution execution) { var platforms = execution.Platform ?? this._hostPlatformDetector.DetectPlatform(); var package = _packageUrlParser.Parse(execution.PackageUrl); foreach (var platform in platforms.Split(',')) { // Create a temporary working directory where we can precache files. var tempDir = Path.Combine(Path.GetTempPath(), "precache-" + HashString(execution.PackageUrl + "|" + platform + "|" + (execution.PrecacheSource == null ? "null" : execution.PrecacheSource.Value ? "true" : "false"))); if (Directory.Exists(tempDir)) { PathUtils.AggressiveDirectoryDelete(tempDir); } Directory.CreateDirectory(tempDir); try { RedirectableConsole.WriteLine("Precaching " + package.Uri + "..."); var metadata = _packageManager.Lookup(tempDir, null, package, platform, null, execution.PrecacheSource, true, false); _packageManager.Resolve(tempDir, metadata, package, "PRECACHE", execution.PrecacheSource, true, false); // Also precache dependencies. if (File.Exists(Path.Combine(tempDir, "Build", "Module.xml"))) { var moduleInfo = ModuleInfo.Load(Path.Combine(tempDir, "Build", "Module.xml")); _packageManager.ResolveAll(tempDir, moduleInfo, platform, execution.UseTaskParallelisation, true, false, execution.PrecacheSource); } } finally { PathUtils.AggressiveDirectoryDelete(tempDir); } } return(0); }
private void ResolveGlobalToolBinary(ProtobuildPackageMetadata protobuildMetadata, bool forceUpgrade) { var toolFolder = _packageGlobalTool.GetGlobalToolInstallationPath(protobuildMetadata.ReferenceURI); if (File.Exists(Path.Combine(toolFolder, ".pkg"))) { if (!forceUpgrade) { Console.WriteLine("Protobuild binary package already present at " + toolFolder); return; } } Console.WriteLine("Creating and emptying " + toolFolder); PathUtils.AggressiveDirectoryDelete(toolFolder); Directory.CreateDirectory(toolFolder); Console.WriteLine("Installing " + protobuildMetadata.ReferenceURI + " at version " + protobuildMetadata.GitCommit); var package = GetProtobuildBinaryPackage(protobuildMetadata); if (package == null) { Console.WriteLine("The specified global tool package is not available for this platform."); return; } ExtractTo(protobuildMetadata.BinaryFormat, package, toolFolder); var file = File.Create(Path.Combine(toolFolder, ".pkg")); file.Close(); _packageGlobalTool.ScanPackageForToolsAndInstall(toolFolder); Console.WriteLine("Binary resolution complete"); }
public byte[] Transform(string workingDirectory, string url, string gitReference, string platform, string format) { var urlAndPackageName = url.Split(new[] { '|' }, 2); if (urlAndPackageName.Length != 2) { RedirectableConsole.ErrorWriteLine( "ERROR: Malformed NuGet package reference '" + url + "'. Make sure you split the NuGet server URL and the package name with a pipe character (|)."); ExecEnvironment.Exit(1); } var repoUrl = urlAndPackageName[0]; var packageName = urlAndPackageName[1]; var originalFolder = DownloadOrUseExistingNuGetPackage(repoUrl.TrimEnd('/'), packageName, gitReference); if (Directory.Exists(Path.Combine(originalFolder, "protobuild"))) { // This is a Protobuild-aware NuGet package. In this case, we just use the contents of the // "protobuild" folder as the content of our package, and ignore everything else. RedirectableConsole.WriteLine("Detected Protobuild-aware package..."); RedirectableConsole.WriteLine("Converting to a Protobuild package..."); var target = new MemoryStream(); var filter = new FileFilter(_getRecursiveUtilitiesInPath.GetRecursiveFilesInPath(originalFolder)); filter.ApplyInclude("protobuild/(.*)"); filter.ApplyRewrite("protobuild/(.*)", "$1"); filter.ImplyDirectories(); _packageCreator.Create( target, filter, originalFolder, format, platform); RedirectableConsole.WriteLine("Package conversion complete."); var bytes2 = new byte[target.Position]; target.Seek(0, SeekOrigin.Begin); target.Read(bytes2, 0, bytes2.Length); return(bytes2); } var folder = Path.GetTempFileName(); File.Delete(folder); Directory.CreateDirectory(folder); byte[] bytes; try { RedirectableConsole.WriteLine("Copying directory for package transformation..."); CopyFolder(new DirectoryInfo(originalFolder), new DirectoryInfo(folder)); RedirectableConsole.WriteLine("Auto-detecting libraries to reference from NuGet package..."); var packagePath = new DirectoryInfo(folder).GetFiles("*.nuspec").First().FullName; var libraryReferences = new Dictionary <string, string>(); var packageDependencies = new Dictionary <string, string>(); // Use the nuspec file if it exists. List <string> references = new List <string>(); if (File.Exists(packagePath)) { var packageDoc = new XmlDocument(); packageDoc.Load(packagePath); // 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.")); } } // 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); } document.Save(Path.Combine(folder, "_ProtobuildExternalProject.xml")); 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 = repoUrl.Replace("http://", "http-nuget://").Replace("https://", "https-nuget://") + "|" + package.Key, GitRef = package.Value.TrimStart('[').TrimEnd(']'), Folder = package.Key }); } generatedModule.Save(Path.Combine(folder, "_ProtobuildModule.xml")); RedirectableConsole.WriteLine("Converting to a Protobuild package..."); var target = new MemoryStream(); var filter = new FileFilter(_getRecursiveUtilitiesInPath.GetRecursiveFilesInPath(folder)); foreach (var kv in libraryReferences) { filter.ApplyInclude( Regex.Escape(kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/'))); filter.ApplyRewrite( Regex.Escape(kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/')), kv.Value.Substring(folder.Length).Replace('\\', '/').TrimStart('/').Replace("%2B", "-")); } filter.ApplyInclude("_ProtobuildExternalProject\\.xml"); filter.ApplyRewrite("_ProtobuildExternalProject\\.xml", "Build/Projects/" + packageName + ".definition"); filter.ApplyInclude("_ProtobuildModule\\.xml"); filter.ApplyRewrite("_ProtobuildModule\\.xml", "Build/Module.xml"); filter.ImplyDirectories(); _packageCreator.Create( target, filter, folder, format, platform); RedirectableConsole.WriteLine("Package conversion complete."); bytes = new byte[target.Position]; target.Seek(0, SeekOrigin.Begin); target.Read(bytes, 0, bytes.Length); } finally { RedirectableConsole.WriteLine("Cleaning up temporary data..."); PathUtils.AggressiveDirectoryDelete(folder); } return(bytes); }
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); } }
private void ResolveLibraryBinary(string workingDirectory, ICachableBinaryPackageMetadata protobuildMetadata, string folder, bool forceUpgrade, Func <byte[]> getBinaryPackage) { var platformFolder = Path.Combine(folder, protobuildMetadata.Platform); if (File.Exists(Path.Combine(platformFolder, ".pkg"))) { if (!forceUpgrade) { RedirectableConsole.WriteLine("Protobuild binary package already present at " + platformFolder); return; } } RedirectableConsole.WriteLine("Creating and emptying " + platformFolder); if (File.Exists(Path.Combine(folder, ".pkg"))) { if (Directory.Exists(platformFolder)) { // Only clear out the target's folder if the reference folder // already contains binary packages (for other platforms) PathUtils.AggressiveDirectoryDelete(platformFolder); } } else { // The reference folder is holding source code, so clear it // out entirely. PathUtils.AggressiveDirectoryDelete(folder); } Directory.CreateDirectory(platformFolder); RedirectableConsole.WriteLine("Marking " + folder + " as ignored for Git"); GitUtils.MarkIgnored(folder); var package = getBinaryPackage(); if (package == null) { return; } ExtractTo(workingDirectory, protobuildMetadata.PackageName, protobuildMetadata.BinaryFormat, package, platformFolder, protobuildMetadata.Platform); // Only copy ourselves to the binary folder if both "Build/Module.xml" and // "Build/Projects" exist in the binary package's folder. This prevents us // from triggering the "create new module?" logic if the package hasn't been // setup correctly. if (Directory.Exists(Path.Combine(platformFolder, "Build", "Projects")) && File.Exists(Path.Combine(platformFolder, "Build", "Module.xml"))) { var sourceProtobuild = Assembly.GetEntryAssembly().Location; File.Copy(sourceProtobuild, Path.Combine(platformFolder, "Protobuild.exe"), true); PathUtils.MakePathExecutable(Path.Combine(platformFolder, "Protobuild.exe"), true); } var file = File.Create(Path.Combine(platformFolder, ".pkg")); file.Close(); file = File.Create(Path.Combine(folder, ".pkg")); file.Close(); RedirectableConsole.WriteLine("Binary resolution complete"); }
/// <summary> /// Returns the required JSIL directories, downloading and building JSIL if necessary. /// </summary> /// <remarks> /// If this returns <c>false</c>, then an error was encountered while downloading or /// building JSIL. /// </remarks> /// <returns><c>true</c>, if JSIL was available or was installed successfully, <c>false</c> otherwise.</returns> /// <param name="jsilDirectory">The runtime directory of JSIL.</param> /// <param name="jsilCompilerFile">The JSIL compiler executable.</param> public bool GetJSIL(out string jsilDirectory, out string jsilCompilerFile) { if (File.Exists(this.GetJSILCompilerPath())) { jsilDirectory = this.GetJSILRuntimeDirectory(); jsilCompilerFile = this.GetJSILCompilerPath(); return(true); } if (this.BuggyMonoDetected()) { Console.WriteLine("=============== Please update Mono ==============="); Console.WriteLine("Mono 3.2.6 is known to be buggy when building "); Console.WriteLine("JSIL. To update Mono, upgrade via your package "); Console.WriteLine("manager on Linux, or if you are on Mac update Mono "); Console.WriteLine("by downloading the latest version from: "); Console.WriteLine(); Console.WriteLine(" http://www.go-mono.com/mono-downloads/download.html"); Console.WriteLine(); Console.WriteLine("============================================================="); jsilDirectory = null; jsilCompilerFile = null; return(false); } Console.WriteLine("=============== JSIL runtime is not installed ==============="); Console.WriteLine("I will now download and build JSIL for the Web platform."); Console.WriteLine("Installing into: " + this.GetJSILRuntimeDirectory()); Console.Write("Removing existing JSIL runtime... "); try { PathUtils.AggressiveDirectoryDelete(this.GetJSILSourceDirectory()); PathUtils.AggressiveDirectoryDelete(this.GetJSILRuntimeDirectory()); Console.WriteLine("done."); } catch (UnauthorizedAccessException) { Console.WriteLine("error!"); Console.WriteLine("Unable to remove existing JSIL runtime or source. Remove"); Console.WriteLine("the files and directories located in the following directory:"); Console.WriteLine(); Console.WriteLine(" " + this.GetJSILDirectory(string.Empty)); Console.WriteLine(); Console.WriteLine("and then try again."); Console.WriteLine(); Console.WriteLine("============================================================="); jsilDirectory = null; jsilCompilerFile = null; return(false); } Console.WriteLine("Downloading JSIL source code via Git... "); try { this.ExecuteGit("clone https://github.com/sq/JSIL.git ."); } catch (InvalidOperationException) { Console.WriteLine("error!"); Console.WriteLine("You don't have Git installed or it currently isn't in your PATH."); Console.WriteLine("JSIL has to be downloaded via Git due to the use of submodules."); Console.WriteLine("============================================================="); jsilDirectory = null; jsilCompilerFile = null; return(false); } Console.WriteLine("Updating JSIL submodules... "); this.ExecuteGit("submodule update --init --recursive"); Console.WriteLine("done."); Console.WriteLine("Patching JSIL project files... "); this.PatchFile( Path.Combine(this.GetJSILSourceDirectory(), "Compiler", "Compiler.csproj"), x => Regex.Replace( Regex.Replace( x, "\\<PreBuildEvent\\>[^\\<]+\\<\\/PreBuildEvent\\>", string.Empty), "\\<PostBuildEvent\\>[^\\<]+\\<\\/PostBuildEvent\\>", string.Empty)); this.PatchFile( Path.Combine( this.GetJSILSourceDirectory(), "Upstream", "ILSpy", "ICSharpCode.Decompiler", "ICSharpCode.Decompiler.csproj"), x => Regex.Replace( Regex.Replace( x, "<Compile Include=\"Properties\\\\AssemblyInfo\\.cs\" />", string.Empty), "<Target Name=\"BeforeBuild\">(.+?)</Target>", string.Empty, RegexOptions.Singleline)); Console.WriteLine("done."); Console.WriteLine("Building JSIL compiler... "); string builderOrError; if (!this.DetectBuilder(out builderOrError)) { Console.WriteLine("error!"); Console.WriteLine("Unable to locate the tool to build C# projects. The exact "); Console.WriteLine("error is: "); Console.WriteLine(); Console.WriteLine(" " + builderOrError); Console.WriteLine(); Console.WriteLine("If you are running on Windows, make sure you are running "); Console.WriteLine("Protobuild under the Visual Studio command prompt."); Console.WriteLine(); Console.WriteLine("============================================================="); jsilDirectory = null; jsilCompilerFile = null; return(false); } if (!this.ExecuteProgram(builderOrError, "Compiler" + Path.DirectorySeparatorChar + "Compiler.csproj")) { Console.WriteLine("error!"); Console.WriteLine("Unable to build the JSIL compiler. This may be caused by an "); Console.WriteLine("incompatible change made in the upstream codebase. Things you "); Console.WriteLine("can try:"); Console.WriteLine(); Console.WriteLine(" 1) Make sure you have the latest version of Protobuild"); Console.WriteLine(" 2) If the problem still persists, file an issue at"); Console.WriteLine(" https://github.com/hach-que/Protobuild/issues"); Console.WriteLine(" with a copy of the above output."); Console.WriteLine(); Console.WriteLine("============================================================="); jsilDirectory = null; jsilCompilerFile = null; return(false); } Console.WriteLine("Copying resulting binaries... "); foreach (var file in new DirectoryInfo(Path.Combine(this.GetJSILSourceDirectory(), "bin")).GetFiles()) { Console.WriteLine("> " + file.Name); file.CopyTo(Path.Combine(this.GetJSILRuntimeDirectory(), file.Name)); } Console.WriteLine("done."); Console.WriteLine("Creating runtime libraries... "); Directory.CreateDirectory(Path.Combine(this.GetJSILRuntimeDirectory(), "Libraries")); Console.WriteLine("done."); Console.WriteLine("Copying runtime libraries... "); this.RecursiveCopy( Path.Combine(this.GetJSILSourceDirectory(), "Libraries"), Path.Combine(this.GetJSILRuntimeDirectory(), "Libraries")); Console.WriteLine("done."); Console.Write("Removing temporary build directory... "); try { PathUtils.AggressiveDirectoryDelete(this.GetJSILSourceDirectory()); } catch (UnauthorizedAccessException) { // Ignore } Console.WriteLine("done."); if (File.Exists(this.GetJSILCompilerPath())) { jsilDirectory = this.GetJSILRuntimeDirectory(); jsilCompilerFile = this.GetJSILCompilerPath(); return(true); } else { Console.WriteLine("error."); Console.WriteLine("The build did not result in a JSILc.exe file being present "); Console.WriteLine("at: " + this.GetJSILCompilerPath()); Console.WriteLine(); Console.WriteLine("============================================================="); jsilDirectory = null; jsilCompilerFile = null; return(false); } }
private void InstallToolIntoUserApplicationFolder(string toolName, string toolPath) { var appToolPath = toolPath.Replace(".exe", ".app"); if (!Directory.Exists(appToolPath)) { return; } var basename = Path.GetFileName(appToolPath); var applicationPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Applications"); Directory.CreateDirectory(applicationPath); var installPath = Path.Combine(applicationPath, basename); try { var stat = System.Diagnostics.Process.Start(new ProcessStartInfo { FileName = "/usr/bin/stat", Arguments = "-f %T '" + installPath + "'", UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true }); var type = stat.StandardOutput.ReadToEnd().Trim(); if (type == "@") { // The file is a symbolic link. File.Delete(installPath); } else { if (Directory.Exists(installPath)) { // Recursive delete. PathUtils.AggressiveDirectoryDelete(installPath); } else { File.Delete(installPath); } } } catch { } // Make sure we don't create a symbolic link inside a symbolically linked directory. if (!File.Exists(installPath) && !Directory.Exists(installPath)) { var install = System.Diagnostics.Process.Start("ln", "-s '" + appToolPath + "' '" + installPath + "'"); if (install != null) { install.WaitForExit(); RedirectableConsole.WriteLine("Global tool '" + toolName + "' is now available in the application menu"); } else { RedirectableConsole.WriteLine("Unable to install global tool '" + toolName + "' into the application menu (unable to create link)"); } } }
private void EmptyReferenceFolder(string folder) { PathUtils.AggressiveDirectoryDelete(folder); }