public void TestWithMultipleDuplicateEntriesFails() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid); var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid); // Generate a file specification with duplicate entries var fileSpecs = new List <FileSpec>(); fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture))); string appPath = BundleHelper.GetAppPath(fixture); fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll")); fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll")); string systemLibPath = Path.Join(BundleHelper.GetPublishPath(fixture), "System.dll"); fileSpecs.Add(new FileSpec(appPath, "rel/system.repeat.dll")); fileSpecs.Add(new FileSpec(systemLibPath, "rel/system.repeat.dll")); Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch); Assert.Throws <ArgumentException>(() => bundler.GenerateBundle(fileSpecs)) .Message .Should().Contain("rel/system.repeat.dll") .And.NotContain("rel/app.repeat.dll") .And.Contain(appPath) .And.Contain(systemLibPath); }
public void TestWithAdditionalContentAfterBundleMetadata() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName); string singleFile = bundler.GenerateBundle(BundleHelper.GetPublishPath(fixture)); using (var file = File.OpenWrite(singleFile)) { file.Position = file.Length; var blob = Encoding.UTF8.GetBytes("Mock signature at the end of the bundle"); file.Write(blob, 0, blob.Length); } Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Hello World!"); }
public void TestWithExactDuplicateEntriesPasses() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid); var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid); // Generate a file specification with duplicate entries var fileSpecs = new List <FileSpec>(); fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture))); string appPath = BundleHelper.GetAppPath(fixture); fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll")); fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll")); string systemLibPath = Path.Join(BundleHelper.GetPublishPath(fixture), "System.dll"); fileSpecs.Add(new FileSpec(systemLibPath, "rel/system.repeat.dll")); fileSpecs.Add(new FileSpec(systemLibPath, "rel/system.repeat.dll")); Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch); bundler.GenerateBundle(fileSpecs); // Exact duplicates are not duplicated in the bundle bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/app.repeat.dll")).Single().Type.Should().Be(FileType.Assembly); bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/system.repeat.dll")).Single().Type.Should().Be(FileType.Assembly); }
private void Run(TestProjectFixture fixture, string publishDir, string singleFileDir) { var dotnet = fixture.SdkDotnet; var hostName = Path.GetFileName(fixture.TestProject.AppExe); // Run the App normally Command.Create(Path.Combine(publishDir, hostName)) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Wow! We now say hello to the big world and you."); // Bundle to a single-file Bundler bundler = new Bundler(hostName, singleFileDir); string singleFile = bundler.GenerateBundle(publishDir); // Extract the file Extractor extractor = new Extractor(singleFile, singleFileDir); extractor.ExtractFiles(); // Run the extracted app Command.Create(singleFile) .CaptureStdErr() .CaptureStdOut() .Execute() .Should() .Pass() .And .HaveStdOutContaining("Wow! We now say hello to the big world and you."); }
protected override void ExecuteCore() { OSPlatform targetOS = RuntimeIdentifier.StartsWith("win") ? OSPlatform.Windows : RuntimeIdentifier.StartsWith("osx") ? OSPlatform.OSX : OSPlatform.Linux; BundleOptions options = BundleOptions.BundleAllContent; options |= IncludeSymbols ? BundleOptions.BundleSymbolFiles : BundleOptions.None; var bundler = new Bundler(AppHostName, OutputDir, options, targetOS, new Version(TargetFrameworkVersion), ShowDiagnosticOutput); var fileSpec = new List <FileSpec>(FilesToBundle.Length); foreach (var item in FilesToBundle) { fileSpec.Add(new FileSpec(sourcePath: item.ItemSpec, bundleRelativePath: item.GetMetadata(MetadataKeys.RelativePath))); } bundler.GenerateBundle(fileSpec); // Certain files are excluded from the bundle, based on BundleOptions. // For example: // Native files and contents files are excluded by default. // hostfxr and hostpolicy are excluded until singlefilehost is available. // Return the set of excluded files in ExcludedFiles, so that they can be placed in the publish directory. ExcludedFiles = FilesToBundle.Zip(fileSpec, (item, spec) => (spec.Excluded) ? item : null).Where(x => x != null).ToArray(); }
/// Generate a bundle containind the (embeddable) files in sourceDir public static string GenerateBundle(Bundler bundler, string sourceDir, string outputDir, bool copyExludedFiles = true) { // Convert sourceDir to absolute path sourceDir = Path.GetFullPath(sourceDir); // Get all files in the source directory and all sub-directories. string[] sources = Directory.GetFiles(sourceDir, searchPattern: "*", searchOption: SearchOption.AllDirectories); // Sort the file names to keep the bundle construction deterministic. Array.Sort(sources, StringComparer.Ordinal); List <FileSpec> fileSpecs = new List <FileSpec>(sources.Length); foreach (var file in sources) { fileSpecs.Add(new FileSpec(file, Path.GetRelativePath(sourceDir, file))); } var singleFile = bundler.GenerateBundle(fileSpecs); if (copyExludedFiles) { foreach (var spec in fileSpecs) { if (spec.Excluded) { var outputFilePath = Path.Combine(outputDir, spec.BundleRelativePath); Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath)); File.Copy(spec.SourcePath, outputFilePath, true); } } } return(singleFile); }
protected override void ExecuteCore() { var bundler = new Bundler(AppHostName, OutputDir, IncludeSymbols, ShowDiagnosticOutput); var fileSpec = new List <FileSpec>(FilesToBundle.Length); foreach (var item in FilesToBundle) { fileSpec.Add(new FileSpec(sourcePath: item.ItemSpec, bundleRelativePath: item.GetMetadata(MetadataKeys.RelativePath))); } bundler.GenerateBundle(fileSpec); }
private void BundleRun(TestProjectFixture fixture, string publishDir, string singleFileDir) { var hostName = BundleHelper.GetHostName(fixture); // Run the App normally RunTheApp(Path.Combine(publishDir, hostName)); // Bundle to a single-file Bundler bundler = new Bundler(hostName, singleFileDir); string singleFile = bundler.GenerateBundle(publishDir); // Run the extracted app RunTheApp(singleFile); }
protected override void ExecuteCore() { BundleOptions options = BundleOptions.BundleAllContent | (IncludeSymbols ? BundleOptions.BundleSymbolFiles : BundleOptions.None); var bundler = new Bundler(AppHostName, OutputDir, options, diagnosticOutput: ShowDiagnosticOutput); var fileSpec = new List <FileSpec>(FilesToBundle.Length); foreach (var item in FilesToBundle) { fileSpec.Add(new FileSpec(sourcePath: item.ItemSpec, bundleRelativePath: item.GetMetadata(MetadataKeys.RelativePath))); } bundler.GenerateBundle(fileSpec); }
public void TestAssemblyAlignment() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); string publishPath = BundleHelper.GetPublishPath(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName); bundler.GenerateBundle(BundleHelper.GetPublishPath(fixture)); bundler.BundleManifest.Files.ForEach(file => Assert.True((file.Type != FileType.IL && file.Type != FileType.Ready2Run) || (file.Offset % Bundler.AssemblyAlignment == 0))); }
protected override void ExecuteCore() { OSPlatform targetOS = RuntimeIdentifier.StartsWith("win") ? OSPlatform.Windows : RuntimeIdentifier.StartsWith("osx") ? OSPlatform.OSX : OSPlatform.Linux; Architecture targetArch = RuntimeIdentifier.EndsWith("-x64") || RuntimeIdentifier.Contains("-x64-") ? Architecture.X64 : RuntimeIdentifier.EndsWith("-x86") || RuntimeIdentifier.Contains("-x86-") ? Architecture.X86 : RuntimeIdentifier.EndsWith("-arm64") || RuntimeIdentifier.Contains("-arm64-") ? Architecture.Arm64 : RuntimeIdentifier.EndsWith("-arm") || RuntimeIdentifier.Contains("-arm-") ? Architecture.Arm : throw new ArgumentException(nameof(RuntimeIdentifier)); BundleOptions options = BundleOptions.None; options |= IncludeNativeLibraries ? BundleOptions.BundleNativeBinaries : BundleOptions.None; options |= IncludeAllContent ? BundleOptions.BundleAllContent : BundleOptions.None; options |= IncludeSymbols ? BundleOptions.BundleSymbolFiles : BundleOptions.None; options |= EnableCompressionInSingleFile ? BundleOptions.EnableCompression : BundleOptions.None; Version version = new Version(TargetFrameworkVersion); var bundler = new Bundler( AppHostName, OutputDir, options, targetOS, targetArch, version, ShowDiagnosticOutput); var fileSpec = new List <FileSpec>(FilesToBundle.Length); foreach (var item in FilesToBundle) { fileSpec.Add(new FileSpec(sourcePath: item.ItemSpec, bundleRelativePath: item.GetMetadata(MetadataKeys.RelativePath))); } bundler.GenerateBundle(fileSpec); // Certain files are excluded from the bundle, based on BundleOptions. // For example: // Native files and contents files are excluded by default. // hostfxr and hostpolicy are excluded until singlefilehost is available. // Return the set of excluded files in ExcludedFiles, so that they can be placed in the publish directory. ExcludedFiles = FilesToBundle.Zip(fileSpec, (item, spec) => (spec.Excluded) ? item : null).Where(x => x != null).ToArray(); }
public void AllBundledFilesAreExtracted() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); var bundler = new Bundler(hostName, bundleDir.FullName); string singleFile = bundler.GenerateBundle(BundleHelper.GetPublishPath(fixture)); var expectedFiles = new List <string>(bundler.BundleManifest.Files.Count); expectedFiles.Add(hostName); bundler.BundleManifest.Files.ForEach(file => expectedFiles.Add(file.RelativePath)); new Extractor(singleFile, bundleDir.FullName).ExtractFiles(); bundleDir.Should().OnlyHaveFiles(expectedFiles); }
public void TestWithDuplicateEntriesFails() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); // Generate a file specification with duplicate entries var fileSpecs = new List <FileSpec>(); fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture))); fileSpecs.Add(new FileSpec(BundleHelper.GetAppPath(fixture), "app.repeat")); fileSpecs.Add(new FileSpec(BundleHelper.GetAppPath(fixture), "app.repeat")); Bundler bundler = new Bundler(hostName, bundleDir.FullName); Assert.Throws <ArgumentException>(() => bundler.GenerateBundle(fileSpecs)); }
public void TestWithoutSpecifyingHostFails() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); var bundleDir = BundleHelper.GetBundleDir(fixture); // Generate a file specification without the apphost var fileSpecs = new List <FileSpec>(); string[] files = { $"{appName}.dll", $"{appName}.deps.json", $"{appName}.runtimeconfig.json" }; Array.ForEach(files, x => fileSpecs.Add(new FileSpec(x, x))); Bundler bundler = new Bundler(hostName, bundleDir.FullName); Assert.Throws <ArgumentException>(() => bundler.GenerateBundle(fileSpecs)); }
public void TestWithEmptySpecFails() { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); Bundler bundler = new Bundler(hostName, bundleDir.FullName); FileSpec[][] invalidSpecs = { new FileSpec[] { new FileSpec(hostName, null) }, new FileSpec[] { new FileSpec(hostName, "") }, new FileSpec[] { new FileSpec(hostName, " ") } }; foreach (var invalidSpec in invalidSpecs) { Assert.Throws <ArgumentException>(() => bundler.GenerateBundle(invalidSpec)); } }
/// Generate a bundle containind the (embeddable) files in sourceDir public static string GenerateBundle(Bundler bundler, string sourceDir) { // Convert sourceDir to absolute path sourceDir = Path.GetFullPath(sourceDir); // Get all files in the source directory and all sub-directories. string[] sources = Directory.GetFiles(sourceDir, searchPattern: "*", searchOption: SearchOption.AllDirectories); // Sort the file names to keep the bundle construction deterministic. Array.Sort(sources, StringComparer.Ordinal); List <FileSpec> fileSpecs = new List <FileSpec>(sources.Length); foreach (var file in sources) { fileSpecs.Add(new FileSpec(file, Path.GetRelativePath(sourceDir, file))); } return(bundler.GenerateBundle(fileSpecs)); }
public void TestFilesNotBundled(bool embedPDBs) { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var appName = Path.GetFileNameWithoutExtension(hostName); string publishPath = BundleHelper.GetPublishPath(fixture); var bundleDir = BundleHelper.GetBundleDir(fixture); // Make up a app.runtimeconfig.dev.json file in the publish directory. File.Copy(Path.Combine(publishPath, $"{appName}.runtimeconfig.json"), Path.Combine(publishPath, $"{appName}.runtimeconfig.dev.json")); var bundler = new Bundler(hostName, bundleDir.FullName, embedPDBs); bundler.GenerateBundle(publishPath); bundler.BundleManifest.Contains($"{appName}.runtimeconfig.dev.json").Should().BeFalse(); bundler.BundleManifest.Contains($"{appName}.pdb").Should().Be(embedPDBs); }
private (string bundleFileName, string bundleId) CreateSampleBundle(bool bundleMultipleFiles) { var fixture = sharedTestState.TestFixture.Copy(); var hostName = BundleHelper.GetHostName(fixture); var bundleDir = Directory.CreateDirectory( Path.Combine(BundleHelper.GetBundleDir(fixture).FullName, Path.GetRandomFileName())); var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid); var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid); var fileSpecs = new List <FileSpec>(); fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture))); if (bundleMultipleFiles) { fileSpecs.Add(new FileSpec(BundleHelper.GetAppPath(fixture), "rel/app.repeat.dll")); } Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch); return(bundler.GenerateBundle(fileSpecs), bundler.BundleManifest.BundleID); }
public static void Main(string[] args) { try { ParseArgs(args); } catch (ArgumentException e) { Fail("ERROR", e.Message); Usage(); return; } if (NeedHelp) { Usage(); return; } if (CreateHost) { HostWriter.CreateAppHost(Template, Path.Combine(SourceDir, Host), App); } if (!CreateBundle) { return; } Bundler bundler = new Bundler(Host, OutputDir, Options, OS, Framework, Diagnostics); // Get all files in the source directory and all sub-directories. string[] sources = Directory.GetFiles(SourceDir, searchPattern: "*", searchOption: SearchOption.AllDirectories); // Sort the file names to keep the bundle construction deterministic. Array.Sort(sources, StringComparer.Ordinal); List <FileSpec> fileSpecs = new List <FileSpec>(sources.Length); foreach (var file in sources) { fileSpecs.Add(new FileSpec(file, Path.GetRelativePath(SourceDir, file))); } bundler.GenerateBundle(fileSpecs); if (!CopyExcluded) { return; } foreach (var spec in fileSpecs) { if (spec.Excluded) { var outputPath = Path.Combine(OutputDir, spec.BundleRelativePath); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); File.Copy(spec.SourcePath, outputPath, true); } } }