Пример #1
0
        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);
        }
Пример #2
0
        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!");
        }
Пример #3
0
        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);
        }
Пример #4
0
        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.");
        }
Пример #5
0
        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();
        }
Пример #6
0
        /// 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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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)));
        }
Пример #11
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();
        }
Пример #12
0
        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);
        }
Пример #13
0
        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));
        }
Пример #14
0
        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));
        }
Пример #15
0
        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));
            }
        }
Пример #16
0
        /// 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));
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
                }
            }
        }