Example #1
0
        /// <summary>
        ///  Create a dg v2 file using msbuild.
        /// </summary>
        private async Task <DependencyGraphSpec> GetDependencyGraphSpecAsync(string[] projectsWithPotentialP2PReferences, string solutionDirectory, string solutionName, string configFile)
        {
            // Create requests based on the solution directory if a solution was used read settings for the solution.
            // If the solution directory is null, then use config file if present
            // Then use restore directory last
            // If all 3 are null, then the directory of the project will be used to evaluate the settings

            int scaleTimeout;

            if (Project2ProjectTimeOut > 0)
            {
                scaleTimeout = Project2ProjectTimeOut * 1000;
            }
            else
            {
                scaleTimeout = MsBuildUtility.MsBuildWaitTime *
                               Math.Max(10, projectsWithPotentialP2PReferences.Length / 2) / 10;
            }

            Console.LogVerbose($"MSBuild P2P timeout [ms]: {scaleTimeout}");

            string restorePackagesWithLockFile = UseLockFile ? bool.TrueString : null;
            var    restoreLockProperties       = new RestoreLockProperties(restorePackagesWithLockFile, LockFilePath, LockedMode);

            // Call MSBuild to resolve P2P references.
            return(await MsBuildUtility.GetProjectReferencesAsync(
                       MsBuildDirectory.Value,
                       projectsWithPotentialP2PReferences,
                       scaleTimeout,
                       Console,
                       Recursive,
                       solutionDirectory,
                       solutionName,
                       configFile,
                       Source.ToArray(),
                       PackagesDirectory,
                       restoreLockProperties
                       ));
        }
        public static string GetMSBuildArguments(
            string entryPointTargetPath,
            string inputTargetPath,
            string nugetExePath,
            string solutionDirectory,
            string solutionName,
            string restoreConfigFile,
            string[] sources,
            string packagesDirectory,
            MsBuildToolset toolset,
            RestoreLockProperties restoreLockProperties,
            IEnvironmentVariableReader reader)
        {
            // args for MSBuild.exe
            var args = new List <string>()
            {
                EscapeQuoted(inputTargetPath),
                "/t:GenerateRestoreGraphFile",
                "/nologo",
                "/nr:false"
            };

            // Set the msbuild verbosity level if specified
            var msbuildVerbosity = reader.GetEnvironmentVariable("NUGET_RESTORE_MSBUILD_VERBOSITY");

            if (string.IsNullOrEmpty(msbuildVerbosity))
            {
                args.Add("/v:q");
            }
            else
            {
                args.Add($"/v:{msbuildVerbosity} ");
            }

            // Override the target under ImportsAfter with the current NuGet.targets version.
            AddProperty(args, "NuGetRestoreTargets", entryPointTargetPath);
            AddProperty(args, "RestoreUseCustomAfterTargets", bool.TrueString);

            // Set path to nuget.exe or the build task
            AddProperty(args, "RestoreTaskAssemblyFile", nugetExePath);

            // Settings
            AddRestoreSources(args, sources);
            AddPropertyIfHasValue(args, "RestoreSolutionDirectory", solutionDirectory);
            AddPropertyIfHasValue(args, "RestoreConfigFile", restoreConfigFile);
            AddPropertyIfHasValue(args, "RestorePackagesPath", packagesDirectory);
            AddPropertyIfHasValue(args, "SolutionDir", solutionDirectory);
            AddPropertyIfHasValue(args, "SolutionName", solutionName);

            // If the MSBuild version used does not support SkipNonextentTargets and BuildInParallel
            // use the performance optimization
            // When BuildInParallel is used with ContinueOnError it does not continue in some scenarios
            if (toolset.ParsedVersion.CompareTo(new Version(15, 5)) < 0)
            {
                AddProperty(args, "RestoreBuildInParallel", bool.FalseString);
                AddProperty(args, "RestoreUseSkipNonexistentTargets", bool.FalseString);
            }

            // Add additional args to msbuild if needed
            var msbuildAdditionalArgs = reader.GetEnvironmentVariable("NUGET_RESTORE_MSBUILD_ARGS");

            if (!string.IsNullOrEmpty(msbuildAdditionalArgs))
            {
                args.Add(msbuildAdditionalArgs);
            }

            AddPropertyIfHasValue(args, "RestorePackagesWithLockFile", restoreLockProperties.RestorePackagesWithLockFile);
            AddPropertyIfHasValue(args, "NuGetLockFilePath", restoreLockProperties.NuGetLockFilePath);
            if (restoreLockProperties.RestoreLockedMode)
            {
                AddProperty(args, "RestoreLockedMode", bool.TrueString);
            }

            return(string.Join(" ", args));
        }
        /// <summary>
        /// Returns the closure of project references for projects specified in <paramref name="projectPaths"/>.
        /// </summary>
        public static async Task <DependencyGraphSpec> GetProjectReferencesAsync(
            MsBuildToolset msbuildToolset,
            string[] projectPaths,
            int timeOut,
            IConsole console,
            bool recursive,
            string solutionDirectory,
            string solutionName,
            string restoreConfigFile,
            string[] sources,
            string packagesDirectory,
            RestoreLockProperties restoreLockProperties)
        {
            var msbuildPath = GetMsbuild(msbuildToolset.Path);

            if (!File.Exists(msbuildPath))
            {
                throw new CommandException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              LocalizedResourceManager.GetString(nameof(NuGetResources.MsBuildDoesNotExistAtPath)),
                              msbuildPath));
            }

            var nugetExePath = Assembly.GetEntryAssembly().Location;

            // Check for the non-ILMerged path
            var buildTasksPath = Path.Combine(Path.GetDirectoryName(nugetExePath), "NuGet.Build.Tasks.dll");

            if (File.Exists(buildTasksPath))
            {
                nugetExePath = buildTasksPath;
            }

            using (var inputTargetPath = new TempFile(".nugetinputs.targets"))
                using (var entryPointTargetPath = new TempFile(".nugetrestore.targets"))
                    using (var resultsPath = new TempFile(".output.dg"))
                    {
                        // Read NuGet.targets from nuget.exe and write it to disk for msbuild.exe
                        ExtractResource(NuGetTargets, entryPointTargetPath);

                        // Build a .targets file of all restore inputs, this is needed to avoid going over the limit on command line arguments.
                        var properties = new Dictionary <string, string>()
                        {
                            { "RestoreUseCustomAfterTargets", "true" },
                            { "RestoreGraphOutputPath", resultsPath },
                            { "RestoreRecursive", recursive.ToString().ToLowerInvariant() },
                            { "RestoreProjectFilterMode", "exclusionlist" }
                        };

                        var inputTargetXML = GetRestoreInputFile(entryPointTargetPath, properties, projectPaths);

                        inputTargetXML.Save(inputTargetPath);

                        // Create msbuild parameters and include global properties that cannot be set in the input targets path
                        var arguments = GetMSBuildArguments(entryPointTargetPath, inputTargetPath, nugetExePath, solutionDirectory, solutionName, restoreConfigFile, sources, packagesDirectory, msbuildToolset, restoreLockProperties, EnvironmentVariableWrapper.Instance);

                        var processStartInfo = new ProcessStartInfo
                        {
                            UseShellExecute        = false,
                            FileName               = msbuildPath,
                            Arguments              = arguments,
                            RedirectStandardError  = true,
                            RedirectStandardOutput = true
                        };

                        console.LogDebug($"{processStartInfo.FileName} {processStartInfo.Arguments}");

                        using (var process = Process.Start(processStartInfo))
                        {
                            var errors   = new StringBuilder();
                            var output   = new StringBuilder();
                            var excluded = new string[] { "msb4011", entryPointTargetPath };

                            // Read console output
                            var errorTask  = ConsumeStreamReaderAsync(process.StandardError, errors, filter: null);
                            var outputTask = ConsumeStreamReaderAsync(process.StandardOutput, output, filter: (line) => IsIgnoredOutput(line, excluded));

                            // Run msbuild
                            var finished = process.WaitForExit(timeOut);

                            // Handle timeouts
                            if (!finished)
                            {
                                try
                                {
                                    process.Kill();
                                }
                                catch (Exception ex)
                                {
                                    throw new CommandException(
                                              LocalizedResourceManager.GetString(nameof(NuGetResources.Error_CannotKillMsBuild)) + " : " +
                                              ex.Message,
                                              ex);
                                }
                            }

                            // Read all console output from msbuild.
                            await Task.WhenAll(outputTask, errorTask);

                            // By default log msbuild output so that it is only
                            // displayed under -Verbosity detailed
                            var logLevel = LogLevel.Verbose;

                            if (process.ExitCode != 0 || !finished)
                            {
                                // If a problem occurred log all msbuild output as an error
                                // so that the user can see it.
                                // By default this runs with /v:q which means that only
                                // errors and warnings will be in the output.
                                logLevel = LogLevel.Error;
                            }

                            // MSBuild writes errors to the output stream, parsing the console output to find
                            // the errors would be error prone so here we log all output combined with any
                            // errors on the error stream (haven't seen the error stream used to date)
                            // to give the user the complete info.
                            await console.LogAsync(logLevel, output.ToString() + errors.ToString());

                            if (!finished)
                            {
                                // MSBuild timed out
                                throw new CommandException(
                                          LocalizedResourceManager.GetString(nameof(NuGetResources.Error_MsBuildTimedOut)));
                            }

                            await outputTask;

                            if (process.ExitCode != 0)
                            {
                                // Do not continue if msbuild failed.
                                throw new ExitCodeException(1);
                            }
                        }

                        DependencyGraphSpec spec = null;

                        if (File.Exists(resultsPath) && new FileInfo(resultsPath).Length != 0)
                        {
                            spec = DependencyGraphSpec.Load(resultsPath);
                            File.Delete(resultsPath);
                        }
                        else
                        {
                            spec = new DependencyGraphSpec();
                        }

                        return(spec);
                    }
        }
Example #4
0
        private ProjectRestoreMetadata CreateProjectRestoreMetadata()
        {
            var projectReference = new ProjectRestoreReference
            {
                ProjectPath       = "Path",
                ProjectUniqueName = "ProjectUniqueName",
                IncludeAssets     = LibraryIncludeFlags.All,
                ExcludeAssets     = LibraryIncludeFlags.Analyzers,
                PrivateAssets     = LibraryIncludeFlags.Build
            };

            var nugetFramework = NuGetFramework.Parse("net461");
            var originalPRMFI  = new ProjectRestoreMetadataFrameworkInfo(nugetFramework)
            {
                ProjectReferences = new List <ProjectRestoreReference>()
                {
                    projectReference
                }
            };

            var targetframeworks = new List <ProjectRestoreMetadataFrameworkInfo>()
            {
                originalPRMFI
            };
            var allWarningsAsErrors = true;
            var noWarn = new HashSet <NuGetLogCode>()
            {
                NuGetLogCode.NU1000, NuGetLogCode.NU1500
            };
            var warningsAsErrors = new HashSet <NuGetLogCode>()
            {
                NuGetLogCode.NU1001, NuGetLogCode.NU1501
            };
            var warningProperties              = new WarningProperties(allWarningsAsErrors: allWarningsAsErrors, warningsAsErrors: warningsAsErrors, noWarn: noWarn);
            var restoreLockProperties          = new RestoreLockProperties(restorePackagesWithLockFile: "true", nuGetLockFilePath: null, restoreLockedMode: false);
            var originalProjectRestoreMetadata = new ProjectRestoreMetadata
            {
                ProjectStyle            = ProjectStyle.PackageReference,
                ProjectPath             = "ProjectPath",
                ProjectJsonPath         = "ProjectJsonPath",
                OutputPath              = "OutputPath",
                ProjectName             = "ProjectName",
                ProjectUniqueName       = "ProjectUniqueName",
                PackagesPath            = "PackagesPath",
                CacheFilePath           = "CacheFilePath",
                CrossTargeting          = true,
                LegacyPackagesDirectory = true,
                ValidateRuntimeAssets   = true,
                SkipContentFileWrite    = true,
                TargetFrameworks        = targetframeworks,
                Sources = new List <PackageSource>()
                {
                    new PackageSource("http://api.nuget.org/v3/index.json")
                },
                FallbackFolders = new List <string>()
                {
                    "fallback1"
                },
                ConfigFilePaths = new List <string>()
                {
                    "config1"
                },
                OriginalTargetFrameworks = new List <string>()
                {
                    "net45"
                },
                Files = new List <ProjectRestoreMetadataFile>()
                {
                    new ProjectRestoreMetadataFile("packagePath", "absolutePath")
                },
                ProjectWideWarningProperties = warningProperties,
                RestoreLockProperties        = restoreLockProperties
            };

            return(originalProjectRestoreMetadata);
        }