protected void ParseAndVerifyProject(
            string projFileName,
            IProjectPredictor predictor,
            IReadOnlyCollection <PredictedItem> expectedInputFiles,
            IReadOnlyCollection <PredictedItem> expectedInputDirectories,
            IReadOnlyCollection <PredictedItem> expectedOutputFiles,
            IReadOnlyCollection <PredictedItem> expectedOutputDirectories)
        {
            var globalProperties = new Dictionary <string, string>
            {
                { "Platform", "amd64" },
                { "Configuration", "debug" },
            };
            var projectCollection = new ProjectCollection();

            var projectOptions = new ProjectOptions
            {
                ProjectCollection = projectCollection,
                GlobalProperties  = globalProperties,
            };

            // TestsData files are marked to CopyToOutput and are available next to the executing assembly
            var projectInstance = ProjectInstance.FromFile(Path.Combine(TestsDirectoryPath, projFileName), projectOptions);

            predictor
            .GetProjectPredictions(projectInstance)
            .AssertPredictions(
                projectInstance,
                expectedInputFiles,
                expectedInputDirectories,
                expectedOutputFiles,
                expectedOutputDirectories);
        }
示例#2
0
        public static IEnumerable <object[]> ProjectInstanceHasEvaluationIdTestData()
        {
            // from file (new)
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) => new ProjectInstance(f, null, null, c)
            });

            // from file (factory method)
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) => ProjectInstance.FromFile(f, new ProjectOptions {
                    ProjectCollection = c
                })
            });

            // from Project
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) => new Project(f, null, null, c).CreateProjectInstance()
            });

            // from DeepCopy
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) => new ProjectInstance(f, null, null, c).DeepCopy()
            });

            // from ProjectRootElement (new)
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) => new ProjectInstance(xml, null, null, c)
            });

            // from ProjectRootElement (factory method)
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) => ProjectInstance.FromProjectRootElement(xml, new ProjectOptions {
                    ProjectCollection = c
                })
            });

            // from translated project instance
            yield return(new ProjectInstanceFactory[]
            {
                (f, xml, c) =>
                {
                    var pi = new ProjectInstance(f, null, null, c);
                    pi.AddItem("foo", "bar");
                    pi.TranslateEntireState = true;

                    ((ITranslatable)pi).Translate(TranslationHelpers.GetWriteTranslator());
                    var copy = ProjectInstance.FactoryForDeserialization(TranslationHelpers.GetReadTranslator());

                    return copy;
                }
            });
        }
示例#3
0
        private static void EvaluateProject(OutputContext output, FileInfo projectFile, Project project)
        {
            var sw = Stopwatch.StartNew();

            ProjectInstance projectInstance;

            try
            {
                output.WriteDebugLine($"Loading project '{projectFile.FullName}'.");
                projectInstance = ProjectInstance.FromFile(projectFile.FullName, new ProjectOptions());
                output.WriteDebugLine($"Loaded project '{projectFile.FullName}'.");
            }
            catch
            {
                throw new CommandException($"Failed to load project: '{projectFile.FullName}'.");
            }

            // Currently we only log at debug level.
            var logger = new ConsoleLogger(
                verbosity: LoggerVerbosity.Normal,
                write: message => output.WriteDebug(message),
                colorSet: null,
                colorReset: null);

            try
            {
                AssemblyLoadContext.Default.Resolving += ResolveAssembly;
                var result = projectInstance.Build(
                    targets: new[] { "Restore", "ResolveReferences", "ResolvePackageDependenciesDesignTime", "PrepareResources", "GetAssemblyAttributes", },
                    loggers: new[] { logger, });

                // If the build fails, we're not really blocked from doing our work.
                // For now we just log the output to debug. There are errors that occur during
                // running these targets we don't really care as long as we get the data.
            }
            finally
            {
                AssemblyLoadContext.Default.Resolving -= ResolveAssembly;
            }

            // Reading both InformationalVersion and Version is more resilant in the face of build failures.
            var version = projectInstance.GetProperty("InformationalVersion")?.EvaluatedValue ?? projectInstance.GetProperty("Version").EvaluatedValue;

            project.Version = version;
            output.WriteDebugLine($"Found application version: {version}");

            var targetFramework = projectInstance.GetPropertyValue("TargetFramework");

            project.TargetFramework = targetFramework;
            output.WriteDebugLine($"Found target framework: {targetFramework}");

            var sharedFrameworks = projectInstance.GetItems("FrameworkReference").Select(i => i.EvaluatedInclude).ToList();

            project.Frameworks.AddRange(sharedFrameworks.Select(s => new Framework(s)));
            output.WriteDebugLine($"Found shared frameworks: {string.Join(", ", sharedFrameworks)}");

            output.WriteDebugLine($"Evaluation Took: {sw.Elapsed.TotalMilliseconds}ms");

            // The Microsoft.Build.Locator doesn't handle the loading of other assemblies
            // that are shipped with MSBuild (ex NuGet).
            //
            // This means that the set of assemblies that need special handling depends on the targets
            // that we run :(
            //
            // This is workaround for this limitation based on the targets we need to run
            // to resolve references and versions.
            //
            // See: https://github.com/microsoft/MSBuildLocator/issues/86
            Assembly?ResolveAssembly(AssemblyLoadContext context, AssemblyName assemblyName)
            {
                if (assemblyName.Name is object && assemblyName.Name.StartsWith("NuGet."))
                {
                    var msbuildDirectory = Environment.GetEnvironmentVariable("MSBuildExtensionsPath") !;
                    var assemblyFilePath = Path.Combine(msbuildDirectory, assemblyName.Name + ".dll");
                    if (File.Exists(assemblyFilePath))
                    {
                        return(context.LoadFromAssemblyPath(assemblyFilePath));
                    }
                }

                return(default);