/// <summary> /// This method takes in a list of file name extensions to ignore. It will then validate the extensions /// to make sure they start with a period, have atleast one character after the period and do not contain /// any invalid path chars or wild cards /// </summary> /// <param name="projectsExtensionsToIgnore"></param> /// <returns></returns> private static Dictionary <string, object> ValidateExtensions(string[] projectsExtensionsToIgnore) { // Dictionary to contain the list of files which match the extensions to ignore. We are using a dictionary for fast lookups of extensions to ignore Dictionary <string, object> extensionsToIgnoreDictionary = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); // Go through each of the extensions to ignore and add them as a key in the dictionary if (projectsExtensionsToIgnore != null && projectsExtensionsToIgnore.Length > 0) { string extension = null; foreach (string extensionToIgnore in projectsExtensionsToIgnore) { // Use the path get extension method to figure out if there is an extension in the passed // in extension to ignore. Will return null or empty if there is no extension in the string try { // Use GetExtension to parse the extension from the extensionToIgnore extension = Path.GetExtension(extensionToIgnore); } catch (ArgumentException) { // There has been an invalid char in the extensionToIgnore InitializationException.Throw("InvalidExtensionToIgnore", extensionToIgnore, null, false); } // if null or empty is returned that means that there was not extension able to be parsed from the string InitializationException.VerifyThrow(!string.IsNullOrEmpty(extension), "InvalidExtensionToIgnore", extensionToIgnore); // There has to be more than a . passed in as the extension InitializationException.VerifyThrow(extension.Length >= 2, "InvalidExtensionToIgnore", extensionToIgnore); // The parsed extension does not match the passed in extension, this means that there were // some other chars before the last extension if (string.Compare(extension, extensionToIgnore, StringComparison.OrdinalIgnoreCase) != 0) { InitializationException.Throw("InvalidExtensionToIgnore", extensionToIgnore, null, false); } // Make sure that no wild cards are in the string because for now we dont allow wild card extensions if (extensionToIgnore.IndexOfAny(s_wildcards) > -1) { InitializationException.Throw("InvalidExtensionToIgnore", extensionToIgnore, null, false); } ; if (!extensionsToIgnoreDictionary.ContainsKey(extensionToIgnore)) { extensionsToIgnoreDictionary.Add(extensionToIgnore, null); } } } return(extensionsToIgnoreDictionary); }
internal static string ProcessProjectSwitch ( string[] parameters, string[] projectsExtensionsToIgnore, DirectoryGetFiles getFiles ) { ErrorUtilities.VerifyThrow(parameters.Length <= 1, "It should not be possible to specify more than 1 project at a time."); string projectFile = null; string projectDirectory = null; if (parameters.Length == 1) { projectFile = FileUtilities.FixFilePath(parameters[0]); if (Directory.Exists(projectFile)) { // If the project file is actually a directory then change the directory to be searched // and null out the project file projectDirectory = projectFile; projectFile = null; } else { InitializationException.VerifyThrow(File.Exists(projectFile), "ProjectNotFoundError", projectFile); } } // We need to look in a directory for a project file... if (projectFile == null) { // Get all files in the current directory that have a proj-like extension string[] potentialProjectFiles = getFiles(projectDirectory ?? ".", "*.*proj"); // Get all files in the current directory that have a sln extension string[] potentialSolutionFiles = getFiles(projectDirectory ?? ".", "*.sln"); List <string> extensionsToIgnore = new List <string>(); if (projectsExtensionsToIgnore != null) { extensionsToIgnore.AddRange(projectsExtensionsToIgnore); } if (potentialProjectFiles != null) { foreach (string s in potentialProjectFiles) { if (s.EndsWith("~", StringComparison.CurrentCultureIgnoreCase)) { extensionsToIgnore.Add(Path.GetExtension(s)); } } } if (potentialSolutionFiles != null) { foreach (string s in potentialSolutionFiles) { if (!FileUtilities.IsSolutionFilename(s)) { extensionsToIgnore.Add(Path.GetExtension(s)); } } } Dictionary <string, object> extensionsToIgnoreDictionary = ValidateExtensions(extensionsToIgnore.ToArray()); // Remove projects that are in the projectExtensionsToIgnore List // If we have no extensions to ignore we can skip removing any extensions if (extensionsToIgnoreDictionary.Count > 0) { // No point removing extensions if we have no project files if (potentialProjectFiles != null && potentialProjectFiles.Length > 0) { potentialProjectFiles = RemoveFilesWithExtensionsToIgnore(potentialProjectFiles, extensionsToIgnoreDictionary); } // No point removing extensions if we have no solutions if (potentialSolutionFiles != null && potentialSolutionFiles.Length > 0) { potentialSolutionFiles = RemoveFilesWithExtensionsToIgnore(potentialSolutionFiles, extensionsToIgnoreDictionary); } } // If there is exactly 1 project file and exactly 1 solution file if ((potentialProjectFiles.Length == 1) && (potentialSolutionFiles.Length == 1)) { // Grab the name of both project and solution without extensions string solutionName = Path.GetFileNameWithoutExtension(potentialSolutionFiles[0]); string projectName = Path.GetFileNameWithoutExtension(potentialProjectFiles[0]); // Compare the names and error if they are not identical InitializationException.VerifyThrow(String.Compare(solutionName, projectName, StringComparison.OrdinalIgnoreCase) == 0, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory); } // If there is more than one solution file in the current directory we have no idea which one to use else if (potentialSolutionFiles.Length > 1) { InitializationException.VerifyThrow(false, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory); } // If there is more than one project file in the current directory we may be able to figure it out else if (potentialProjectFiles.Length > 1) { // We have more than one project, it is ambiguous at the moment bool isAmbiguousProject = true; // If there are exactly two projects and one of them is a .proj use that one and ignore the other if (potentialProjectFiles.Length == 2) { string firstPotentialProjectExtension = Path.GetExtension(potentialProjectFiles[0]); string secondPotentialProjectExtension = Path.GetExtension(potentialProjectFiles[1]); // If the two projects have the same extension we can't decide which one to pick if (String.Compare(firstPotentialProjectExtension, secondPotentialProjectExtension, StringComparison.OrdinalIgnoreCase) != 0) { // Check to see if the first project is the proj, if it is use it if (String.Compare(firstPotentialProjectExtension, ".proj", StringComparison.OrdinalIgnoreCase) == 0) { potentialProjectFiles = new string[] { potentialProjectFiles[0] }; // We have made a decision isAmbiguousProject = false; } // If the first project is not the proj check to see if the second one is the proj, if so use it else if (String.Compare(secondPotentialProjectExtension, ".proj", StringComparison.OrdinalIgnoreCase) == 0) { potentialProjectFiles = new string[] { potentialProjectFiles[1] }; // We have made a decision isAmbiguousProject = false; } } } InitializationException.VerifyThrow(!isAmbiguousProject, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory); } // if there are no project or solution files in the directory, we can't build else if ((potentialProjectFiles.Length == 0) && (potentialSolutionFiles.Length == 0)) { InitializationException.VerifyThrow(false, "MissingProjectError"); } // We are down to only one project or solution. // If only 1 solution build the solution. If only 1 project build the project // If 1 solution and 1 project and they are of the same name build the solution projectFile = (potentialSolutionFiles.Length == 1) ? potentialSolutionFiles[0] : potentialProjectFiles[0]; } return(projectFile); }