public void LinkedServerProjectCache_Ctor() { LinkedServerProjectCache cache; ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { // Null project file throws ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache(null, "breadCrumb", logger, projectFileReader), "rootProjectPath"); ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache(String.Empty, "breadCrumb", logger, projectFileReader), "rootProjectPath"); // Null logger throws ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", null, logger, projectFileReader), "historyFilePath"); ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", String.Empty, logger, projectFileReader), "historyFilePath"); // Null logger throws ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", "breadCrumb", null, projectFileReader), "logger"); // Null projectFileLogger throws ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", "breadCrumb", logger, null), "projectFileReader"); // Valid ctor succeeds cache = new LinkedServerProjectCache("proj", "breadCrumb", logger, projectFileReader); } }
public void ProjectFileReader_Bad_Project_File_Warns() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); File.WriteAllText(badProjectPath, "neener neener"); try { projectFileReader.LoadProject(badProjectPath); // Simulate the exception so we get the exact text string warningMessage = null; try { Engine engine = new Engine(); Project project = new Project(engine); project.Load(badProjectPath); } catch (InvalidProjectFileException ipfe) { warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Open_Project, badProjectPath, ipfe.Message); } TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(badProjectPath); } } }
public void ProjectFileReader_Ctor() { ConsoleLogger logger = new ConsoleLogger(); ExceptionHelper.ExpectArgumentNullExceptionStandard(() => new ProjectFileReader(null), "logger"); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { } }
public void ProjectFileReader_Dispose_Multiple() { ConsoleLogger logger = new ConsoleLogger(); ProjectFileReader projectFileReader; using (projectFileReader = new ProjectFileReader(logger)) { } projectFileReader.Dispose(); projectFileReader.Dispose(); System.GC.Collect(); System.GC.WaitForPendingFinalizers(); projectFileReader.Dispose(); }
public void ProjectSourceFileCache_Indexer() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { ProjectSourceFileCache cache = new ProjectSourceFileCache("proj", "breadCrumb", logger, projectFileReader); // First access allocates empty instance Assert.IsNotNull(cache.SourceFilesByProject); Assert.AreEqual(0, cache.SourceFilesByProject.Count, "Expected empty cache"); // Indexer setter can be called cache["proj"] = new string[] { "a", "b", "c" }; // Which invalidates the currency of the cache Assert.IsFalse(cache.IsFileCacheCurrent, "Adding to the cache should have marked the file cache as out of date."); // And indexer getter returns the inputs IEnumerable<string> files = cache["proj"]; Assert.IsNotNull(files); Assert.AreEqual(3, files.Count()); Assert.IsTrue(files.Contains("a")); Assert.IsTrue(files.Contains("b")); Assert.IsTrue(files.Contains("c")); // Cache is case insensitive. Should overwrite entry differing only in case cache["PrOj"] = new string[] { "d", "e" }; Assert.AreEqual(1, cache.SourceFilesByProject.Count, "Key differing only in case should have overwritten existing one"); files = cache["PrOj"]; Assert.IsNotNull(files); // And can read out again in different case files = cache["pRoJ"]; Assert.IsNotNull(files); // Null value clears entry cache["proj"] = null; files = cache["proj"]; Assert.IsNull(files); // ArgNull exception on null/empty index setter ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache[null] = new string[] { "a" }, "projectPath"); ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache[string.Empty] = new string[] { "a" }, "projectPath"); // ArgNull exception on null/empty index getter ExceptionHelper.ExpectArgumentNullExceptionStandard(() => files = cache[null], "projectPath"); ExceptionHelper.ExpectArgumentNullExceptionStandard(() => files = cache[string.Empty], "projectPath"); } }
public void LinkedServerProjectCache_Indexer() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string projectFile = this.CreateMockProjectFile(); string historyFile = this.CreateMockHistoryFile(); LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); try { // First access allocates empty instance Assert.IsNotNull(cache.LinkedServerProjectsByProject, "Expected non null dictionary after ctor"); Assert.AreEqual(0, cache.LinkedServerProjectsByProject.Count, "Expected empty cache"); // Null indexer parameter throws on sets ExceptionHelper.ExpectArgumentNullExceptionStandard((() => cache[null] = "x"), "projectPath"); ExceptionHelper.ExpectArgumentNullExceptionStandard((() => cache[string.Empty] = "x"), "projectPath"); // Null indexer parameter throws on gets string unused; ExceptionHelper.ExpectArgumentNullExceptionStandard((() => unused = cache[null]), "projectPath"); ExceptionHelper.ExpectArgumentNullExceptionStandard((() => unused = cache[string.Empty]), "projectPath"); // Indexer setter can be called with valid values cache["proj1"] = "proj1.Web"; cache["proj2"] = "proj2.Web"; // Nulls are permitted cache["proj3"] = null; Assert.AreEqual(3, cache.LinkedServerProjectsByProject.Count, "Expected this many entries in cache"); Assert.AreEqual("proj1.Web", cache["proj1"]); Assert.AreEqual("proj2.Web", cache["proj2"]); Assert.IsNull(cache["proj3"], "Null should have been allowed in cache"); // Cache is case insensitive. Should overwrite entry differing only in case cache["PrOj1"] = "PrOj1.wEb"; Assert.AreEqual(3, cache.LinkedServerProjectsByProject.Count, "Key differing only in case should have overwritten existing one"); Assert.AreEqual("PrOj1.wEb", cache["PrOj1"]); } finally { File.Delete(projectFile); File.Delete(historyFile); } } }
public TargetFrameworkResolutionTests() { var analyzerManagerMock = new Mock <IAnalyzerManager>(); var projectAnalyzerMock = new Mock <IProjectAnalyzer>(); var analyzerResultsMock = new Mock <IAnalyzerResults>(); analyzerManagerMock .Setup(m => m.GetProject(It.IsAny <string>())) .Returns(projectAnalyzerMock.Object); projectAnalyzerMock .Setup(m => m.Build()) .Returns(analyzerResultsMock.Object); analyzerResultsMock .Setup(m => m.GetEnumerator()) .Returns(() => _analyzerResults.GetEnumerator()); _projectFileReader = new ProjectFileReader(manager: analyzerManagerMock.Object); }
public void ProjectFileReader_Nonexistent_Project_File_Warns() { ConsoleLogger logger = new ConsoleLogger(); string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { try { projectFileReader.LoadProject(badProjectPath); string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath); TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(badProjectPath); } } }
public void ProjectFileReader_Nonexistent_Project_File_Warns() { ConsoleLogger logger = new ConsoleLogger(); string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { try { projectFileReader.LoadProject(badProjectPath); string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath); TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(badProjectPath); } } }
public void LinkedServerProjectCache_RiaLinks() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string projectFile = this.CreateMockProjectFile(); string historyFile = this.CreateMockHistoryFile(); try { LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); cache["p1"] = "w1"; cache["p2"] = null; cache["p3"] = "w3"; cache["p4"] = string.Empty; Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache"); List <string> projectRefs = cache.ProjectReferences.ToList(); Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache"); Assert.IsTrue(projectRefs.Contains("p1"), "expected p1 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains("p2"), "expected p2 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains("p3"), "expected p3 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains("p4"), "expected p4 to be in list of project refs"); List <string> riaLinks = cache.LinkedServerProjects.ToList(); Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links"); Assert.IsTrue(riaLinks.Contains("w1"), "expected p1 to be in list of RIA links"); Assert.IsTrue(riaLinks.Contains("w3"), "expected p3 to be in list of RIA links"); } finally { File.Delete(projectFile); File.Delete(historyFile); } } }
public void ProjectSourceFileCache_Nonexistent_Project_File_Warns() { ConsoleLogger logger = new ConsoleLogger(); string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { try { ProjectSourceFileCache cache = new ProjectSourceFileCache(badProjectPath, "breadCrumb", logger, projectFileReader); IEnumerable <string> projects = cache.GetAllKnownProjects(); string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath); TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(badProjectPath); } } }
public void ProjectFileReader_Bad_Project_File_Warns() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); File.WriteAllText(badProjectPath, "neener neener"); try { projectFileReader.LoadProject(badProjectPath); // Simulate the exception so we get the exact text string warningMessage = TestHelper.GetFailedToOpenProjectMessage(badProjectPath); TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(badProjectPath); } } }
public void CommandViewModelTo(GetProjectName cmd) { ProjectFileReader Reader = new ProjectFileReader(cmd.LoadedProjectFileAbsolutePath); cmd.FetchedProjectName = Reader.LoadProjectName(); }
public void LinkedServerProjectCache_Load_Real_Project() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { // We will create valid MSBuild projects with this shape: // - projectFile: contains 3 project references // - 2 of the 3 projects referenced point to unique RIA Link server project // - 1 of the 3 projects references points to the same RIA Link project as another // (this tests the ability of our model to handle multiple clients pointing to the same server) string serverProject1 = this.CreateMockProjectFile(); string serverProject2 = this.CreateMockProjectFile(); string refProject1Contents = string.Format(@" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <PropertyGroup> <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject> </PropertyGroup> </Project>", serverProject1); string refProject2Contents = string.Format(@" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <PropertyGroup> <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject> </PropertyGroup> </Project>", serverProject2); string refProject1 = this.CreateTempFile("csproj", refProject1Contents); string refProject2 = this.CreateTempFile("csproj", refProject2Contents); string refProject3 = this.CreateTempFile("csproj", refProject2Contents); string projectContents = string.Format(@" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <ItemGroup> <ProjectReference Include=""{0}""></ProjectReference> <ProjectReference Include=""{1}""></ProjectReference> <ProjectReference Include=""{2}""></ProjectReference> </ItemGroup> </Project>", refProject1, refProject2, refProject3); string projectFile = this.CreateTempFile("csproj", projectContents); string historyFile = this.CreateTempFile("txt", null); // <-- null prevents us from creating file on disk try { LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); // Validate we see our 3 project references List<string> projectRefs = cache.ProjectReferences.ToList(); Assert.AreEqual(3, projectRefs.Count, "Expected this many project references"); Assert.IsTrue(projectRefs.Contains(refProject1), "Expected ref project 1 in project references."); Assert.IsTrue(projectRefs.Contains(refProject2), "Expected ref project 2 in project references."); Assert.IsTrue(projectRefs.Contains(refProject3), "Expected ref project 3 in project references."); // Validate that we extracted the RIA Links for those project references List<string> riaLinks = cache.LinkedServerProjects.ToList(); Assert.AreEqual(2, riaLinks.Count, "Expected to find 2 RIA links"); Assert.IsTrue(riaLinks.Contains(serverProject1), "Expected server project 1 RIA link"); Assert.IsTrue(riaLinks.Contains(serverProject2), "Expected server project 2 RIA link"); // Validate that we can ask for the source of each RIA Link target List<string> sources = cache.GetLinkedServerProjectSources(serverProject1).ToList(); Assert.AreEqual(1, sources.Count, "Expected 1 source to for RIA link to server project 1"); Assert.IsTrue(sources.Contains(refProject1), "Expected refProject 1 to be shown as RIA Link source 1"); sources = cache.GetLinkedServerProjectSources(serverProject2).ToList(); Assert.AreEqual(2, sources.Count, "Expected 2 sources to for RIA link to server project 2"); Assert.IsTrue(sources.Contains(refProject2), "Expected refProject 2 to be shown as RIA Link source 2"); Assert.IsTrue(sources.Contains(refProject3), "Expected refProject 2 to be shown as RIA Link source 2"); } finally { File.Delete(projectFile); File.Delete(historyFile); File.Delete(refProject1); File.Delete(refProject2); File.Delete(refProject3); File.Delete(serverProject1); File.Delete(serverProject2); } } }
public void LinkedServerProjectCache_LoadAndSaveFile() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string historyFile = this.CreateMockHistoryFile(); string projectFile = this.CreateMockProjectFile(); string p1 = this.CreateMockProjectFile(); string p2 = this.CreateMockProjectFile(); string p3 = this.CreateMockProjectFile(); string p4 = this.CreateMockProjectFile(); string w1 = this.CreateMockProjectFile(); string w3 = this.CreateMockProjectFile(); LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); cache[p1] = w1; cache[p2] = null; cache[p3] = w3; cache[p4] = string.Empty; Assert.IsFalse(cache.IsFileCacheCurrent, "expected file cache not to be current after set some properties"); try { // Save to the cache and verify side effects of that bool success = cache.SaveCacheToFile(); Assert.IsTrue(success, "Expected successful save of cache to history file"); Assert.IsTrue(File.Exists(historyFile), "Expected history file " + historyFile + " to have been written"); Assert.IsTrue(cache.IsFileCacheCurrent, "Expected cache to be considered current"); // zap our cache and read back in from file cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); // The following methods and properties will lazy load the cache Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache"); List<string> projectRefs = cache.ProjectReferences.ToList(); Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache"); Assert.IsTrue(projectRefs.Contains(p1), "expected p1 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains(p2), "expected p2 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains(p3), "expected p3 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains(p4), "expected p4 to be in list of project refs"); List<string> riaLinks = cache.LinkedServerProjects.ToList(); Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links"); Assert.IsTrue(riaLinks.Contains(w1), "expected w1 to be in list of RIA links"); Assert.IsTrue(riaLinks.Contains(w3), "expected w3 to be in list of RIA links"); } finally { File.Delete(historyFile); File.Delete(projectFile); File.Delete(p1); File.Delete(p2); File.Delete(p3); File.Delete(p4); File.Delete(w1); File.Delete(w3); } } }
public void LinkedServerProjectCache_RiaLinks() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string projectFile = this.CreateMockProjectFile(); string historyFile = this.CreateMockHistoryFile(); try { LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); cache["p1"] = "w1"; cache["p2"] = null; cache["p3"] = "w3"; cache["p4"] = string.Empty; Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache"); List<string> projectRefs = cache.ProjectReferences.ToList(); Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache"); Assert.IsTrue(projectRefs.Contains("p1"), "expected p1 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains("p2"), "expected p2 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains("p3"), "expected p3 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains("p4"), "expected p4 to be in list of project refs"); List<string> riaLinks = cache.LinkedServerProjects.ToList(); Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links"); Assert.IsTrue(riaLinks.Contains("w1"), "expected p1 to be in list of RIA links"); Assert.IsTrue(riaLinks.Contains("w3"), "expected p3 to be in list of RIA links"); } finally { File.Delete(projectFile); File.Delete(historyFile); } } }
public void ProjectSourceFileCache_Loads_Real_Project() { string projectPath = null; string outputPath = null; TestHelper.GetProjectPaths("SSFC", out projectPath, out outputPath); string serverProjectPath = CodeGenHelper.ServerClassLibProjectPath(projectPath); string breadCrumbFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt"); ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { try { // Instantiate the cache. ProjectSourceFileCache cache = new ProjectSourceFileCache(serverProjectPath, breadCrumbFile, logger, projectFileReader); // Initially, it will not have loaded anything Assert.AreEqual(0, cache.SourceFilesByProject.Count); // ------------------------------------------------------------- // Validate cache is loaded correctly from .csproj files // ------------------------------------------------------------- this.ValidateProjectSourceFileCache(cache, projectPath); // Ask to write out the breadcrumb file Assert.IsFalse(File.Exists(breadCrumbFile)); bool success = cache.SaveCacheToFile(); Assert.IsTrue(success); Assert.IsTrue(File.Exists(breadCrumbFile)); // Clear the cache and force it to read from breadcrumb cache.SourceFilesByProject.Clear(); success = cache.LoadCacheFromFile(); Assert.IsTrue(success, "Failed to load from breadCrumb file"); Assert.IsTrue(cache.IsFileCacheCurrent, "Loading from file should have marked cache as current with file."); // ------------------------------------------------------------- // Validate cache is loaded correctly from breadcrumb file // ------------------------------------------------------------- this.ValidateProjectSourceFileCache(cache, projectPath); // Now mark the breadcrumb file as if it had been written before the ServerClassLib project cache.SourceFilesByProject.Clear(); DateTime serverLastWriteTime = File.GetLastWriteTime(serverProjectPath); DateTime beforeServerLastWriteTime = new DateTime(serverLastWriteTime.Ticks - 1000); File.SetLastWriteTime(breadCrumbFile, beforeServerLastWriteTime); // ------------------------------------------------------------- // Validate cache is *not* loaded if timestamp is before project's // ------------------------------------------------------------- success = cache.LoadCacheFromFile(); Assert.IsFalse(success, "Expected breadCrumbFile time stamp to be caught and reject load"); Assert.IsFalse(cache.IsFileCacheCurrent, "Failed load from file should have marked cache as *not* current with file."); // Cache should still be empty Assert.AreEqual(0, cache.SourceFilesByProject.Count); // ------------------------------------------------------------- // Validate cache loaded in presence of out-of-date breadcrumb // file loads correctly // ------------------------------------------------------------- this.ValidateProjectSourceFileCache(cache, projectPath); Assert.IsFalse(cache.IsFileCacheCurrent, "Loading from project should have marked cache as *not* current with file."); } finally { if (File.Exists(breadCrumbFile)) { File.Delete(breadCrumbFile); } } } }
public void ProjectSourceFileCache_Nonexistent_Project_File_SourceFiles_Warns() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); try { ProjectSourceFileCache cache = new ProjectSourceFileCache("proj", "breadCrumb", logger, projectFileReader); IEnumerable<string> sourceFiles = projectFileReader.LoadSourceFilesFromProject(badProjectPath); string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath); TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(badProjectPath); } } }
/// <summary> /// Creates a new instance /// </summary> /// <param name="rootProjectPath">Full file path to client project to use as root.</param> /// <param name="historyFilePath">Full file path to file to read and write in-memory cache.</param> /// <param name="logger">Instance of an <see cref="ILogger"/> to receive messages.</param> /// <param name="projectFileReader">Instance to use to read the project files.</param> internal LinkedServerProjectCache(string rootProjectPath, string historyFilePath, ILogger logger, ProjectFileReader projectFileReader) { if (string.IsNullOrEmpty(rootProjectPath)) { throw new ArgumentNullException("rootProjectPath"); } if (string.IsNullOrEmpty(historyFilePath)) { throw new ArgumentNullException("historyFilePath"); } if (logger == null) { throw new ArgumentNullException("logger"); } if (projectFileReader == null) { throw new ArgumentNullException("projectFileReader"); } _rootProjectPath = rootProjectPath; _historyFilePath = historyFilePath; _logger = logger; _projectFileReader = projectFileReader; }
#pragma warning restore CS0164 private void DebugButton_Click(object sender, EventArgs e) { bool outputSessionData = checkBox1.Checked; bool parseCodeData = checkBox2.Checked; bool outputTextCode = checkBox3.Checked; string fileName = textBox2.Text; textBox1.Text = "正在处理..."; new Task(() => { try { CodeSectionInfo codeSectionInfo = null; ResourceSectionInfo resourceSectionInfo = null; LosableSectionInfo losableSectionInfo = null; Encoding encoding = Encoding.GetEncoding("gbk"); var output = new StringBuilder(); using (var projectFileReader = new ProjectFileReader(File.OpenRead(fileName), InputPassword)) { while (!projectFileReader.IsFinish) { var section = projectFileReader.ReadSection(); if (outputSessionData) { output.AppendLine("---------------" + section.Name + "---------------"); output.AppendLine("CanSkip: " + section.CanSkip.ToString()); output.AppendLine("Key: 0x" + section.Key.ToString("X8")); output.Append("Data: "); } switch (section.Key) { case ESystemInfo.SectionKey: { var systemInfo = ESystemInfo.Parse(section.Data); encoding = systemInfo.Encoding; if (outputSessionData) { output.AppendLine(systemInfo.ToString()); } } break; case ProjectConfigInfo.SectionKey: { var projectConfig = ProjectConfigInfo.Parse(section.Data, encoding); if (outputSessionData) { output.AppendLine(projectConfig.ToString()); } } break; case CodeSectionInfo.SectionKey: codeSectionInfo = CodeSectionInfo.Parse(section.Data, encoding, projectFileReader.CryptEc); if (outputSessionData) { output.AppendLine(codeSectionInfo.ToString()); } break; case EPackageInfo.SectionKey: { var packageInfo = EPackageInfo.Parse(section.Data, encoding); if (outputSessionData) { output.AppendLine(packageInfo.ToString()); } } break; case ResourceSectionInfo.SectionKey: resourceSectionInfo = ResourceSectionInfo.Parse(section.Data, encoding); if (outputSessionData) { output.AppendLine(resourceSectionInfo.ToString()); } break; case InitEcSectionInfo.SectionKey: { var initEcSectionInfo = InitEcSectionInfo.Parse(section.Data, encoding); if (outputSessionData) { output.AppendLine(initEcSectionInfo.ToString()); } } break; case LosableSectionInfo.SectionKey: { losableSectionInfo = LosableSectionInfo.Parse(section.Data, encoding); if (outputSessionData) { output.AppendLine(losableSectionInfo.ToString()); } } break; case FolderSectionInfo.SectionKey: { var folderSectionInfo = FolderSectionInfo.Parse(section.Data, encoding); if (outputSessionData) { output.AppendLine(folderSectionInfo.ToString()); } } break; default: if (outputSessionData) { output.AppendLine("{"); output.Append(" \"Unknown\": \""); output.Append(section.Data.ToHexString()); output.AppendLine("\""); output.AppendLine("}"); } break; } } if (parseCodeData) { output.AppendLine("<<<<<<<<<<<<<<<ParseTest>>>>>>>>>>>>>>>"); foreach (var method in codeSectionInfo.Methods) { output.AppendLine($"###Method: {(string.IsNullOrEmpty(method.Name) ? "Unknown" : method.Name)}{$"Id: {method.Id})###"}"); try { #pragma warning disable CS0612 // 类型或成员已过时 var block = CodeDataParser.ParseStatementBlock(method.CodeData.ExpressionData, encoding, out var lineOffest, out var blockOffest); #pragma warning restore CS0612 // 类型或成员已过时 var GenCodeData = block.ToCodeData(encoding); output.Append("Raw: "); output.AppendLine(method.CodeData.ToString()); output.Append("FullRewrite: "); output.AppendLine(GenCodeData.ToString()); output.Append("OldOffestRepairer: "); output.AppendLine("{"); output.AppendLine(" \"LineOffest\": \"" + lineOffest.ToHexString() + "\""); output.AppendLine(" \"BlockOffest\": \"" + blockOffest.ToHexString() + "\""); output.AppendLine("}"); } catch (Exception exception) { output.AppendLine("出现错误:"); output.AppendLine(exception.ToString()); output.AppendLine(); } } } if (outputTextCode) { output.AppendLine("<<<<<<<<<<<<<<<TextCode>>>>>>>>>>>>>>>"); var nameMap = new IdToNameMap(codeSectionInfo, resourceSectionInfo, losableSectionInfo); output.AppendLine(".版本 2"); output.AppendLine(); output.AppendLine(codeSectionInfo.ToTextCode(nameMap)); output.AppendLine(resourceSectionInfo.ToTextCode(nameMap)); } } Invoke(new Action(() => { textBox1.Text = output.ToString(); })); } catch (Exception exception) { Invoke(new Action(() => { textBox1.Text = $"出现错误:\r\n{exception}\r\n请加群后将文件发送给作者以便修复此问题"; })); } }) .Start(); }
/// <summary> /// Sole constructor /// </summary> /// <param name="rootProjectPath">Full path to the root project file.</param> /// <param name="historyFilePath">Full path to the file where we are allowed to write results between builds.</param> /// <param name="logger">The <see cref="ILogger"/> to use for warnings and errors.</param> /// <param name="projectFileReader">Instance to use to read the project files.</param> internal ProjectSourceFileCache(string rootProjectPath, string historyFilePath, ILogger logger, ProjectFileReader projectFileReader) { if (string.IsNullOrEmpty(rootProjectPath)) { throw new ArgumentNullException("rootProjectPath"); } if (string.IsNullOrEmpty(historyFilePath)) { throw new ArgumentNullException("historyFilePath"); } if (logger == null) { throw new ArgumentNullException("logger"); } if (projectFileReader == null) { throw new ArgumentNullException("projectFileReader"); } this._rootProjectPath = rootProjectPath; this._historyFilePath = historyFilePath; this._projectFileReader = projectFileReader; this._logger = logger; }
/// <summary> /// Loads the internal state from the breadcrumb file passed to the ctor. /// </summary> /// <remarks> /// If the root project has been modified since the breadcrumb file /// was written, the entire cache is considered invalid and <c>false</c> is returned. /// If any cached project has been touched since the cache was last written, just /// is portion of the cache will be reloaded from the project file. /// </remarks> /// <returns>A <c>true</c> means the cache was loaded from the breadcrumb file successfully. /// If we detect the cache is out of date or does not exist, a <c>false</c> is returned. /// </returns> internal bool LoadCacheFromFile() { this.IsFileCacheCurrent = false; if (!File.Exists(this._historyFilePath)) { return(false); } // If the root project itself has been touched since the // time we wrote the file, we can't trust anything in our cache DateTime projectWriteTime = File.GetLastWriteTime(this._rootProjectPath); DateTime breadCrumbWriteTime = File.GetLastWriteTime(this._historyFilePath); if (projectWriteTime.CompareTo(breadCrumbWriteTime) > 0) { return(false); } // Read the breadcrumb file. // Format is: // One line per project: path, lastWriteTime, list of source files separated by commas string fileContents = File.ReadAllText(this._historyFilePath); string[] projectEntries = fileContents.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); foreach (string projectEntry in projectEntries) { string[] projectItems = projectEntry.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // Fewer than 2 is formatting problem -- maybe the file is corrupt. Just discard cache and rebuild. if (projectItems.Length < 2) { // Always clear out any partial results when returning false this.SourceFilesByProject.Clear(); return(false); } string projectPath = projectItems[0]; // If that project no longer exists, remove it from the cache but keep running if (!File.Exists(projectPath)) { continue; } List <string> files = new List <string>(); // Projects with no source files have only the first 2 items (name and timestamp). // Those will be added to our cache with an empty list to show that we know they // have no source files (otherwise, we would need to open them again to know). // Any project with some number of source files falls into the body of this 'if' if (projectItems.Length >= 3) { // Check whether the project file was touched since the last time // we analyzed it. Failure to parse last write time or discovery // the project has been touched more recently causes us to reload // just that project. Incidentally, the use of Ticks here is more // reliable than DateTime.ToString() which does not round-trip accurately. projectWriteTime = File.GetLastWriteTime(projectPath); long breadCrumbWriteTimeTicks = 0; if (!long.TryParse(projectItems[1], out breadCrumbWriteTimeTicks) || projectWriteTime.Ticks > breadCrumbWriteTimeTicks) { // Go load from the project file and ignore what we had cached files.AddRange(this._projectFileReader.LoadSourceFilesFromProject(projectPath)); } else { // The last write time shows the project has not changed since // we cached the results, so extract them from the text for (int i = 2; i < projectItems.Length; ++i) { string file = projectItems[i]; if (string.IsNullOrEmpty(file)) { continue; } // We write relative paths, so convert back to full string fullFilePath = ProjectFileReader.ConvertToFullPath(file, projectPath); // If the file has ceased to exist, but the project says it // does, we do not add it to our internal lists if (File.Exists(fullFilePath)) { files.Add(fullFilePath); } } } } this[projectPath] = files; } this.IsFileCacheCurrent = true; return(true); }
public void ProjectSourceFileCache_Loads_Real_Project() { string projectPath = null; string outputPath = null; TestHelper.GetProjectPaths("SSFC", out projectPath, out outputPath); string serverProjectPath = CodeGenHelper.ServerClassLibProjectPath(projectPath); string breadCrumbFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt"); ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { try { // Instantiate the cache. ProjectSourceFileCache cache = new ProjectSourceFileCache(serverProjectPath, breadCrumbFile, logger, projectFileReader); // Initially, it will not have loaded anything Assert.AreEqual(0, cache.SourceFilesByProject.Count); // ------------------------------------------------------------- // Validate cache is loaded correctly from .csproj files // ------------------------------------------------------------- this.ValidateProjectSourceFileCache(cache, projectPath); // Ask to write out the breadcrumb file Assert.IsFalse(File.Exists(breadCrumbFile)); bool success = cache.SaveCacheToFile(); Assert.IsTrue(success); Assert.IsTrue(File.Exists(breadCrumbFile)); // Clear the cache and force it to read from breadcrumb cache.SourceFilesByProject.Clear(); success = cache.LoadCacheFromFile(); Assert.IsTrue(success, "Failed to load from breadCrumb file"); Assert.IsTrue(cache.IsFileCacheCurrent, "Loading from file should have marked cache as current with file."); // ------------------------------------------------------------- // Validate cache is loaded correctly from breadcrumb file // ------------------------------------------------------------- this.ValidateProjectSourceFileCache(cache, projectPath); // Now mark the breadcrumb file as if it had been written before the ServerClassLib project cache.SourceFilesByProject.Clear(); DateTime serverLastWriteTime = File.GetLastWriteTime(serverProjectPath); DateTime beforeServerLastWriteTime = new DateTime(serverLastWriteTime.Ticks - 1000); File.SetLastWriteTime(breadCrumbFile, beforeServerLastWriteTime); // ------------------------------------------------------------- // Validate cache is *not* loaded if timestamp is before project's // ------------------------------------------------------------- success = cache.LoadCacheFromFile(); Assert.IsFalse(success, "Expected breadCrumbFile time stamp to be caught and reject load"); Assert.IsFalse(cache.IsFileCacheCurrent, "Failed load from file should have marked cache as *not* current with file."); // Cache should still be empty Assert.AreEqual(0, cache.SourceFilesByProject.Count); // ------------------------------------------------------------- // Validate cache loaded in presence of out-of-date breadcrumb // file loads correctly // ------------------------------------------------------------- this.ValidateProjectSourceFileCache(cache, projectPath); Assert.IsFalse(cache.IsFileCacheCurrent, "Loading from project should have marked cache as *not* current with file."); } finally { if (File.Exists(breadCrumbFile)) File.Delete(breadCrumbFile); } } }
public void ProjectSourceFileCache_Failed_BreadCrumb_Save_Warns() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string projectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj"); string breadCrumbPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt"); string csFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".cs"); // Need file on disk only for timestamp File.WriteAllText(projectPath, "neener neener"); File.WriteAllText(breadCrumbPath, "bread crumbs"); File.WriteAllText(csFile, "//"); try { ProjectSourceFileCache cache = new ProjectSourceFileCache(projectPath, breadCrumbPath, logger, projectFileReader); cache.SourceFilesByProject[projectPath] = new string[] { csFile }; // Setup for failure File.SetAttributes(breadCrumbPath, FileAttributes.ReadOnly); // Ask to write to readonly file -- should fail cache.SaveCacheToFile(); // Simulate the exception so we get the exact text string warningMessage = null; try { // this should fail File.WriteAllText(breadCrumbPath, "stuff"); } catch (UnauthorizedAccessException uae) { warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Write_File, breadCrumbPath, uae.Message); } TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage }); } finally { File.Delete(projectPath); File.SetAttributes(breadCrumbPath, File.GetAttributes(breadCrumbPath) & ~FileAttributes.ReadOnly); File.Delete(breadCrumbPath); File.Delete(csFile); } } }
public void LinkedServerProjectCache_LoadAndSaveFile() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { string historyFile = this.CreateMockHistoryFile(); string projectFile = this.CreateMockProjectFile(); string p1 = this.CreateMockProjectFile(); string p2 = this.CreateMockProjectFile(); string p3 = this.CreateMockProjectFile(); string p4 = this.CreateMockProjectFile(); string w1 = this.CreateMockProjectFile(); string w3 = this.CreateMockProjectFile(); LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); cache[p1] = w1; cache[p2] = null; cache[p3] = w3; cache[p4] = string.Empty; Assert.IsFalse(cache.IsFileCacheCurrent, "expected file cache not to be current after set some properties"); try { // Save to the cache and verify side effects of that bool success = cache.SaveCacheToFile(); Assert.IsTrue(success, "Expected successful save of cache to history file"); Assert.IsTrue(File.Exists(historyFile), "Expected history file " + historyFile + " to have been written"); Assert.IsTrue(cache.IsFileCacheCurrent, "Expected cache to be considered current"); // zap our cache and read back in from file cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); // The following methods and properties will lazy load the cache Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache"); List <string> projectRefs = cache.ProjectReferences.ToList(); Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache"); Assert.IsTrue(projectRefs.Contains(p1), "expected p1 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains(p2), "expected p2 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains(p3), "expected p3 to be in list of project refs"); Assert.IsTrue(projectRefs.Contains(p4), "expected p4 to be in list of project refs"); List <string> riaLinks = cache.LinkedServerProjects.ToList(); Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links"); Assert.IsTrue(riaLinks.Contains(w1), "expected w1 to be in list of RIA links"); Assert.IsTrue(riaLinks.Contains(w3), "expected w3 to be in list of RIA links"); } finally { File.Delete(historyFile); File.Delete(projectFile); File.Delete(p1); File.Delete(p2); File.Delete(p3); File.Delete(p4); File.Delete(w1); File.Delete(w3); } } }
public void ProjectSourceFileCache_AllKnownProjects() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { ProjectSourceFileCache cache = new ProjectSourceFileCache("proj", "breadCrumb", logger, projectFileReader); cache["p1"] = new string[] { "a", "b" }; cache["p2"] = new string[] { "c" }; IEnumerable<string> projects = cache.GetAllKnownProjects(); Assert.IsNotNull(projects); Assert.AreEqual(2, projects.Count()); Assert.IsTrue(projects.Contains("p1")); Assert.IsTrue(projects.Contains("p2")); } }
public void LinkedServerProjectCache_Load_Real_Project() { ConsoleLogger logger = new ConsoleLogger(); using (ProjectFileReader projectFileReader = new ProjectFileReader(logger)) { // We will create valid MSBuild projects with this shape: // - projectFile: contains 3 project references // - 2 of the 3 projects referenced point to unique RIA Link server project // - 1 of the 3 projects references points to the same RIA Link project as another // (this tests the ability of our model to handle multiple clients pointing to the same server) string serverProject1 = this.CreateMockProjectFile(); string serverProject2 = this.CreateMockProjectFile(); string refProject1Contents = string.Format(@" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <PropertyGroup> <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject> </PropertyGroup> </Project>", serverProject1); string refProject2Contents = string.Format(@" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <PropertyGroup> <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject> </PropertyGroup> </Project>", serverProject2); string refProject1 = this.CreateTempFile("csproj", refProject1Contents); string refProject2 = this.CreateTempFile("csproj", refProject2Contents); string refProject3 = this.CreateTempFile("csproj", refProject2Contents); string projectContents = string.Format(@" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> <ItemGroup> <ProjectReference Include=""{0}""></ProjectReference> <ProjectReference Include=""{1}""></ProjectReference> <ProjectReference Include=""{2}""></ProjectReference> </ItemGroup> </Project>", refProject1, refProject2, refProject3); string projectFile = this.CreateTempFile("csproj", projectContents); string historyFile = this.CreateTempFile("txt", null); // <-- null prevents us from creating file on disk try { LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader); // Validate we see our 3 project references List <string> projectRefs = cache.ProjectReferences.ToList(); Assert.AreEqual(3, projectRefs.Count, "Expected this many project references"); Assert.IsTrue(projectRefs.Contains(refProject1), "Expected ref project 1 in project references."); Assert.IsTrue(projectRefs.Contains(refProject2), "Expected ref project 2 in project references."); Assert.IsTrue(projectRefs.Contains(refProject3), "Expected ref project 3 in project references."); // Validate that we extracted the RIA Links for those project references List <string> riaLinks = cache.LinkedServerProjects.ToList(); Assert.AreEqual(2, riaLinks.Count, "Expected to find 2 RIA links"); Assert.IsTrue(riaLinks.Contains(serverProject1), "Expected server project 1 RIA link"); Assert.IsTrue(riaLinks.Contains(serverProject2), "Expected server project 2 RIA link"); // Validate that we can ask for the source of each RIA Link target List <string> sources = cache.GetLinkedServerProjectSources(serverProject1).ToList(); Assert.AreEqual(1, sources.Count, "Expected 1 source to for RIA link to server project 1"); Assert.IsTrue(sources.Contains(refProject1), "Expected refProject 1 to be shown as RIA Link source 1"); sources = cache.GetLinkedServerProjectSources(serverProject2).ToList(); Assert.AreEqual(2, sources.Count, "Expected 2 sources to for RIA link to server project 2"); Assert.IsTrue(sources.Contains(refProject2), "Expected refProject 2 to be shown as RIA Link source 2"); Assert.IsTrue(sources.Contains(refProject3), "Expected refProject 2 to be shown as RIA Link source 2"); } finally { File.Delete(projectFile); File.Delete(historyFile); File.Delete(refProject1); File.Delete(refProject2); File.Delete(refProject3); File.Delete(serverProject1); File.Delete(serverProject2); } } }