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]);
        }
Esempio n. 2
0
        /// <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;
        }
        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 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 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");
        }
        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]);
        }