Пример #1
0
        public bool BuildNativeImages(BundleRoot root)
        {
            var success = true;
            foreach (var runtime in root.Runtimes)
            {
                NuGetDependencyResolver resolver;
                if (!_resolverLookup.TryGetValue(runtime.Framework, out resolver))
                {
                    throw new InvalidOperationException("No matching framework is found for " + runtime.Framework);
                }

                var runtimeBin = Path.Combine(runtime.TargetPath, "bin");

                var options = new CrossgenOptions()
                {
                    CrossgenPath = Path.Combine(runtimeBin, "crossgen.exe"),
                    InputPaths = ResolveOutputAssemblies(root, resolver),
                    RuntimePath = runtimeBin,
                    Symbols = false
                };

                var crossgenManager = new CrossgenManager(options);
                success &= crossgenManager.GenerateNativeImages();

                if (!success)
                {
                    return false;
                }
            }
            return success;
        }
Пример #2
0
        public void PostProcess(BundleRoot root)
        {
            // If --wwwroot-out doesn't have a non-empty value, we don't need a public app folder in output
            if (string.IsNullOrEmpty(WwwRootOut))
            {
                return;
            }

            Runtime.Project project;
            if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project))
            {
                throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name);
            }

            // Construct path to public app folder, which contains content files and tool dlls
            // The name of public app folder is specified with "--appfolder" option
            // Default name of public app folder is the same as main project
            var wwwRootOutPath = Path.Combine(root.OutputPath, WwwRootOut);

            // Delete old public app folder because we don't want leftovers from previous operations
            root.Operations.Delete(wwwRootOutPath);
            Directory.CreateDirectory(wwwRootOutPath);

            // Copy content files (e.g. html, js and images) of main project into public app folder
            CopyContentFiles(root, project, wwwRootOutPath);

            GenerateWebConfigFileForWwwRootOut(root, project, wwwRootOutPath);

            CopyAspNetLoaderDll(root, wwwRootOutPath);
        }
Пример #3
0
 public BundleRuntime(BundleRoot root, FrameworkName frameworkName, string runtimePath)
 {
     _frameworkName = frameworkName;
     _runtimePath = runtimePath;
     Name = new DirectoryInfo(_runtimePath).Name;
     TargetPath = Path.Combine(root.TargetPackagesPath, Name);
 }
Пример #4
0
 public BundleRuntime(BundleRoot root, FrameworkName frameworkName, string runtimePath)
 {
     _frameworkName = frameworkName;
     _runtimePath   = runtimePath;
     Name           = new DirectoryInfo(_runtimePath).Name;
     TargetPath     = Path.Combine(root.TargetPackagesPath, Name);
 }
Пример #5
0
        public bool BuildNativeImages(BundleRoot root)
        {
            var success = true;

            foreach (var runtime in root.Runtimes)
            {
                NuGetDependencyResolver resolver;
                if (!_resolverLookup.TryGetValue(runtime.Framework, out resolver))
                {
                    throw new InvalidOperationException("No matching framework is found for " + runtime.Framework);
                }

                var runtimeBin = Path.Combine(runtime.TargetPath, "bin");

                var options = new CrossgenOptions()
                {
                    CrossgenPath = Path.Combine(runtimeBin, "crossgen.exe"),
                    InputPaths   = ResolveOutputAssemblies(root, resolver),
                    RuntimePath  = runtimeBin,
                    Symbols      = false
                };

                var crossgenManager = new CrossgenManager(options);
                success &= crossgenManager.GenerateNativeImages();

                if (!success)
                {
                    return(false);
                }
            }
            return(success);
        }
Пример #6
0
        private void EmitSource(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("  Copying source code from {0} dependency {1}",
                                         _libraryDescription.Type, _libraryDescription.Identity.Name);

            Runtime.Project project;
            if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project))
            {
                throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name);
            }

            var targetName = project.Name;

            TargetPath = Path.Combine(root.OutputPath, BundleRoot.AppRootName, "src", targetName);

            // If root.OutputPath is specified by --out option, it might not be a full path
            TargetPath = Path.GetFullPath(TargetPath);

            root.Reports.Quiet.WriteLine("    Source {0}", _libraryDescription.Path.Bold());
            root.Reports.Quiet.WriteLine("    Target {0}", TargetPath);

            root.Operations.Delete(TargetPath);

            CopyProject(root, project, TargetPath, includeSource: true);

            CopyRelativeSources(project);

            UpdateWebRoot(root, TargetPath);

            _applicationBase = Path.Combine("..", BundleRoot.AppRootName, "src", project.Name);
        }
Пример #7
0
        private static string GetBootstrapperVersion(BundleRoot root)
        {
            // Use version of Microsoft.AspNet.Loader.IIS.Interop as version of bootstrapper
            var package = root.Packages.SingleOrDefault(
                x => string.Equals(x.Library.Name, "Microsoft.AspNet.Loader.IIS.Interop"));

            return(package == null ? string.Empty : package.Library.Version.ToString());
        }
Пример #8
0
        bool TryAddRuntime(BundleRoot root, FrameworkName frameworkName, string runtimePath)
        {
            if (!Directory.Exists(runtimePath))
            {
                return(false);
            }

            root.Runtimes.Add(new BundleRuntime(root, frameworkName, runtimePath));
            return(true);
        }
Пример #9
0
 public void Emit(BundleRoot root)
 {
     root.Reports.Quiet.WriteLine("Using {0} dependency {1}", _libraryDescription.Type, Library);
     foreach (var context in root.LibraryDependencyContexts[Library])
     {
         root.Reports.Quiet.WriteLine("  Copying files for {0}",
                                      context.FrameworkName.ToString().Yellow().Bold());
         Emit(root, context.PackageAssemblies[Library.Name]);
         root.Reports.Quiet.WriteLine();
     }
 }
Пример #10
0
 public void Emit(BundleRoot root)
 {
     root.Reports.Quiet.WriteLine("Using {0} dependency {1}", _libraryDescription.Type, Library);
     foreach (var context in root.LibraryDependencyContexts[Library])
     {
         root.Reports.Quiet.WriteLine("  Copying files for {0}",
             context.FrameworkName.ToString().Yellow().Bold());
         Emit(root, context.PackageAssemblies[Library.Name]);
         root.Reports.Quiet.WriteLine();
     }
 }
Пример #11
0
        private void CopyContentFiles(BundleRoot root, Runtime.Project project, string targetFolderPath)
        {
            root.Reports.Quiet.WriteLine("Copying contents of {0} dependency {1} to {2}",
                                         _libraryDescription.Type, _libraryDescription.Identity.Name, targetFolderPath);

            var contentSourcePath = GetWwwRootSourcePath(project.ProjectDirectory, WwwRoot);

            root.Reports.Quiet.WriteLine("  Source {0}", contentSourcePath);
            root.Reports.Quiet.WriteLine("  Target {0}", targetFolderPath);

            root.Operations.Copy(contentSourcePath, targetFolderPath);
        }
Пример #12
0
        private void CopyProject(BundleRoot root, Runtime.Project project, string targetPath, bool includeSource)
        {
            // A set of excluded files/directories used as a filter when doing copy
            var excludeSet   = new HashSet <string>(project.BundleExcludeFiles, StringComparer.OrdinalIgnoreCase);
            var contentFiles = new HashSet <string>(project.ContentFiles, StringComparer.OrdinalIgnoreCase);

            // If a public folder is specified with 'webroot' or '--wwwroot', we ignore it when copying project files
            var wwwRootPath = string.Empty;

            if (!string.IsNullOrEmpty(WwwRoot))
            {
                wwwRootPath = Path.Combine(project.ProjectDirectory, WwwRoot);
                wwwRootPath = PathUtility.EnsureTrailingSlash(wwwRootPath);
            }

            // If project root is used as value of '--wwwroot', we shouldn't exclude it when copying
            if (string.Equals(wwwRootPath, PathUtility.EnsureTrailingSlash(project.ProjectDirectory)))
            {
                wwwRootPath = string.Empty;
            }

            root.Operations.Copy(project.ProjectDirectory, targetPath, itemPath =>
            {
                // If current file/folder is in the exclusion list, we don't copy it
                if (excludeSet.Contains(itemPath))
                {
                    return(false);
                }

                // If current file is in the public folder, we don't copy it to destination project
                if (!string.IsNullOrEmpty(wwwRootPath) && itemPath.StartsWith(wwwRootPath))
                {
                    return(false);
                }

                // The full path of target generated by copy operation should also be excluded
                var targetFullPath = itemPath.Replace(project.ProjectDirectory, TargetPath);
                excludeSet.Add(targetFullPath);

                if (includeSource)
                {
                    return(true);
                }

                if (Directory.Exists(itemPath))
                {
                    return(true);
                }

                return(contentFiles.Contains(itemPath));
            });
        }
Пример #13
0
        private void UpdateWebRoot(BundleRoot root, string targetPath)
        {
            // Update the 'webroot' property, which was specified with '--wwwroot-out' option
            if (!string.IsNullOrEmpty(WwwRootOut))
            {
                var targetProjectJson = Path.Combine(targetPath, Runtime.Project.ProjectFileName);

                UpdateJson(targetProjectJson, jsonObj =>
                {
                    var targetWebRootPath = Path.Combine(root.OutputPath, WwwRootOut);
                    jsonObj["webroot"]    = PathUtility.GetRelativePath(targetProjectJson, targetWebRootPath, separator: '/');
                });
            }
        }
Пример #14
0
        public void Emit(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("Using {0} dependency {1} for {2}", _libraryDescription.Type,
                _libraryDescription.Identity, _libraryDescription.Framework.ToString().Yellow().Bold());

            if (root.NoSource)
            {
                EmitNupkg(root);
            }
            else
            {
                EmitSource(root);
            }
            root.Reports.Quiet.WriteLine();
        }
Пример #15
0
        public void Emit(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("Using {0} dependency {1} for {2}", _libraryDescription.Type,
                                         _libraryDescription.Identity, _libraryDescription.Framework.ToString().Yellow().Bold());

            if (root.NoSource)
            {
                EmitNupkg(root);
            }
            else
            {
                EmitSource(root);
            }
            root.Reports.Quiet.WriteLine();
        }
Пример #16
0
        /// <summary>
        /// This is a helper method for looking up directories that directly contains assemblies that would be loaded
        /// given the bundled runtime framework. We should run crossgen on these folders
        /// </summary>
        private IEnumerable <string> ResolveOutputAssemblies(BundleRoot root, NuGetDependencyResolver resolver)
        {
            var outputPathsMap = root.Packages
                                 .ToDictionary(
                pkg => pkg.Library,
                pkg => pkg.TargetPath
                );

            var result              = new HashSet <string>();
            var libraryNotInOutput  = new List <Library>();
            var missingOutputFolder = new List <string>();

            foreach (var dependency in resolver.PackageAssemblyLookup.Values)
            {
                var    libId             = dependency.Library.Identity;
                var    libPath           = dependency.Library.Path;
                var    assemblyDir       = Path.GetDirectoryName(dependency.Path);
                var    assemblySelection = assemblyDir.Substring(libPath.Length);
                string outputLibLocation;
                if (!outputPathsMap.TryGetValue(libId, out outputLibLocation))
                {
                    libraryNotInOutput.Add(libId);
                    continue;
                }
                var output = outputLibLocation + assemblySelection;

                if (!Directory.Exists(output))
                {
                    missingOutputFolder.Add(output);
                }
                else
                {
                    result.Add(output);
                }
            }

            if (libraryNotInOutput.Any())
            {
                throw new InvalidOperationException(string.Format("Library {0} cannot be found in the bundled output.", string.Join(", ", libraryNotInOutput)));
            }

            if (missingOutputFolder.Any())
            {
                throw new InvalidOperationException("Bundled output does not contain directory:\n" + string.Join("\n", missingOutputFolder));
            }

            return(result);
        }
Пример #17
0
        public void Emit(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("Bundling runtime {0}", Name);

            if (Directory.Exists(TargetPath))
            {
                root.Reports.Quiet.WriteLine("  {0} already exists.", TargetPath);
                return;
            }

            if (!Directory.Exists(TargetPath))
            {
                Directory.CreateDirectory(TargetPath);
            }

            new BundleOperations().Copy(_runtimePath, TargetPath);
        }
Пример #18
0
        public void Emit(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("Bundling runtime {0}", Name);

            if (Directory.Exists(TargetPath))
            {
                root.Reports.Quiet.WriteLine("  {0} already exists.", TargetPath);
                return;
            }

            if (!Directory.Exists(TargetPath))
            {
                Directory.CreateDirectory(TargetPath);
            }

            new BundleOperations().Copy(_runtimePath, TargetPath);
        }
Пример #19
0
        private void CopyFile(BundleRoot root, string srcPath, string targetPath, bool overwrite)
        {
            var targetFolder = Path.GetDirectoryName(targetPath);
            Directory.CreateDirectory(targetFolder);

            if (File.Exists(targetPath))
            {
                if (overwrite)
                {
                    File.Delete(targetPath);
                }
                else
                {
                    root.Reports.Quiet.WriteLine("    {0} already exists", targetPath);
                    return;
                }
            }

            File.Copy(srcPath, targetPath);
        }
Пример #20
0
        /// <summary>
        /// This is the factory method to instantiate a PackNativeManager, if parameters are in invalid state and native
        /// generation cannot be performed, it would return null
        /// </summary>
        public static NativeImageGenerator Create(BundleOptions options, BundleRoot root, IEnumerable<DependencyContext> contexts)
        {
            if (options.Runtimes.Count() == 0)
            {
                options.Reports.Information.WriteLine(
                    "Please provide target CoreCLR runtimes using --runtime flags".Yellow());
                return null;
            }

            foreach (var runtime in root.Runtimes)
            {
                var frameworkName = runtime.Framework;
                // NOTE: !IsDesktop == IsCore and only Core packages can be crossgened at least for now
                if (VersionUtility.IsDesktop(frameworkName))
                {
                    options.Reports.Information.WriteLine(
                        "Native image generation is only supported for .NET Core flavors.".Yellow());
                    return null;
                }
            }

            var duplicates = options.Runtimes
                .GroupBy(r => CrossgenManager.ResolveProcessorArchitecture(r))
                .Where(g => g.Count() > 1);

            if (duplicates.Any())
            {
                var message = "The following runtimes will result in output conflicts. Please provide distinct runtime flavor for each processor architecture:\n"
                    + string.Join("\n", duplicates.Select(
                        g => string.Format("Architecture: {0}\nRuntimes: {1}", g.Key, string.Join(", ", g))));
                options.Reports.Information.WriteLine(message.Yellow());
                return null;
            }

            var contextMap = contexts.ToDictionary(
                context => context.FrameworkName,
                context => context.NuGetDependencyResolver
            );

            return new NativeImageGenerator(contextMap);
        }
Пример #21
0
        /// <summary>
        /// This is the factory method to instantiate a PackNativeManager, if parameters are in invalid state and native
        /// generation cannot be performed, it would return null
        /// </summary>
        public static NativeImageGenerator Create(BundleOptions options, BundleRoot root, IEnumerable <DependencyContext> contexts)
        {
            if (options.Runtimes.Count() == 0)
            {
                options.Reports.Information.WriteLine(
                    "Please provide target CoreCLR runtimes using --runtime flags".Yellow());
                return(null);
            }

            foreach (var runtime in root.Runtimes)
            {
                var frameworkName = runtime.Framework;
                // NOTE: !IsDesktop == IsCore and only Core packages can be crossgened at least for now
                if (VersionUtility.IsDesktop(frameworkName))
                {
                    options.Reports.Information.WriteLine(
                        "Native image generation is only supported for .NET Core flavors.".Yellow());
                    return(null);
                }
            }

            var duplicates = options.Runtimes
                             .GroupBy(r => CrossgenManager.ResolveProcessorArchitecture(r))
                             .Where(g => g.Count() > 1);

            if (duplicates.Any())
            {
                var message = "The following runtimes will result in output conflicts. Please provide distinct runtime flavor for each processor architecture:\n"
                              + string.Join("\n", duplicates.Select(
                                                g => string.Format("Architecture: {0}\nRuntimes: {1}", g.Key, string.Join(", ", g))));
                options.Reports.Information.WriteLine(message.Yellow());
                return(null);
            }

            var contextMap = contexts.ToDictionary(
                context => context.FrameworkName,
                context => context.NuGetDependencyResolver
                );

            return(new NativeImageGenerator(contextMap));
        }
Пример #22
0
        private void CopyFile(BundleRoot root, string srcPath, string targetPath, bool overwrite)
        {
            var targetFolder = Path.GetDirectoryName(targetPath);

            Directory.CreateDirectory(targetFolder);

            if (File.Exists(targetPath))
            {
                if (overwrite)
                {
                    File.Delete(targetPath);
                }
                else
                {
                    root.Reports.Quiet.WriteLine("    {0} already exists", targetPath);
                    return;
                }
            }

            File.Copy(srcPath, targetPath);
        }
Пример #23
0
        private void CopyFolder(BundleRoot root, string srcFolder, string targetFolder)
        {
            if (!Directory.Exists(srcFolder))
            {
                return;
            }

            if (Directory.Exists(targetFolder))
            {
                if (root.Overwrite)
                {
                    root.Operations.Delete(targetFolder);
                }
                else
                {
                    root.Reports.Quiet.WriteLine("    {0} already exists", targetFolder);
                    return;
                }
            }

            Directory.CreateDirectory(targetFolder);
            root.Operations.Copy(srcFolder, targetFolder);
        }
Пример #24
0
        private void CopyFolder(BundleRoot root, string srcFolder, string targetFolder)
        {
            if (!Directory.Exists(srcFolder))
            {
                return;
            }

            if (Directory.Exists(targetFolder))
            {
                if (root.Overwrite)
                {
                    root.Operations.Delete(targetFolder);
                }
                else
                {
                    root.Reports.Quiet.WriteLine("    {0} already exists", targetFolder);
                    return;
                }
            }

            Directory.CreateDirectory(targetFolder);
            root.Operations.Copy(srcFolder, targetFolder);
        }
Пример #25
0
        private static void CopyAspNetLoaderDll(BundleRoot root, string wwwRootOutPath)
        {
            // Tool dlls including AspNet.Loader.dll go to bin folder under public app folder
            var wwwRootOutBinPath = Path.Combine(wwwRootOutPath, "bin");

            // Copy Microsoft.AspNet.Loader.IIS.Interop/tools/*.dll into bin to support AspNet.Loader.dll
            var package = root.Packages.SingleOrDefault(
                x => string.Equals(x.Library.Name, "Microsoft.AspNet.Loader.IIS.Interop"));

            if (package == null)
            {
                return;
            }

            var resolver         = new DefaultPackagePathResolver(root.SourcePackagesPath);
            var packagePath      = resolver.GetInstallPath(package.Library.Name, package.Library.Version);
            var packageToolsPath = Path.Combine(packagePath, "tools");

            if (Directory.Exists(packageToolsPath))
            {
                foreach (var packageToolFile in Directory.EnumerateFiles(packageToolsPath, "*.dll").Select(Path.GetFileName))
                {
                    // Create the bin folder only when we need to put something inside it
                    if (!Directory.Exists(wwwRootOutBinPath))
                    {
                        Directory.CreateDirectory(wwwRootOutBinPath);
                    }

                    // Copy to bin folder under public app folder
                    File.Copy(
                        Path.Combine(packageToolsPath, packageToolFile),
                        Path.Combine(wwwRootOutBinPath, packageToolFile),
                        overwrite: true);
                }
            }
        }
Пример #26
0
        private void Emit(BundleRoot root, IEnumerable <PackageAssembly> assemblies)
        {
            var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath);

            TargetPath = resolver.GetInstallPath(Library.Name, Library.Version);

            root.Reports.Quiet.WriteLine("    Source: {0}", _libraryDescription.Path);
            root.Reports.Quiet.WriteLine("    Target: {0}", TargetPath);

            Directory.CreateDirectory(TargetPath);

            // Copy nuspec
            var nuspecName = resolver.GetManifestFileName(Library.Name, Library.Version);

            root.Reports.Quiet.WriteLine("    File: {0}", nuspecName.Bold());
            CopyFile(root, Path.Combine(_libraryDescription.Path, nuspecName), Path.Combine(TargetPath, nuspecName), root.Overwrite);

            // Copy assemblies for current framework
            foreach (var assembly in assemblies)
            {
                root.Reports.Quiet.WriteLine("    File: {0}", assembly.RelativePath.Bold());

                var targetAssemblyPath = Path.Combine(TargetPath, assembly.RelativePath);
                CopyFile(root, assembly.Path, targetAssemblyPath, root.Overwrite);
            }

            // Special cases
            var specialFolders = new[] { "native", "InteropAssemblies", "redist", Path.Combine("lib", "contract") };

            foreach (var folder in specialFolders)
            {
                var srcFolder    = Path.Combine(_libraryDescription.Path, folder);
                var targetFolder = Path.Combine(TargetPath, folder);
                CopyFolder(root, srcFolder, targetFolder);
            }
        }
Пример #27
0
        private void Emit(BundleRoot root, IEnumerable<PackageAssembly> assemblies)
        {
            var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath);

            TargetPath = resolver.GetInstallPath(Library.Name, Library.Version);

            root.Reports.Quiet.WriteLine("    Source: {0}", _libraryDescription.Path);
            root.Reports.Quiet.WriteLine("    Target: {0}", TargetPath);

            Directory.CreateDirectory(TargetPath);

            // Copy nuspec
            var nuspecName = resolver.GetManifestFileName(Library.Name, Library.Version);
            root.Reports.Quiet.WriteLine("    File: {0}", nuspecName.Bold());
            CopyFile(root, Path.Combine(_libraryDescription.Path, nuspecName), Path.Combine(TargetPath, nuspecName), root.Overwrite);

            // Copy assemblies for current framework
            foreach (var assembly in assemblies)
            {
                root.Reports.Quiet.WriteLine("    File: {0}", assembly.RelativePath.Bold());

                var targetAssemblyPath = Path.Combine(TargetPath, assembly.RelativePath);
                CopyFile(root, assembly.Path, targetAssemblyPath, root.Overwrite);
            }

            // Special cases
            var specialFolders = new[] { "native", "InteropAssemblies", "redist", Path.Combine("lib", "contract") };
            foreach (var folder in specialFolders)
            {
                var srcFolder = Path.Combine(_libraryDescription.Path, folder);
                var targetFolder = Path.Combine(TargetPath, folder);
                CopyFolder(root, srcFolder, targetFolder);
            }
        }
Пример #28
0
        private void EmitNupkg(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("  Packing nupkg from {0} dependency {1}",
                                         _libraryDescription.Type, _libraryDescription.Identity.Name);

            Runtime.Project project;
            if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project))
            {
                throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name);
            }

            var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath);

            var targetNupkg = resolver.GetPackageFileName(project.Name, project.Version);

            TargetPath = resolver.GetInstallPath(project.Name, project.Version);

            root.Reports.Quiet.WriteLine("    Source {0}", _libraryDescription.Path.Bold());
            root.Reports.Quiet.WriteLine("    Target {0}", TargetPath);

            if (Directory.Exists(TargetPath))
            {
                if (root.Overwrite)
                {
                    root.Operations.Delete(TargetPath);
                }
                else
                {
                    root.Reports.Quiet.WriteLine("  {0} already exists.", TargetPath);
                    return;
                }
            }

            // Generate nupkg from this project dependency
            var buildOptions = new BuildOptions();

            buildOptions.ProjectDir = project.ProjectDirectory;
            buildOptions.OutputDir  = Path.Combine(project.ProjectDirectory, "bin");
            buildOptions.Configurations.Add(root.Configuration);
            buildOptions.Reports          = root.Reports;
            buildOptions.GeneratePackages = true;
            var buildManager = new BuildManager(root.HostServices, buildOptions);

            if (!buildManager.Build())
            {
                return;
            }

            // Extract the generated nupkg to target path
            var srcNupkgPath    = Path.Combine(buildOptions.OutputDir, root.Configuration, targetNupkg);
            var targetNupkgPath = resolver.GetPackageFilePath(project.Name, project.Version);
            var hashFile        = resolver.GetHashPath(project.Name, project.Version);

            using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read))
            {
                using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read))
                {
                    root.Operations.ExtractNupkg(archive, TargetPath);
                }
            }

            using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read))
            {
                using (var targetStream = new FileStream(targetNupkgPath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    sourceStream.CopyTo(targetStream);
                }

                sourceStream.Seek(0, SeekOrigin.Begin);
                var sha512Bytes = SHA512.Create().ComputeHash(sourceStream);
                File.WriteAllText(hashFile, Convert.ToBase64String(sha512Bytes));
            }

            // Copy content files (e.g. html, js and images) of main project into "root" folder of the exported package
            var rootFolderPath  = Path.Combine(TargetPath, "root");
            var rootProjectJson = Path.Combine(rootFolderPath, Runtime.Project.ProjectFileName);

            CopyProject(root, project, rootFolderPath, includeSource: false);

            UpdateWebRoot(root, rootFolderPath);

            UpdateJson(rootProjectJson, jsonObj =>
            {
                // Update the project entrypoint
                jsonObj["entryPoint"] = _libraryDescription.Identity.Name;

                // Set mark this as non loadable
                jsonObj["loadable"] = false;

                // Update the dependencies node to reference the main project
                var deps = new JObject();
                jsonObj["dependencies"] = deps;

                deps[_libraryDescription.Identity.Name] = _libraryDescription.Identity.Version.ToString();
            });

            _applicationBase = Path.Combine("..", BundleRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root");
        }
Пример #29
0
        private void GenerateWebConfigFileForWwwRootOut(BundleRoot root, Runtime.Project project, string wwwRootOutPath)
        {
            // Generate web.config for public app folder
            var wwwRootOutWebConfigFilePath = Path.Combine(wwwRootOutPath, "web.config");
            var wwwRootSourcePath           = GetWwwRootSourcePath(project.ProjectDirectory, WwwRoot);
            var webConfigFilePath           = Path.Combine(wwwRootSourcePath, "web.config");

            XDocument xDoc;

            if (File.Exists(webConfigFilePath))
            {
                xDoc = XDocument.Parse(File.ReadAllText(webConfigFilePath));
            }
            else
            {
                xDoc = new XDocument();
            }

            if (xDoc.Root == null)
            {
                xDoc.Add(new XElement("configuration"));
            }

            if (xDoc.Root.Name != "configuration")
            {
                throw new InvalidDataException("'configuration' is the only valid name for root element of web.config file");
            }

            var appSettingsElement = GetOrAddElement(parent: xDoc.Root, name: "appSettings");

            var relativePackagesPath = PathUtility.GetRelativePath(wwwRootOutWebConfigFilePath, root.TargetPackagesPath);
            var defaultRuntime       = root.Runtimes.FirstOrDefault();

            var keyValuePairs = new Dictionary <string, string>()
            {
                { Runtime.Constants.WebConfigKpmPackagePath, relativePackagesPath },
                { Runtime.Constants.WebConfigBootstrapperVersion, GetBootstrapperVersion(root) },
                { Runtime.Constants.WebConfigRuntimePath, relativePackagesPath },
                { Runtime.Constants.WebConfigRuntimeVersion, GetRuntimeVersion(defaultRuntime) },
                { Runtime.Constants.WebConfigRuntimeFlavor, GetRuntimeFlavor(defaultRuntime) },
                { Runtime.Constants.WebConfigRuntimeAppBase, _applicationBase },
            };

            foreach (var pair in keyValuePairs)
            {
                var addElement = appSettingsElement.Elements()
                                 .Where(x => x.Name == "add" && x.Attribute("key").Value == pair.Key)
                                 .SingleOrDefault();
                if (addElement == null)
                {
                    addElement = new XElement("add");
                    addElement.SetAttributeValue("key", pair.Key);
                    appSettingsElement.Add(addElement);
                }

                addElement.SetAttributeValue("value", pair.Value);
            }

            var xmlWriterSettings = new XmlWriterSettings
            {
                Indent           = true,
                ConformanceLevel = ConformanceLevel.Auto
            };

            using (var xmlWriter = XmlWriter.Create(File.Create(wwwRootOutWebConfigFilePath), xmlWriterSettings))
            {
                xDoc.WriteTo(xmlWriter);
            }
        }
Пример #30
0
        private static void CopyAspNetLoaderDll(BundleRoot root, string wwwRootOutPath)
        {
            // Tool dlls including AspNet.Loader.dll go to bin folder under public app folder
            var wwwRootOutBinPath = Path.Combine(wwwRootOutPath, "bin");

            // Copy Microsoft.AspNet.Loader.IIS.Interop/tools/*.dll into bin to support AspNet.Loader.dll
            var package = root.Packages.SingleOrDefault(
                x => string.Equals(x.Library.Name, "Microsoft.AspNet.Loader.IIS.Interop"));
            if (package == null)
            {
                return;
            }

            var resolver = new DefaultPackagePathResolver(root.SourcePackagesPath);
            var packagePath = resolver.GetInstallPath(package.Library.Name, package.Library.Version);
            var packageToolsPath = Path.Combine(packagePath, "tools");
            if (Directory.Exists(packageToolsPath))
            {
                foreach (var packageToolFile in Directory.EnumerateFiles(packageToolsPath, "*.dll").Select(Path.GetFileName))
                {
                    // Create the bin folder only when we need to put something inside it
                    if (!Directory.Exists(wwwRootOutBinPath))
                    {
                        Directory.CreateDirectory(wwwRootOutBinPath);
                    }

                    // Copy to bin folder under public app folder
                    File.Copy(
                        Path.Combine(packageToolsPath, packageToolFile),
                        Path.Combine(wwwRootOutBinPath, packageToolFile),
                        overwrite: true);
                }
            }
        }
Пример #31
0
        /// <summary>
        /// This is a helper method for looking up directories that directly contains assemblies that would be loaded
        /// given the bundled runtime framework. We should run crossgen on these folders
        /// </summary>
        private IEnumerable<string> ResolveOutputAssemblies(BundleRoot root, NuGetDependencyResolver resolver)
        {
            var outputPathsMap = root.Packages
                .ToDictionary(
                    pkg => pkg.Library,
                    pkg => pkg.TargetPath
                );

            var result = new HashSet<string>();
            var libraryNotInOutput = new List<Library>();
            var missingOutputFolder = new List<string>();

            foreach (var dependency in resolver.PackageAssemblyLookup.Values)
            {
                var libId = dependency.Library.Identity;
                var libPath = dependency.Library.Path;
                var assemblyDir = Path.GetDirectoryName(dependency.Path);
                var assemblySelection = assemblyDir.Substring(libPath.Length);
                string outputLibLocation;
                if (!outputPathsMap.TryGetValue(libId, out outputLibLocation))
                {
                    libraryNotInOutput.Add(libId);
                    continue;
                }
                var output = outputLibLocation + assemblySelection;

                if (!Directory.Exists(output))
                {
                    missingOutputFolder.Add(output);
                }
                else
                {
                    result.Add(output);
                }
            }

            if (libraryNotInOutput.Any())
            {
                throw new InvalidOperationException(string.Format("Library {0} cannot be found in the bundled output.", string.Join(", ", libraryNotInOutput)));
            }

            if (missingOutputFolder.Any())
            {
                throw new InvalidOperationException("Bundled output does not contain directory:\n" + string.Join("\n", missingOutputFolder));
            }

            return result;
        }
Пример #32
0
        bool TryAddRuntime(BundleRoot root, FrameworkName frameworkName, string runtimePath)
        {
            if (!Directory.Exists(runtimePath))
            {
                return false;
            }

            root.Runtimes.Add(new BundleRuntime(root, frameworkName, runtimePath));
            return true;
        }
Пример #33
0
        public bool Bundle()
        {
            Runtime.Project project;
            if (!Runtime.Project.TryGetProject(_options.ProjectDir, out project))
            {
                _options.Reports.Error.WriteLine("Unable to locate {0}.'".Red(), Runtime.Project.ProjectFileName);
                return false;
            }

            // '--wwwroot' option can override 'webroot' property in project.json
            _options.WwwRoot = _options.WwwRoot ?? project.WebRoot;
            _options.WwwRootOut = _options.WwwRootOut ?? _options.WwwRoot;

            if (string.IsNullOrEmpty(_options.WwwRoot) && !string.IsNullOrEmpty(_options.WwwRootOut))
            {
                _options.Reports.Error.WriteLine(
                    "'--wwwroot-out' option can be used only when the '--wwwroot' option or 'webroot' in project.json is specified.".Red());
                return false;
            }

            if (!string.IsNullOrEmpty(_options.WwwRoot) &&
                !Directory.Exists(Path.Combine(project.ProjectDirectory, _options.WwwRoot)))
            {
                _options.Reports.Error.WriteLine(
                    "The specified wwwroot folder '{0}' doesn't exist in the project directory.".Red(), _options.WwwRoot);
                return false;
            }

            if (string.Equals(_options.WwwRootOut, BundleRoot.AppRootName, StringComparison.OrdinalIgnoreCase))
            {
                _options.Reports.Error.WriteLine(
                    "'{0}' is a reserved folder name. Please choose another name for the wwwroot-out folder.".Red(),
                    BundleRoot.AppRootName);
                return false;
            }

            var sw = Stopwatch.StartNew();

            string outputPath = _options.OutputDir;

            var projectDir = project.ProjectDirectory;

            var frameworkContexts = new Dictionary<FrameworkName, DependencyContext>();

            var root = new BundleRoot(project, outputPath, _hostServices, _options.Reports)
            {
                Overwrite = _options.Overwrite,
                Configuration = _options.Configuration,
                NoSource = _options.NoSource
            };

            Func<string, string> getVariable = key =>
            {
                return null;
            };

            if (!ScriptExecutor.Execute(project, "prepare", getVariable))
            {
                _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                return false;
            }

            if (!ScriptExecutor.Execute(project, "prebundle", getVariable))
            {
                _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                return false;
            }

            foreach (var runtime in _options.Runtimes)
            {
                var frameworkName = DependencyContext.GetFrameworkNameForRuntime(Path.GetFileName(runtime));
                var runtimeLocated = TryAddRuntime(root, frameworkName, runtime);
                List<string> runtimeProbePaths = null;

                if (!runtimeLocated)
                {
                    runtimeProbePaths = new List<string>();
                    runtimeProbePaths.Add(runtime);
                    var runtimeHome = Environment.GetEnvironmentVariable(EnvironmentNames.Home);
                    if (string.IsNullOrEmpty(runtimeHome))
                    {
                        var runtimeGlobalPath = Environment.GetEnvironmentVariable(EnvironmentNames.GlobalPath);
            #if ASPNETCORE50
                        runtimeHome = @"%USERPROFILE%\" + Constants.DefaultLocalRuntimeHomeDir + ";" + runtimeGlobalPath;
            #else
                        var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                        runtimeHome = Path.Combine(userProfile, Constants.DefaultLocalRuntimeHomeDir) + ";" + runtimeGlobalPath;
            #endif
                    }

                    foreach (var portion in runtimeHome.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        var packagesPath = Path.Combine(
                            Environment.ExpandEnvironmentVariables(portion),
                            "runtimes",
                            runtime);

                        if (TryAddRuntime(root, frameworkName, packagesPath))
                        {
                            runtimeLocated = true;
                            break;
                        }

                        runtimeProbePaths.Add(packagesPath);
                    }
                }

                if (!runtimeLocated)
                {
                    _options.Reports.Error.WriteLine(string.Format("Unable to locate runtime '{0}'", runtime.Red().Bold()));
                    if (runtimeProbePaths != null)
                    {
                        _options.Reports.Error.WriteLine(string.Format("Locations probed:{0}{1}", Environment.NewLine, string.Join(Environment.NewLine, runtimeProbePaths)));
                    }
                    return false;
                }

                if (!project.GetTargetFrameworks().Any(x => x.FrameworkName == frameworkName))
                {
                    _options.Reports.Error.WriteLine(
                        string.Format("'{0}' is not a target framework of the project being bundled",
                        frameworkName.ToString().Red().Bold()));
                    return false;
                }

                if (!frameworkContexts.ContainsKey(frameworkName))
                {
                    frameworkContexts[frameworkName] = CreateDependencyContext(project, frameworkName);
                }
            }

            // If there is no target framework filter specified with '--runtime',
            // the bundled output targets all frameworks specified in project.json
            if (!_options.Runtimes.Any())
            {
                foreach (var frameworkInfo in project.GetTargetFrameworks())
                {
                    if (!frameworkContexts.ContainsKey(frameworkInfo.FrameworkName))
                    {
                        frameworkContexts[frameworkInfo.FrameworkName] =
                            CreateDependencyContext(project, frameworkInfo.FrameworkName);
                    }
                }
            }

            if (!frameworkContexts.Any())
            {
                var frameworkName = DependencyContext.GetFrameworkNameForRuntime(Constants.RuntimeNamePrefix + "clr-win-x86.*");
                frameworkContexts[frameworkName] = CreateDependencyContext(project, frameworkName);
            }

            root.SourcePackagesPath = frameworkContexts.First().Value.PackagesDirectory;

            bool anyUnresolvedDependency = false;
            foreach (var dependencyContext in frameworkContexts.Values)
            {
                // If there's any unresolved dependencies then complain and keep working
                if (dependencyContext.DependencyWalker.Libraries.Any(l => !l.Resolved))
                {
                    anyUnresolvedDependency = true;
                    var message = "Warning: " +
                        dependencyContext.DependencyWalker.GetMissingDependenciesWarning(
                            dependencyContext.FrameworkName);
                    _options.Reports.Quiet.WriteLine(message.Yellow());
                }

                foreach (var libraryDescription in dependencyContext.NuGetDependencyResolver.Dependencies)
                {
                    IList<DependencyContext> contexts;
                    if (!root.LibraryDependencyContexts.TryGetValue(libraryDescription.Identity, out contexts))
                    {
                        root.Packages.Add(new BundlePackage(libraryDescription));
                        contexts = new List<DependencyContext>();
                        root.LibraryDependencyContexts[libraryDescription.Identity] = contexts;
                    }
                    contexts.Add(dependencyContext);
                }

                foreach (var libraryDescription in dependencyContext.ProjectReferenceDependencyProvider.Dependencies)
                {
                    if (!root.Projects.Any(p => p.Name == libraryDescription.Identity.Name))
                    {
                        var bundleProject = new BundleProject(
                            dependencyContext.ProjectReferenceDependencyProvider,
                            dependencyContext.ProjectResolver,
                            libraryDescription);

                        if (bundleProject.Name == project.Name)
                        {
                            bundleProject.WwwRoot = _options.WwwRoot;
                            bundleProject.WwwRootOut = _options.WwwRootOut;
                        }
                        root.Projects.Add(bundleProject);
                    }
                }
            }

            NativeImageGenerator nativeImageGenerator = null;
            if (_options.Native)
            {
                nativeImageGenerator = NativeImageGenerator.Create(_options, root, frameworkContexts.Values);
                if (nativeImageGenerator == null)
                {
                    _options.Reports.Error.WriteLine("Fail to initiate native image generation process.".Red());
                    return false;
                }
            }

            root.Emit();

            if (!ScriptExecutor.Execute(project, "postbundle", getVariable))
            {
                _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                return false;
            }

            if (_options.Native && !nativeImageGenerator.BuildNativeImages(root))
            {
                _options.Reports.Error.WriteLine("Native image generation failed.");
                return false;
            }

            sw.Stop();

            _options.Reports.Information.WriteLine("Time elapsed {0}", sw.Elapsed);
            return !anyUnresolvedDependency;
        }
Пример #34
0
 private static string GetBootstrapperVersion(BundleRoot root)
 {
     // Use version of Microsoft.AspNet.Loader.IIS.Interop as version of bootstrapper
     var package = root.Packages.SingleOrDefault(
         x => string.Equals(x.Library.Name, "Microsoft.AspNet.Loader.IIS.Interop"));
     return package == null ? string.Empty : package.Library.Version.ToString();
 }
Пример #35
0
        public bool Bundle()
        {
            Runtime.Project project;
            if (!Runtime.Project.TryGetProject(_options.ProjectDir, out project))
            {
                _options.Reports.Error.WriteLine("Unable to locate {0}.'".Red(), Runtime.Project.ProjectFileName);
                return(false);
            }

            // '--wwwroot' option can override 'webroot' property in project.json
            _options.WwwRoot    = _options.WwwRoot ?? project.WebRoot;
            _options.WwwRootOut = _options.WwwRootOut ?? _options.WwwRoot;

            if (string.IsNullOrEmpty(_options.WwwRoot) && !string.IsNullOrEmpty(_options.WwwRootOut))
            {
                _options.Reports.Error.WriteLine(
                    "'--wwwroot-out' option can be used only when the '--wwwroot' option or 'webroot' in project.json is specified.".Red());
                return(false);
            }

            if (!string.IsNullOrEmpty(_options.WwwRoot) &&
                !Directory.Exists(Path.Combine(project.ProjectDirectory, _options.WwwRoot)))
            {
                _options.Reports.Error.WriteLine(
                    "The specified wwwroot folder '{0}' doesn't exist in the project directory.".Red(), _options.WwwRoot);
                return(false);
            }

            if (string.Equals(_options.WwwRootOut, BundleRoot.AppRootName, StringComparison.OrdinalIgnoreCase))
            {
                _options.Reports.Error.WriteLine(
                    "'{0}' is a reserved folder name. Please choose another name for the wwwroot-out folder.".Red(),
                    BundleRoot.AppRootName);
                return(false);
            }

            var sw = Stopwatch.StartNew();

            string outputPath = _options.OutputDir;

            var projectDir = project.ProjectDirectory;

            var frameworkContexts = new Dictionary <FrameworkName, DependencyContext>();

            var root = new BundleRoot(project, outputPath, _hostServices, _options.Reports)
            {
                Overwrite     = _options.Overwrite,
                Configuration = _options.Configuration,
                NoSource      = _options.NoSource
            };

            Func <string, string> getVariable = key =>
            {
                return(null);
            };

            if (!ScriptExecutor.Execute(project, "prepare", getVariable))
            {
                _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                return(false);
            }

            if (!ScriptExecutor.Execute(project, "prebundle", getVariable))
            {
                _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                return(false);
            }

            foreach (var runtime in _options.Runtimes)
            {
                var           frameworkName     = DependencyContext.GetFrameworkNameForRuntime(Path.GetFileName(runtime));
                var           runtimeLocated    = TryAddRuntime(root, frameworkName, runtime);
                List <string> runtimeProbePaths = null;

                if (!runtimeLocated)
                {
                    runtimeProbePaths = new List <string>();
                    runtimeProbePaths.Add(runtime);
                    var runtimeHome = Environment.GetEnvironmentVariable(EnvironmentNames.Home);
                    if (string.IsNullOrEmpty(runtimeHome))
                    {
                        var runtimeGlobalPath = Environment.GetEnvironmentVariable(EnvironmentNames.GlobalPath);
#if ASPNETCORE50
                        runtimeHome = @"%USERPROFILE%\" + Constants.DefaultLocalRuntimeHomeDir + ";" + runtimeGlobalPath;
#else
                        var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                        runtimeHome = Path.Combine(userProfile, Constants.DefaultLocalRuntimeHomeDir) + ";" + runtimeGlobalPath;
#endif
                    }

                    foreach (var portion in runtimeHome.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        var packagesPath = Path.Combine(
                            Environment.ExpandEnvironmentVariables(portion),
                            "runtimes",
                            runtime);

                        if (TryAddRuntime(root, frameworkName, packagesPath))
                        {
                            runtimeLocated = true;
                            break;
                        }

                        runtimeProbePaths.Add(packagesPath);
                    }
                }

                if (!runtimeLocated)
                {
                    _options.Reports.Error.WriteLine(string.Format("Unable to locate runtime '{0}'", runtime.Red().Bold()));
                    if (runtimeProbePaths != null)
                    {
                        _options.Reports.Error.WriteLine(string.Format("Locations probed:{0}{1}", Environment.NewLine, string.Join(Environment.NewLine, runtimeProbePaths)));
                    }
                    return(false);
                }

                if (!project.GetTargetFrameworks().Any(x => x.FrameworkName == frameworkName))
                {
                    _options.Reports.Error.WriteLine(
                        string.Format("'{0}' is not a target framework of the project being bundled",
                                      frameworkName.ToString().Red().Bold()));
                    return(false);
                }

                if (!frameworkContexts.ContainsKey(frameworkName))
                {
                    frameworkContexts[frameworkName] = CreateDependencyContext(project, frameworkName);
                }
            }

            // If there is no target framework filter specified with '--runtime',
            // the bundled output targets all frameworks specified in project.json
            if (!_options.Runtimes.Any())
            {
                foreach (var frameworkInfo in project.GetTargetFrameworks())
                {
                    if (!frameworkContexts.ContainsKey(frameworkInfo.FrameworkName))
                    {
                        frameworkContexts[frameworkInfo.FrameworkName] =
                            CreateDependencyContext(project, frameworkInfo.FrameworkName);
                    }
                }
            }

            if (!frameworkContexts.Any())
            {
                var frameworkName = DependencyContext.GetFrameworkNameForRuntime(Constants.RuntimeNamePrefix + "clr-win-x86.*");
                frameworkContexts[frameworkName] = CreateDependencyContext(project, frameworkName);
            }

            root.SourcePackagesPath = frameworkContexts.First().Value.PackagesDirectory;

            bool anyUnresolvedDependency = false;
            foreach (var dependencyContext in frameworkContexts.Values)
            {
                // If there's any unresolved dependencies then complain and keep working
                if (dependencyContext.DependencyWalker.Libraries.Any(l => !l.Resolved))
                {
                    anyUnresolvedDependency = true;
                    var message = "Warning: " +
                                  dependencyContext.DependencyWalker.GetMissingDependenciesWarning(
                        dependencyContext.FrameworkName);
                    _options.Reports.Quiet.WriteLine(message.Yellow());
                }

                foreach (var libraryDescription in dependencyContext.NuGetDependencyResolver.Dependencies)
                {
                    IList <DependencyContext> contexts;
                    if (!root.LibraryDependencyContexts.TryGetValue(libraryDescription.Identity, out contexts))
                    {
                        root.Packages.Add(new BundlePackage(libraryDescription));
                        contexts = new List <DependencyContext>();
                        root.LibraryDependencyContexts[libraryDescription.Identity] = contexts;
                    }
                    contexts.Add(dependencyContext);
                }

                foreach (var libraryDescription in dependencyContext.ProjectReferenceDependencyProvider.Dependencies)
                {
                    if (!root.Projects.Any(p => p.Name == libraryDescription.Identity.Name))
                    {
                        var bundleProject = new BundleProject(
                            dependencyContext.ProjectReferenceDependencyProvider,
                            dependencyContext.ProjectResolver,
                            libraryDescription);

                        if (bundleProject.Name == project.Name)
                        {
                            bundleProject.WwwRoot    = _options.WwwRoot;
                            bundleProject.WwwRootOut = _options.WwwRootOut;
                        }
                        root.Projects.Add(bundleProject);
                    }
                }
            }

            NativeImageGenerator nativeImageGenerator = null;
            if (_options.Native)
            {
                nativeImageGenerator = NativeImageGenerator.Create(_options, root, frameworkContexts.Values);
                if (nativeImageGenerator == null)
                {
                    _options.Reports.Error.WriteLine("Fail to initiate native image generation process.".Red());
                    return(false);
                }
            }

            root.Emit();

            if (!ScriptExecutor.Execute(project, "postbundle", getVariable))
            {
                _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                return(false);
            }

            if (_options.Native && !nativeImageGenerator.BuildNativeImages(root))
            {
                _options.Reports.Error.WriteLine("Native image generation failed.");
                return(false);
            }

            sw.Stop();

            _options.Reports.Information.WriteLine("Time elapsed {0}", sw.Elapsed);
            return(!anyUnresolvedDependency);
        }
Пример #36
0
        private void CopyContentFiles(BundleRoot root, Runtime.Project project, string targetFolderPath)
        {
            root.Reports.Quiet.WriteLine("Copying contents of {0} dependency {1} to {2}",
                _libraryDescription.Type, _libraryDescription.Identity.Name, targetFolderPath);

            var contentSourcePath = GetWwwRootSourcePath(project.ProjectDirectory, WwwRoot);

            root.Reports.Quiet.WriteLine("  Source {0}", contentSourcePath);
            root.Reports.Quiet.WriteLine("  Target {0}", targetFolderPath);

            root.Operations.Copy(contentSourcePath, targetFolderPath);
        }
Пример #37
0
        public void PostProcess(BundleRoot root)
        {
            // If --wwwroot-out doesn't have a non-empty value, we don't need a public app folder in output
            if (string.IsNullOrEmpty(WwwRootOut))
            {
                return;
            }

            Runtime.Project project;
            if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project))
            {
                throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name);
            }

            // Construct path to public app folder, which contains content files and tool dlls
            // The name of public app folder is specified with "--appfolder" option
            // Default name of public app folder is the same as main project
            var wwwRootOutPath = Path.Combine(root.OutputPath, WwwRootOut);

            // Delete old public app folder because we don't want leftovers from previous operations
            root.Operations.Delete(wwwRootOutPath);
            Directory.CreateDirectory(wwwRootOutPath);

            // Copy content files (e.g. html, js and images) of main project into public app folder
            CopyContentFiles(root, project, wwwRootOutPath);

            GenerateWebConfigFileForWwwRootOut(root, project, wwwRootOutPath);

            CopyAspNetLoaderDll(root, wwwRootOutPath);
        }
Пример #38
0
        private void UpdateWebRoot(BundleRoot root, string targetPath)
        {
            // Update the 'webroot' property, which was specified with '--wwwroot-out' option
            if (!string.IsNullOrEmpty(WwwRootOut))
            {
                var targetProjectJson = Path.Combine(targetPath, Runtime.Project.ProjectFileName);

                UpdateJson(targetProjectJson, jsonObj =>
                {
                    var targetWebRootPath = Path.Combine(root.OutputPath, WwwRootOut);
                    jsonObj["webroot"] = PathUtility.GetRelativePath(targetProjectJson, targetWebRootPath, separator: '/');
                });
            }
        }
Пример #39
0
        private void GenerateWebConfigFileForWwwRootOut(BundleRoot root, Runtime.Project project, string wwwRootOutPath)
        {
            // Generate web.config for public app folder
            var wwwRootOutWebConfigFilePath = Path.Combine(wwwRootOutPath, "web.config");
            var wwwRootSourcePath = GetWwwRootSourcePath(project.ProjectDirectory, WwwRoot);
            var webConfigFilePath = Path.Combine(wwwRootSourcePath, "web.config");

            XDocument xDoc;
            if (File.Exists(webConfigFilePath))
            {
                xDoc = XDocument.Parse(File.ReadAllText(webConfigFilePath));
            }
            else
            {
                xDoc = new XDocument();
            }

            if (xDoc.Root == null)
            {
                xDoc.Add(new XElement("configuration"));
            }

            if (xDoc.Root.Name != "configuration")
            {
                throw new InvalidDataException("'configuration' is the only valid name for root element of web.config file");
            }

            var appSettingsElement = GetOrAddElement(parent: xDoc.Root, name: "appSettings");

            var relativePackagesPath = PathUtility.GetRelativePath(wwwRootOutWebConfigFilePath, root.TargetPackagesPath);
            var defaultRuntime = root.Runtimes.FirstOrDefault();

            var keyValuePairs = new Dictionary<string, string>()
            {
                { Runtime.Constants.WebConfigKpmPackagePath, relativePackagesPath},
                { Runtime.Constants.WebConfigBootstrapperVersion, GetBootstrapperVersion(root)},
                { Runtime.Constants.WebConfigRuntimePath, relativePackagesPath},
                { Runtime.Constants.WebConfigRuntimeVersion, GetRuntimeVersion(defaultRuntime)},
                { Runtime.Constants.WebConfigRuntimeFlavor, GetRuntimeFlavor(defaultRuntime)},
                { Runtime.Constants.WebConfigRuntimeAppBase, _applicationBase},
            };

            foreach (var pair in keyValuePairs)
            {
                var addElement = appSettingsElement.Elements()
                    .Where(x => x.Name == "add" && x.Attribute("key").Value == pair.Key)
                    .SingleOrDefault();
                if (addElement == null)
                {
                    addElement = new XElement("add");
                    addElement.SetAttributeValue("key", pair.Key);
                    appSettingsElement.Add(addElement);
                }

                addElement.SetAttributeValue("value", pair.Value);
            }

            var xmlWriterSettings = new XmlWriterSettings
            {
                Indent = true,
                ConformanceLevel = ConformanceLevel.Auto
            };

            using (var xmlWriter = XmlWriter.Create(File.Create(wwwRootOutWebConfigFilePath), xmlWriterSettings))
            {
                xDoc.WriteTo(xmlWriter);
            }
        }
Пример #40
0
        private void EmitSource(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("  Copying source code from {0} dependency {1}",
                _libraryDescription.Type, _libraryDescription.Identity.Name);

            Runtime.Project project;
            if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project))
            {
                throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name);
            }

            var targetName = project.Name;
            TargetPath = Path.Combine(root.OutputPath, BundleRoot.AppRootName, "src", targetName);

            // If root.OutputPath is specified by --out option, it might not be a full path
            TargetPath = Path.GetFullPath(TargetPath);

            root.Reports.Quiet.WriteLine("    Source {0}", _libraryDescription.Path.Bold());
            root.Reports.Quiet.WriteLine("    Target {0}", TargetPath);

            root.Operations.Delete(TargetPath);

            CopyProject(root, project, TargetPath, includeSource: true);

            CopyRelativeSources(project);

            UpdateWebRoot(root, TargetPath);

            _applicationBase = Path.Combine("..", BundleRoot.AppRootName, "src", project.Name);
        }
Пример #41
0
        private void EmitNupkg(BundleRoot root)
        {
            root.Reports.Quiet.WriteLine("  Packing nupkg from {0} dependency {1}",
                _libraryDescription.Type, _libraryDescription.Identity.Name);

            Runtime.Project project;
            if (!_projectResolver.TryResolveProject(_libraryDescription.Identity.Name, out project))
            {
                throw new Exception("TODO: unable to resolve project named " + _libraryDescription.Identity.Name);
            }

            var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath);

            var targetNupkg = resolver.GetPackageFileName(project.Name, project.Version);
            TargetPath = resolver.GetInstallPath(project.Name, project.Version);

            root.Reports.Quiet.WriteLine("    Source {0}", _libraryDescription.Path.Bold());
            root.Reports.Quiet.WriteLine("    Target {0}", TargetPath);

            if (Directory.Exists(TargetPath))
            {
                if (root.Overwrite)
                {
                    root.Operations.Delete(TargetPath);
                }
                else
                {
                    root.Reports.Quiet.WriteLine("  {0} already exists.", TargetPath);
                    return;
                }
            }

            // Generate nupkg from this project dependency
            var buildOptions = new BuildOptions();
            buildOptions.ProjectDir = project.ProjectDirectory;
            buildOptions.OutputDir = Path.Combine(project.ProjectDirectory, "bin");
            buildOptions.Configurations.Add(root.Configuration);
            buildOptions.Reports = root.Reports;
            buildOptions.GeneratePackages = true;
            var buildManager = new BuildManager(root.HostServices, buildOptions);
            if (!buildManager.Build())
            {
                return;
            }

            // Extract the generated nupkg to target path
            var srcNupkgPath = Path.Combine(buildOptions.OutputDir, root.Configuration, targetNupkg);
            var targetNupkgPath = resolver.GetPackageFilePath(project.Name, project.Version);
            var hashFile = resolver.GetHashPath(project.Name, project.Version);

            using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read))
            {
                using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read))
                {
                    root.Operations.ExtractNupkg(archive, TargetPath);
                }
            }

            using (var sourceStream = new FileStream(srcNupkgPath, FileMode.Open, FileAccess.Read))
            {
                using (var targetStream = new FileStream(targetNupkgPath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    sourceStream.CopyTo(targetStream);
                }

                sourceStream.Seek(0, SeekOrigin.Begin);
                var sha512Bytes = SHA512.Create().ComputeHash(sourceStream);
                File.WriteAllText(hashFile, Convert.ToBase64String(sha512Bytes));
            }

            // Copy content files (e.g. html, js and images) of main project into "root" folder of the exported package
            var rootFolderPath = Path.Combine(TargetPath, "root");
            var rootProjectJson = Path.Combine(rootFolderPath, Runtime.Project.ProjectFileName);

            CopyProject(root, project, rootFolderPath, includeSource: false);

            UpdateWebRoot(root, rootFolderPath);

            UpdateJson(rootProjectJson, jsonObj =>
            {
                // Update the project entrypoint
                jsonObj["entryPoint"] = _libraryDescription.Identity.Name;

                // Set mark this as non loadable
                jsonObj["loadable"] = false;

                // Update the dependencies node to reference the main project
                var deps = new JObject();
                jsonObj["dependencies"] = deps;

                deps[_libraryDescription.Identity.Name] = _libraryDescription.Identity.Version.ToString();
            });

            _applicationBase = Path.Combine("..", BundleRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root");
        }
Пример #42
0
        private void CopyProject(BundleRoot root, Runtime.Project project, string targetPath, bool includeSource)
        {
            // A set of excluded files/directories used as a filter when doing copy
            var excludeSet = new HashSet<string>(project.BundleExcludeFiles, StringComparer.OrdinalIgnoreCase);
            var contentFiles = new HashSet<string>(project.ContentFiles, StringComparer.OrdinalIgnoreCase);

            // If a public folder is specified with 'webroot' or '--wwwroot', we ignore it when copying project files
            var wwwRootPath = string.Empty;
            if (!string.IsNullOrEmpty(WwwRoot))
            {
                wwwRootPath = Path.Combine(project.ProjectDirectory, WwwRoot);
                wwwRootPath = PathUtility.EnsureTrailingSlash(wwwRootPath);
            }

            // If project root is used as value of '--wwwroot', we shouldn't exclude it when copying
            if (string.Equals(wwwRootPath, PathUtility.EnsureTrailingSlash(project.ProjectDirectory)))
            {
                wwwRootPath = string.Empty;
            }

            root.Operations.Copy(project.ProjectDirectory, targetPath, itemPath =>
            {
                // If current file/folder is in the exclusion list, we don't copy it
                if (excludeSet.Contains(itemPath))
                {
                    return false;
                }

                // If current file is in the public folder, we don't copy it to destination project
                if (!string.IsNullOrEmpty(wwwRootPath) && itemPath.StartsWith(wwwRootPath))
                {
                    return false;
                }

                // The full path of target generated by copy operation should also be excluded
                var targetFullPath = itemPath.Replace(project.ProjectDirectory, TargetPath);
                excludeSet.Add(targetFullPath);

                if (includeSource)
                {
                    return true;
                }

                if (Directory.Exists(itemPath))
                {
                    return true;
                }

                return contentFiles.Contains(itemPath);
            });
        }