/// <summary> /// Identifies/detects a switch that takes no parameters. /// </summary> internal static bool IsParameterlessSwitch ( string switchName ) { ParameterlessSwitch parameterlessSwitch; string duplicateSwitchErrorMessage; return CommandLineSwitches.IsParameterlessSwitch(switchName, out parameterlessSwitch, out duplicateSwitchErrorMessage); }
public void GatherCommandLineSwitchesTwoProperties() { CommandLineSwitches switches = new CommandLineSwitches(); ArrayList arguments = new ArrayList(); arguments.AddRange(new string[] { "/p:a=b", "/p:c=d" }); MSBuildApp.GatherCommandLineSwitches(arguments, switches); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.Property]; Assert.Equal("a=b", parameters[0]); Assert.Equal("c=d", parameters[1]); }
public void GatherCommandLineSwitchesMaxCpuCountWithoutArgumentButWithColon() { CommandLineSwitches switches = new CommandLineSwitches(); ArrayList arguments = new ArrayList(); arguments.AddRange(new string[] { "/m:" }); MSBuildApp.GatherCommandLineSwitches(arguments, switches); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.MaxCPUCount]; Assert.Equal(0, parameters.Length); Assert.True(switches.HaveErrors()); }
public void GatherCommandLineSwitchesMaxCpuCountWithoutArgument() { CommandLineSwitches switches = new CommandLineSwitches(); ArrayList arguments = new ArrayList(); arguments.AddRange(new string[] { "/m:3", "/m" }); MSBuildApp.GatherCommandLineSwitches(arguments, switches); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.MaxCPUCount]; Assert.Equal(Convert.ToString(Environment.ProcessorCount), parameters[1]); Assert.Equal(2, parameters.Length); Assert.Equal(false, switches.HaveErrors()); }
public void GatherCommandLineSwitchesMaxCpuCountWithArgument() { CommandLineSwitches switches = new CommandLineSwitches(); ArrayList arguments = new ArrayList(); arguments.AddRange(new string[] { "/m:2" }); MSBuildApp.GatherCommandLineSwitches(arguments, switches); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.MaxCPUCount]; Assert.Equal("2", parameters[0]); Assert.Equal(1, parameters.Length); Assert.Equal(false, switches.HaveErrors()); }
internal void Append(CommandLineSwitches switchesToAppend) { if (!this.HaveErrors() && switchesToAppend.HaveErrors()) { this.errorMessage = switchesToAppend.errorMessage; this.badCommandLineArg = switchesToAppend.badCommandLineArg; this.innerException = switchesToAppend.innerException; this.isParameterError = switchesToAppend.isParameterError; } for (int i = 0; i < 0x13; i++) { if (switchesToAppend.IsParameterlessSwitchSet((ParameterlessSwitch)i)) { if (!this.IsParameterlessSwitchSet((ParameterlessSwitch)i) || (parameterlessSwitchesMap[i].duplicateSwitchErrorMessage == null)) { this.parameterlessSwitches[i].commandLineArg = switchesToAppend.parameterlessSwitches[i].commandLineArg; } else { this.SetSwitchError(parameterlessSwitchesMap[i].duplicateSwitchErrorMessage, switchesToAppend.GetParameterlessSwitchCommandLineArg((ParameterlessSwitch)i)); } } } for (int j = 0; j < 0x18; j++) { if (switchesToAppend.IsParameterizedSwitchSet((ParameterizedSwitch)j)) { if (!this.IsParameterizedSwitchSet((ParameterizedSwitch)j) || (parameterizedSwitchesMap[j].duplicateSwitchErrorMessage == null)) { if (this.parameterizedSwitches[j].commandLineArg == null) { this.parameterizedSwitches[j].parameters = new ArrayList(); } this.parameterizedSwitches[j].commandLineArg = switchesToAppend.parameterizedSwitches[j].commandLineArg; this.parameterizedSwitches[j].parameters.AddRange(switchesToAppend.parameterizedSwitches[j].parameters); } else { this.SetSwitchError(parameterizedSwitchesMap[j].duplicateSwitchErrorMessage, switchesToAppend.GetParameterizedSwitchCommandLineArg((ParameterizedSwitch)j)); } } } }
public void AppendErrorTests1() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); CommandLineSwitches switchesRight = new CommandLineSwitches(); Assert.False(switchesLeft.HaveErrors()); Assert.False(switchesRight.HaveErrors()); switchesLeft.Append(switchesRight); Assert.False(switchesLeft.HaveErrors()); Assert.False(switchesRight.HaveErrors()); switchesLeft.SetUnknownSwitchError("/bogus"); Assert.True(switchesLeft.HaveErrors()); Assert.False(switchesRight.HaveErrors()); switchesLeft.Append(switchesRight); Assert.True(switchesLeft.HaveErrors()); Assert.False(switchesRight.HaveErrors()); VerifySwitchError(switchesLeft, "/bogus"); switchesRight.Append(switchesLeft); Assert.True(switchesLeft.HaveErrors()); Assert.True(switchesRight.HaveErrors()); VerifySwitchError(switchesLeft, "/bogus"); VerifySwitchError(switchesRight, "/bogus"); }
/// <summary> /// Appends the given collection of command-line switches to this one. /// </summary> /// <remarks> /// Command-line switches have left-to-right precedence i.e. switches on the right override switches on the left. As a /// result, this "append" operation is also performed in a left-to-right manner -- the switches being appended to are /// considered to be on the "left", and the switches being appended are on the "right". /// </remarks> /// <param name="switchesToAppend"></param> internal void Append(CommandLineSwitches switchesToAppend) { // if this collection doesn't already have an error registered, but the collection being appended does if (!HaveErrors() && switchesToAppend.HaveErrors()) { // register the error from the given collection // NOTE: we always store the first error found (parsing left-to-right), and since this collection is considered to // be on the "left" of the collection being appended, the error flagged in this collection takes priority over the // error in the collection being appended _errorMessage = switchesToAppend._errorMessage; _badCommandLineArg = switchesToAppend._badCommandLineArg; _innerException = switchesToAppend._innerException; _isParameterError = switchesToAppend._isParameterError; } // NOTE: we might run into some duplicate switch errors below, but if we've already registered the error from the // collection being appended, all the duplicate switch errors will be ignored; this is fine because we really have no // way of telling which error would occur first in the left-to-right order without keeping track of a lot more error // information -- so we play it safe, and register the guaranteed error // append the parameterless switches with left-to-right precedence, flagging duplicate switches as necessary for (int i = 0; i < (int)ParameterlessSwitch.NumberOfParameterlessSwitches; i++) { if (switchesToAppend.IsParameterlessSwitchSet((ParameterlessSwitch)i)) { if (!IsParameterlessSwitchSet((ParameterlessSwitch)i) || (s_parameterlessSwitchesMap[i].duplicateSwitchErrorMessage == null)) { _parameterlessSwitches[i].commandLineArg = switchesToAppend._parameterlessSwitches[i].commandLineArg; } else { SetSwitchError(s_parameterlessSwitchesMap[i].duplicateSwitchErrorMessage, switchesToAppend.GetParameterlessSwitchCommandLineArg((ParameterlessSwitch)i)); } } } // append the parameterized switches with left-to-right precedence, flagging duplicate switches as necessary for (int j = 0; j < (int)ParameterizedSwitch.NumberOfParameterizedSwitches; j++) { if (switchesToAppend.IsParameterizedSwitchSet((ParameterizedSwitch)j)) { if (!IsParameterizedSwitchSet((ParameterizedSwitch)j) || (s_parameterizedSwitchesMap[j].duplicateSwitchErrorMessage == null)) { if (_parameterizedSwitches[j].commandLineArg == null) { _parameterizedSwitches[j].parameters = new ArrayList(); } _parameterizedSwitches[j].commandLineArg = switchesToAppend._parameterizedSwitches[j].commandLineArg; _parameterizedSwitches[j].parameters.AddRange(switchesToAppend._parameterizedSwitches[j].parameters); } else { SetSwitchError(s_parameterizedSwitchesMap[j].duplicateSwitchErrorMessage, switchesToAppend.GetParameterizedSwitchCommandLineArg((ParameterizedSwitch)j)); } } } }
/// <summary> /// Coordinates the processing of all detected switches. It gathers information necessary to invoke the build engine, and /// performs deeper error checking on the switches and their parameters. /// </summary> /// <returns>true, if build can be invoked</returns> private static bool ProcessCommandLineSwitches ( CommandLineSwitches switchesFromAutoResponseFile, CommandLineSwitches switchesNotFromAutoResponseFile, ref string projectFile, ref string[] targets, ref string toolsVersion, ref Dictionary<string, string> globalProperties, ref ILogger[] loggers, ref LoggerVerbosity verbosity, ref List<DistributedLoggerRecord> distributedLoggerRecords, ref bool needToValidateProject, ref string schemaFile, ref int cpuCount, ref bool enableNodeReuse, ref TextWriter preprocessWriter, ref bool debugger, ref bool detailedSummary, bool recursing ) { bool invokeBuild = false; // combine the auto-response file switches with the command line switches in a left-to-right manner, where the // auto-response file switches are on the left (default options), and the command line switches are on the // right (overriding options) so that we consume switches in the following sequence of increasing priority: // (1) switches from the msbuild.rsp file/s, including recursively included response files // (2) switches from the command line, including recursively included response file switches inserted at the point they are declared with their "@" symbol CommandLineSwitches commandLineSwitches = new CommandLineSwitches(); commandLineSwitches.Append(switchesFromAutoResponseFile); // lowest precedence commandLineSwitches.Append(switchesNotFromAutoResponseFile); // show copyright message if nologo switch is not set // NOTE: we heed the nologo switch even if there are switch errors if (!recursing && !commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.NoLogo] && !commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Preprocess)) { DisplayCopyrightMessage(); } // if help switch is set (regardless of switch errors), show the help message and ignore the other switches if (commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.Help]) { ShowHelpMessage(); } else if (commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.NodeMode)) { StartLocalNode(commandLineSwitches); } else { // if help switch is not set, and errors were found, abort (don't process the remaining switches) commandLineSwitches.ThrowErrors(); // if version switch is set, just show the version and quit (ignore the other switches) if (commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.Version]) { ShowVersion(); } else { // figure out what project we are building projectFile = ProcessProjectSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Project], commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.IgnoreProjectExtensions], Directory.GetFiles); if (!recursing && !commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.NoAutoResponse]) { // gather any switches from an msbuild.rsp that is next to the project or solution file itself string projectDirectory = Path.GetDirectoryName(Path.GetFullPath(projectFile)); bool found = false; // Don't look for more response files if it's only in the same place we already looked (next to the exe) if (!String.Equals(projectDirectory, s_exePath, StringComparison.OrdinalIgnoreCase)) { // this combines any found, with higher precedence, with the switches from the original auto response file switches found = GatherAutoResponseFileSwitches(projectDirectory, switchesFromAutoResponseFile); } if (found) { // we presumably read in more switches, so start our switch processing all over again, // so that we consume switches in the following sequence of increasing priority: // (1) switches from the msbuild.rsp next to msbuild.exe, including recursively included response files // (2) switches from this msbuild.rsp next to the project or solution <<--------- these we have just now merged with (1) // (3) switches from the command line, including recursively included response file switches inserted at the point they are declared with their "@" symbol return ProcessCommandLineSwitches( switchesFromAutoResponseFile, switchesNotFromAutoResponseFile, ref projectFile, ref targets, ref toolsVersion, ref globalProperties, ref loggers, ref verbosity, ref distributedLoggerRecords, ref needToValidateProject, ref schemaFile, ref cpuCount, ref enableNodeReuse, ref preprocessWriter, ref debugger, ref detailedSummary, recursing: true ); } } // figure out which targets we are building targets = ProcessTargetSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Target]); // figure out which ToolsVersion has been set on the command line toolsVersion = ProcessToolsVersionSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.ToolsVersion]); // figure out which properties have been set on the command line globalProperties = ProcessPropertySwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Property]); // figure out if there was a max cpu count provided cpuCount = ProcessMaxCPUCountSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.MaxCPUCount]); // figure out if we shold reuse nodes enableNodeReuse = ProcessNodeReuseSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.NodeReuse]); // determine what if any writer to preprocess to preprocessWriter = null; if (commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Preprocess)) { preprocessWriter = ProcessPreprocessSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Preprocess]); } #if FEATURE_MSBUILD_DEBUGGER debugger = commandLineSwitches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Debugger); #endif detailedSummary = commandLineSwitches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.DetailedSummary); // figure out which loggers are going to listen to build events string[][] groupedFileLoggerParameters = commandLineSwitches.GetFileLoggerParameters(); loggers = ProcessLoggingSwitches( commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Logger], commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.DistributedLogger], commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Verbosity], commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger], commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.DistributedFileLogger], commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.FileLoggerParameters], // used by DistributedFileLogger commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.ConsoleLoggerParameters], groupedFileLoggerParameters, out distributedLoggerRecords, out verbosity, ref detailedSummary, cpuCount ); // If we picked up switches from the autoreponse file, let the user know. This could be a useful // hint to a user that does not know that we are picking up the file automatically. // Since this is going to happen often in normal use, only log it in high verbosity mode. // Also, only log it to the console; logging to loggers would involve increasing the public API of // the Engine, and we don't want to do that. if (usingSwitchesFromAutoResponseFile && LoggerVerbosity.Diagnostic == verbosity) { Console.WriteLine(ResourceUtilities.FormatResourceString("PickedUpSwitchesFromAutoResponse", autoResponseFileName)); } if (verbosity == LoggerVerbosity.Diagnostic) { string equivalentCommandLine = commandLineSwitches.GetEquivalentCommandLineExceptProjectFile(); Console.WriteLine(Path.Combine(s_exePath, s_exeName) + " " + equivalentCommandLine + " " + projectFile); } // figure out if the project needs to be validated against a schema needToValidateProject = commandLineSwitches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Validate); schemaFile = ProcessValidateSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.Validate]); invokeBuild = true; } } ErrorUtilities.VerifyThrow(!invokeBuild || !String.IsNullOrEmpty(projectFile), "We should have a project file if we're going to build."); return invokeBuild; }
/// <summary> /// Called when a switch that takes parameters is detected on the command line. This method flags errors and stores the /// switch parameters. /// </summary> /// <param name="commandLineSwitches"></param> /// <param name="parameterizedSwitch"></param> /// <param name="switchParameters"></param> /// <param name="duplicateSwitchErrorMessage"></param> /// <param name="multipleParametersAllowed"></param> /// <param name="missingParametersErrorMessage"></param> /// <param name="unquoteParameters"></param> /// <param name="unquotedCommandLineArg"></param> private static void GatherParameterizedCommandLineSwitch ( CommandLineSwitches commandLineSwitches, CommandLineSwitches.ParameterizedSwitch parameterizedSwitch, string switchParameters, string duplicateSwitchErrorMessage, bool multipleParametersAllowed, string missingParametersErrorMessage, bool unquoteParameters, string unquotedCommandLineArg ) { if (// switch must have parameters (switchParameters.Length > 1) || // unless the parameters are optional (missingParametersErrorMessage == null)) { // check if switch is duplicated, and if that's allowed if (!commandLineSwitches.IsParameterizedSwitchSet(parameterizedSwitch) || (duplicateSwitchErrorMessage == null)) { // skip the parameter indicator (if any) if (switchParameters.Length > 0) { switchParameters = switchParameters.Substring(1); } // save the parameters after unquoting and splitting them if necessary if (!commandLineSwitches.SetParameterizedSwitch(parameterizedSwitch, unquotedCommandLineArg, switchParameters, multipleParametersAllowed, unquoteParameters)) { // if parsing revealed there were no real parameters, flag an error, unless the parameters are optional if (missingParametersErrorMessage != null) { commandLineSwitches.SetSwitchError(missingParametersErrorMessage, unquotedCommandLineArg); } } } else { commandLineSwitches.SetSwitchError(duplicateSwitchErrorMessage, unquotedCommandLineArg); } } else { commandLineSwitches.SetSwitchError(missingParametersErrorMessage, unquotedCommandLineArg); } }
/// <summary> /// Called when a response file switch is detected on the command line. It loads the specified response file, and parses /// each line in it like a command line. It also prevents multiple (or recursive) inclusions of the same response file. /// </summary> /// <param name="unquotedCommandLineArg"></param> /// <param name="commandLineSwitches"></param> private static void GatherResponseFileSwitch(string unquotedCommandLineArg, CommandLineSwitches commandLineSwitches) { try { string responseFile = unquotedCommandLineArg.Substring(1); if (responseFile.Length == 0) { commandLineSwitches.SetSwitchError("MissingResponseFileError", unquotedCommandLineArg); } else if (!File.Exists(responseFile)) { commandLineSwitches.SetParameterError("ResponseFileNotFoundError", unquotedCommandLineArg); } else { // normalize the response file path to help catch multiple (or recursive) inclusions responseFile = Path.GetFullPath(responseFile); // NOTE: for network paths or mapped paths, normalization is not guaranteed to work bool isRepeatedResponseFile = false; foreach (string includedResponseFile in s_includedResponseFiles) { if (String.Compare(responseFile, includedResponseFile, StringComparison.OrdinalIgnoreCase) == 0) { commandLineSwitches.SetParameterError("RepeatedResponseFileError", unquotedCommandLineArg); isRepeatedResponseFile = true; break; } } if (!isRepeatedResponseFile) { s_includedResponseFiles.Add(responseFile); ArrayList argsFromResponseFile; using (StreamReader responseFileContents = new StreamReader(responseFile, Encoding.Default)) // HIGHCHAR: If response files have no byte-order marks, then assume ANSI rather than ASCII. { argsFromResponseFile = new ArrayList(); while (responseFileContents.Peek() != -1) { // ignore leading whitespace on each line string responseFileLine = responseFileContents.ReadLine().TrimStart(); // skip comment lines beginning with # if (!responseFileLine.StartsWith("#", StringComparison.Ordinal)) { // treat each line of the response file like a command line i.e. args separated by whitespace argsFromResponseFile.AddRange(QuotingUtilities.SplitUnquoted(Environment.ExpandEnvironmentVariables(responseFileLine))); } } } GatherCommandLineSwitches(argsFromResponseFile, commandLineSwitches); } } } catch (NotSupportedException e) { commandLineSwitches.SetParameterError("ReadResponseFileError", unquotedCommandLineArg, e); } catch (SecurityException e) { commandLineSwitches.SetParameterError("ReadResponseFileError", unquotedCommandLineArg, e); } catch (UnauthorizedAccessException e) { commandLineSwitches.SetParameterError("ReadResponseFileError", unquotedCommandLineArg, e); } catch (IOException e) { commandLineSwitches.SetParameterError("ReadResponseFileError", unquotedCommandLineArg, e); } }
/// <summary> /// Gets all specified switches, from the command line, as well as all /// response files, including the auto-response file. /// </summary> /// <param name="commandLine"></param> /// <returns>Combined bag of switches.</returns> private static void GatherAllSwitches(string commandLine, out CommandLineSwitches switchesFromAutoResponseFile, out CommandLineSwitches switchesNotFromAutoResponseFile) { // split the command line on (unquoted) whitespace ArrayList commandLineArgs = QuotingUtilities.SplitUnquoted(commandLine); // discard the first piece, because that's the path to the executable -- the rest are args s_exeName = QuotingUtilities.Unquote((string)commandLineArgs[0]); if (!s_exeName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { s_exeName += ".exe"; } commandLineArgs.RemoveAt(0); // parse the command line, and flag syntax errors and obvious switch errors switchesNotFromAutoResponseFile = new CommandLineSwitches(); GatherCommandLineSwitches(commandLineArgs, switchesNotFromAutoResponseFile); // parse the auto-response file (if "/noautoresponse" is not specified), and combine those switches with the // switches on the command line switchesFromAutoResponseFile = new CommandLineSwitches(); if (!switchesNotFromAutoResponseFile[CommandLineSwitches.ParameterlessSwitch.NoAutoResponse]) { GatherAutoResponseFileSwitches(s_exePath, switchesFromAutoResponseFile); } }
public void AppendParameterizedSwitchesTests1() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "tempproject.proj", "tempproject.proj", false, true); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); Assert.False(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); CommandLineSwitches switchesRight = new CommandLineSwitches(); switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:build", "build", true, true); Assert.False(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); Assert.True(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); switchesLeft.Append(switchesRight); Assert.Equal("tempproject.proj", switchesLeft.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Project)); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); string[] parameters = switchesLeft[CommandLineSwitches.ParameterizedSwitch.Project]; Assert.NotNull(parameters); Assert.Equal(1, parameters.Length); Assert.Equal("tempproject.proj", parameters[0]); Assert.Equal("/t:build", switchesLeft.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); parameters = switchesLeft[CommandLineSwitches.ParameterizedSwitch.Target]; Assert.NotNull(parameters); Assert.Equal(1, parameters.Length); Assert.Equal("build", parameters[0]); }
public void AppendParameterizedSwitchesTests3() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "tempproject.proj", "tempproject.proj", false, true); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); CommandLineSwitches switchesRight = new CommandLineSwitches(); switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Project, "Rhubarb.proj", "Rhubarb.proj", false, true); Assert.True(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); switchesLeft.Append(switchesRight); Assert.Equal("tempproject.proj", switchesLeft.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Project)); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Project)); string[] parameters = switchesLeft[CommandLineSwitches.ParameterizedSwitch.Project]; Assert.NotNull(parameters); Assert.Equal(1, parameters.Length); Assert.Equal("tempproject.proj", parameters[0]); Assert.True(switchesLeft.HaveErrors()); VerifySwitchError(switchesLeft, "Rhubarb.proj"); }
public void AppendParameterizedSwitchesTests2() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); switchesLeft.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/target:Clean", "Clean", true, true); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); CommandLineSwitches switchesRight = new CommandLineSwitches(); switchesRight.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:\"RESOURCES\";build", "\"RESOURCES\";build", true, true); Assert.True(switchesRight.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); switchesLeft.Append(switchesRight); Assert.Equal("/t:\"RESOURCES\";build", switchesLeft.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); Assert.True(switchesLeft.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); string[] parameters = switchesLeft[CommandLineSwitches.ParameterizedSwitch.Target]; Assert.NotNull(parameters); Assert.Equal(3, parameters.Length); Assert.Equal("Clean", parameters[0]); Assert.Equal("RESOURCES", parameters[1]); Assert.Equal("build", parameters[2]); }
public void AppendErrorTests2() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); CommandLineSwitches switchesRight = new CommandLineSwitches(); Assert.False(switchesLeft.HaveErrors()); Assert.False(switchesRight.HaveErrors()); switchesLeft.SetUnknownSwitchError("/bogus"); switchesRight.SetUnexpectedParametersError("/nologo:foo"); Assert.True(switchesLeft.HaveErrors()); Assert.True(switchesRight.HaveErrors()); VerifySwitchError(switchesLeft, "/bogus"); VerifySwitchError(switchesRight, "/nologo:foo"); switchesLeft.Append(switchesRight); VerifySwitchError(switchesLeft, "/bogus"); VerifySwitchError(switchesRight, "/nologo:foo"); }
public void AppendParameterlessSwitchesTests() { CommandLineSwitches switchesLeft = new CommandLineSwitches(); switchesLeft.SetParameterlessSwitch(CommandLineSwitches.ParameterlessSwitch.Help, "/?"); Assert.True(switchesLeft.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.False(switchesLeft.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); CommandLineSwitches switchesRight1 = new CommandLineSwitches(); switchesRight1.SetParameterlessSwitch(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger, "/noconlog"); Assert.False(switchesRight1.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.True(switchesRight1.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); switchesLeft.Append(switchesRight1); Assert.Equal("/noconlog", switchesLeft.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); Assert.True(switchesLeft.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); Assert.True(switchesLeft[CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger]); // this switch is not affected Assert.Equal("/?", switchesLeft.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.True(switchesLeft.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.True(switchesLeft[CommandLineSwitches.ParameterlessSwitch.Help]); CommandLineSwitches switchesRight2 = new CommandLineSwitches(); switchesRight2.SetParameterlessSwitch(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger, "/NOCONSOLELOGGER"); Assert.False(switchesRight2.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.True(switchesRight2.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); switchesLeft.Append(switchesRight2); Assert.Equal("/NOCONSOLELOGGER", switchesLeft.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); Assert.True(switchesLeft.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger)); Assert.True(switchesLeft[CommandLineSwitches.ParameterlessSwitch.NoConsoleLogger]); Assert.Equal("/?", switchesLeft.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.True(switchesLeft.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Help)); Assert.True(switchesLeft[CommandLineSwitches.ParameterlessSwitch.Help]); Assert.False(switchesLeft.HaveErrors()); }
public void TestHaveAnySwitchesBeenSet() { // Check if method works with parameterized switch CommandLineSwitches switches = new CommandLineSwitches(); Assert.False(switches.HaveAnySwitchesBeenSet()); switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/v:q", "q", false, true); Assert.True(switches.HaveAnySwitchesBeenSet()); // Check if method works with parameterless switches switches = new CommandLineSwitches(); Assert.False(switches.HaveAnySwitchesBeenSet()); switches.SetParameterlessSwitch(CommandLineSwitches.ParameterlessSwitch.Help, "/?"); Assert.True(switches.HaveAnySwitchesBeenSet()); }
/// <summary> /// Verifies that a switch collection has an error registered for the given command line arg. /// </summary> /// <param name="switches"></param> /// <param name="badCommandLineArg"></param> private void VerifySwitchError(CommandLineSwitches switches, string badCommandLineArg) { bool caughtError = false; try { switches.ThrowErrors(); } catch (CommandLineSwitchException e) { Assert.Equal(badCommandLineArg, e.CommandLineArg); caughtError = true; // so I can see the message in NUnit's "Standard Out" window Console.WriteLine(e.Message); } finally { Assert.True(caughtError); } }
/// <summary> /// Coordinates the parsing of the command line. It detects switches on the command line, gathers their parameters, and /// flags syntax errors, and other obvious switch errors. /// </summary> /// <remarks> /// Internal for unit testing only. /// </remarks> internal static void GatherCommandLineSwitches(ArrayList commandLineArgs, CommandLineSwitches commandLineSwitches) { foreach (string commandLineArg in commandLineArgs) { int doubleQuotesRemovedFromArg; string unquotedCommandLineArg = QuotingUtilities.Unquote(commandLineArg, out doubleQuotesRemovedFromArg); if (unquotedCommandLineArg.Length > 0) { // response file switch starts with @ if (unquotedCommandLineArg.StartsWith("@", StringComparison.Ordinal)) { GatherResponseFileSwitch(unquotedCommandLineArg, commandLineSwitches); } else { string switchName; string switchParameters; // all switches should start with - or / unless a project is being specified if (!unquotedCommandLineArg.StartsWith("-", StringComparison.Ordinal) && !unquotedCommandLineArg.StartsWith("/", StringComparison.Ordinal)) { switchName = null; // add a (fake) parameter indicator for later parsing switchParameters = ":" + commandLineArg; } else { // check if switch has parameters (look for the : parameter indicator) int switchParameterIndicator = unquotedCommandLineArg.IndexOf(':'); // extract the switch name and parameters -- the name is sandwiched between the switch indicator (the // leading - or /) and the parameter indicator (if the switch has parameters); the parameters (if any) // follow the parameter indicator if (switchParameterIndicator == -1) { switchName = unquotedCommandLineArg.Substring(1); switchParameters = String.Empty; } else { switchName = unquotedCommandLineArg.Substring(1, switchParameterIndicator - 1); switchParameters = ExtractSwitchParameters(commandLineArg, unquotedCommandLineArg, doubleQuotesRemovedFromArg, switchName, switchParameterIndicator); } } CommandLineSwitches.ParameterlessSwitch parameterlessSwitch; CommandLineSwitches.ParameterizedSwitch parameterizedSwitch; string duplicateSwitchErrorMessage; bool multipleParametersAllowed; string missingParametersErrorMessage; bool unquoteParameters; // Special case: for the switch "/m" or "/maxCpuCount" we wish to pretend we saw "/m:<number of cpus>" // This allows a subsequent /m:n on the command line to override it. // We could create a new kind of switch with optional parameters, but it's a great deal of churn for this single case. // Note that if no "/m" or "/maxCpuCount" switch -- either with or without parameters -- is present, then we still default to 1 cpu // for backwards compatibility. if (String.IsNullOrEmpty(switchParameters)) { if (String.Equals(switchName, "m", StringComparison.OrdinalIgnoreCase) || String.Equals(switchName, "maxcpucount", StringComparison.OrdinalIgnoreCase)) { int numberOfCpus = Environment.ProcessorCount; switchParameters = ":" + numberOfCpus; } } if (CommandLineSwitches.IsParameterlessSwitch(switchName, out parameterlessSwitch, out duplicateSwitchErrorMessage)) { GatherParameterlessCommandLineSwitch(commandLineSwitches, parameterlessSwitch, switchParameters, duplicateSwitchErrorMessage, unquotedCommandLineArg); } else if (CommandLineSwitches.IsParameterizedSwitch(switchName, out parameterizedSwitch, out duplicateSwitchErrorMessage, out multipleParametersAllowed, out missingParametersErrorMessage, out unquoteParameters)) { GatherParameterizedCommandLineSwitch(commandLineSwitches, parameterizedSwitch, switchParameters, duplicateSwitchErrorMessage, multipleParametersAllowed, missingParametersErrorMessage, unquoteParameters, unquotedCommandLineArg); } else { commandLineSwitches.SetUnknownSwitchError(unquotedCommandLineArg); } } } } }
public void SetParameterlessSwitchTests() { CommandLineSwitches switches = new CommandLineSwitches(); switches.SetParameterlessSwitch(CommandLineSwitches.ParameterlessSwitch.NoLogo, "/nologo"); Assert.Equal("/nologo", switches.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.NoLogo)); Assert.True(switches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoLogo)); Assert.True(switches[CommandLineSwitches.ParameterlessSwitch.NoLogo]); // set it again switches.SetParameterlessSwitch(CommandLineSwitches.ParameterlessSwitch.NoLogo, "-NOLOGO"); Assert.Equal("-NOLOGO", switches.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.NoLogo)); Assert.True(switches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.NoLogo)); Assert.True(switches[CommandLineSwitches.ParameterlessSwitch.NoLogo]); // we didn't set this switch Assert.Null(switches.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.Version)); Assert.False(switches.IsParameterlessSwitchSet(CommandLineSwitches.ParameterlessSwitch.Version)); Assert.False(switches[CommandLineSwitches.ParameterlessSwitch.Version]); }
/// <summary> /// Called when a switch that doesn't take parameters is detected on the command line. /// </summary> /// <param name="commandLineSwitches"></param> /// <param name="parameterlessSwitch"></param> /// <param name="switchParameters"></param> /// <param name="duplicateSwitchErrorMessage"></param> /// <param name="unquotedCommandLineArg"></param> private static void GatherParameterlessCommandLineSwitch ( CommandLineSwitches commandLineSwitches, CommandLineSwitches.ParameterlessSwitch parameterlessSwitch, string switchParameters, string duplicateSwitchErrorMessage, string unquotedCommandLineArg ) { // switch should not have any parameters if (switchParameters.Length == 0) { // check if switch is duplicated, and if that's allowed if (!commandLineSwitches.IsParameterlessSwitchSet(parameterlessSwitch) || (duplicateSwitchErrorMessage == null)) { commandLineSwitches.SetParameterlessSwitch(parameterlessSwitch, unquotedCommandLineArg); } else { commandLineSwitches.SetSwitchError(duplicateSwitchErrorMessage, unquotedCommandLineArg); } } else { commandLineSwitches.SetUnexpectedParametersError(unquotedCommandLineArg); } }
public void SetParameterizedSwitchTests1() { CommandLineSwitches switches = new CommandLineSwitches(); Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/v:q", "q", false, true)); Assert.Equal("/v:q", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Verbosity)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Verbosity)); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.Verbosity]; Assert.NotNull(parameters); Assert.Equal(1, parameters.Length); Assert.Equal("q", parameters[0]); // set it again -- this is bogus, because the /verbosity switch doesn't allow multiple parameters, but for the // purposes of testing the SetParameterizedSwitch() method, it doesn't matter Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Verbosity, "/verbosity:\"diag\";minimal", "\"diag\";minimal", true, true)); Assert.Equal("/v:q /verbosity:\"diag\";minimal", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Verbosity)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Verbosity)); parameters = switches[CommandLineSwitches.ParameterizedSwitch.Verbosity]; Assert.NotNull(parameters); Assert.Equal(3, parameters.Length); Assert.Equal("q", parameters[0]); Assert.Equal("diag", parameters[1]); Assert.Equal("minimal", parameters[2]); }
/// <summary> /// Parses the auto-response file (assumes the "/noautoresponse" switch is not specified on the command line), and combines the /// switches from the auto-response file with the switches passed in. /// Returns true if the response file was found. /// </summary> private static bool GatherAutoResponseFileSwitches(string path, CommandLineSwitches switchesFromAutoResponseFile) { string autoResponseFile = Path.Combine(path, autoResponseFileName); bool found = false; // if the auto-response file does not exist, only use the switches on the command line if (File.Exists(autoResponseFile)) { found = true; GatherResponseFileSwitch("@" + autoResponseFile, switchesFromAutoResponseFile); // if the "/noautoresponse" switch was set in the auto-response file, flag an error if (switchesFromAutoResponseFile[CommandLineSwitches.ParameterlessSwitch.NoAutoResponse]) { switchesFromAutoResponseFile.SetSwitchError("CannotAutoDisableAutoResponseFile", switchesFromAutoResponseFile.GetParameterlessSwitchCommandLineArg(CommandLineSwitches.ParameterlessSwitch.NoAutoResponse)); } if (switchesFromAutoResponseFile.HaveAnySwitchesBeenSet()) { // we picked up some switches from the auto-response file usingSwitchesFromAutoResponseFile = true; } } return found; }
public void SetParameterizedSwitchTests2() { CommandLineSwitches switches = new CommandLineSwitches(); // we haven't set this switch yet Assert.Null(switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); Assert.False(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.Target]; Assert.NotNull(parameters); Assert.Equal(0, parameters.Length); // fake/missing parameters -- this is bogus because the /target switch allows multiple parameters but we're turning // that off here just for testing purposes Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:\"", "\"", false, true)); // switch has been set Assert.Equal("/t:\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); parameters = switches[CommandLineSwitches.ParameterizedSwitch.Target]; // but no parameters Assert.NotNull(parameters); Assert.Equal(0, parameters.Length); // more fake/missing parameters Assert.False(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Target, "/t:A,\"\";B", "A,\"\";B", true, true)); Assert.Equal("/t:\" /t:A,\"\";B", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Target)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Target)); parameters = switches[CommandLineSwitches.ParameterizedSwitch.Target]; // now we have some parameters Assert.NotNull(parameters); Assert.Equal(2, parameters.Length); Assert.Equal("A", parameters[0]); Assert.Equal("B", parameters[1]); }
/// <summary> /// Uses the input from thinNodeMode switch to start a local node server /// </summary> /// <param name="commandLineSwitches"></param> private static void StartLocalNode(CommandLineSwitches commandLineSwitches) { string[] input = commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.NodeMode]; int nodeModeNumber = 0; if (input.Length > 0) { try { nodeModeNumber = int.Parse(input[0], CultureInfo.InvariantCulture); } catch (FormatException ex) { CommandLineSwitchException.Throw("InvalidNodeNumberValue", input[0], ex.Message); } catch (OverflowException ex) { CommandLineSwitchException.Throw("InvalidNodeNumberValue", input[0], ex.Message); } CommandLineSwitchException.VerifyThrow(nodeModeNumber >= 0, "InvalidNodeNumberValueIsNegative", input[0]); } #if !STANDALONEBUILD if (!commandLineSwitches[CommandLineSwitches.ParameterlessSwitch.OldOM]) #endif { bool restart = true; while (restart) { Exception nodeException = null; NodeEngineShutdownReason shutdownReason = NodeEngineShutdownReason.Error; // normal OOP node case if (nodeModeNumber == 1) { OutOfProcNode node = new OutOfProcNode(); shutdownReason = node.Run(ProcessNodeReuseSwitch(commandLineSwitches[CommandLineSwitches.ParameterizedSwitch.NodeReuse]), out nodeException); FileUtilities.ClearCacheDirectory(); } else if (nodeModeNumber == 2) { OutOfProcTaskHostNode node = new OutOfProcTaskHostNode(); shutdownReason = node.Run(out nodeException); } else { CommandLineSwitchException.Throw("InvalidNodeNumberValue", input[0]); } if (shutdownReason == NodeEngineShutdownReason.Error) { Debug.WriteLine("An error has happened, throwing an exception"); throw nodeException; } if (shutdownReason != NodeEngineShutdownReason.BuildCompleteReuse) { restart = false; } } } #if !STANDALONEBUILD else { StartLocalNodeOldOM(nodeModeNumber); } #endif }
public void SetParameterizedSwitchTests3() { CommandLineSwitches switches = new CommandLineSwitches(); // we haven't set this switch yet Assert.Null(switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger)); Assert.False(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Logger)); string[] parameters = switches[CommandLineSwitches.ParameterizedSwitch.Logger]; Assert.NotNull(parameters); Assert.Equal(0, parameters.Length); // don't unquote fake/missing parameters Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/l:\"", "\"", false, false)); Assert.Equal("/l:\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Logger)); parameters = switches[CommandLineSwitches.ParameterizedSwitch.Logger]; Assert.NotNull(parameters); Assert.Equal(1, parameters.Length); Assert.Equal("\"", parameters[0]); // don't unquote multiple fake/missing parameters -- this is bogus because the /logger switch does not take multiple // parameters, but for testing purposes this is fine Assert.True(switches.SetParameterizedSwitch(CommandLineSwitches.ParameterizedSwitch.Logger, "/LOGGER:\"\",asm;\"p,a;r\"", "\"\",asm;\"p,a;r\"", true, false)); Assert.Equal("/l:\" /LOGGER:\"\",asm;\"p,a;r\"", switches.GetParameterizedSwitchCommandLineArg(CommandLineSwitches.ParameterizedSwitch.Logger)); Assert.True(switches.IsParameterizedSwitchSet(CommandLineSwitches.ParameterizedSwitch.Logger)); parameters = switches[CommandLineSwitches.ParameterizedSwitch.Logger]; Assert.NotNull(parameters); Assert.Equal(4, parameters.Length); Assert.Equal("\"", parameters[0]); Assert.Equal("\"\"", parameters[1]); Assert.Equal("asm", parameters[2]); Assert.Equal("\"p,a;r\"", parameters[3]); }