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); }
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; } }); }
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);