Пример #1
0
        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;
                }
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
                }
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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));
                }
            }
        }