public void Emit(PublishRoot 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 PublishOperations().Copy(_runtimePath, TargetPath); if (PlatformHelper.IsMono) { // Executable permissions on dnx lost on copy. var dnxPath = Path.Combine(TargetPath, "bin", "dnx"); if (!FileOperationUtils.MarkExecutable(dnxPath)) { root.Reports.Information.WriteLine("Failed to mark {0} as executable".Yellow(), dnxPath); } } }
public void PostProcess(PublishRoot root) { // At this point, all nupkgs generated from dependency projects are available in packages folder // So we can add them to lockfile now UpdateLockFile(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; } var project = GetCurrentProject(); // 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); }
public bool BuildNativeImages(PublishRoot 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 PublishRuntime(PublishRoot root, FrameworkName frameworkName, string runtimePath) { _frameworkName = frameworkName; _runtimePath = runtimePath; Name = new DirectoryInfo(_runtimePath).Name; TargetPath = Path.Combine(root.TargetRuntimesPath, Name); }
public bool BuildNativeImages(PublishRoot 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 bool Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Bundling runtime {0}", Name); if (Directory.Exists(TargetPath)) { root.Reports.Quiet.WriteLine(" {0} already exists.", TargetPath); // REVIEW: IS this correct? return true; } if (!Directory.Exists(TargetPath)) { Directory.CreateDirectory(TargetPath); } new PublishOperations().Copy(_runtimePath, TargetPath); if (!RuntimeEnvironmentHelper.IsWindows) { // Executable permissions on dnx lost on copy. var dnxPath = Path.Combine(TargetPath, "bin", "dnx"); if (!FileOperationUtils.MarkExecutable(dnxPath)) { root.Reports.Information.WriteLine("Failed to mark {0} as executable".Yellow(), dnxPath); } } return true; }
private void CopyProject(PublishRoot root, Runtime.Project project, string targetPath, bool includeSource) { var additionalExcluding = new List <string>(); // 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.GetFullPath(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; } if (!string.IsNullOrEmpty(wwwRootPath)) { additionalExcluding.Add(wwwRootPath.Substring(PathUtility.EnsureTrailingSlash(project.ProjectDirectory).Length)); } var sourceFiles = project.Files.GetFilesForBundling(includeSource, additionalExcluding); root.Operations.Copy(sourceFiles, project.ProjectDirectory, targetPath); }
private void EmitSource(PublishRoot root) { root.Reports.Quiet.WriteLine(" Copying source code from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); var project = GetCurrentProject(); var targetName = project.Name; TargetPath = Path.Combine(root.OutputPath, PublishRoot.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("..", PublishRoot.AppRootName, "src", project.Name); }
public bool Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Bundling runtime {0}", Name); if (Directory.Exists(TargetPath)) { root.Reports.Quiet.WriteLine(" {0} already exists.", TargetPath); // REVIEW: IS this correct? return(true); } if (!Directory.Exists(TargetPath)) { Directory.CreateDirectory(TargetPath); } new PublishOperations().Copy(_runtimePath, TargetPath); if (!RuntimeEnvironmentHelper.IsWindows) { // Executable permissions on dnx lost on copy. var dnxPath = Path.Combine(TargetPath, "bin", "dnx"); if (!FileOperationUtils.MarkExecutable(dnxPath)) { root.Reports.Information.WriteLine("Failed to mark {0} as executable".Yellow(), dnxPath); } } return(true); }
private static string GetBootstrapperVersion(PublishRoot 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()); }
bool TryAddRuntime(PublishRoot root, FrameworkName frameworkName, string runtimePath) { if (!Directory.Exists(runtimePath)) { return(false); } root.Runtimes.Add(new PublishRuntime(root, frameworkName, runtimePath)); return(true); }
public void Emit(PublishRoot 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 CopyFile(PublishRoot root, string srcPath, string targetPath) { var targetFolder = Path.GetDirectoryName(targetPath); Directory.CreateDirectory(targetFolder); if (File.Exists(targetPath)) { File.Delete(targetPath); } File.Copy(srcPath, targetPath); }
private void CopyContentFiles(PublishRoot 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 UpdateWebRoot(PublishRoot 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: '/'); }); } }
private void CopyFolder(PublishRoot root, string srcFolder, string targetFolder) { if (!Directory.Exists(srcFolder)) { return; } if (Directory.Exists(targetFolder)) { root.Operations.Delete(targetFolder); } Directory.CreateDirectory(targetFolder); root.Operations.Copy(srcFolder, targetFolder); }
/// <summary> /// This is a helper method for looking up directories that directly contains assemblies that would be loaded /// given the published runtime framework. We should run crossgen on these folders /// </summary> private IEnumerable <string> ResolveOutputAssemblies(PublishRoot 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 published output.", string.Join(", ", libraryNotInOutput))); } if (missingOutputFolder.Any()) { throw new InvalidOperationException("Published output does not contain directory:\n" + string.Join("\n", missingOutputFolder)); } return(result); }
public void Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Using {0} dependency {1}", _libraryDescription.Type, Library); var srcNupkgPath = Path.Combine(_libraryDescription.Path, Library.Name + "." + Library.Version + ".nupkg"); var options = new Microsoft.Framework.PackageManager.Packages.AddOptions { NuGetPackage = srcNupkgPath, SourcePackages = root.TargetPackagesPath, Reports = root.Reports }; var packagesAddCommand = new Microsoft.Framework.PackageManager.Packages.AddCommand(options); packagesAddCommand.Execute().GetAwaiter().GetResult(); }
public void Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Using {0} dependency {1}", _libraryDescription.Type, Library); var packagePathResolver = new DefaultPackagePathResolver(root.SourcePackagesPath); var srcNupkgPath = packagePathResolver.GetPackageFilePath(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version); var options = new Microsoft.Framework.PackageManager.Packages.AddOptions { NuGetPackage = srcNupkgPath, SourcePackages = root.TargetPackagesPath, Reports = root.Reports }; var packagesAddCommand = new Microsoft.Framework.PackageManager.Packages.AddCommand(options); packagesAddCommand.Execute().GetAwaiter().GetResult(); }
private void Emit(PublishRoot 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)); // 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); } // Special cases var specialFolders = new List <string> { "native", "InteropAssemblies", "redist", Path.Combine("lib", "contract") }; if (!root.NoSource) { // 'shared' folder is build time dependency, so we only copy it when deploying with source specialFolders.Add("shared"); } foreach (var folder in specialFolders) { var srcFolder = Path.Combine(_libraryDescription.Path, folder); var targetFolder = Path.Combine(TargetPath, folder); CopyFolder(root, srcFolder, targetFolder); } }
private bool UpdateLockFile(PublishRoot root) { var appEnv = (IApplicationEnvironment)root.HostServices.GetService(typeof(IApplicationEnvironment)); var feedOptions = new FeedOptions(); feedOptions.IgnoreFailedSources = true; feedOptions.Sources.Add(root.TargetPackagesPath); feedOptions.TargetPackagesFolder = root.TargetPackagesPath; var tasks = new Task <bool> [root.Projects.Count]; for (int i = 0; i < root.Projects.Count; i++) { var project = root.Projects[i]; var restoreCommand = new RestoreCommand(appEnv); foreach (var runtime in root.Runtimes) { restoreCommand.TargetFrameworks.Add(project.SelectFrameworkForRuntime(runtime)); } var restoreDirectory = project.IsPackage ? Path.Combine(project.TargetPath, "root") : project.TargetPath; restoreCommand.SkipRestoreEvents = true; restoreCommand.SkipInstall = true; // This is a workaround for #1322. Since we use restore to generate the lock file // after publish, it's possible to fail restore after copying the closure // if framework assemblies and packages have the same name. This is more likely now // since dependencies may exist in the top level restoreCommand.IgnoreMissingDependencies = true; restoreCommand.CheckHashFile = false; restoreCommand.RestoreDirectories.Add(restoreDirectory); restoreCommand.FeedOptions = feedOptions; restoreCommand.Reports = root.Reports.ShallowCopy(); // Mute "dnu restore" completely if it is invoked by "dnu publish --quiet" restoreCommand.Reports.Information = root.Reports.Quiet; tasks[i] = restoreCommand.Execute(); } Task.WaitAll(tasks); return(tasks.All(t => t.Result)); }
private static void CopyAspNetLoaderDll(PublishRoot root, string wwwRootOutPath) { // Tool dlls including AspNet.Loader.dll go to bin folder under public app folder var wwwRootOutBinPath = Path.Combine(wwwRootOutPath, "bin"); // Check for an environment variable which can be used (generally in tests) // to override where AspNet.Loader.dll is located. var loaderPath = Environment.GetEnvironmentVariable(EnvironmentNames.AspNetLoaderPath); if (string.IsNullOrEmpty(loaderPath)) { // 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); loaderPath = Path.Combine(packagePath, "tools"); } if (!string.IsNullOrEmpty(loaderPath) && Directory.Exists(loaderPath)) { foreach (var packageToolFile in Directory.EnumerateFiles(loaderPath, "*.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(loaderPath, packageToolFile), Path.Combine(wwwRootOutBinPath, packageToolFile), overwrite: true); } } }
public bool Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Using {0} dependency {1} for {2}", _libraryDescription.Type, _libraryDescription.Identity, _libraryDescription.Framework.ToString().Yellow().Bold()); var success = true; if (root.NoSource || IsWrappingAssembly()) { success = EmitNupkg(root); } else { EmitSource(root); } root.Reports.Quiet.WriteLine(); return success; }
public bool Emit(PublishRoot root) { root.Reports.Quiet.WriteLine("Using {0} dependency {1} for {2}", _libraryDescription.Type, _libraryDescription.Identity, _libraryDescription.Framework.ToString().Yellow().Bold()); var success = true; if (root.NoSource || IsWrappingAssembly()) { success = EmitNupkg(root); } else { EmitSource(root); } root.Reports.Quiet.WriteLine(); return(success); }
/// <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(PublishOptions options, PublishRoot 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)); }
/// <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(PublishOptions options, PublishRoot 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); }
public bool Publish() { var warnings = new List<ICompilationMessage>(); Runtime.Project project; if (!Runtime.Project.TryGetProject(_options.ProjectDir, out project, warnings)) { _options.Reports.Error.WriteLine("Unable to locate {0}.".Red(), Runtime.Project.ProjectFileName); return false; } foreach (var warning in warnings) { _options.Reports.Information.WriteLine(warning.FormattedMessage.Yellow()); } // '--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, PublishRoot.AppRootName, StringComparison.OrdinalIgnoreCase)) { _options.Reports.Error.WriteLine( "'{0}' is a reserved folder name. Please choose another name for the wwwroot-out folder.".Red(), PublishRoot.AppRootName); return false; } var sw = Stopwatch.StartNew(); string outputPath = _options.OutputDir; var projectDir = project.ProjectDirectory; var frameworkContexts = new Dictionary<FrameworkName, DependencyContext>(); var root = new PublishRoot(project, outputPath, _hostServices, _options.Reports) { 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, "prepublish", getVariable)) { _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage); return false; } if (!ResolveActualRuntimeNames(_options.Runtimes)) { 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 DNXCORE50 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 published", 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 published 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 PublishPackage(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 publishProject = new PublishProject( dependencyContext.ProjectReferenceDependencyProvider, dependencyContext.ProjectResolver, libraryDescription); if (publishProject.Name == project.Name) { publishProject.WwwRoot = _options.WwwRoot; publishProject.WwwRootOut = _options.WwwRootOut; } root.Projects.Add(publishProject); } } } 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; } } var success = root.Emit(); if (!ScriptExecutor.Execute(project, "postpublish", 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 && success; }
bool TryAddRuntime(PublishRoot root, FrameworkName frameworkName, string runtimePath) { if (!Directory.Exists(runtimePath)) { return false; } root.Runtimes.Add(new PublishRuntime(root, frameworkName, runtimePath)); return true; }
private void Emit(PublishRoot 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)); // 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); } // Special cases var specialFolders = new List<string> { "native", "InteropAssemblies", "redist", Path.Combine("lib", "contract") }; if (!root.NoSource) { // 'shared' folder is build time dependency, so we only copy it when deploying with source specialFolders.Add("shared"); } foreach (var folder in specialFolders) { var srcFolder = Path.Combine(_libraryDescription.Path, folder); var targetFolder = Path.Combine(TargetPath, folder); CopyFolder(root, srcFolder, targetFolder); } }
private bool EmitNupkg(PublishRoot root) { root.Reports.Quiet.WriteLine(" Packing nupkg from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); IsPackage = true; var project = GetCurrentProject(); 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)) { root.Operations.Delete(TargetPath); } // Generate nupkg from this project dependency var buildOptions = new BuildOptions(); buildOptions.ProjectPatterns.Add(project.ProjectDirectory); buildOptions.OutputDir = Path.Combine(project.ProjectDirectory, "bin"); buildOptions.Configurations.Add(root.Configuration); buildOptions.GeneratePackages = true; buildOptions.Reports = root.Reports.ShallowCopy(); // Mute "dnu pack" completely if it is invoked by "dnu publish --quiet" buildOptions.Reports.Information = root.Reports.Quiet; var buildManager = new BuildManager(root.HostServices, buildOptions); if (!buildManager.Build()) { return(false); } // Extract the generated nupkg to target path var srcNupkgPath = Path.Combine(buildOptions.OutputDir, root.Configuration, targetNupkg); var srcSymbolsNupkgPath = Path.ChangeExtension(srcNupkgPath, "symbols.nupkg"); var options = new Microsoft.Framework.PackageManager.Packages.AddOptions { NuGetPackage = root.IncludeSymbols ? srcSymbolsNupkgPath : srcNupkgPath, SourcePackages = root.TargetPackagesPath, Reports = root.Reports }; var packagesAddCommand = new Microsoft.Framework.PackageManager.Packages.AddCommand(options); packagesAddCommand.Execute().GetAwaiter().GetResult(); // 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); root.Operations.Delete(rootFolderPath); 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(); }); var appBase = Path.Combine(PublishRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root"); _relativeAppBase = Path.Combine("..", appBase); ApplicationBasePath = Path.Combine(root.OutputPath, appBase); root.Reports.Quiet.WriteLine("Removing {0}", srcNupkgPath); File.Delete(srcNupkgPath); root.Reports.Quiet.WriteLine("Removing {0}", srcSymbolsNupkgPath); File.Delete(srcSymbolsNupkgPath); return(true); }
/// <summary> /// This is a helper method for looking up directories that directly contains assemblies that would be loaded /// given the published runtime framework. We should run crossgen on these folders /// </summary> private IEnumerable<string> ResolveOutputAssemblies(PublishRoot 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 published output.", string.Join(", ", libraryNotInOutput))); } if (missingOutputFolder.Any()) { throw new InvalidOperationException("Published output does not contain directory:\n" + string.Join("\n", missingOutputFolder)); } return result; }
private bool PrunePackages(PublishRoot root) { var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath); // Special cases (for backwards compat) var specialFolders = new List <string> { "native", "InteropAssemblies", "redist" }; if (!root.NoSource) { // 'shared' folder is build time dependency, so we only copy it when deploying with source specialFolders.Add("shared"); } var keep = new HashSet <string>(); foreach (var project in root.Projects) { var lockFilePath = Path.GetFullPath(Path.Combine(ApplicationBasePath, LockFileFormat.LockFileName)); var format = new LockFileFormat(); var lockFile = format.Read(lockFilePath); foreach (var target in lockFile.Targets) { foreach (var library in target.Libraries) { var packagesDir = resolver.GetInstallPath(library.Name, library.Version); var manifest = resolver.GetManifestFilePath(library.Name, library.Version); keep.Add(manifest); foreach (var path in library.RuntimeAssemblies) { keep.Add(CombinePath(packagesDir, path)); } foreach (var path in library.CompileTimeAssemblies) { keep.Add(CombinePath(packagesDir, path)); } foreach (var path in library.NativeLibraries) { keep.Add(CombinePath(packagesDir, path)); } foreach (var specialFolder in specialFolders) { var specialFolderPath = CombinePath(packagesDir, specialFolder); if (!Directory.Exists(specialFolderPath)) { continue; } keep.AddRange(Directory.EnumerateFiles(specialFolderPath, "*.*", SearchOption.AllDirectories)); } } } } foreach (var package in root.Packages) { var packageDir = resolver.GetInstallPath(package.Library.Name, package.Library.Version); var packageFiles = Directory.EnumerateFiles(packageDir, "*.*", SearchOption.AllDirectories); foreach (var file in packageFiles) { if (!keep.Contains(file)) { File.Delete(file); } } root.Operations.DeleteEmptyFolders(packageDir); } return(true); }
private void UpdateLockFile(PublishRoot root) { var lockFileFormat = new LockFileFormat(); string lockFilePath; if (root.NoSource) { lockFilePath = Path.Combine(TargetPath, "root", LockFileFormat.LockFileName); } else { lockFilePath = Path.Combine(TargetPath, LockFileFormat.LockFileName); } LockFile lockFile; if (File.Exists(lockFilePath)) { lockFile = lockFileFormat.Read(lockFilePath); } else { lockFile = new LockFile { Islocked = false }; var project = GetCurrentProject(); // Restore dependency groups for future lockfile validation lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, project.Dependencies.Select(x => x.LibraryRange.ToString()))); foreach (var frameworkInfo in project.GetTargetFrameworks()) { lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( frameworkInfo.FrameworkName.ToString(), frameworkInfo.Dependencies.Select(x => x.LibraryRange.ToString()))); } } if (root.NoSource) { // The dependency group shared by all frameworks should only contain the main nupkg (i.e. entrypoint) lockFile.ProjectFileDependencyGroups.RemoveAll(g => string.IsNullOrEmpty(g.FrameworkName)); lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, new[] { _libraryDescription.LibraryRange.ToString() })); } var repository = new PackageRepository(root.TargetPackagesPath); var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath); // For dependency projects that were published to nupkgs // Add them to lockfile to ensure the contents of lockfile are still valid using (var sha512 = SHA512.Create()) { foreach (var publishProject in root.Projects.Where(p => p.IsPackage)) { var packageInfo = repository.FindPackagesById(publishProject.Name) .SingleOrDefault(); if (packageInfo == null) { root.Reports.Information.WriteLine("Unable to locate published package {0} in {1}", publishProject.Name.Yellow(), repository.RepositoryRoot); continue; } var package = packageInfo.Package; var nupkgPath = resolver.GetPackageFilePath(package.Id, package.Version); var project = publishProject.GetCurrentProject(); lockFile.Libraries.Add(LockFileUtils.CreateLockFileLibraryForProject( project, package, sha512, project.GetTargetFrameworks().Select(f => f.FrameworkName), resolver)); } } lockFileFormat.Write(lockFilePath, lockFile); }
private void CopyProject(PublishRoot root, Runtime.Project project, string targetPath, bool includeSource) { var additionalExcluding = new List<string>(); // 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.GetFullPath(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; } if (!string.IsNullOrEmpty(wwwRootPath)) { additionalExcluding.Add(wwwRootPath.Substring(PathUtility.EnsureTrailingSlash(project.ProjectDirectory).Length)); } var sourceFiles = project.Files.GetFilesForBundling(includeSource, additionalExcluding); root.Operations.Copy(sourceFiles, project.ProjectDirectory, targetPath); }
private void CopyContentFiles(PublishRoot 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); if (Directory.Exists(contentSourcePath)) { root.Operations.Copy(contentSourcePath, targetFolderPath); } }
private static string GetBootstrapperVersion(PublishRoot 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 bool PostProcess(PublishRoot root) { // At this point, all nupkgs generated from dependency projects are available in packages folder // So we can add them to lockfile now if (!UpdateLockFile(root)) { return false; } // Prune the packages folder only leaving things that are required if (!PrunePackages(root)) { return false; } // 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 true; } var project = GetCurrentProject(); // 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); return true; }
private bool EmitNupkg(PublishRoot root) { root.Reports.Quiet.WriteLine(" Packing nupkg from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); IsPackage = true; var project = GetCurrentProject(); 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)) { root.Operations.Delete(TargetPath); } // 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(false); } // 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); root.Operations.Delete(rootFolderPath); 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("..", PublishRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root"); root.Reports.Quiet.WriteLine("Removing {0}", srcNupkgPath); File.Delete(srcNupkgPath); srcNupkgPath = Path.ChangeExtension(srcNupkgPath, "symbols.nupkg"); root.Reports.Quiet.WriteLine("Removing {0}", srcNupkgPath); File.Delete(srcNupkgPath); return(true); }
public bool Publish() { var warnings = new List <ICompilationMessage>(); Runtime.Project project; if (!Runtime.Project.TryGetProject(_options.ProjectDir, out project, warnings)) { _options.Reports.Error.WriteLine("Unable to locate {0}.".Red(), Runtime.Project.ProjectFileName); return(false); } foreach (var warning in warnings) { _options.Reports.Information.WriteLine(warning.FormattedMessage.Yellow()); } // '--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.Equals(_options.WwwRootOut, PublishRoot.AppRootName, StringComparison.OrdinalIgnoreCase)) { _options.Reports.Error.WriteLine( "'{0}' is a reserved folder name. Please choose another name for the wwwroot-out folder.".Red(), PublishRoot.AppRootName); return(false); } var sw = Stopwatch.StartNew(); string outputPath = _options.OutputDir; var projectDir = project.ProjectDirectory; var frameworkContexts = new Dictionary <FrameworkName, DependencyContext>(); var root = new PublishRoot(project, outputPath, _hostServices, _options.Reports) { Configuration = _options.Configuration, NoSource = _options.NoSource, IncludeSymbols = _options.IncludeSymbols }; 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, "prepublish", getVariable)) { _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage); return(false); } if (!ResolveActualRuntimeNames(_options.Runtimes)) { return(false); } foreach (var runtime in _options.Runtimes) { // Calculate the runtime name by taking the last path segment (since it could be a path), // but first strip off any trailing '\' or '/' in case the path provided was something like // "C:\Foo\Bar\dnx-clr-win-x64...\" var runtimeName = new DirectoryInfo(runtime).Name; var frameworkName = DependencyContext.SelectFrameworkNameForRuntime( project.GetTargetFrameworks().Select(x => x.FrameworkName), runtimeName); if (frameworkName == null) { _options.Reports.Error.WriteLine( "The project being published does not support the runtime '{0}'", runtime.ToString().Red().Bold()); return(false); } 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 = DnuEnvironment.GetFolderPath(DnuFolderPath.DnxGlobalPath); var defaultRuntimeHome = DnuEnvironment.GetFolderPath(DnuFolderPath.DefaultDnxHome); runtimeHome = $"{defaultRuntimeHome};{runtimeGlobalPath}"; } 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 (!frameworkContexts.ContainsKey(frameworkName)) { frameworkContexts[frameworkName] = CreateDependencyContext(project, frameworkName); } } // If there is no target framework filter specified with '--runtime', // the published 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()) { // We can only get here if the project has no frameworks section, which we don't actually support any more _options.Reports.Error.WriteLine("The project being published has no frameworks listed in the 'frameworks' section."); return(false); } 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 PublishPackage(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 publishProject = new PublishProject( dependencyContext.ProjectReferenceDependencyProvider, dependencyContext.ProjectResolver, libraryDescription); if (publishProject.Name == project.Name) { publishProject.WwwRoot = _options.WwwRoot; publishProject.WwwRootOut = _options.WwwRootOut; } root.Projects.Add(publishProject); } } } 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); } } var success = root.Emit(); if (!ScriptExecutor.Execute(project, "postpublish", 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 && success); }
public bool Publish() { var warnings = new List <ICompilationMessage>(); Runtime.Project project; if (!Runtime.Project.TryGetProject(_options.ProjectDir, out project, warnings)) { _options.Reports.Error.WriteLine("Unable to locate {0}.".Red(), Runtime.Project.ProjectFileName); return(false); } foreach (var warning in warnings) { _options.Reports.Information.WriteLine(warning.FormattedMessage.Yellow()); } // '--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, PublishRoot.AppRootName, StringComparison.OrdinalIgnoreCase)) { _options.Reports.Error.WriteLine( "'{0}' is a reserved folder name. Please choose another name for the wwwroot-out folder.".Red(), PublishRoot.AppRootName); return(false); } var sw = Stopwatch.StartNew(); string outputPath = _options.OutputDir; var projectDir = project.ProjectDirectory; var frameworkContexts = new Dictionary <FrameworkName, DependencyContext>(); var root = new PublishRoot(project, outputPath, _hostServices, _options.Reports) { 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, "prepublish", getVariable)) { _options.Reports.Error.WriteLine(ScriptExecutor.ErrorMessage); return(false); } if (!ResolveActualRuntimeNames(_options.Runtimes)) { 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 DNXCORE50 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 published", 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 published 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 PublishPackage(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 publishProject = new PublishProject( dependencyContext.ProjectReferenceDependencyProvider, dependencyContext.ProjectResolver, libraryDescription); if (publishProject.Name == project.Name) { publishProject.WwwRoot = _options.WwwRoot; publishProject.WwwRootOut = _options.WwwRootOut; } root.Projects.Add(publishProject); } } } 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); } } var success = root.Emit(); if (!ScriptExecutor.Execute(project, "postpublish", 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 && success); }
private void GenerateWebConfigFileForWwwRootOut(PublishRoot 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"); // Always generate \ since web.config is a IIS thing only var relativeRuntimesPath = PathUtility.GetRelativePath(wwwRootOutWebConfigFilePath, root.TargetRuntimesPath) .Replace(Path.DirectorySeparatorChar, '\\'); var defaultRuntime = root.Runtimes.FirstOrDefault(); var appBase = _relativeAppBase.Replace(Path.DirectorySeparatorChar, '\\'); var keyValuePairs = new Dictionary<string, string>() { { Runtime.Constants.WebConfigBootstrapperVersion, GetBootstrapperVersion(root) }, { Runtime.Constants.WebConfigRuntimePath, relativeRuntimesPath }, { Runtime.Constants.WebConfigRuntimeVersion, GetRuntimeVersion(defaultRuntime) }, { Runtime.Constants.WebConfigRuntimeFlavor, GetRuntimeFlavor(defaultRuntime) }, { Runtime.Constants.WebConfigRuntimeAppBase, appBase }, }; 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); } // Generate target framework information ApplyTargetFramework(xDoc, project); var xmlWriterSettings = new XmlWriterSettings { Indent = true, ConformanceLevel = ConformanceLevel.Auto }; using (var xmlWriter = XmlWriter.Create(File.Create(wwwRootOutWebConfigFilePath), xmlWriterSettings)) { xDoc.WriteTo(xmlWriter); } }
private bool PrunePackages(PublishRoot root) { var resolver = new DefaultPackagePathResolver(root.TargetPackagesPath); // Special cases (for backwards compat) var specialFolders = new List<string> { "native", "InteropAssemblies", "redist" }; if (!root.NoSource) { // 'shared' folder is build time dependency, so we only copy it when deploying with source specialFolders.Add("shared"); } var keep = new HashSet<string>(); foreach (var project in root.Projects) { var lockFilePath = Path.GetFullPath(Path.Combine(ApplicationBasePath, LockFileFormat.LockFileName)); var format = new LockFileFormat(); var lockFile = format.Read(lockFilePath); foreach (var target in lockFile.Targets) { foreach (var library in target.Libraries) { var packagesDir = resolver.GetInstallPath(library.Name, library.Version); var manifest = resolver.GetManifestFilePath(library.Name, library.Version); keep.Add(manifest); foreach (var path in library.RuntimeAssemblies) { keep.Add(CombinePath(packagesDir, path)); } foreach (var path in library.CompileTimeAssemblies) { keep.Add(CombinePath(packagesDir, path)); } foreach (var path in library.NativeLibraries) { keep.Add(CombinePath(packagesDir, path)); } foreach (var specialFolder in specialFolders) { var specialFolderPath = CombinePath(packagesDir, specialFolder); if (!Directory.Exists(specialFolderPath)) { continue; } keep.AddRange(Directory.EnumerateFiles(specialFolderPath, "*.*", SearchOption.AllDirectories)); } } } } foreach (var package in root.Packages) { var packageDir = resolver.GetInstallPath(package.Library.Name, package.Library.Version); var packageFiles = Directory.EnumerateFiles(packageDir, "*.*", SearchOption.AllDirectories); foreach (var file in packageFiles) { if (!keep.Contains(file)) { File.Delete(file); } } root.Operations.DeleteEmptyFolders(packageDir); } return true; }
private bool UpdateLockFile(PublishRoot root) { var appEnv = (IApplicationEnvironment)root.HostServices.GetService(typeof(IApplicationEnvironment)); var feedOptions = new FeedOptions(); feedOptions.IgnoreFailedSources = true; feedOptions.Sources.Add(root.TargetPackagesPath); feedOptions.TargetPackagesFolder = root.TargetPackagesPath; var tasks = new Task<bool>[root.Projects.Count]; for (int i = 0; i < root.Projects.Count; i++) { var project = root.Projects[i]; var restoreCommand = new RestoreCommand(appEnv); foreach (var runtime in root.Runtimes) { restoreCommand.TargetFrameworks.Add(project.SelectFrameworkForRuntime(runtime)); } var restoreDirectory = project.IsPackage ? Path.Combine(project.TargetPath, "root") : project.TargetPath; restoreCommand.SkipRestoreEvents = true; restoreCommand.SkipInstall = true; // This is a workaround for #1322. Since we use restore to generate the lock file // after publish, it's possible to fail restore after copying the closure // if framework assemblies and packages have the same name. This is more likely now // since dependencies may exist in the top level restoreCommand.IgnoreMissingDependencies = true; restoreCommand.CheckHashFile = false; restoreCommand.RestoreDirectories.Add(restoreDirectory); restoreCommand.FeedOptions = feedOptions; restoreCommand.Reports = root.Reports.ShallowCopy(); // Mute "dnu restore" completely if it is invoked by "dnu publish --quiet" restoreCommand.Reports.Information = root.Reports.Quiet; tasks[i] = restoreCommand.Execute(); } Task.WaitAll(tasks); return tasks.All(t => t.Result); }
private bool EmitNupkg(PublishRoot root) { root.Reports.Quiet.WriteLine(" Packing nupkg from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); IsPackage = true; var project = GetCurrentProject(); 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)) { root.Operations.Delete(TargetPath); } // Generate nupkg from this project dependency var buildOptions = new BuildOptions(); buildOptions.ProjectPatterns.Add(project.ProjectDirectory); buildOptions.OutputDir = Path.Combine(project.ProjectDirectory, "bin"); buildOptions.Configurations.Add(root.Configuration); buildOptions.GeneratePackages = true; buildOptions.Reports = root.Reports.ShallowCopy(); // Mute "dnu pack" completely if it is invoked by "dnu publish --quiet" buildOptions.Reports.Information = root.Reports.Quiet; var buildManager = new BuildManager(root.HostServices, buildOptions); if (!buildManager.Build()) { return false; } // Extract the generated nupkg to target path var srcNupkgPath = Path.Combine(buildOptions.OutputDir, root.Configuration, targetNupkg); var srcSymbolsNupkgPath = Path.ChangeExtension(srcNupkgPath, "symbols.nupkg"); var options = new Microsoft.Framework.PackageManager.Packages.AddOptions { NuGetPackage = root.IncludeSymbols ? srcSymbolsNupkgPath : srcNupkgPath, SourcePackages = root.TargetPackagesPath, Reports = root.Reports }; var packagesAddCommand = new Microsoft.Framework.PackageManager.Packages.AddCommand(options); packagesAddCommand.Execute().GetAwaiter().GetResult(); // 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); root.Operations.Delete(rootFolderPath); 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(); }); var appBase = Path.Combine(PublishRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root"); _relativeAppBase = Path.Combine("..", appBase); ApplicationBasePath = Path.Combine(root.OutputPath, appBase); root.Reports.Quiet.WriteLine("Removing {0}", srcNupkgPath); File.Delete(srcNupkgPath); root.Reports.Quiet.WriteLine("Removing {0}", srcSymbolsNupkgPath); File.Delete(srcSymbolsNupkgPath); return true; }
private bool EmitNupkg(PublishRoot root) { root.Reports.Quiet.WriteLine(" Packing nupkg from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); IsPackage = true; var project = GetCurrentProject(); 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)) { root.Operations.Delete(TargetPath); } // 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 false; } // 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); root.Operations.Delete(rootFolderPath); 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("..", PublishRoot.AppRootName, "packages", resolver.GetPackageDirectory(_libraryDescription.Identity.Name, _libraryDescription.Identity.Version), "root"); root.Reports.Quiet.WriteLine("Removing {0}", srcNupkgPath); File.Delete(srcNupkgPath); srcNupkgPath = Path.ChangeExtension(srcNupkgPath, "symbols.nupkg"); root.Reports.Quiet.WriteLine("Removing {0}", srcNupkgPath); File.Delete(srcNupkgPath); return true; }
private void EmitSource(PublishRoot root) { root.Reports.Quiet.WriteLine(" Copying source code from {0} dependency {1}", _libraryDescription.Type, _libraryDescription.Identity.Name); var project = GetCurrentProject(); var targetName = project.Name; TargetPath = Path.Combine(root.OutputPath, PublishRoot.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); var appBase = Path.Combine(PublishRoot.AppRootName, "src", project.Name); _relativeAppBase = Path.Combine("..", appBase); ApplicationBasePath = Path.Combine(root.OutputPath, appBase); }
private void GenerateWebConfigFileForWwwRootOut(PublishRoot 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.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); } }