private void CopyContentFiles(PackRoot root, Project project, string appFolderName) { Console.WriteLine("Copying contents of project dependency {0} to {1}", _libraryDescription.Identity.Name, appFolderName); var appFolderPath = Path.Combine(root.OutputPath, appFolderName); Console.WriteLine(" Source {0}", project.ProjectDirectory); Console.WriteLine(" Target {0}", appFolderPath); // A set of content files that should be copied var contentFiles = new HashSet <string>(project.ContentFiles, StringComparer.OrdinalIgnoreCase); root.Operations.Copy(project.ProjectDirectory, appFolderPath, (isRoot, filePath) => { // We always explore a directory if (Directory.Exists(filePath)) { return(true); } var fileName = Path.GetFileName(filePath); // Public app folder doesn't need project.json if (string.Equals(fileName, "project.json", StringComparison.OrdinalIgnoreCase)) { return(false); } return(contentFiles.Contains(filePath)); }); }
public void PostProcess(PackRoot 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, wwwRootOutPath); CopyAspNetLoaderDll(root, wwwRootOutPath); }
private void EmitSource(PackRoot 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, PackRoot.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("..", PackRoot.AppRootName, "src", project.Name); }
public bool BuildNativeImages(PackRoot 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); }
public PackRuntime(PackRoot root, FrameworkName frameworkName, string kreNupkgPath) { _frameworkName = frameworkName; _kreNupkgPath = kreNupkgPath; Name = Path.GetFileName(Path.GetDirectoryName(_kreNupkgPath)); TargetPath = Path.Combine(root.TargetPackagesPath, Name); }
private static string GetBootstrapperVersion(PackRoot 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()); }
public void Emit(PackRoot 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(); } }
private void CopyContentFiles(PackRoot 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); }
private void CopyProject(PackRoot 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.PackExcludeFiles, 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)); }); }
private void UpdateWebRoot(PackRoot 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); }); } }
public void Emit(PackRoot root) { var package = _nugetDependencyResolver.FindCandidate( _libraryDescription.Identity.Name, _libraryDescription.Identity.Version); Console.WriteLine("Packing nupkg dependency {0} {1}", package.Id, package.Version); var resolver = new DefaultPackagePathResolver(root.PackagesPath); TargetPath = resolver.GetInstallPath(package.Id, package.Version); if (Directory.Exists(TargetPath)) { if (root.Overwrite) { root.Operations.Delete(TargetPath); } else { Console.WriteLine(" {0} already exists.", TargetPath); return; } } Console.WriteLine(" Target {0}", TargetPath); var targetNupkgPath = resolver.GetPackageFilePath(package.Id, package.Version); var hashPath = resolver.GetHashPath(package.Id, package.Version); using (var sourceStream = package.GetStream()) { using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read)) { root.Operations.ExtractNupkg(archive, TargetPath); } } using (var sourceStream = package.GetStream()) { 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(hashPath, Convert.ToBase64String(sha512Bytes)); } }
public void Emit(PackRoot 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(); }
/// <summary> /// This is a helper method for looking up directories that directly contains assemblies that would be loaded /// given the packed runtime framework. We should run crossgen on these folders /// </summary> private IEnumerable <string> ResolveOutputAssemblies(PackRoot 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 packed output.", string.Join(", ", libraryNotInOutput))); } if (missingOutputFolder.Any()) { throw new InvalidOperationException("Packed output does not contain directory:\n" + string.Join("\n", missingOutputFolder)); } return(result); }
private void CopyContentFiles(PackRoot 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 contentSourceFolder = WwwRoot ?? string.Empty; var contentSourcePath = Path.Combine(project.ProjectDirectory, contentSourceFolder); // If the value of '--wwwroot' is ".", we need to pack the project root dir // Use Path.GetFullPath() to get rid of the trailing "." contentSourcePath = Path.GetFullPath(contentSourcePath); root.Reports.Quiet.WriteLine(" Source {0}", contentSourcePath); root.Reports.Quiet.WriteLine(" Target {0}", targetFolderPath); root.Operations.Copy(contentSourcePath, targetFolderPath); }
bool TryAddRuntime(PackRoot root, FrameworkName frameworkName, string krePath) { if (!Directory.Exists(krePath)) { return(false); } var kreName = Path.GetFileName(Path.GetDirectoryName(Path.Combine(krePath, "."))); var kreNupkgPath = Path.Combine(krePath, kreName + ".nupkg"); if (!File.Exists(kreNupkgPath)) { return(false); } root.Runtimes.Add(new PackRuntime(root, frameworkName, kreNupkgPath)); return(true); }
/// <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(PackOptions options, PackRoot 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 KLR 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 KRE 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)); }
private void CopyFile(PackRoot 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); }
public void Emit(PackRoot root) { Name = Path.GetFileName(Path.GetDirectoryName(_kreNupkgPath)); Console.WriteLine("Packing runtime {0}", Name); TargetPath = Path.Combine(root.PackagesPath, Name); if (Directory.Exists(TargetPath)) { Console.WriteLine(" {0} already exists.", TargetPath); return; } if (!Directory.Exists(TargetPath)) { Directory.CreateDirectory(TargetPath); } var targetNupkgPath = Path.Combine(TargetPath, Name + ".nupkg"); using (var sourceStream = File.OpenRead(_kreNupkgPath)) { using (var archive = new ZipArchive(sourceStream, ZipArchiveMode.Read)) { root.Operations.ExtractNupkg(archive, TargetPath); } } using (var sourceStream = File.OpenRead(_kreNupkgPath)) { 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(targetNupkgPath + ".sha512", Convert.ToBase64String(sha512Bytes)); } }
public void EmitSource(PackRoot root) { Console.WriteLine("Packing project dependency {0}", _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, PackRoot.AppRootName, "src", targetName); // If root.OutputPath is specified by --out option, it might not be a full path TargetPath = Path.GetFullPath(TargetPath); Console.WriteLine(" Source {0}", project.ProjectDirectory); Console.WriteLine(" Target {0}", TargetPath); root.Operations.Delete(TargetPath); // A set of excluded files/directories used as a filter when doing copy var excludeSet = new HashSet <string>(project.PackExcludeFiles, StringComparer.OrdinalIgnoreCase); root.Operations.Copy(project.ProjectDirectory, TargetPath, (isRoot, filePath) => { if (excludeSet.Contains(filePath)) { return(false); } // The full path of target generated by copy operation should also be excluded var targetFullPath = filePath.Replace(project.ProjectDirectory, TargetPath); excludeSet.Add(targetFullPath); return(true); }); }
private void CopyFolder(PackRoot 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); }
private static void CopyAspNetLoaderDll(PackRoot 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); } } }
private void Emit(PackRoot 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); } }
public bool Package() { Runtime.Project project; if (!Runtime.Project.TryGetProject(_options.ProjectDir, out project)) { Console.WriteLine("Unable to locate {0}.'", Runtime.Project.ProjectFileName); return(false); } var sw = Stopwatch.StartNew(); string outputPath = _options.OutputDir ?? Path.Combine(_options.ProjectDir, "bin", "output"); var projectDir = project.ProjectDirectory; var dependencyContexts = new List <DependencyContext>(); var root = new PackRoot(project, outputPath, _hostServices) { Overwrite = _options.Overwrite, Configuration = _options.Configuration, NoSource = _options.NoSource }; Func <string, string> getVariable = key => { return(null); }; ScriptExecutor.Execute(project, "prepare", getVariable); ScriptExecutor.Execute(project, "prepack", getVariable); foreach (var runtime in _options.Runtimes) { var runtimeLocated = TryAddRuntime(root, runtime); var kreHome = Environment.GetEnvironmentVariable("KRE_HOME"); if (string.IsNullOrEmpty(kreHome)) { kreHome = Environment.GetEnvironmentVariable("ProgramFiles") + @"\KRE;%USERPROFILE%\.kre"; } foreach (var portion in kreHome.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var packagesPath = Path.Combine( Environment.ExpandEnvironmentVariables(portion), "packages", runtime); if (TryAddRuntime(root, packagesPath)) { runtimeLocated = true; break; } } if (!runtimeLocated) { Console.WriteLine(string.Format("Unable to locate runtime '{0}'", runtime)); return(false); } var frameworkName = DependencyContext.GetFrameworkNameForRuntime(Path.GetFileName(runtime)); if (!dependencyContexts.Any(dc => dc.FrameworkName == frameworkName)) { var dependencyContext = new DependencyContext(projectDir, _options.Configuration, frameworkName); dependencyContext.Walk(project.Name, project.Version); dependencyContexts.Add(dependencyContext); } } if (!dependencyContexts.Any()) { var frameworkName = DependencyContext.GetFrameworkNameForRuntime("KRE-svr50-x86.*"); var dependencyContext = new DependencyContext(projectDir, _options.Configuration, frameworkName); dependencyContext.Walk(project.Name, project.Version); dependencyContexts.Add(dependencyContext); } foreach (var dependencyContext in dependencyContexts) { foreach (var libraryDescription in dependencyContext.NuGetDependencyResolver.Dependencies) { if (!root.Packages.Any(p => p.Library == libraryDescription.Identity)) { root.Packages.Add(new PackPackage(dependencyContext.NuGetDependencyResolver, libraryDescription)); } } foreach (var libraryDescription in dependencyContext.ProjectReferenceDependencyProvider.Dependencies) { if (!root.Projects.Any(p => p.Name == libraryDescription.Identity.Name)) { var packProject = new PackProject(dependencyContext.ProjectReferenceDependencyProvider, dependencyContext.ProjectResolver, libraryDescription); if (packProject.Name == project.Name) { packProject.AppFolder = _options.AppFolder; } root.Projects.Add(packProject); } } } root.Emit(); ScriptExecutor.Execute(project, "postpack", getVariable); sw.Stop(); Console.WriteLine("Time elapsed {0}", sw.Elapsed); return(true); }
public void EmitNupkg(PackRoot root) { Console.WriteLine("Packing nupkg from project dependency {0}", _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.PackagesPath); var targetNupkg = resolver.GetPackageFileName(project.Name, project.Version); TargetPath = resolver.GetInstallPath(project.Name, project.Version); Console.WriteLine(" Source {0}", project.ProjectDirectory); Console.WriteLine(" Target {0}", TargetPath); if (Directory.Exists(TargetPath)) { if (root.Overwrite) { root.Operations.Delete(TargetPath); } else { Console.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); 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)); } }
public bool Package() { 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, PackRoot.AppRootName, StringComparison.OrdinalIgnoreCase)) { _options.Reports.Error.WriteLine( "'{0}' is a reserved folder name. Please choose another name for the wwwroot-out folder.".Red(), PackRoot.AppRootName); return(false); } var sw = Stopwatch.StartNew(); string outputPath = _options.OutputDir; var projectDir = project.ProjectDirectory; var frameworkContexts = new Dictionary <FrameworkName, DependencyContext>(); var root = new PackRoot(project, outputPath, _hostServices, _options.Reports) { Overwrite = _options.Overwrite, Configuration = _options.Configuration, NoSource = _options.NoSource }; Func <string, string> getVariable = key => { return(null); }; ScriptExecutor.Execute(project, "prepare", getVariable); ScriptExecutor.Execute(project, "prepack", getVariable); foreach (var runtime in _options.Runtimes) { var frameworkName = DependencyContext.GetFrameworkNameForRuntime(Path.GetFileName(runtime)); var runtimeLocated = TryAddRuntime(root, frameworkName, runtime); if (!runtimeLocated) { var kreHome = Environment.GetEnvironmentVariable("KRE_HOME"); if (string.IsNullOrEmpty(kreHome)) { #if ASPNETCORE50 kreHome = Environment.GetEnvironmentVariable("ProgramFiles") + @"\KRE;%USERPROFILE%\.kre"; #else var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); kreHome = Path.Combine(userProfile, ".kre"); if (!PlatformHelper.IsMono) { var programFilesPath = Environment.GetEnvironmentVariable("ProgramFiles"); kreHome = Path.Combine(programFilesPath, "KRE") + ";" + kreHome; } #endif } foreach (var portion in kreHome.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var packagesPath = Path.Combine( Environment.ExpandEnvironmentVariables(portion), "packages", runtime); if (TryAddRuntime(root, frameworkName, packagesPath)) { runtimeLocated = true; break; } } } if (!runtimeLocated) { _options.Reports.Error.WriteLine(string.Format("Unable to locate runtime '{0}'", runtime.Red().Bold())); 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 packed", 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 packed 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("KRE-CLR-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 PackPackage(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 packProject = new PackProject( dependencyContext.ProjectReferenceDependencyProvider, dependencyContext.ProjectResolver, libraryDescription); if (packProject.Name == project.Name) { packProject.WwwRoot = _options.WwwRoot; packProject.WwwRootOut = _options.WwwRootOut; } root.Projects.Add(packProject); } } } 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(); ScriptExecutor.Execute(project, "postpack", getVariable); 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); }
private void GenerateWebConfigFileForWwwrootOut(PackRoot root, string wwwRootOutPath) { // Generate k.ini for public app folder var wwwRootOutWebConfigFilePath = Path.Combine(wwwRootOutPath, "web.config"); var webConfigFilePath = Path.Combine(TargetPath, "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>() { { "kpm-package-path", relativePackagesPath }, { "bootstrapper-version", GetBootstrapperVersion(root) }, { "kre-package-path", relativePackagesPath }, { "kre-version", GetRuntimeVersion(defaultRuntime) }, { "kre-clr", GetRuntimeFlavor(defaultRuntime) }, { "kre-app-base", _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); } }
private void EmitNupkg(PackRoot 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; 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("..", PackRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root"); }
public void PostProcess(PackRoot root) { 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 appFolderName = AppFolder ?? PackRoot.DefaultAppFolderName; var appFolderPath = Path.Combine(root.OutputPath, appFolderName); // Delete old public app folder because we don't want leftovers from previous operations root.Operations.Delete(appFolderPath); Directory.CreateDirectory(appFolderPath); // Copy content files (e.g. html, js and images) of main project into public app folder CopyContentFiles(root, project, appFolderName); // Tool dlls including AspNet.Loader.dll go to bin folder under public app folder var appFolderBinPath = Path.Combine(appFolderPath, "bin"); var defaultRuntime = root.Runtimes.FirstOrDefault(); var iniFilePath = Path.Combine(TargetPath, "k.ini"); if (defaultRuntime != null && !File.Exists(iniFilePath)) { var parts = defaultRuntime.Name.Split(new[] { '.' }, 2); if (parts.Length == 2) { var versionNumber = parts[1]; parts = parts[0].Split(new[] { '-' }, 3); if (parts.Length == 3) { var flavor = parts[1]; File.WriteAllText(iniFilePath, string.Format(@"[Runtime] KRE_VERSION={0} KRE_FLAVOR={1} KRE_CONFIGURATION={2} ", versionNumber, flavor == "svrc50" ? "CoreCLR" : "DesktopCLR", root.Configuration)); } } } // Generate k.ini for public app folder var appFolderIniFilePath = Path.Combine(appFolderPath, "k.ini"); var appBaseLine = string.Format("APP_BASE={0}", Path.Combine("..", PackRoot.AppRootName, "src", project.Name)); var iniContents = string.Empty; if (File.Exists(iniFilePath)) { iniContents = File.ReadAllText(iniFilePath); } File.WriteAllText(appFolderIniFilePath, string.Format("{0}{1}", iniContents, appBaseLine)); // Copy tools/*.dll into bin to support AspNet.Loader.dll foreach (var package in root.Packages) { var packageToolsPath = Path.Combine(package.TargetPath, "tools"); if (Directory.Exists(packageToolsPath)) { foreach (var packageToolFile in Directory.EnumerateFiles(packageToolsPath, "*.dll").Select(Path.GetFileName)) { if (!Directory.Exists(appFolderBinPath)) { Directory.CreateDirectory(appFolderBinPath); } // Copy to bin folder under public app folder File.Copy( Path.Combine(packageToolsPath, packageToolFile), Path.Combine(appFolderBinPath, packageToolFile), true); } } } }