public AmmyProject(IReadOnlyList <string> referenceAssemblies, IReadOnlyList <AmmyFileMeta> ammyFiles, CSharpProject csharpProject, object compilationData, string projectDir, string outputPath, string rootNamespace, string assemblyName, string targetPath) { _cts = new CancellationTokenSource(); CSharpProject = csharpProject; TargetPath = targetPath; References = referenceAssemblies.Distinct() .SelectMany(path => new[] { new FileLibReference(path) }) .ToList(); FsProject = new FsProject <Top>(new FsSolution <Top>(), projectDir, References) { Data = compilationData }; Files = ammyFiles.SelectMany((meta, index) => { if (!System.IO.File.Exists(meta.Filename)) { MissingFiles.Add(meta.Filename); return(new AmmyFile <Top> [0]); } // If file is not cached by VS extension create new if (meta.File == null) { meta.File = new AmmyFile <Top>(index, meta, AmmyLanguage, projectDir, FsProject); } else { FsProject.FsFiles.Add(meta.File); } return(new[] { meta.File }); }).ToList(); OutputPath = outputPath; RootNamespace = rootNamespace; AssemblyName = assemblyName; ProjectSupport = (Start)FsProject.GetProjectSupport(); if (ProjectSupport != null) { Platform = ProjectSupport.Platform = GetCompatiblePlatform(); } }
// --- functions --- /// <summary>Reports a problem to the host application.</summary> /// <param name="type">The type of problem that is reported.</param> /// <param name="text">The textual message that describes the problem.</param> public override void ReportProblem(ProblemType type, string text) { switch (type) { case ProblemType.DirectoryNotFound: case ProblemType.FileNotFound: case ProblemType.PathNotFound: if (!MissingFiles.Contains(text)) { Interface.AddMessage(MessageType.Error, true, type + " : " + text); MissingFiles.Add(text); } break; default: Interface.AddMessage(MessageType.Error, false, type + " : " + text); break; } }
protected void UpdateRecursive( DirectoryInfo currentDirectoryInfo, ManifestDirectoryInfo currentManfestDirInfo) { // Setup data for current directory Dictionary <String, FileInfo> fileDict = new Dictionary <string, FileInfo>(); Dictionary <String, DirectoryInfo> dirDict = new Dictionary <string, DirectoryInfo>(); if (currentDirectoryInfo != null) { FileInfo[] fileList = null; try { fileList = currentDirectoryInfo.GetFiles(); } catch (Exception) { WriteLine(Manifest.MakeStandardPathString( currentManfestDirInfo)); if (IgnoreFile(Manifest.MakeStandardPathString( currentManfestDirInfo)) == true) { // This was implemented primarily to allow the user to // silence the process of skipping over inaccessible // system directories by ignoring them. For example, // in some cases the "$RECYCLE BIN" under Windows // is not accessible and will generate an error. The // user can now add such directories to the ignore list // and they will be silently ignored. The special // message for showProgress alerts the user that the // directory is actually being skipped altogether // since it can't be accessed. The only significant // implication of this is that the ignored files won't // be enumerated and counted as being ignored. if (ShowProgress) { WriteLine( Manifest.MakeStandardPathString(currentManfestDirInfo) + " [IGNORED DIRECTORY AND CANNOT ACCESS]"); } } else { ForceWriteLine("Could not access contents of: " + currentDirectoryInfo.FullName); } return; } foreach (FileInfo nextFileInfo in fileList) { fileDict.Add(nextFileInfo.Name.Normalize(), nextFileInfo); } DirectoryInfo[] dirList = currentDirectoryInfo.GetDirectories(); foreach (DirectoryInfo nextDirInfo in dirList) { dirDict.Add(nextDirInfo.Name.Normalize(), nextDirInfo); } } // Clone in case we modify during iteration List <ManifestFileInfo> fileListClone = new List <ManifestFileInfo>(currentManfestDirInfo.Files.Values); // Iterate through existing manifest entries foreach (ManifestFileInfo nextManFileInfo in fileListClone) { if (ShowProgress) { Write(Manifest.MakeStandardPathString(nextManFileInfo)); } if (fileDict.ContainsKey(nextManFileInfo.Name)) { FileCheckedCount++; FileInfo nextFileInfo = fileDict[nextManFileInfo.Name]; if (IgnoreFile(Manifest.MakeStandardPathString(nextManFileInfo))) { Write(" [NEWLY IGNORED]"); currentManfestDirInfo.Files.Remove( nextManFileInfo.Name); NewlyIgnoredFiles.Add(nextManFileInfo); } else if (nextFileInfo.Length != nextManFileInfo.FileLength && Update == false && AlwaysCheckHash == false) { // Don't compute hash if we aren't doing an update Write(" [DIFFERENT]"); ChangedFiles.Add(nextManFileInfo); } else if (AlwaysCheckHash == true || MakeNewHash == true || nextManFileInfo.FileHash == null || Manifest.CompareManifestDateToFilesystemDate(nextFileInfo.LastWriteTimeUtc, nextManFileInfo.LastModifiedUtc) == false || nextFileInfo.Length != nextManFileInfo.FileLength) { FileHash checkHash = null; Exception exception = null; try { string hashType = Manifest.DefaultHashMethod; if (nextManFileInfo.FileHash != null) { hashType = nextManFileInfo.FileHash.HashType; } checkHash = FileHash.ComputeHash( nextFileInfo, hashType); } catch (Exception ex) { exception = ex; } if (exception != null) { WriteLine(" [ERROR]"); WriteLine(exception.ToString()); ErrorFiles.Add(nextManFileInfo); } else { if (nextManFileInfo.FileHash == null) { Write(" [NULL HASH IN MANIFEST]"); ChangedFiles.Add(nextManFileInfo); } else if (checkHash.Equals(nextManFileInfo.FileHash) == false) { Write(" [DIFFERENT]"); ChangedFiles.Add(nextManFileInfo); } else { if (Manifest.CompareManifestDateToFilesystemDate( nextFileInfo.LastWriteTimeUtc, nextManFileInfo.LastModifiedUtc) == false) { Write(" [LAST MODIFIED DATE]"); LastModifiedDateFiles.Add(nextManFileInfo); if (BackDate == true) { nextFileInfo.LastWriteTimeUtc = nextManFileInfo.LastModifiedUtc; } } } } FileHash newHash = checkHash; if (MakeNewHash) { newHash = FileHash.ComputeHash( nextFileInfo, GetNewHashType(Manifest)); } // Update hash and last modified date accordingly nextManFileInfo.FileHash = newHash; nextManFileInfo.LastModifiedUtc = nextFileInfo.LastWriteTimeUtc; nextManFileInfo.FileLength = nextFileInfo.Length; } else { Write(" [SKIPPED]"); } } else { Write(" [MISSING]"); currentManfestDirInfo.Files.Remove(nextManFileInfo.Name); MissingFiles.Add(nextManFileInfo); } WriteLine(""); } // Clone in case we modify during iteration List <ManifestDirectoryInfo> directoryListClone = new List <ManifestDirectoryInfo>( currentManfestDirInfo.Subdirectories.Values); foreach (ManifestDirectoryInfo nextManDirInfo in directoryListClone) { DirectoryInfo nextDirInfo = null; if (dirDict.ContainsKey(nextManDirInfo.Name)) { nextDirInfo = dirDict[nextManDirInfo.Name]; } UpdateRecursive( nextDirInfo, nextManDirInfo); if (nextManDirInfo.Empty) { currentManfestDirInfo.Subdirectories.Remove( nextManDirInfo.Name); } } // Look for new files foreach (String nextFileName in fileDict.Keys) { FileInfo nextFileInfo = fileDict[nextFileName]; if (currentManfestDirInfo.Files.ContainsKey( nextFileName) == false) { ManifestFileInfo newManFileInfo = new ManifestFileInfo( nextFileName, currentManfestDirInfo); Write(Manifest.MakeStandardPathString(newManFileInfo)); if (IgnoreFile(Manifest.MakeStandardPathString(newManFileInfo))) { IgnoredFiles.Add(newManFileInfo); // Don't groom the manifest file! if (Manifest.MakeNativePathString(newManFileInfo) != ManifestNativeFilePath) { IgnoredFilesForGroom.Add(nextFileInfo); } Write(" [IGNORED]"); } else { FileCheckedCount++; bool checkHash = false; if (Update == true || AlwaysCheckHash == true || TrackMoves == true) { checkHash = true; } Exception exception = null; if (checkHash) { try { newManFileInfo.FileHash = FileHash.ComputeHash( nextFileInfo, GetNewHashType(Manifest)); } catch (Exception ex) { exception = ex; } } if (checkHash && newManFileInfo.FileHash == null) { ErrorFiles.Add(newManFileInfo); WriteLine(" [ERROR]"); WriteLine(exception.ToString()); } else { NewFiles.Add(newManFileInfo); NewFilesForGroom.Add(nextFileInfo); Write(" [NEW]"); } newManFileInfo.FileLength = nextFileInfo.Length; newManFileInfo.LastModifiedUtc = nextFileInfo.LastWriteTimeUtc; newManFileInfo.RegisteredUtc = DateTime.Now.ToUniversalTime(); currentManfestDirInfo.Files.Add( nextFileName, newManFileInfo); } WriteLine(""); } } // Recurse looking for new directories foreach (String nextDirName in dirDict.Keys) { DirectoryInfo nextDirInfo = dirDict[nextDirName]; if (currentManfestDirInfo.Subdirectories.ContainsKey( nextDirName) == false) { ManifestDirectoryInfo nextManDirInfo = new ManifestDirectoryInfo( nextDirName, currentManfestDirInfo); currentManfestDirInfo.Subdirectories.Add( nextDirName, nextManDirInfo); UpdateRecursive( nextDirInfo, nextManDirInfo); if (nextManDirInfo.Empty) { currentManfestDirInfo.Subdirectories.Remove( nextDirName); } } } }
/// <summary> /// Returns FileScans that are not consistent with the FileList /// </summary> /// <returns></returns> public List <FileScan> Scan() { int listCount = FileList.Count; List <FileScan> scanResults = ScanDirectory(DirectoryToMonitor); List <FileScan> outOfDateResults = new List <FileScan>(scanResults.Count); bool[] accountedFor = new bool[listCount]; for (int i = 0; i < listCount; i++) { accountedFor[i] = false; } // Find all out of date and deleted files int index; for (int i = 0; i < scanResults.Count; i++) { FileScan scanResult = scanResults[i]; index = FindInList(scanResult.FileName); if (index < 0) { outOfDateResults.Add(scanResult); } else if (LazyMode) { if (FileList[index].ProcessedBytes < scanResult.Bytes || FileList[index].Bytes != scanResult.Bytes || FileList[index].TimeOfModification != scanResult.TimeOfModification) { scanResult.ProcessedBytes = FileList[index].ProcessedBytes; outOfDateResults.Add(scanResult); accountedFor[index] = true; } else { accountedFor[index] = true; } } else { if (FileList[index].ProcessedBytes < scanResult.Bytes || FileList[index].Hash != scanResult.Hash) { scanResult.ProcessedBytes = FileList[index].ProcessedBytes; outOfDateResults.Add(scanResult); accountedFor[index] = true; } else { accountedFor[index] = true; } } } MissingFiles.Clear(); for (int i = 0; i < listCount; i++) { if (!accountedFor[i]) { MissingFiles.Add(FileList[i]); } } return(outOfDateResults); }
protected override void Analyze(string fileName, ExceptionHandler exceptionHandler) { ProjectFilename = fileName; //var path = ProjectPath; foreach (var item in Items) { try { var propertyGroup = item as PropertyGroup; if (propertyGroup != null) { var assembly = propertyGroup.AssemblyName; if (assembly != null) { Assemblies.Add(new VsAssemblyInfo(propertyGroup)); } if (!string.IsNullOrWhiteSpace(propertyGroup.TargetFrameworkVersion)) { TargetFrameworkVersion = propertyGroup.TargetFrameworkVersion; } continue; } var itemGroup = item as ItemGroup; if (itemGroup != null) { if (itemGroup?.Reference != null) { foreach (var reference in itemGroup.Reference) { var r = VsAssemblyInfo.CreateIfValid(reference, this); if (r != null) { References.Add(r); } } } SourceFiles.AddRange(itemGroup.SourceFiles(this)); } } catch (Exception exc) { if (exceptionHandler != null) { exceptionHandler(null, exc); } else { throw; } } } base.Analyze(fileName, exceptionHandler); foreach (var r in References) { if (!r.Exists) { if (!string.IsNullOrWhiteSpace(r.Path)) { MissingFiles.Add(new ProjectFile(r.Name, ResourceType.Reference, r.Path)); } else { MissingFiles.Add(new ProjectFile(r.Name, ResourceType.Reference, this)); } } } }