public async Task SaveAsync(ILogger logger, CancellationToken cancellationToken) { ThrowOnDisposed(); cancellationToken.ThrowIfCancellationRequested(); if (!_isSaved) { using (await SafeLogger.WriteStartOperationAsync(logger, $"Saving project file: \"{this.FullPath}\"").ConfigureAwait(false)) { if (!Directory.Exists(this.DirectoryPath)) { Directory.CreateDirectory(this.DirectoryPath); _ownsDirectory = true; } using (StreamWriter writer = File.CreateText(this.FullPath)) { await AsyncHelper.RunAsync(() => ProjectNode.Save(writer), cancellationToken).ConfigureAwait(false); } _isSaved = true; } } }
internal async Task <string> GenerateParamsFileAsync(ILogger logger, CancellationToken cancellationToken) { var paramsFilePath = Path.Combine(this.MSBuildProj.DirectoryPath, s_bootstrapperParamsFileName); using (await SafeLogger.WriteStartOperationAsync(logger, $"Generating {paramsFilePath} params file ...").ConfigureAwait(false)) { await AsyncHelper.RunAsync(() => this.Options.Save(paramsFilePath), cancellationToken).ConfigureAwait(false); return(paramsFilePath); } }
private static async Task GenerateParamsFileAsync(CommandProcessorOptions options, ILogger logger, CancellationToken cancellationToken) { // params file is generated on first run, never on update and never by the bootstrapper. if (!(options.IsUpdateOperation || options.NoProjectUpdates == true)) { using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, "Generating svcutil params file ...").ConfigureAwait(false)) { var updateOptions = options.CloneAs <UpdateOptions>(); updateOptions.ProviderId = Tool.ToolName; updateOptions.Version = Tool.PackageVersion; ProjectDependency.RemoveRedundantReferences(updateOptions.References); updateOptions.MakePathsRelativeTo(options.OutputDir); var paramsFile = Path.Combine(options.OutputDir.FullName, CommandProcessorOptions.SvcutilParamsFileName); await AsyncHelper.RunAsync(() => updateOptions.Save(paramsFile), cancellationToken).ConfigureAwait(false); } } }
private async Task <List <ProjectDependency> > ResolveAssemblyReferencesAsync(ILogger logger, CancellationToken cancellationToken) { ThrowOnDisposed(); cancellationToken.ThrowIfCancellationRequested(); var assemblyDependencies = new List <ProjectDependency>(); using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, $"Resolving assembly references for {this.TargetFramework} target framework ...").ConfigureAwait(false)) { await ResolveProperyValuesAsync(new string[] { "OutputPath", "TargetPath" }, logger, cancellationToken).ConfigureAwait(false); var outputPath = this._resolvedProperties["OutputPath"]; if (!Path.IsPathRooted(outputPath)) { outputPath = Path.Combine(this.DirectoryPath, outputPath.Trim(new char[] { '\"' })); } var depsFile = this.GlobalProperties.TryGetValue("Configuration", out var activeConfiguration) && !string.IsNullOrWhiteSpace(activeConfiguration) ? Path.Combine(outputPath, $"{Path.GetFileNameWithoutExtension(this.FileName)}.deps.json") : await ResolveDepsFilePathFromBuildConfigAsync(outputPath, logger, cancellationToken).ConfigureAwait(false); if (File.Exists(depsFile)) { await AsyncHelper.RunAsync(async() => { try { DependencyContext depContext = null; using (var stream = File.OpenRead(depsFile)) { depContext = new DependencyContextJsonReader().Read(stream); } var targetLib = Path.GetFileName(this._resolvedProperties["TargetPath"].Trim('\"')); if (string.IsNullOrEmpty(targetLib)) { targetLib = $"{Path.ChangeExtension(this.FileName, ".dll")}"; } foreach (var rtLib in depContext.RuntimeLibraries.Where(l => l.NativeLibraryGroups.Count == 0)) { ProjectDependency dependency = null; switch (rtLib.Type) { case "project": case "reference": foreach (var assemblyGroup in rtLib.RuntimeAssemblyGroups) { foreach (var assetPath in assemblyGroup.AssetPaths) { if (!Path.GetFileName(assetPath).Equals(targetLib, RuntimeEnvironmentHelper.FileStringComparison)) { dependency = ProjectDependency.FromAssembly(Path.Combine(outputPath, assetPath)); if (File.Exists(dependency.FullPath) && !assemblyDependencies.Contains(dependency)) { assemblyDependencies.Add(dependency); } } } } break; //case "package": default: break; } } } catch (Exception ex) { if (Utils.IsFatalOrUnexpected(ex)) { throw; } await safeLogger.WriteWarningAsync(ex.Message, logToUI: false).ConfigureAwait(false); } }, cancellationToken).ConfigureAwait(false); assemblyDependencies.Sort(); } else { await safeLogger.WriteWarningAsync("Deps file not found (project not built), unable to resolve assembly/project dependencies!", logToUI : false).ConfigureAwait(false); } await safeLogger.WriteMessageAsync($"Assembly reference count: {assemblyDependencies.Count}", logToUI : false).ConfigureAwait(false); } return(assemblyDependencies); }
private async Task <List <ProjectDependency> > ResolvePackageReferencesAsync(ILogger logger, CancellationToken cancellationToken) { ThrowOnDisposed(); cancellationToken.ThrowIfCancellationRequested(); var packageDependencies = new List <ProjectDependency>(); using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, "Resolving package references ...").ConfigureAwait(false)) { await AsyncHelper.RunAsync(async() => { try { var assetsFile = new FileInfo(Path.Combine(this.DirectoryPath, "obj", "project.assets.json")).FullName; if (File.Exists(assetsFile)) { LockFile lockFile = LockFileUtilities.GetLockFile(assetsFile, logger as NuGet.Common.ILogger); if (lockFile != null) { if (lockFile.Targets.Count == 1) { foreach (var lib in lockFile.Targets[0].Libraries) { bool isPackage = StringComparer.OrdinalIgnoreCase.Compare(lib.Type, "package") == 0; if (isPackage) { foreach (var compiletimeAssembly in lib.CompileTimeAssemblies) { if (Path.GetExtension(compiletimeAssembly.Path) == ".dll") { var dependency = ProjectDependency.FromPackage(Path.GetFileNameWithoutExtension(compiletimeAssembly.Path), lib.Name, lib.Version.ToNormalizedString()); var itemIdx = packageDependencies.IndexOf(dependency); if (itemIdx == -1) { packageDependencies.Add(dependency); } else if (dependency.IsFramework) { // packages can be described individually and/or as part of a platform metapackage in the lock file; for instance: Microsoft.CSharp is a package that is part of Microsoft.NetCore. packageDependencies[itemIdx] = dependency; } } } } } packageDependencies.Sort(); } else { await safeLogger.WriteWarningAsync(Shared.Resources.WarningMultiFxOrNoSupportedDnxVersion, logToUI: true).ConfigureAwait(false); } } else { await safeLogger.WriteWarningAsync(Shared.Resources.WarningCannotResolveProjectReferences, logToUI: true).ConfigureAwait(false); } } } catch (Exception ex) { if (Utils.IsFatalOrUnexpected(ex)) { throw; } await safeLogger.WriteWarningAsync(ex.Message, logToUI: false).ConfigureAwait(false); } }, cancellationToken).ConfigureAwait(false); await safeLogger.WriteMessageAsync($"Package reference count: {packageDependencies.Count}", logToUI : false).ConfigureAwait(false); } return(packageDependencies); }
public static async Task <ProcessResult> RunAsync(string processName, string processArgs, string currentDir, bool redirectOutput, bool throwOnError, IDictionary <string, string> environmentVariables, ILogger logger, CancellationToken cancellationToken) { bool isErrorLogged = false; var errorTextBldr = new StringBuilder(); var outputTextBldr = new StringBuilder(); cancellationToken.ThrowIfCancellationRequested(); if (string.IsNullOrWhiteSpace(currentDir)) { currentDir = Directory.GetCurrentDirectory(); } using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, $"Executing command [\"{currentDir}\"]{Environment.NewLine}>{processName} {processArgs}").ConfigureAwait(false)) { using (var proc = new Process()) { proc.StartInfo.WorkingDirectory = Path.GetFullPath(currentDir); proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = redirectOutput; proc.StartInfo.RedirectStandardError = redirectOutput; proc.StartInfo.RedirectStandardOutput = redirectOutput; proc.StartInfo.FileName = processName; proc.StartInfo.Arguments = processArgs; proc.EnableRaisingEvents = true; foreach (var environmentVar in environmentVariables.Where(e => !string.IsNullOrWhiteSpace(e.Key))) { proc.StartInfo.Environment.Add(environmentVar); } if (redirectOutput) { // The default encoding might not work while redirecting non-ANSI characters. // Standard error encoding is only supported when standard error is redirected. proc.StartInfo.StandardErrorEncoding = Encoding.UTF8; proc.StartInfo.StandardOutputEncoding = Encoding.UTF8; } proc.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (!string.IsNullOrWhiteSpace(e.Data)) { errorTextBldr.AppendLine(e.Data); safeLogger.WriteErrorAsync(e.Data, false).ConfigureAwait(false); isErrorLogged = true; } }; proc.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { outputTextBldr.AppendLine(e.Data); safeLogger.WriteMessageAsync(e.Data, false).ConfigureAwait(false); }; proc.Start(); #if DEBUG if (DebugUtils.SvcutilDebug == 1) { try { Console.WriteLine($"Starting process in the background: {Path.GetFileName(proc.ProcessName)}, ID: {proc.Id}."); Console.WriteLine($"{Path.GetFileName(currentDir)}>{processName} {processArgs}{Environment.NewLine}"); } catch { } } #endif if (redirectOutput) { proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); } await AsyncHelper.RunAsync(() => proc.WaitForExit(), () => { try { proc.Kill(); } catch { } }, cancellationToken).ConfigureAwait(false); if (!cancellationToken.IsCancellationRequested) { // allow for processing message packets a few more times as they can keep coming after the process has finished. int waitCount = 3; while (waitCount-- > 0) { proc.WaitForExit(); await Task.Delay(100); } } cancellationToken.ThrowIfCancellationRequested(); var outputText = outputTextBldr.ToString().Trim(); var errorText = errorTextBldr.ToString().Trim(); await safeLogger.WriteMessageAsync($"Exit code: {proc.ExitCode}", false).ConfigureAwait(false); if (throwOnError && (isErrorLogged || proc.ExitCode != 0)) { // avoid reporting a foreign tool's exit code. var exitCode = Path.GetFileName(processName) == Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) ? proc.ExitCode : -1; throw new ProcessException(string.IsNullOrWhiteSpace(errorText) ? outputText : errorText, exitCode); } else if (string.IsNullOrWhiteSpace(outputText)) { outputText = errorText; } return(new ProcessResult(proc.ExitCode, outputText)); } } }