public void Create(Stream target, FileFilter filter, string basePath, string packageFormat) { Stream archive = new MemoryStream(); string cleanUp = null; try { switch (packageFormat) { case PackageManager.ARCHIVE_FORMAT_TAR_GZIP: { Console.WriteLine("Writing package in tar/gzip format..."); break; } case PackageManager.ARCHIVE_FORMAT_TAR_LZMA: default: { Console.WriteLine("Writing package in tar/lzma format..."); break; } } switch (packageFormat) { case PackageManager.ARCHIVE_FORMAT_TAR_GZIP: case PackageManager.ARCHIVE_FORMAT_TAR_LZMA: default: { var state = _deduplicator.CreateState(); Console.Write("Deduplicating files in package..."); var progressHelper = new DedupProgressRenderer(filter.Count()); var current = 0; foreach (var kv in filter.OrderBy(kv => kv.Value)) { if (kv.Value.EndsWith("/")) { // Directory _deduplicator.AddDirectory(state, kv.Value); } else { // File var realFile = Path.Combine(basePath, kv.Key); var realFileInfo = new FileInfo(realFile); _deduplicator.AddFile(state, realFileInfo, kv.Value); } current++; progressHelper.SetProgress(current); } progressHelper.Finalize(); Console.WriteLine("Adding files to package..."); try { using (var writer = new tar_cs.TarWriter(archive)) { _deduplicator.PushToTar(state, writer); } } catch (OutOfMemoryException ex) { // It's possible the archive is too large to store in memory. Fall // back to using a temporary file on disk. cleanUp = Path.GetTempFileName(); Console.WriteLine( "WARNING: Out-of-memory while creating TAR file, falling back to storing " + "temporary file on disk at " + cleanUp + " during package creation."); archive.Dispose(); archive = new FileStream(cleanUp, FileMode.Create, FileAccess.ReadWrite); using (var writer = new tar_cs.TarWriter(archive)) { _deduplicator.PushToTar(state, writer); } } break; } } archive.Seek(0, SeekOrigin.Begin); switch (packageFormat) { case PackageManager.ARCHIVE_FORMAT_TAR_GZIP: { Console.WriteLine("Compressing package..."); using (var compress = new GZipStream(target, CompressionMode.Compress)) { archive.CopyTo(compress); } break; } case PackageManager.ARCHIVE_FORMAT_TAR_LZMA: default: { Console.Write("Compressing package..."); var progressHelper = new CompressProgressRenderer(archive.Length); LZMA.LzmaHelper.Compress(archive, target, progressHelper); progressHelper.Finalize(); break; } } } finally { if (cleanUp != null) { try { File.Delete(cleanUp); } catch { Console.WriteLine("WARNING: Unable to clean up temporary package file at " + cleanUp); } } } }
public int Execute(Execution execution) { if (!Directory.Exists(execution.PackageSourceFolder)) { throw new InvalidOperationException("The source folder " + execution.PackageSourceFolder + " does not exist."); } var allowAutopackage = true; var moduleExpectedPath = Path.Combine(execution.PackageSourceFolder, "Build", "Module.xml"); ModuleInfo rootModule = null; if (!File.Exists(moduleExpectedPath)) { if (execution.PackageFilterFile == null) { Console.WriteLine( "There is no module in the path '" + execution.PackageSourceFolder + "' (expected to " + "find a Build\\Module.xml file within that directory)."); return(1); } else { // We allow this mode if the user has provided a filter file and are constructing // the package manually. allowAutopackage = false; } } else { rootModule = ModuleInfo.Load(moduleExpectedPath); } var customDirectives = new Dictionary <string, Action <FileFilter> >() { { "autopackage", f => { if (allowAutopackage && rootModule != null) { this.m_AutomaticProjectPackager.Autopackage( f, execution, rootModule, execution.PackageSourceFolder, execution.PackagePlatform); } else { Console.WriteLine( "WARNING: There is no module in the path '" + execution.PackageSourceFolder + "' (expected to " + "find a Build\\Module.xml file within that directory). Ignoring the 'autopackage' directive."); } } } }; Console.WriteLine("Starting package creation for " + execution.PackagePlatform); var filter = new FileFilter(GetRecursiveFilesInPath(execution.PackageSourceFolder)); if (execution.PackageFilterFile != null) { using (var reader = new StreamReader(execution.PackageFilterFile)) { var contents = reader.ReadToEnd(); contents = contents.Replace("%PLATFORM%", execution.PackagePlatform); using (var inputStream = new MemoryStream(Encoding.ASCII.GetBytes(contents))) { this.m_FileFilterParser.ParseAndApply(filter, inputStream, customDirectives); } } } else { customDirectives["autopackage"](filter); } if (File.Exists(execution.PackageDestinationFile)) { Console.WriteLine("The destination file " + execution.PackageDestinationFile + " already exists; it will be overwritten."); File.Delete(execution.PackageDestinationFile); } filter.ImplyDirectories(); var filterDictionary = filter.ToDictionary(k => k.Key, v => v.Value); if (!filterDictionary.ContainsValue("Build/")) { Console.WriteLine("ERROR: The Build directory does not exist in the source folder."); if (execution.PackageFilterFile != null) { this.PrintFilterMappings(filterDictionary); } return(1); } if (!filterDictionary.ContainsValue("Build/Projects/")) { Console.WriteLine("ERROR: The Build\\Projects directory does not exist in the source folder."); if (execution.PackageFilterFile != null) { this.PrintFilterMappings(filterDictionary); } return(1); } if (!filterDictionary.ContainsValue("Build/Module.xml")) { Console.WriteLine("ERROR: The Build\\Module.xml file does not exist in the source folder."); if (execution.PackageFilterFile != null) { this.PrintFilterMappings(filterDictionary); } return(1); } if (filterDictionary.ContainsValue("Protobuild.exe")) { Console.WriteLine("ERROR: The Protobuild.exe file should not be included in the package file."); if (execution.PackageFilterFile != null) { this.PrintFilterMappings(filterDictionary); } return(1); } using (var target = new FileStream(execution.PackageDestinationFile, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { var archive = new MemoryStream(); switch (execution.PackageFormat) { case PackageManager.ARCHIVE_FORMAT_TAR_GZIP: { Console.WriteLine("Writing package in tar/gzip format..."); break; } case PackageManager.ARCHIVE_FORMAT_TAR_LZMA: default: { Console.WriteLine("Writing package in tar/lzma format..."); break; } } switch (execution.PackageFormat) { case PackageManager.ARCHIVE_FORMAT_TAR_GZIP: case PackageManager.ARCHIVE_FORMAT_TAR_LZMA: default: { var state = this.m_Deduplicator.CreateState(); Console.Write("Deduplicating files in package..."); var progressHelper = new DedupProgressRenderer(filter.Count()); var current = 0; foreach (var kv in filter.OrderBy(kv => kv.Value)) { if (kv.Value.EndsWith("/")) { // Directory this.m_Deduplicator.AddDirectory(state, kv.Value); } else { // File var realFile = Path.Combine(execution.PackageSourceFolder, kv.Key); var realFileInfo = new FileInfo(realFile); this.m_Deduplicator.AddFile(state, realFileInfo, kv.Value); } current++; progressHelper.SetProgress(current); } Console.WriteLine(); Console.WriteLine("Adding files to package..."); using (var writer = new tar_cs.TarWriter(archive)) { this.m_Deduplicator.PushToTar(state, writer); } break; } } archive.Seek(0, SeekOrigin.Begin); switch (execution.PackageFormat) { case PackageManager.ARCHIVE_FORMAT_TAR_GZIP: { Console.WriteLine("Compressing package..."); using (var compress = new GZipStream(target, CompressionMode.Compress)) { archive.CopyTo(compress); } break; } case PackageManager.ARCHIVE_FORMAT_TAR_LZMA: default: { Console.Write("Compressing package..."); var progressHelper = new CompressProgressRenderer(archive.Length); LZMA.LzmaHelper.Compress(archive, target, progressHelper); Console.WriteLine(); break; } } } Console.WriteLine("\rPackage written to " + execution.PackageDestinationFile + " successfully."); return(0); }