public void Should_contain_three_projects() { var parser = new SolutionParser(); var projects = parser.Parse(solutionFile_); Assert.IsNotNull(projects); Assert.That(projects.Count, Is.EqualTo(3)); }
public void TestConfigurationPlatformDefaults1() { string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 9.00 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Win32 = Debug|Win32 Release|Any CPU = Release|Any CPU Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 EndGlobalSection EndGlobal "; SolutionParser solution = SolutionParser_Tests.ParseSolutionHelper(solutionFileContents); Project msbuildProject = new Project(); SolutionWrapperProject.Generate(solution, msbuildProject, null, null); // Default for Configuration is "Debug", if present Assertion.AssertEquals("Debug", msbuildProject.GetEvaluatedProperty("Configuration")); // Default for Platform is "Mixed Platforms", if present Assertion.AssertEquals("Mixed Platforms", msbuildProject.GetEvaluatedProperty("Platform")); }
public void TestDisambiguateProjectTargetName() { string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'Build', 'Build\Build.csproj', '{21397922-C38F-4A0E-B950-77B3FBD51881}' EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {21397922-C38F-4A0E-B950-77B3FBD51881}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {21397922-C38F-4A0E-B950-77B3FBD51881}.Debug|Any CPU.Build.0 = Debug|Any CPU {21397922-C38F-4A0E-B950-77B3FBD51881}.Release|Any CPU.ActiveCfg = Release|Any CPU {21397922-C38F-4A0E-B950-77B3FBD51881}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal "; SolutionParser solution = SolutionParser_Tests.ParseSolutionHelper(solutionFileContents); Project msbuildProject = new Project(); SolutionWrapperProject.Generate(solution, msbuildProject, null, null); Assertion.AssertNotNull(msbuildProject.Targets["Build"]); Assertion.AssertNotNull(msbuildProject.Targets["Solution:Build"]); Assertion.AssertNotNull(msbuildProject.Targets["Solution:Build:Clean"]); Assertion.AssertNotNull(msbuildProject.Targets["Solution:Build:Rebuild"]); Assertion.AssertNotNull(msbuildProject.Targets["Solution:Build:Publish"]); Assertion.AssertEquals(null, msbuildProject.Targets["Build"].TargetElement.ChildNodes[0].Attributes["Targets"]); Assertion.AssertEquals("Clean", msbuildProject.Targets["Clean"].TargetElement.ChildNodes[0].Attributes["Targets"].Value); Assertion.AssertEquals("Rebuild", msbuildProject.Targets["Rebuild"].TargetElement.ChildNodes[0].Attributes["Targets"].Value); Assertion.AssertEquals("Publish", msbuildProject.Targets["Publish"].TargetElement.ChildNodes[0].Attributes["Targets"].Value); Assertion.AssertEquals("@(BuildLevel0)", msbuildProject.Targets["Build"].TargetElement.ChildNodes[0].Attributes["Projects"].Value); Assertion.AssertEquals("@(BuildLevel0)", msbuildProject.Targets["Clean"].TargetElement.ChildNodes[0].Attributes["Projects"].Value); Assertion.AssertEquals("@(BuildLevel0)", msbuildProject.Targets["Rebuild"].TargetElement.ChildNodes[0].Attributes["Projects"].Value); Assertion.AssertEquals("@(BuildLevel0)", msbuildProject.Targets["Publish"].TargetElement.ChildNodes[0].Attributes["Projects"].Value); // Here we check that the set of standard entry point targets in the solution project // matches those defined in ProjectInSolution.projectNamesToDisambiguate = { "Build", "Rebuild", "Clean", "Publish" }; int countOfStandardTargets = 0; foreach (Target t in msbuildProject.Targets) { if (!t.Name.Contains(":")) { countOfStandardTargets += 1; } } // NOTE: ValidateSolutionConfiguration and ValidateToolsVersions are always added, so we need to add two extras Assertion.AssertEquals(ProjectInSolution.projectNamesToDisambiguate.Length + 2, countOfStandardTargets); }
public void TestAddPropertyGroupForSolutionConfiguration() { string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}' EndProject Project('{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}') = 'MainApp', 'MainApp\MainApp.vcxproj', '{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}' EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU {A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.ActiveCfg = VCConfig1|Win32 {A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.Build.0 = VCConfig1|Win32 EndGlobalSection EndGlobal "; SolutionParser solution = SolutionParser_Tests.ParseSolutionHelper(solutionFileContents); Engine engine = new Engine(); Project msbuildProject = new Project(engine); foreach (ConfigurationInSolution solutionConfiguration in solution.SolutionConfigurations) { SolutionWrapperProject.AddPropertyGroupForSolutionConfiguration(msbuildProject, solution, solutionConfiguration); } // Both projects configurations should be present for solution configuration "Debug|Mixed Platforms" msbuildProject.GlobalProperties.SetProperty("Configuration", "Debug"); msbuildProject.GlobalProperties.SetProperty("Platform", "Mixed Platforms"); string solutionConfigurationContents = msbuildProject.GetEvaluatedProperty("CurrentSolutionConfigurationContents"); Assertion.Assert(solutionConfigurationContents.Contains("{6185CC21-BE89-448A-B3C0-D1C27112E595}")); Assertion.Assert(solutionConfigurationContents.Contains("CSConfig1|AnyCPU")); Assertion.Assert(solutionConfigurationContents.Contains("{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}")); Assertion.Assert(solutionConfigurationContents.Contains("VCConfig1|Win32")); // Only the C# project should be present for solution configuration "Release|Any CPU", since the VC project // is missing msbuildProject.GlobalProperties.SetProperty("Configuration", "Release"); msbuildProject.GlobalProperties.SetProperty("Platform", "Any CPU"); solutionConfigurationContents = msbuildProject.GetEvaluatedProperty("CurrentSolutionConfigurationContents"); Assertion.Assert(solutionConfigurationContents.Contains("{6185CC21-BE89-448A-B3C0-D1C27112E595}")); Assertion.Assert(solutionConfigurationContents.Contains("CSConfig2|AnyCPU")); Assertion.Assert(!solutionConfigurationContents.Contains("{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}")); }
public void TestVs2008Sln() { byte[] bytes = Properties.Resources.Lextm_CBC2_Full; string tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(ToolElement.Tool35Version, parser.Version); }
public void InstanceTest() { SolutionParser instance = SolutionParser.Instance; Assert.AreSame(instance, SolutionParser.Instance); Assert.IsNotNull(instance.Extensions); }
public void TestVs2005Sln() { byte[] bytes = Properties.Resources.MSBuildShellExtension; string tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(ToolElement.Tool20Version, parser.Version); }
public void TestVs12Sln() { var bytes = Properties.Resources.Obfuscar; var tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(ToolElement.Tool120Version, parser.Version); }
public void TestVs2010Sln() { byte[] bytes = Properties.Resources.SharpSnmpLib1; string tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(ToolElement.Tool40Version, parser.Version); }
public static void Execute(ICakeContext context, FilePath solutionFile, FilePath settingsFile) { if (solutionFile == null) { throw new ArgumentNullException(nameof(solutionFile), "Solution file path is null."); } var solutionParser = new SolutionParser(context.FileSystem, context.Environment); var projectParser = new ProjectParser(context.FileSystem, context.Environment); var stylecopSettingsFile = settingsFile == null ? null : settingsFile.ToString(); var projectPath = Cake.Common.IO.DirectoryAliases.Directory(context, solutionFile.MakeAbsolute(context.Environment).GetDirectory().FullPath); Cake.Common.Diagnostics.LoggingAliases.Information(context, string.Format("Project Path: {0}", projectPath.Path.FullPath)); var styleCopConsole = new StyleCop.StyleCopConsole( stylecopSettingsFile, false, /* Input Cache Result */ null, /* Output file */ null, true); var styleCopProjects = new List <CodeProject>(); var solution = solutionParser.Parse(solutionFile); foreach (var solutionProject in solution.Projects) { var project = projectParser.Parse(solutionProject.Path); var styleCopProject = new CodeProject(0, solutionProject.Path.GetDirectory().ToString(), new Configuration(null)); styleCopProjects.Add(styleCopProject); foreach (var projectFile in project.Files) { if (projectFile.FilePath.GetExtension() == ".cs") { styleCopConsole.Core.Environment.AddSourceCode( styleCopProject, projectFile.FilePath.ToString(), null); } } } var handler = new StylecopHandlers(context); styleCopConsole.OutputGenerated += handler.OnOutputGenerated; styleCopConsole.ViolationEncountered += handler.ViolationEncountered; styleCopConsole.Start(styleCopProjects.ToArray(), true); styleCopConsole.OutputGenerated -= handler.OnOutputGenerated; styleCopConsole.ViolationEncountered -= handler.ViolationEncountered; if (handler.TotalViolations > 0) { throw new Exception(string.Format("{0} StyleCop violations encountered.", handler.TotalViolations)); } }
private static void Convert(Options options) { StreamReader reader = null; try { var serializer = new XmlSerializer(typeof(Report)); Console.WriteLine("Reading input file {0}", options.Input); var solutionDirectoryDepth = GetSolutionDirectoryDepth(options.Input); reader = new StreamReader(options.Input); var report = (Report)serializer.Deserialize(reader); reader.Dispose(); var sonarQubeReports = Map(report, solutionDirectoryDepth); // We need to write dummy report because SonarQube MSBuild reads a report from the root if (string.IsNullOrEmpty(options.Project)) { try { var solution = SolutionParser.Parse(report.Information.Solution); WriteReport(CombineOutputPath(options, options.Output), SonarQubeReport.Empty); foreach (var sonarQubeReport in sonarQubeReports) { var filePath = CombineOutputPath(options, Path.Combine(GetFolderProject(solution, sonarQubeReport, solutionDirectoryDepth), options.Output)); WriteReport(filePath, sonarQubeReport); } TryWriteMissingReports(solution, options, sonarQubeReports, solutionDirectoryDepth); } catch (Exception e) { Console.WriteLine(e); } } else { var projectToWrite = sonarQubeReports.FirstOrDefault(r => string.Equals(r.ProjectName, options.Project, StringComparison.OrdinalIgnoreCase)); if (projectToWrite == null) { Console.WriteLine("Project " + options.Project + " not found or it contains no issues."); } WriteReport(CombineOutputPath(options, options.Output), projectToWrite ?? SonarQubeReport.Empty); } } catch (Exception e) { Console.Error.WriteLine(e); } finally { reader?.Dispose(); } }
public void SolutionParserShouldNotIncreaseNumberOfProjectsLoadedByHost() { string oldValueForMSBuildEmitSolution = Environment.GetEnvironmentVariable("MSBuildEmitSolution"); Environment.SetEnvironmentVariable("MSBuildEmitSolution", "1"); string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project('{F184B08F-C81C-45F6-A57F-5ABD9991F28F}') = 'ConsoleApplication1', 'ConsoleApplication1\ConsoleApplication1.vbproj', '{AB3413A6-D689-486D-B7F0-A095371B3F13}' EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|AnyCPU = Debug|AnyCPU Release|AnyCPU = Release|AnyCPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {AB3413A6-D689-486D-B7F0-A095371B3F13}.Debug|AnyCPU.ActiveCfg = Debug|AnyCPU {AB3413A6-D689-486D-B7F0-A095371B3F13}.Debug|AnyCPU.Build.0 = Debug|AnyCPU {AB3413A6-D689-486D-B7F0-A095371B3F13}.Release|AnyCPU.ActiveCfg = Release|AnyCPU {AB3413A6-D689-486D-B7F0-A095371B3F13}.Release|AnyCPU.Build.0 = Release|AnyCPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal "; SolutionParser solution = SolutionParser_Tests.ParseSolutionHelper(solutionFileContents); Engine engine = new Engine(); Project project = new Project(engine, null); // This project considers itself loaded-by-host. Setting a file name on it, causes it to // ensure the engine believes it is loaded-by-host... project.FullFileName = "my project"; Assertion.AssertEquals(1, engine.ProjectsLoadedByHost.Count); // Create a bogus cache file in the same place -- just to exercise the solution wrapper code that creates a new project string solutionCacheFile = solution.SolutionFile + ".cache"; using (StreamWriter writer = new StreamWriter(solutionCacheFile)) { writer.WriteLine("xxx"); } SolutionWrapperProject.Generate(solution, project, null, null); Assertion.AssertEquals(1, engine.ProjectsLoadedByHost.Count); // Clean up. Delete temp files and reset environment variables. Assertion.Assert("Solution parser should have written in-memory project to disk", File.Exists(solution.SolutionFile + ".proj")); File.Delete(solution.SolutionFile + ".proj"); File.Delete(solutionCacheFile); Environment.SetEnvironmentVariable("MSBuildEmitSolution", oldValueForMSBuildEmitSolution); }
private List <ProjectInfo> TryGetProjectsInfo(string filePath) { var solutionInfos = new List <ProjectInfo>(); try { var solution = SolutionParser.Parse(filePath); var solutionDirectory = Path.GetDirectoryName(filePath); if (solutionDirectory == null) { _logger.Message($"Solution directory wasn't found for file {filePath}"); return(solutionInfos); } foreach (var project in solution.Projects) { if (project.TypeGuid == ProjectTypeGuids.SolutionFolder) { continue; } var projectFilePath = Path.Combine(solutionDirectory, project.Path); var projectDirectory = Path.GetDirectoryName(projectFilePath); if (projectDirectory == null) { _logger.Message($"Project directory wasn't found for project {project.Name}"); return(solutionInfos); } var packageConfigPath = Path.Combine(projectDirectory, "packages.config"); if (File.Exists(packageConfigPath)) { var packages = _projectParser.ParsePackageConfig(packageConfigPath); solutionInfos.Add(new ProjectInfo(project.Name, packages)); } else if (File.Exists(projectFilePath)) { var packages = _projectParser.ParseProjectFile(projectFilePath); solutionInfos.Add(new ProjectInfo(project.Name, packages)); } else { _logger.Message($"Unable to find project or package.config file for project {project.Path}"); } } return(solutionInfos); } catch (Exception e) { _logger.Message($"Unable to get project info for {filePath}\r\n {e}"); } return(solutionInfos); }
public void Should_parse_valid_solution_file() { var solutionInfo = SolutionParser.LoadFromFile(new DefaultSolutionCopConsole(), new FileInfo(@"..\..\Data\ValidSolutionVS2013.sln").FullName); Assert.True(solutionInfo.IsParsed); Assert.NotEmpty(solutionInfo.ProjectFilePaths); Approvals.VerifyAll(solutionInfo.ProjectFilePaths.Select(x => Path.GetFileName(x)), "PathsToProjects"); Assert.Equal(5, solutionInfo.ProjectFilePaths.Count()); }
public void ExtractProjectPaths_PathInvalid_ThrowsException() { var path = "this does not work"; var solutionParser = new SolutionParser(); var projects = solutionParser.ExtractSolutionProjects(path, ".csproj"); Assert.Throws <FileNotFoundException>(() => projects.ToList()); }
public void ExtractProjectPaths_NoLineStartsWithProject_ReturnsEmptyEnumerable() { var path = @"../../../TestSolutionFiles/README.txt"; var solutionParser = new SolutionParser(); var projects = solutionParser.ExtractSolutionProjects(path, ".csproj"); Assert.Empty(projects); }
private static void ExecuteSlnParser() { SolutionParser parser1 = new SolutionParser(@"G:\Coding\Dotnet\ConsoleApp1\ConsoleApp1.sln"); parser1.ParseSolution(); var sln = parser1.Solution; CommonUtil.SlnToCSV(sln); }
public void Should_contain_one_wpf_project() { var parser = new SolutionParser(); var projects = parser.Parse(solutionFile_); Assert.IsNotNull(projects); var wpfProject = projects.Single(p => p.Name == "WpfApplication1"); Assert.That(wpfProject.TargetFrameworkVersion, Is.EqualTo(TargetFrameworkVersion.NetFramework45)); }
public void Retrieves_project_classes() { var solution = SolutionParser.ParseSolution(_testSolutionFilePath); var project = solution.Projects.ElementAt(0); Assert.AreEqual(3, project.Classes.Count()); Assert.AreEqual("Class1", project.Classes.ElementAt(0).Name); }
/// <summary> /// This function is the callback used to execute a command when the a menu item is clicked. /// See the Initialize method to see how the menu item is associated to this function using /// the OleMenuCommandService service and the MenuCommand class. /// </summary> private void MenuItemCallback(object sender, EventArgs e) { string yUMLUrl; SolutionParser parser = new SolutionParser(); ProjectItem codeProjectItem = parser.GetSelectedFirstCodeProjectItem(); if (codeProjectItem == null) { return; } List <CodeElement> codeElementList = parser.GetCodeElementList(codeProjectItem); if (codeElementList.Count > 0) { yUMLUrl = new YUMLURLBuilder(codeElementList).Build(); if (!string.IsNullOrEmpty(yUMLUrl)) { Navigate(yUMLUrl); } } //string assemblyPath = GetSelectedProjectAssemblyPath(); //Assembly assembly = Assembly.LoadFile(assemblyPath); //List<Type> typeList = new List<Type>(); //foreach (CodeClass codeClass in codeClassList) //{ // typeList.Add(assembly.GetType(codeClass.FullName)); //} //yUMLUrl = new YumlGenerator(typeList).Yuml(); //Debug.Write(yUMLUrl); //OpenYuml(yUMLUrl); /* * * // Show a Message Box to prove we were here * IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); * Guid clsid = Guid.Empty; * int result; * Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox( * 0, * ref clsid, * "Aljeida.VisualStudio.YUMLPackage", * string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.ToString()), * string.Empty, * 0, * OLEMSGBUTTON.OLEMSGBUTTON_OK, * OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, * OLEMSGICON.OLEMSGICON_INFO, * 0, // false * out result)); */ }
public void Retrieves_solution_projects() { var solution = SolutionParser.ParseSolution(_testSolutionFilePath); Assert.AreEqual(1, solution.Projects.Count()); var project = solution.Projects.ElementAt(0); Assert.AreEqual("TestProject1", project.Name); }
public void ExtractProjectPaths_LargeSolution_ParsesWithoutErrors() { var path = @"../../../TestSolutionFiles/LargeSolution.txt"; var solutionParser = new SolutionParser(); var projects = solutionParser.ExtractSolutionProjects(path, ".csproj").ToList(); Assert.NotEmpty(projects); Assert.Equal(142, projects.Count); }
public void TestVs2005Sln() { byte[] bytes = Properties.Resources.MSBuildShellExtension; string tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(Tool.Tool20Version, parser.Version); }
//public static IEnumerable<FileInfo> GetSQLScripts(this FileInfo source) //{ //[TestMethod] //public void parsedatabaseProject() //{ // string folderName = ""; // var scriptsList = new List<KeyValuePair<string, FileInfo>>(); // foreach (var line in System.IO.File.ReadAllLines(@"C:\DeploymentsTemp\ProjectFiles\db.dbp")) // { // if (line.Trim().StartsWith("Begin Folder")) // folderName = GetQuoted(line.Trim()); // if (line.Trim().StartsWith("Script")) // scriptsList.Add(new KeyValuePair<string,FileInfo>(folderName, new FileInfo(GetQuoted(line.Trim())))); // } // foreach (var item in scriptsList) // { // Console.WriteLine(item.Key + "\t" + item.Value); // } //} //} public static IEnumerable <FileInfo> GetSSISPackages(this FileInfo source) { var ssisFiles = new List <FileInfo>(); foreach (var item in SolutionParser.GetProjectXmlDocPaths(source.FullName, ".dtproj")) { ssisFiles.AddRange(SSISProjectFileParser.GetSSISPackages(item)); } return(ssisFiles.AsEnumerable()); }
public void TestVs14Sln() { var bytes = Properties.Resources.VS2015; var tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(Tool.Tool140Version, parser.Version); }
public void TestVs2008Sln() { byte[] bytes = Properties.Resources.Lextm_CBC2_Full; string tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(Tool.Tool35Version, parser.Version); }
public void TestVs2010Sln() { byte[] bytes = Properties.Resources.SharpSnmpLib1; string tempFileName = Path.GetTempFileName(); File.WriteAllBytes(tempFileName, bytes); var parser = new SolutionParser(tempFileName); Assert.AreEqual(Tool.Tool40Version, parser.Version); }
public void SetUp() { ParserHelper.RegisterParserServices(); var solutionParser = new SolutionParser(Path.GetFullPath("..\\..\\..\\CR_StyleCop.TestCode.sln")); var solution = solutionParser.GetParsedSolution(); var project = solution.AllProjects.Cast <ProjectElement>().First(); this.files = project.AllFiles.Cast <SourceFile>(); this.plugin = new CR_StyleCopPlugIn(); }
public void Retrieves_base_type() { var solution = SolutionParser.ParseSolution(_testSolutionFilePath); var project = solution.Projects.ElementAt(0); var csClass = project.Classes.ElementAt(1); Assert.AreEqual("Class1Child1", csClass.Name); Assert.AreEqual("Class1", csClass.ParentName); }
public void Retrieves_type_methods() { CsSolution solution = SolutionParser.ParseSolution(_testSolutionFilePath); var project = solution.Projects.ElementAt(0); var csClass = project.GetClass(nameof(Class2)); var csMethods = csClass.Methods; Assert.AreEqual(1, csMethods.Count(), "Unexpected number of methods."); Assert.AreEqual(nameof(Class2.MethodInternalExternalVars), csMethods.First().Name, "Unexpected method name."); }
public Solution(string solutionFileName) { var parser = new SolutionParser(); using (var streamReader = new StreamReader(solutionFileName)) { parser.SolutionReader = streamReader; parser.ParseSolution(); } Projects = parser.Projects.ToList(); }
public void Should_Throw_If_SolutionPath_Is_Null() { // Given var fixture = new SolutionParserFixture(); var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); // When var result = Record.Exception(() => solutionParser.Parse(null)); // Then AssertEx.IsArgumentNullException(result, "solutionPath"); }
/// <summary> /// Given the full path to a solution, returns a string containing the v3.5 MSBuild-format /// wrapper project for that solution. /// </summary> /// <param name="solutionPath">Full path to the solution we are wrapping</param> /// <param name="toolsVersionOverride">May be null. If non-null, contains the ToolsVersion passed in on the command line</param>\ /// <param name="projectBuildEventContext">An event context for logging purposes.</param> /// <returns></returns> static public string Generate(string solutionPath, string toolsVersionOverride, BuildEventContext projectBuildEventContext) { Project msbuildProject = new Project(); SolutionParser solution = new SolutionParser(); solution.SolutionFile = solutionPath; solution.ParseSolutionFile(); Generate(solution, msbuildProject, toolsVersionOverride, projectBuildEventContext); return msbuildProject.Xml; }
public void CheckProjectReferencesInSolution_TwoProjectsInSolutionOneReferencesOther_AllGood() { var solutionParser = new SolutionParser(); var referencesExtractorMock = new CsprojReferencesExtractor(); var checker = new ReferencesExistenceChecker(solutionParser, referencesExtractorMock); var messages = checker.CheckProjectReferencesExistenceInSolution(@"../../../TestSolutionFiles/SmallValidTestSolution.txt", ".xml"); Assert.Empty(messages); }
private void LoadSolution(string localPath, string serverPath) { var parser = new SolutionParser(); SolutionModel model = parser.ParseSolution(localPath); if (!string.IsNullOrEmpty(serverPath)) { model.ServerPath = serverPath; } _solution = model; OnSolutionLoaded(); }
public void ToolsVersionOverrideShouldBeSpecifiedOnMSBuildTaskInvocations() { string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project('{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}') = 'ClassLibrary1', 'ClassLibrary1\ClassLibrary1.csproj', '{6185CC21-BE89-448A-B3C0-D1C27112E595}' EndProject Project('{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}') = 'MainApp', 'MainApp\MainApp.vcxproj', '{A6F99D27-47B9-4EA4-BFC9-25157CBDC281}' EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU {A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.ActiveCfg = VCConfig1|Win32 {A6F99D27-47B9-4EA4-BFC9-25157CBDC281}.Debug|Mixed Platforms.Build.0 = VCConfig1|Win32 EndGlobalSection EndGlobal "; // We're not passing in a /tv:xx switch, so the solution project will have tools version 3.5 Project project = new Project(); SolutionParser solution = SolutionParser_Tests.ParseSolutionHelper(solutionFileContents); BuildEventContext buildEventContext = new BuildEventContext(0, 0, 0, 0); SolutionWrapperProject.Generate(solution, project, "3.5", buildEventContext); foreach (Target target in project.Targets) { foreach (XmlNode childNode in target.TargetElement) { if (0 == String.Compare(childNode.Name, "MSBuild", StringComparison.OrdinalIgnoreCase)) { // we found an MSBuild task invocation, now let's verify that it has the correct // ToolsVersion parameter set XmlAttribute toolsVersionAttribute = childNode.Attributes["ToolsVersion"]; Assertion.Assert(0 == String.Compare( toolsVersionAttribute.Value, "$(ProjectToolsVersion)", StringComparison.OrdinalIgnoreCase) ); } } } }
public CSolution Convert(string slnPath) { var solution = new CSolution(); solution.SolutionName = Path.GetFileName(slnPath); var rawSolution = SolutionParser.Parse(slnPath); solution.SolutionPath = slnPath; foreach (var rawProject in rawSolution.Projects) { //skip "folders" if (rawProject.TypeGuid == Guid.Parse("{2150e333-8fdc-42a3-9474-1a3956d46de8}")) { continue; } var fullPath = Path.Combine(Path.GetDirectoryName(slnPath), rawProject.Path); if (!File.Exists(fullPath)) { continue; } var projectText = File.ReadAllText(fullPath); if (IgnoreTestProjects && projectText.Contains("{3AC096D0-A1C2-E12C-1390-A8335801FDAB}")) { //test project continue; } if (IgnoreTestProjects && rawProject.Name.Contains("Test")) { //test project continue; } var project = new CProject { }; project.ProjectGuid = rawProject.Guid; project.ProjectShortName = rawProject.Name; project.ProjectName = rawProject.Name; project.Path = Path.Combine(Path.GetDirectoryName(slnPath), rawProject.Path); project.HasDockerFile = HasDockerFile(project.Path); var projectExtension = Path.GetExtension(project.Path).ToLower(); if (projectExtension == ".sqlproj") { project.ProjectType = CProjectType.SqlProj; project.ProjectIs = CProjectIs.DataBase; } solution.Project.Add(project); } return(solution); }
private static void ConvertToXml(Options options) { string path = options.InputFile; VerifyPath(path, "sln"); var tokenizer = new SlnTokenizer(File.ReadAllText(path)); tokenizer.Initialise(); tokenizer.SetSkip(true, TokenType.WhiteSpace); SolutionParser solutionParser = new SolutionParser(tokenizer); var document = solutionParser.Execute(); var converter = new SlnToXmlConverter(); string outputName = !String.IsNullOrEmpty(options.OutputFile) ? options.OutputFile : ConvertInput(path); converter.WriteDocument(document, outputName); }
public void ParseFirstProjectLineWithDifferentSpacing() { SolutionParser p = new SolutionParser(); p.SolutionFile = "foobar.sln"; ProjectInSolution proj = new ProjectInSolution(p); p.ParseFirstProjectLine ( "Project(\" {Project GUID} \") = \" Project name \", \" Relative path to project file \" , \" Unique name-GUID \"", proj ); Assertion.AssertEquals(SolutionProjectType.Unknown, proj.ProjectType); Assertion.AssertEquals("Project name", proj.ProjectName); Assertion.AssertEquals("Relative path to project file", proj.RelativePath); Assertion.AssertEquals("Unique name-GUID", proj.ProjectGuid); }
/// <summary> /// This method generates an XmlDocument representing an MSBuild project file from the list of /// projects and project dependencies that have been collected from the solution file. /// </summary> /// <param name="solution"></param> /// <param name="msbuildProject"></param> /// <param name="toolsVersionOverride">Tools Version override (may be null). /// Any /tv:xxx switch would cause a value here.</param> /// <returns></returns> /// <owner>RGoel</owner> static internal void Generate(SolutionParser solution, Project msbuildProject, string toolsVersionOverride, BuildEventContext projectBuildEventContext) { // Validate against our minimum for upgradable projects ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile((solution.Version >= SolutionParser.slnFileMinVersion), "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseUpgradeNeeded"); // Although we only return an XmlDocument back, we need to make decisions about tools versions because // we have to choose what <UsingTask> tags to put in, whether to put a ToolsVersion parameter // on <MSBuild> task tags, and what MSBuildToolsPath to use when scanning child projects // for dependency information. string wrapperProjectToolsVersion = DetermineWrapperProjectToolsVersion(toolsVersionOverride); msbuildProject.DefaultTargets = "Build"; msbuildProject.DefaultToolsVersion = wrapperProjectToolsVersion; Engine parentEngine = msbuildProject.ParentEngine; string solutionProjectCache = solution.SolutionFile + ".cache"; bool? upToDate = LoadCache(solution, msbuildProject, projectBuildEventContext, wrapperProjectToolsVersion, parentEngine, solutionProjectCache); if (upToDate == true) { // Cache exists, was loaded, and was up to date: we're done return; } // Cache didn't exist or wasn't up to date; generate a new one Project solutionProject = msbuildProject; if (upToDate == false) { // We have already loaded a cache file we can't use; we need to work in a new project object solutionProject = CreateNewProject(solution, wrapperProjectToolsVersion, parentEngine, solutionProject); } CreateSolutionProject(solution, solutionProject, projectBuildEventContext, wrapperProjectToolsVersion, parentEngine, solutionProjectCache); if (upToDate == false) { // Put the contents of the new project object into the one we were passed msbuildProject.LoadFromXmlDocument(solutionProject.XmlDocument, projectBuildEventContext, msbuildProject.LoadSettings); } // Write a new cache file, hopefully we can use it next time UpdateCache(parentEngine, msbuildProject, solutionProjectCache, projectBuildEventContext); }
/// <summary> /// Given an empty project and a solution, create a new solution project from the solution. /// </summary> private static void CreateSolutionProject(SolutionParser solution, Project msbuildProject, BuildEventContext projectBuildEventContext, string wrapperProjectToolsVersion, Engine parentEngine, string solutionProjectCache) { // We have to figure out what tools version the children will be built with, because we will // have to load and scan them to construct the solution wrapper project, and we should use the // same tools version they'll build with. string childProjectToolsVersion = DetermineChildProjectToolsVersion(parentEngine, wrapperProjectToolsVersion); string taskAssembly; if (String.Equals(msbuildProject.ToolsVersion, "2.0", StringComparison.OrdinalIgnoreCase)) { taskAssembly = "Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; } else { taskAssembly = "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; } // Fully qualified class names are more performant msbuildProject.AddNewUsingTaskFromAssemblyName("Microsoft.Build.Tasks.CreateTemporaryVCProject", taskAssembly); msbuildProject.AddNewUsingTaskFromAssemblyName("Microsoft.Build.Tasks.ResolveVCProjectOutput", taskAssembly); AddFakeReleaseSolutionConfigurationIfNecessary(solution); Dictionary<int, List<ProjectInSolution>> projectsByDependencyLevel = new Dictionary<int, List<ProjectInSolution>>(); string fullSolutionConfigurationName = PredictActiveSolutionConfigurationName(solution, parentEngine); ScanProjectDependencies(solution, parentEngine, childProjectToolsVersion, fullSolutionConfigurationName, projectBuildEventContext); ConvertVcToVcDependenciesToReferences(solution, parentEngine, projectBuildEventContext); AssignDependencyLevels(solution, projectsByDependencyLevel); AddVirtualReferencesForStaticLibraries(solution); // Add config, platform and tools version to indicate relevance of cache AddCacheRelatedProperties(msbuildProject, fullSolutionConfigurationName, wrapperProjectToolsVersion, solution.ProjectsInOrder); // Add default solution configuration/platform names in case the user doesn't specify them on the command line AddConfigurationPlatformDefaults(msbuildProject, solution); // Add default Venus configuration names (for more details, see comments for this method) AddVenusConfigurationDefaults(msbuildProject); // Add solution related macros AddGlobalProperties(msbuildProject, solution); // Add a property group for each solution configuration, each with one XML property containing the // project configurations in this solution configuration. foreach (ConfigurationInSolution solutionConfiguration in solution.SolutionConfigurations) { AddPropertyGroupForSolutionConfiguration(msbuildProject, solution, solutionConfiguration); } // Add the initial target with some solution configuration validation/information // Only do it if we actually have any solution configurations... if (solution.SolutionConfigurations.Count > 0) { AddInitialTargets(msbuildProject); } // Add a <target> element for each project we have foreach (ProjectInSolution proj in solution.ProjectsInOrder) { string errorMessage = null; // is it a solution folder? if (proj.ProjectType == SolutionProjectType.SolutionFolder) { // Don't add any targets. Solution folder "projects" aren't actually projects at all and should be ignored. } else if (proj.ProjectType == SolutionProjectType.WebProject) { AddTargetForWebProject(msbuildProject, solution, proj, null); AddTargetForWebProject(msbuildProject, solution, proj, "Clean"); AddTargetForWebProject(msbuildProject, solution, proj, "Rebuild"); AddTargetForWebProject(msbuildProject, solution, proj, "Publish"); } else if (proj.ProjectType == SolutionProjectType.VCProject) { AddTargetForVCProject(msbuildProject, solution, proj, null); AddTargetForVCProject(msbuildProject, solution, proj, "Clean"); AddTargetForVCProject(msbuildProject, solution, proj, "Rebuild"); AddTargetForVCProject(msbuildProject, solution, proj, "Publish"); } // is it an MSBuild project? else if ((proj.ProjectType == SolutionProjectType.ManagedProject) || (proj.CanBeMSBuildProjectFile(out errorMessage))) { string safeItemNameFromProjectName = MakeIntoSafeItemName(proj.ProjectName); string targetOutputItemName = string.Format(CultureInfo.InvariantCulture, "{0}BuildOutput", safeItemNameFromProjectName); AddTargetForManagedProject(msbuildProject, solution, proj, targetOutputItemName, null); AddTargetForManagedProject(msbuildProject, solution, proj, null, "Clean"); AddTargetForManagedProject(msbuildProject, solution, proj, targetOutputItemName, "Rebuild"); AddTargetForManagedProject(msbuildProject, solution, proj, null, "Publish"); } else { AddTargetForUnknownProjectType(msbuildProject, solution, proj, null, errorMessage); AddTargetForUnknownProjectType(msbuildProject, solution, proj, "Clean", errorMessage); AddTargetForUnknownProjectType(msbuildProject, solution, proj, "Rebuild", errorMessage); AddTargetForUnknownProjectType(msbuildProject, solution, proj, "Publish", errorMessage); } } // Add a target called "Build" that depends on all the other projects. This will be the // default target that is invoked when the "project" is built. AddAllDependencyTarget(msbuildProject, "Build", "CollectedBuildOutput", null, projectsByDependencyLevel); Target cleanTarget = AddAllDependencyTarget(msbuildProject, "Clean", null, "Clean", projectsByDependencyLevel); // As far as cleaning the solution project cache (if any) goes, we can't do it easily, because by the time we know we // need to do a clean, we've already loaded the cache. Instead, at the end of a solution clean, we'll delete the cache // file if any. A solution rebuild won't delete the cache, because probably one would expect a rebuild to leave it behind. if (IsSolutionCacheEnabled()) { BuildTask deleteTask = cleanTarget.AddNewTask("Delete"); // Don't use $(MSBuildProjectFile) for safety, in case user has copied and re-purposed this cache file deleteTask.SetParameterValue("Files", Path.GetFileName(solutionProjectCache)); } AddAllDependencyTarget(msbuildProject, "Rebuild", "CollectedBuildOutput", "Rebuild", projectsByDependencyLevel); AddAllDependencyTarget(msbuildProject, "Publish", null, "Publish", projectsByDependencyLevel); // Special environment variable to allow people to see the in-memory MSBuild project generated // to represent the SLN. if (Environment.GetEnvironmentVariable("MSBuildEmitSolution") != null) { msbuildProject.Save(solution.SolutionFile + ".proj"); } }
/// <summary> /// Create a new project to construct a solution wrapper cache inside /// </summary> private static Project CreateNewProject(SolutionParser solution, string wrapperProjectToolsVersion, Engine parentEngine, Project solutionProject) { try { solutionProject = new Project(parentEngine, wrapperProjectToolsVersion); solutionProject.DefaultTargets = "Build"; solutionProject.DefaultToolsVersion = wrapperProjectToolsVersion; solutionProject.IsLoadedByHost = false; } catch (InvalidOperationException) { BuildEventFileInfo fileInfo = new BuildEventFileInfo(solution.SolutionFile); string errorCode; string helpKeyword; string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "UnrecognizedToolsVersion", wrapperProjectToolsVersion); throw new InvalidProjectFileException(solution.SolutionFile, fileInfo.Line, fileInfo.Column, fileInfo.EndLine, fileInfo.EndColumn, message, null, errorCode, helpKeyword); } return solutionProject; }
/// <summary> /// Recursive helper for AddVirtualReferencesForStaticLibraries /// </summary> private static void GatherChildReferencesForStaticLibraries(SolutionParser solution, ProjectInSolution project) { // We don't need to worry about cycles since we've already run the dependency level assignment // which already checked for them. if (!project.ChildReferencesGathered) { List<string> referenceGuidsToAdd = new List<string>(); foreach (string referenceGuid in project.ProjectReferences) { ProjectInSolution referencedProject = (ProjectInSolution)solution.ProjectsByGuid[referenceGuid]; // Gather references for all child projects recursively... GatherChildReferencesForStaticLibraries(solution, referencedProject); // ... and pass on references from any static lib children we have to ourselves if (referencedProject.IsStaticLibrary) { foreach (string childReferenceGuid in referencedProject.ProjectReferences) { if (!project.ProjectReferences.Contains(childReferenceGuid) && !referenceGuidsToAdd.Contains(childReferenceGuid)) { referenceGuidsToAdd.Add(childReferenceGuid); } } } } project.ProjectReferences.AddRange(referenceGuidsToAdd); project.ChildReferencesGathered = true; } }
/// <summary> /// Adds a new property group with contents of the given solution configuration to the project /// Internal for unit-testing. /// </summary> /// <param name="msbuildProject"></param> /// <param name="solution"></param> /// <param name="solutionConfiguration"></param> /// <owner>LukaszG</owner> static internal void AddPropertyGroupForSolutionConfiguration ( Project msbuildProject, SolutionParser solution, ConfigurationInSolution solutionConfiguration ) { BuildPropertyGroup propertyGroup = msbuildProject.AddNewPropertyGroup(true /* insertAtEndOfProject = true */); propertyGroup.Condition = GetConditionStringForConfiguration(solutionConfiguration); StringBuilder solutionConfigurationContents = new StringBuilder("<SolutionConfiguration>"); // add a project configuration entry for each project in the solution foreach (ProjectInSolution project in solution.ProjectsInOrder) { ProjectConfigurationInSolution projectConfiguration = null; if (project.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out projectConfiguration)) { solutionConfigurationContents.AppendFormat( CultureInfo.InvariantCulture, "<ProjectConfiguration Project=\"{0}\">{1}</ProjectConfiguration>", project.ProjectGuid, projectConfiguration.FullName ); } } solutionConfigurationContents.Append("</SolutionConfiguration>"); propertyGroup.AddNewProperty("CurrentSolutionConfigurationContents", solutionConfigurationContents.ToString(), true /* treat as literal */); }
/// <summary> /// Adds tasks that create a temporary VC project file with pre-resolved project references (that is, /// replaced with file references) /// </summary> /// <param name="solution"></param> /// <param name="target"></param> /// <param name="proj"></param> /// <param name="solutionConfiguration"></param> /// <param name="subTargetName"></param> /// <param name="projectConfigurationName"></param> /// <returns>The path to the temporary project file</returns> /// <owner>LukaszG</owner> static private string AddCreateTemporaryVCProjectTasks ( SolutionParser solution, Project msbuildProject, Target target, ProjectInSolution proj, ConfigurationInSolution solutionConfiguration, string subTargetName, string projectConfigurationName ) { StringBuilder referenceItemName = new StringBuilder(GenerateSafePropertyName(proj, "References")); if (!string.IsNullOrEmpty(subTargetName)) { referenceItemName.Append('_'); referenceItemName.Append(subTargetName); } StringBuilder importLibraryItemName = new StringBuilder(GenerateSafePropertyName(proj, "ImportLibraries")); if (!string.IsNullOrEmpty(subTargetName)) { importLibraryItemName.Append('_'); importLibraryItemName.Append(subTargetName); } string referenceGuidsToRemove = null; AddResolveProjectReferenceTasks(solution, msbuildProject, target, proj, solutionConfiguration, referenceItemName.ToString(), importLibraryItemName.ToString(), out referenceGuidsToRemove); if (string.IsNullOrEmpty(referenceGuidsToRemove)) referenceGuidsToRemove = string.Empty; string fullProjectPath = null; string tmpExtension = null; string projectPath = null; try { fullProjectPath = proj.AbsolutePath; tmpExtension = string.Format(CultureInfo.InvariantCulture, ".tmp_{0}_{1}.vcproj", solutionConfiguration.ConfigurationName, solutionConfiguration.PlatformName); projectPath = Path.ChangeExtension(fullProjectPath, tmpExtension); } catch (Exception e) { if (ExceptionHandling.NotExpectedException(e)) throw; ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseInvalidProjectFileName", proj.RelativePath, e.Message); } // Create the temporary VC project BuildTask createVCProjectTask = target.AddNewTask("CreateTemporaryVCProject"); createVCProjectTask.SetParameterValue("ProjectFile", fullProjectPath, true /* treat as literal */); createVCProjectTask.SetParameterValue("Configuration", projectConfigurationName, true /* treat as literal */); createVCProjectTask.SetParameterValue("OutputProjectFile", projectPath, true /* treat as literal */); createVCProjectTask.SetParameterValue("ReferenceGuids", referenceGuidsToRemove, false /* Contains semicolon-separated list. DO NOT treat as literal */); createVCProjectTask.SetParameterValue("ReferenceAssemblies", string.Format(CultureInfo.InvariantCulture, "@({0})", referenceItemName.ToString()), false /* DO NOT treat as literal */); createVCProjectTask.SetParameterValue("ReferenceImportLibraries", string.Format(CultureInfo.InvariantCulture, "@({0})", importLibraryItemName.ToString()), false /* DO NOT treat as literal */); createVCProjectTask.Condition = GetConditionStringForConfiguration(solutionConfiguration); return projectPath; }
/// <summary> /// Adds a dependency to the project based on the specified guid string. /// </summary> /// <remarks> /// If the string is null or empty, no dependency is added and this is not considered an error. /// </remarks> /// <param name="solution">The solution in which the project exists</param> /// <param name="project">The project to which the dependency will be added</param> /// <param name="parentEngine">The engine handling the conversion</param> /// <param name="projectBuildEventContext">The build event context</param> /// <param name="dependencyGuid">The guid, in string form, of the dependency project</param> static private void AddDependencyByGuid(SolutionParser solution, ProjectInSolution project, Engine parentEngine, BuildEventContext projectBuildEventContext, string dependencyGuid) { if (!String.IsNullOrEmpty(dependencyGuid)) { if (solution.ProjectsByGuid.ContainsKey(dependencyGuid)) { project.Dependencies.Add(dependencyGuid); } else { parentEngine.LoggingServices.LogWarning(projectBuildEventContext, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseProjectDepNotFoundError", project.ProjectGuid, dependencyGuid); } } }
/// <summary> /// Loads each MSBuild project in this solution and looks for its project-to-project references so that /// we know what build order we should use when building the solution. /// </summary> /// <owner>LukaszG</owner> static private void ScanProjectDependencies(SolutionParser solution, Engine parentEngine, string childProjectToolsVersion, string fullSolutionConfigurationName, BuildEventContext projectBuildEventContext) { string message = null; // Don't bother with all this if the solution configuration doesn't even exist. if (fullSolutionConfigurationName == null) { return; } foreach (ProjectInSolution project in solution.ProjectsInOrder) { // Skip the project if we don't have its configuration in this solution configuration if (!project.ProjectConfigurations.ContainsKey(fullSolutionConfigurationName)) { continue; } if ((project.ProjectType == SolutionProjectType.ManagedProject) || ((project.ProjectType == SolutionProjectType.Unknown) && (project.CanBeMSBuildProjectFile(out message)))) { try { //Will fail to load a throw an error if the tools version is incorrect. Project msbuildProject = new Project(parentEngine, childProjectToolsVersion); msbuildProject.IsLoadedByHost = false; // this is before building the solution wrapper project, so the current directory may be not set to // the one containing the solution file, and we'd get the relative path wrong msbuildProject.Load(project.AbsolutePath); // Project references for MSBuild projects could be affected by the active configuration, // so set it before retrieving references. msbuildProject.GlobalProperties.SetProperty("Configuration", project.ProjectConfigurations[fullSolutionConfigurationName].ConfigurationName, true /* treat as literal */); msbuildProject.GlobalProperties.SetProperty("Platform", project.ProjectConfigurations[fullSolutionConfigurationName].PlatformName, true /* treat as literal */); BuildItemGroup references = msbuildProject.GetEvaluatedItemsByName("ProjectReference"); foreach (BuildItem reference in references) { string referencedProjectGuid = reference.GetEvaluatedMetadata("Project"); // Need unescaped data here. AddDependencyByGuid(solution, project, parentEngine, projectBuildEventContext, referencedProjectGuid); } // // ProjectDependency items work exactly like ProjectReference items from the point of // view of determining that project B depends on project A. This item must cause // project A to be built prior to project B. // references = msbuildProject.GetEvaluatedItemsByName("ProjectDependency"); foreach (BuildItem reference in references) { string referencedProjectGuid = reference.GetEvaluatedMetadata("Project"); // Need unescaped data here. AddDependencyByGuid(solution, project, parentEngine, projectBuildEventContext, referencedProjectGuid); } // // If this is a web deployment project, we have a reference specified as a property // "SourceWebProject" rather than as a ProjectReference item. This has the format // {GUID}|PATH_TO_CSPROJ // where // GUID is the project guid for the "source" project // PATH_TO_CSPROJ is the solution-relative path to the csproj file. // // NOTE: This is obsolete and is intended only for backward compatability with // Whidbey-generated web deployment projects. New projects should use the // ProjectDependency item above. // string referencedWebProjectGuid = msbuildProject.GetEvaluatedProperty("SourceWebProject"); if (!string.IsNullOrEmpty(referencedWebProjectGuid)) { // Grab the guid with its curly braces... referencedWebProjectGuid = referencedWebProjectGuid.Substring(0, 38); AddDependencyByGuid(solution, project, parentEngine, projectBuildEventContext, referencedWebProjectGuid); } } // We don't want any problems scanning the project file to result in aborting the build. catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) throw; parentEngine.LoggingServices.LogWarning(projectBuildEventContext, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(project.RelativePath), "SolutionScanProjectDependenciesFailed", project.RelativePath, e.Message); } } else if (project.ProjectType == SolutionProjectType.VCProject) { try { XmlDocument doc = new XmlDocument(); doc.Load(project.AbsolutePath); project.IsStaticLibrary = VCProjectParser.IsStaticLibrary(doc, project.ProjectConfigurations[fullSolutionConfigurationName].FullName); // this is before building the solution wrapper project, so the current directory may be not set to // the one containing the solution file, and we'd get the relative path wrong List<string> referencedProjectGuids = VCProjectParser.GetReferencedProjectGuids(doc); foreach (string referencedProjectGuid in referencedProjectGuids) { if (!string.IsNullOrEmpty(referencedProjectGuid)) { if (solution.ProjectsByGuid.ContainsKey(referencedProjectGuid)) { project.Dependencies.Add(referencedProjectGuid); project.ProjectReferences.Add(referencedProjectGuid); } else { parentEngine.LoggingServices.LogWarning(projectBuildEventContext, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseProjectDepNotFoundError", project.ProjectGuid, referencedProjectGuid); } } } } // We don't want any problems scanning the project file to result in aborting the build. catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) throw; parentEngine.LoggingServices.LogWarning(projectBuildEventContext, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(project.RelativePath), "SolutionScanProjectDependenciesFailed", project.RelativePath, e.Message); } } } }
/// <summary> /// Figure out what solution configuration we are going to build, whether or not it actually exists in the solution /// file. /// </summary> private static string DetermineLikelyActiveSolutionConfiguration(SolutionParser solution, Engine parentEngine) { string activeSolutionConfiguration; string activeSolutionPlatform; BuildProperty configurationProperty = parentEngine.GlobalProperties["Configuration"]; BuildProperty platformProperty = parentEngine.GlobalProperties["Platform"]; if (configurationProperty != null) { activeSolutionConfiguration= configurationProperty.FinalValue; } else { activeSolutionConfiguration = solution.GetDefaultConfigurationName(); } if (platformProperty != null) { activeSolutionPlatform = platformProperty.FinalValue; } else { activeSolutionPlatform = solution.GetDefaultPlatformName(); } ConfigurationInSolution configurationInSolution = new ConfigurationInSolution(activeSolutionConfiguration, activeSolutionPlatform); return configurationInSolution.FullName; }
/// <summary> /// Normally the active solution configuration/platform is determined when we build the solution /// wrapper project, not when we create it. However, we need to know them to scan project references /// for the right project configuration/platform. It's unlikely that references would be conditional, /// but still possible and we want to get that case right. /// </summary> /// <returns></returns> /// <owner>LukaszG</owner> static internal string PredictActiveSolutionConfigurationName(SolutionParser solution, Engine parentEngine) { string candidateFullSolutionConfigurationName = DetermineLikelyActiveSolutionConfiguration(solution, parentEngine); // Now check if this solution configuration actually exists string fullSolutionConfigurationName = null; foreach (ConfigurationInSolution solutionConfiguration in solution.SolutionConfigurations) { if (String.Equals(solutionConfiguration.FullName, candidateFullSolutionConfigurationName, StringComparison.OrdinalIgnoreCase)) { fullSolutionConfigurationName = solutionConfiguration.FullName; break; } } return fullSolutionConfigurationName; }
/// <summary> /// Special hack for web projects. It can happen that there is no Release configuration for solutions /// containing web projects, yet we still want to be able to build the Release configuration for /// those projects. Since the ASP.NET project configuration defaults to the solution configuration, /// we allow Release even if it doesn't actually exist in the solution. /// </summary> /// <param name="solution"></param> /// <owner>LukaszG</owner> static private void AddFakeReleaseSolutionConfigurationIfNecessary(SolutionParser solution) { if (solution.ContainsWebProjects) { bool solutionHasReleaseConfiguration = false; foreach (ConfigurationInSolution solutionConfiguration in solution.SolutionConfigurations) { if (string.Compare(solutionConfiguration.ConfigurationName, "Release", StringComparison.OrdinalIgnoreCase) == 0) { solutionHasReleaseConfiguration = true; break; } } if ((!solutionHasReleaseConfiguration) && (solution.SolutionConfigurations.Count > 0)) { solution.SolutionConfigurations.Add(new ConfigurationInSolution("Release", solution.GetDefaultPlatformName())); } } }
/// <summary> /// Adds solution related build event macros and other global properties to the wrapper project /// </summary> /// <param name="msbuildProject"></param> /// <param name="solution"></param> /// <owner>LukaszG</owner> static private void AddGlobalProperties(Project msbuildProject, SolutionParser solution) { BuildPropertyGroup propertyGroup = msbuildProject.AddNewPropertyGroup(true /* insertAtEndOfProject = true */); string directoryName = solution.SolutionFileDirectory; if (!directoryName.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) { directoryName += Path.DirectorySeparatorChar; } propertyGroup.AddNewProperty("SolutionDir", directoryName, true /* treat as literal */); propertyGroup.AddNewProperty("SolutionExt", Path.GetExtension(solution.SolutionFile), true /* treat as literal */); propertyGroup.AddNewProperty("SolutionFileName", Path.GetFileName(solution.SolutionFile), true /* treat as literal */); propertyGroup.AddNewProperty("SolutionName", Path.GetFileNameWithoutExtension(solution.SolutionFile), true /* treat as literal */); propertyGroup.AddNewProperty("SolutionPath", Path.Combine(solution.SolutionFileDirectory, Path.GetFileName(solution.SolutionFile)), true /* treat as literal */); // Add other global properties BuildPropertyGroup propertyGroup2 = msbuildProject.AddNewPropertyGroup(true /* insertAtEndOfProject = true */); // Set the property "TargetFrameworkVersion". This is needed for the GetFrameworkPath target. // If TargetFrameworkVersion is already set by the user, use that value. // Otherwise if MSBuildToolsVersion is 2.0, use "v2.0" // Otherwise if MSBuildToolsVersion is 3.5, use "v3.5" // Otherwise use "v4.0". BuildProperty v20Property = propertyGroup2.AddNewProperty("TargetFrameworkVersion", "v2.0", true /* treat as literal */); BuildProperty v35Property = propertyGroup2.AddNewProperty("TargetFrameworkVersion", "v3.5", true /* treat as literal */); BuildProperty v40Property = propertyGroup2.AddNewProperty("TargetFrameworkVersion", "v4.0", true /* treat as literal */); v20Property.Condition = "'$(TargetFrameworkVersion)' == '' and '$(MSBuildToolsVersion)' == '2.0'"; v35Property.Condition = "'$(TargetFrameworkVersion)' == '' and ('$(MSBuildToolsVersion)' == '3.5' or '$(MSBuildToolsVersion)' == '3.0')"; v40Property.Condition = "'$(TargetFrameworkVersion)' == '' and '$(MSBuildToolsVersion)' == '4.0'"; }
/// <summary> /// For MSBuild projects, project dependencies you can set in the IDE only represent build order constraints. /// If both projects are VC however, the VC project system treats dependencies as regular P2P references. /// This behavior is a carry-over from the days of VC5/6, that's how P2P refs were done back then. Tricky. /// To compensate for that, we need to add a P2P reference for every dependency between two VC projects. /// MSBuild -> VC, VC -> MSBuild dependencies are not affected. /// </summary> /// <param name="solution"></param> /// <param name="parentEngine"></param> /// <owner>LukaszG</owner> static internal void ConvertVcToVcDependenciesToReferences(SolutionParser solution, Engine parentEngine, BuildEventContext projectBuildEventContext) { // Go through the list of the projects in solution looking for VC projects foreach (ProjectInSolution project in solution.ProjectsInOrder) { if (project.ProjectType == SolutionProjectType.VCProject) { // Found a VC project. Does it have any dependencies on other VC projects? foreach (string dependentProjectGuid in project.Dependencies) { if (solution.ProjectsByGuid.ContainsKey(dependentProjectGuid)) { ProjectInSolution dependentProject = (ProjectInSolution)solution.ProjectsByGuid[dependentProjectGuid]; // Found a dependency on another VC project. If there's not already a P2P reference between // the two, add it. if ((dependentProject.ProjectType == SolutionProjectType.VCProject) && (!project.ProjectReferences.Contains(dependentProjectGuid))) { project.ProjectReferences.Add(dependentProjectGuid); } } else { parentEngine.LoggingServices.LogWarning(projectBuildEventContext, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseProjectDepNotFoundError", project.ProjectGuid, dependentProjectGuid); } } } } }
/// <summary> /// Add a target for a project into the XML doc that's being generated. /// </summary> /// <param name="msbuildProject"></param> /// <param name="solution"></param> /// <param name="proj"></param> /// <param name="targetOutputItemName">The name of the item exposing this target's outputs. May be null.</param> /// <param name="subTargetName"></param> /// <owner>RGoel, LukaszG</owner> static private void AddTargetForManagedProject ( Project msbuildProject, SolutionParser solution, ProjectInSolution proj, string targetOutputItemName, string subTargetName ) { string targetName = ProjectInSolution.DisambiguateProjectTargetName(proj.GetUniqueProjectName()); if (subTargetName != null && subTargetName.Length > 0) { targetName = targetName + ":" + subTargetName; } Target newTarget = msbuildProject.Targets.AddNewTarget(targetName); newTarget.DependsOnTargets = GetProjectDependencies(proj.ParentSolution, proj, subTargetName); newTarget.Condition = "'$(CurrentSolutionConfigurationContents)' != ''"; if (!String.IsNullOrEmpty(targetOutputItemName)) { newTarget.TargetElement.SetAttribute("Outputs", string.Format(CultureInfo.InvariantCulture, "@({0})", targetOutputItemName)); } // Only create build items if we're called with the null subtarget. We're getting called // a total of four times and only want to create the build items once. bool createBuildItems = (subTargetName == null); foreach (ConfigurationInSolution solutionConfiguration in solution.SolutionConfigurations) { ProjectConfigurationInSolution projectConfiguration = null; string condition = GetConditionStringForConfiguration(solutionConfiguration); // Create the build item group for this configuration if we haven't already if (solutionConfiguration.ProjectBuildItems == null) { solutionConfiguration.ProjectBuildItems = msbuildProject.AddNewItemGroup(); solutionConfiguration.ProjectBuildItems.Condition = condition; } if (proj.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out projectConfiguration)) { if (projectConfiguration.IncludeInBuild) { // We want to specify ToolsVersion on the MSBuild task only if the solution // is building with a non-Whidbey toolset, because the Whidbey MSBuild task // does not support the ToolsVersion parameter. If the user explicitly requested // the 2.0 toolset be used to build the solution while specifying some value // for the ProjectToolsVersion property, then one of the InitialTargets should // have produced an error before reaching this point. // PERF: We could emit two <MSBuild> tasks, with a condition on them. But this doubles the size of // the solution wrapper project, and the cost is too high. The consequence is that when solution wrapper // projects are emitted to disk (with MSBUILDEMITSOLUION=1) they cannot be reused for tools version v2.0. bool specifyProjectToolsVersion = String.Equals(msbuildProject.ToolsVersion, "2.0", StringComparison.OrdinalIgnoreCase) ? false : true; BuildTask msbuildTask = AddMSBuildTaskElement(newTarget, proj.RelativePath, subTargetName, projectConfiguration.ConfigurationName, projectConfiguration.PlatformName, specifyProjectToolsVersion); msbuildTask.Condition = condition; if (!String.IsNullOrEmpty(targetOutputItemName)) { msbuildTask.AddOutputItem("TargetOutputs", targetOutputItemName); } if (createBuildItems) { string baseItemName = "BuildLevel" + proj.DependencyLevel; BuildItem projectItem = solutionConfiguration.ProjectBuildItems.AddNewItem(baseItemName, proj.RelativePath, true /* treat as literal */); projectItem.SetMetadata("Configuration", EscapingUtilities.Escape(projectConfiguration.ConfigurationName)); projectItem.SetMetadata("Platform", EscapingUtilities.Escape(projectConfiguration.PlatformName)); } } else { BuildTask messageTask = AddErrorWarningMessageElement(newTarget, XMakeElements.message, true, "SolutionProjectSkippedForBuilding", proj.ProjectName, solutionConfiguration.FullName); messageTask.Condition = condition; if (createBuildItems) { string baseItemName = "SkipLevel" + proj.DependencyLevel; BuildItem projectItem = solutionConfiguration.ProjectBuildItems.AddNewItem(baseItemName, proj.ProjectName, true /* treat as literal */); } } } else { BuildTask warningTask = AddErrorWarningMessageElement(newTarget, XMakeElements.warning, true, "SolutionProjectConfigurationMissing", proj.ProjectName, solutionConfiguration.FullName); warningTask.Condition = condition; if (createBuildItems) { string baseItemName = "MissingConfigLevel" + proj.DependencyLevel; BuildItem projectItem = solutionConfiguration.ProjectBuildItems.AddNewItem(baseItemName, proj.ProjectName, true /* treat as literal */); } } } }
/// <summary> /// Figure out the dependency level of the given project. /// </summary> /// <param name="project"></param> /// <param name="solution"></param> /// <param name="projectsByDependencyLevel"></param> static private void AssignDependencyLevel(ProjectInSolution project, SolutionParser solution, Dictionary<int, List<ProjectInSolution>> projectsByDependencyLevel) { // if we ever try to recurse into a project whose dependency level we're calculating above, // we have a circular dependency. if (project.DependencyLevel == ProjectInSolution.DependencyLevelBeingDetermined) { ProjectErrorUtilities.VerifyThrowInvalidProject(false, null, "SolutionCircularDependencyError", project.ProjectName); } if (project.DependencyLevel == ProjectInSolution.DependencyLevelUnknown) { project.DependencyLevel = ProjectInSolution.DependencyLevelBeingDetermined; int maxDependencyLevel = 0; // First, go through dependencies and ensure they have their dependency level set correctly. foreach (string dependencyGuid in project.Dependencies) { ProjectInSolution referencedProject = (ProjectInSolution) solution.ProjectsByGuid[dependencyGuid]; AssignDependencyLevel(referencedProject, solution, projectsByDependencyLevel); if (referencedProject.DependencyLevel + 1 > maxDependencyLevel) { maxDependencyLevel = referencedProject.DependencyLevel + 1; } } // Our dependency level is the highest dependency level of all our dependencies plus 1, or 0 if we had // no dependencies. project.DependencyLevel = maxDependencyLevel; if (!projectsByDependencyLevel.ContainsKey(maxDependencyLevel)) { projectsByDependencyLevel.Add(maxDependencyLevel, new List<ProjectInSolution>()); } projectsByDependencyLevel[maxDependencyLevel].Add(project); } }
/// <summary> /// Adds MSBuild and ResolveVCProjectOutput tasks to a project target to pre-resolve its project references /// </summary> /// <param name="solution"></param> /// <param name="target"></param> /// <param name="proj"></param> /// <param name="solutionConfiguration"></param> /// <param name="outputReferenceItemName"></param> /// <param name="outputImportLibraryItemName"></param> /// <param name="addedReferenceGuids"></param> /// <owner>LukaszG</owner> static private void AddResolveProjectReferenceTasks ( SolutionParser solution, Project msbuildProject, Target target, ProjectInSolution proj, ConfigurationInSolution solutionConfiguration, string outputReferenceItemName, string outputImportLibraryItemName, out string addedReferenceGuids ) { StringBuilder referenceGuids = new StringBuilder(); string message = null; // Suffix for the reference item name. Since we need to attach additional (different) metadata to every // reference item, we need to have helper item lists each with only one item int outputReferenceItemNameSuffix = 0; // Pre-resolve the MSBuild/VC project references foreach (string projectReferenceGuid in proj.ProjectReferences) { ProjectInSolution referencedProject = (ProjectInSolution)solution.ProjectsByGuid[projectReferenceGuid]; ProjectConfigurationInSolution referencedProjectConfiguration = null; if ((referencedProject != null) && (referencedProject.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out referencedProjectConfiguration)) && (referencedProjectConfiguration != null)) { string outputReferenceItemNameWithSuffix = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", outputReferenceItemName, outputReferenceItemNameSuffix); bool addCreateItem = false; if ((referencedProject.ProjectType == SolutionProjectType.ManagedProject) || ((referencedProject.ProjectType == SolutionProjectType.Unknown) && (referencedProject.CanBeMSBuildProjectFile(out message)))) { string condition = GetConditionStringForConfiguration(solutionConfiguration); bool specifyProjectToolsVersion = String.Equals(msbuildProject.ToolsVersion, "2.0", StringComparison.OrdinalIgnoreCase) ? false : true; BuildTask msbuildTask = AddMSBuildTaskElement(target, referencedProject.RelativePath, "GetTargetPath", referencedProjectConfiguration.ConfigurationName, referencedProjectConfiguration.PlatformName, specifyProjectToolsVersion); msbuildTask.Condition = condition; msbuildTask.AddOutputItem("TargetOutputs", outputReferenceItemNameWithSuffix); if (referenceGuids.Length > 0) { referenceGuids.Append(';'); } referenceGuids.Append(projectReferenceGuid); addCreateItem = true; } else if (referencedProject.ProjectType == SolutionProjectType.VCProject) { BuildTask vcbuildTask = null; try { vcbuildTask = AddResolveVCProjectOutputTaskElement(target, Path.Combine(solution.SolutionFileDirectory, Path.GetFileName(solution.SolutionFile)), referencedProject.AbsolutePath, referencedProjectConfiguration.FullName); } catch (Exception e) { if (ExceptionHandling.NotExpectedException(e)) throw; ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseInvalidProjectFileName", referencedProject.RelativePath, e.Message); } vcbuildTask.Condition = GetConditionStringForConfiguration(solutionConfiguration); vcbuildTask.AddOutputItem("ResolvedOutputPaths", outputReferenceItemNameWithSuffix); if (outputImportLibraryItemName != null) { vcbuildTask.AddOutputItem("ResolvedImportLibraryPaths", outputImportLibraryItemName); } if (referenceGuids.Length > 0) { referenceGuids.Append(';'); } referenceGuids.Append(projectReferenceGuid); addCreateItem = true; } // Add create item if either of the conditions above was true. // This merges the one-item item list into the main list, adding the appropriate guid metadata if (addCreateItem) { BuildTask createItemTask = target.AddNewTask("CreateItem"); createItemTask.SetParameterValue("Include", "@(" + outputReferenceItemNameWithSuffix + ")", false /* do not treat as literal */); createItemTask.SetParameterValue("AdditionalMetadata", "Guid=" + projectReferenceGuid, false /* do not treat as literal */); createItemTask.AddOutputItem("Include", outputReferenceItemName); } outputReferenceItemNameSuffix++; } } addedReferenceGuids = referenceGuids.ToString(); }
/// <summary> /// This method returns a string containing a semicolon-separated list of "friendly" project names /// on which the specified project depends. If the null is specified, a list of all projects /// is returned. /// </summary> /// <param name="solution"></param> /// <param name="project"></param> /// <param name="subTargetName"></param> /// <returns></returns> /// <owner>RGoel</owner> static private string GetProjectDependencies(SolutionParser solution, ProjectInSolution project, string subTargetName) { ErrorUtilities.VerifyThrow(project != null, "We should always have a project for this method"); StringBuilder dependencies = new StringBuilder(); // Get all the dependencies for this project foreach (string dependency in project.Dependencies) { if (dependencies.Length != 0) { dependencies.Append(";"); } string projectUniqueName = solution.GetProjectUniqueNameByGuid(dependency); ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(projectUniqueName != null, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseProjectDepNotFoundError", project.ProjectGuid, dependency); dependencies.Append(ProjectInSolution.DisambiguateProjectTargetName(projectUniqueName)); if (subTargetName != null && subTargetName.Length > 0) { dependencies.Append(":"); dependencies.Append(subTargetName); } } return dependencies.ToString(); }
/// <summary> /// Add a target for a project into the XML doc that's being generated. /// </summary> /// <param name="msbuildProject"></param> /// <param name="solution"></param> /// <param name="proj"></param> /// <param name="subTargetName"></param> /// <owner>LukaszG, RGoel</owner> static private void AddTargetForVCProject ( Project msbuildProject, SolutionParser solution, ProjectInSolution proj, string subTargetName ) { string targetName = ProjectInSolution.DisambiguateProjectTargetName(proj.GetUniqueProjectName()); if (subTargetName != null && subTargetName.Length > 0) { targetName = targetName + ":" + subTargetName; } Target newTarget = msbuildProject.Targets.AddNewTarget(targetName); newTarget.DependsOnTargets = GetProjectDependencies(proj.ParentSolution, proj, subTargetName); newTarget.Condition = "'$(CurrentSolutionConfigurationContents)' != ''"; if (subTargetName == "Publish") { // Well, hmmm. The VCBuild doesn't support any kind of // a "Publish" operation. The best we can really do is offer up a // message saying so. AddErrorWarningMessageElement(newTarget, XMakeElements.warning, true, "SolutionVCProjectNoPublish"); // ... and now pretend it's a Build subtarget. This way references to VC projects from projects // that are about to publish will at least get built. subTargetName = null; } string projectPath = null; try { projectPath = proj.AbsolutePath; } catch (Exception e) { if (ExceptionHandling.NotExpectedException(e)) throw; ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solution.SolutionFile), "SolutionParseInvalidProjectFileName", proj.RelativePath, e.Message); } foreach (ConfigurationInSolution solutionConfiguration in solution.SolutionConfigurations) { string solutionConfigurationCondition = GetConditionStringForConfiguration(solutionConfiguration); ProjectConfigurationInSolution vcProjectConfiguration = null; BuildTask newTask = null; if (proj.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out vcProjectConfiguration)) { if (vcProjectConfiguration.IncludeInBuild) { // Create a temporary VC project with references to MSBuild projects replaced with file references. if (proj.ProjectReferences.Count > 0) { projectPath = AddCreateTemporaryVCProjectTasks(solution, msbuildProject, newTarget, proj, solutionConfiguration, subTargetName, vcProjectConfiguration.FullName); } newTask = VCWrapperProject.AddVCBuildTaskElement( msbuildProject, newTarget, EscapingUtilities.Escape(Path.Combine(solution.SolutionFileDirectory, Path.GetFileName(solution.SolutionFile))), projectPath, subTargetName, null, EscapingUtilities.Escape(vcProjectConfiguration.FullName)); // Delete the temporary VC project if (proj.ProjectReferences.Count > 0) { BuildTask deleteTask = newTarget.AddNewTask("Delete"); deleteTask.SetParameterValue("Files", projectPath, true /* treat as literal */); deleteTask.Condition = solutionConfigurationCondition; } } else { newTask = AddErrorWarningMessageElement(newTarget, XMakeElements.message, true, "SolutionProjectSkippedForBuilding", proj.ProjectName, solutionConfiguration.FullName); } } else { newTask = AddErrorWarningMessageElement(newTarget, XMakeElements.warning, true, "SolutionProjectConfigurationMissing", proj.ProjectName, solutionConfiguration.FullName); } if (newTask != null) { newTask.Condition = solutionConfigurationCondition; } } }
/// <summary> /// Add virtual references for reference chains containing VC static library projects. /// Since static libraries have no link step, any references they have have to be passed /// to their parent project, if any. So for example, in a chain like /// native dll -> native static lib1 -> native static lib2 /// we need to add a virtual reference between the native dll and the static lib2 /// to maintain parity with the IDE behavior. /// </summary> /// <param name="solution"></param> private static void AddVirtualReferencesForStaticLibraries(SolutionParser solution) { foreach (ProjectInSolution project in solution.ProjectsInOrder) { GatherChildReferencesForStaticLibraries(solution, project); } }
/// <summary> /// Main entry point for figuring out the dependency levels. A dependency level is a set of projects that /// have no intra-dependencies and depend only on projects fron dependency level N-1. Dependency level 0 /// projects have no dependencies whatsoever. /// </summary> /// <param name="solution"></param> /// <param name="projectsByDependencyLevel"></param> static private void AssignDependencyLevels(SolutionParser solution, Dictionary<int, List<ProjectInSolution>> projectsByDependencyLevel) { foreach (ProjectInSolution project in solution.ProjectsInOrder) { AssignDependencyLevel(project, solution, projectsByDependencyLevel); } }
/// <summary> /// Creates default Configuration and Platform values based on solution configurations present in the solution /// </summary> /// <param name="msbuildProject"></param> /// <param name="solution"></param> /// <owner>LukaszG</owner> static private void AddConfigurationPlatformDefaults ( Project msbuildProject, SolutionParser solution ) { BuildPropertyGroup configurationDefaultingPropertyGroup = msbuildProject.AddNewPropertyGroup(true /* insertAtEndOfProject = true */); configurationDefaultingPropertyGroup.Condition = " '$(Configuration)' == '' "; configurationDefaultingPropertyGroup.AddNewProperty("Configuration", solution.GetDefaultConfigurationName(), true /* treat as literal */); BuildPropertyGroup platformDefaultingPropertyGroup = msbuildProject.AddNewPropertyGroup(true /* insertAtEndOfProject = true */); platformDefaultingPropertyGroup.Condition = " '$(Platform)' == '' "; platformDefaultingPropertyGroup.AddNewProperty("Platform", solution.GetDefaultPlatformName(), true /* treat as literal */); }