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")); }
private bool HasBinaryPackage(ICachableBinaryPackageMetadata metadata) { var file = Path.Combine( _packageCacheConfiguration.GetCacheDirectory(), this.GetPackageName(metadata)); return(File.Exists(file)); }
private string GetPackageName(ICachableBinaryPackageMetadata metadata) { var sha1 = new SHA1Managed(); var urlHashBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(NormalizeURIForCache(metadata.CanonicalURI))); var urlHashString = BitConverter.ToString(urlHashBytes).Replace("-", "").ToLowerInvariant(); var gitHashString = metadata.GitCommitOrRef.ToLowerInvariant(); var platformString = metadata.Platform.ToLowerInvariant(); return(urlHashString + "-" + gitHashString + "-" + platformString + TranslateToExtension(metadata.BinaryFormat)); }
private byte[] DownloadBinaryPackage(ICachableBinaryPackageMetadata metadata) { try { return(_progressiveWebOperation.Get(metadata.BinaryUri)); } catch (InvalidOperationException) { RedirectableConsole.WriteLine("Unable to download binary package for version \"" + metadata.GitCommitOrRef + "\" and platform \"" + metadata.Platform + "\", falling back to source version"); return(null); } }
private bool DownloadBinaryPackage(ICachableBinaryPackageMetadata metadata, string targetPath) { if (File.Exists(targetPath)) { File.Delete(targetPath); } var packageData = this.DownloadBinaryPackage(metadata); if (packageData == null) { // There is no binary package available. return(false); } var attempts = 10; while (attempts > 0) { try { using (var stream = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None)) { stream.Write(packageData, 0, packageData.Length); } break; } catch (IOException) { // On Windows, we can't write out the package file if another instance of Protobuild // is writing it out at the moment. Just wait and retry in another second. RedirectableConsole.WriteLine("WARNING: Unable to write downloaded package file (attempt " + (11 - attempts) + " / 10)"); System.Threading.Thread.Sleep(5000); attempts--; } } if (attempts == 0) { RedirectableConsole.WriteLine( "WARNING: Unable to write out downloaded package! Assuming " + "another instance of Protobuild will provide it."); } return(true); }
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 byte[] GetBinaryPackage(ICachableBinaryPackageMetadata metadata) { if (metadata.BinaryFormat == null || metadata.BinaryUri == null) { // There is no binary format for this package. return(null); } var localFileExists = false; try { localFileExists = File.Exists(metadata.BinaryUri); } catch { } if (metadata.BinaryFormat != null && localFileExists) { // This is a local package file, read it directly. using (var stream = new FileStream(metadata.BinaryUri, FileMode.Open, FileAccess.Read, FileShare.Read)) { var data = new byte[stream.Length]; stream.Read(data, 0, data.Length); return(data); } } if (this.HasBinaryPackage(metadata)) { // We have it already downloaded in the cache. var file = Path.Combine( _packageCacheConfiguration.GetCacheDirectory(), this.GetPackageName(metadata)); using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { var data = new byte[stream.Length]; stream.Read(data, 0, data.Length); return(data); } } // We must use the package retrieval interface to download a copy // of the package. var tempFile = Path.Combine( _packageCacheConfiguration.GetCacheDirectory(), this.GetPackageName(metadata) + ".tmp"); if (!DownloadBinaryPackage(metadata, tempFile)) { return(null); } var saveFile = Path.Combine( _packageCacheConfiguration.GetCacheDirectory(), this.GetPackageName(metadata)); try { File.Move(tempFile, saveFile); } catch (Exception) { RedirectableConsole.WriteLine("WARNING: Unable to save package to cache."); saveFile = tempFile; } byte[] saveData; using (var stream = new FileStream(saveFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { saveData = new byte[stream.Length]; stream.Read(saveData, 0, saveData.Length); } if (saveFile == tempFile) { File.Delete(tempFile); } return(saveData); }
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"); }
private void ResolveLibraryBinary(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) { Console.WriteLine("Protobuild binary package already present at " + platformFolder); return; } } Console.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); Console.WriteLine("Marking " + folder + " as ignored for Git"); GitUtils.MarkIgnored(folder); var package = getBinaryPackage(); if (package == null) { return; } ExtractTo(protobuildMetadata.BinaryFormat, package, platformFolder); // 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); try { var chmodStartInfo = new ProcessStartInfo { FileName = "chmod", Arguments = "a+x Protobuild.exe", WorkingDirectory = platformFolder, UseShellExecute = false }; Process.Start(chmodStartInfo); } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { } } var file = File.Create(Path.Combine(platformFolder, ".pkg")); file.Close(); file = File.Create(Path.Combine(folder, ".pkg")); file.Close(); Console.WriteLine("Binary resolution complete"); }
private bool HasBinaryPackage(ICachableBinaryPackageMetadata metadata) { var file = Path.Combine( _packageCacheConfiguration.GetCacheDirectory(), this.GetPackageName(metadata)); return File.Exists(file); }
private string GetPackageName(ICachableBinaryPackageMetadata metadata) { var sha1 = new SHA1Managed(); var urlHashBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(NormalizeURIForCache(metadata.CanonicalURI))); var urlHashString = BitConverter.ToString(urlHashBytes).Replace("-", "").ToLowerInvariant(); var gitHashString = metadata.GitCommitOrRef.ToLowerInvariant(); var platformString = metadata.Platform.ToLowerInvariant(); return urlHashString + "-" + gitHashString + "-" + platformString + TranslateToExtension(metadata.BinaryFormat); }