Exemplo n.º 1
0
            private void validate()
            {
                if (_arch == null)
                {
                    if (_verbose)
                    {
                        Console.WriteLine("Defaulting architecture to x64.");
                    }
                    _arch = "x64";
                }

                if (_build == null)
                {
                    if (_verbose)
                    {
                        Console.WriteLine("Defaulting build to Debug.");
                    }

                    _build = "Debug";
                }

                if (_os == null)
                {
                    if (_verbose)
                    {
                        Console.WriteLine("Discovering operating system.");
                    }

                    SetPlatform();

                    if (_verbose)
                    {
                        Console.WriteLine("Operating system is {0}", _os);
                    }
                }

                if (_srcDirectory == null)
                {
                    if (_verbose)
                    {
                        Console.WriteLine("Formatting jit directory.");
                    }
                    _srcDirectory = "jit";
                }

                if (_projects.Count == 0 && _verbose)
                {
                    Console.WriteLine("Formatting dll project.");
                }

                if (!_untidy && ((_arch == null) || (_os == null) || (_build == null)))
                {
                    _syntaxResult.ReportError("Specify --arch, --os, and --build for clang-tidy run.");
                }

                if (_rootPath == null)
                {
                    if (_verbose)
                    {
                        Console.WriteLine("Discovering --coreclr.");
                    }
                    _rootPath = Utility.GetRepoRoot(_verbose);
                    _rootPath = Path.Combine(_rootPath, "src", "coreclr");
                    if (_rootPath == null)
                    {
                        _syntaxResult.ReportError("Specify --coreclr");
                    }
                    else
                    {
                        Console.WriteLine("Using --coreclr={0}", _rootPath);
                    }
                }

                if (!Directory.Exists(_rootPath))
                {
                    // If _rootPath doesn't exist, it is an invalid path
                    _syntaxResult.ReportError("Invalid path to coreclr directory. Specify with --coreclr");
                }
                else if (!File.Exists(Path.Combine(_rootPath, "build-runtime.cmd")) || !File.Exists(Path.Combine(_rootPath, "build-runtime.sh")) || !File.Exists(Path.Combine(_rootPath, "clr.featuredefines.props")))
                {
                    // Doesn't look like the coreclr directory.
                    _syntaxResult.ReportError("Invalid path to coreclr directory. Specify with --coreclr");
                }

                // Check that we can find compile_commands.json on windows
                if (_os.ToLower() == "windows")
                {
                    // If the user didn't specify a compile_commands.json, we need to see if one exists, and if not, create it.
                    if (!_untidy && _compileCommands == null)
                    {
                        string[] compileCommandsPath = { _rootPath, "..", "..", "artifacts", "nmakeobj", _os + "." + _arch + "." + _build, "compile_commands.json" };
                        _compileCommands        = Path.Combine(compileCommandsPath);
                        _rewriteCompileCommands = true;

                        if (!File.Exists(_compileCommands))
                        {
                            // We haven't done a build, so we need to do one.
                            if (_verbose)
                            {
                                Console.WriteLine("Neither compile_commands.json exists, nor is there a build log. Running CMake to generate compile_commands.json.");
                            }

                            string[] commandArgs = { _arch, _build, "usenmakemakefiles" };
                            string   buildPath   = Path.Combine(_rootPath, "build-runtime.cmd");

                            if (_verbose)
                            {
                                Console.WriteLine("Running: {0} {1}", buildPath, String.Join(" ", commandArgs));
                            }

                            ProcessResult result = Utility.ExecuteProcess(buildPath, commandArgs, !_verbose, _rootPath);

                            if (result.ExitCode != 0)
                            {
                                Console.WriteLine("There was an error running CMake to generate compile_commands.json. Please do a full build to generate a build log.");
                                Environment.Exit(-1);
                            }
                        }
                    }
                }

                // Check that we can find the compile_commands.json file on other platforms
                else
                {
                    // If the user didn't specify a compile_commands.json, we need to see if one exists, and if not, create it.
                    if (!_untidy && _compileCommands == null)
                    {
                        string[] compileCommandsPath = { _rootPath, "..", "..", "artifacts", "obj", "coreclr", _os + "." + _arch + "." + _build, "compile_commands.json" };
                        _compileCommands        = Path.Combine(compileCommandsPath);
                        _rewriteCompileCommands = true;

                        if (!File.Exists(Path.Combine(compileCommandsPath)))
                        {
                            Console.WriteLine("Can't find compile_commands.json file. Running configure.");
                            string[] commandArgs = { _arch, _build, "configureonly", "-cmakeargs", "-DCMAKE_EXPORT_COMPILE_COMMANDS=1" };
                            string   buildPath   = Path.Combine(_rootPath, "build-runtime.sh");

                            if (_verbose)
                            {
                                Console.WriteLine("Running: {0} {1}", buildPath, String.Join(" ", commandArgs));
                            }

                            ProcessResult result = Utility.ExecuteProcess(buildPath, commandArgs, true, _rootPath);

                            if (result.ExitCode != 0)
                            {
                                Console.WriteLine("There was an error running CMake to generate compile_commands.json. Please run build-runtime.sh configureonly");
                                Environment.Exit(-1);
                            }
                        }
                    }
                }
            }
Exemplo n.º 2
0
        public static bool RunClangFormat(List <string> filenames, bool fix, bool verbose)
        {
            string formatFix            = fix ? "-i" : "";
            string outputReplacementXml = fix ? "" : "-output-replacements-xml";
            bool   formatOk             = true;
            int    quietErrorLimit      = 10;

            List <string> clangFormatErrors = new List <string>();

            Parallel.ForEach(filenames, (filename) =>
            {
                Process process = new Process();

                // Run clang-format
                List <string> commandArgs = new List <string> {
                    formatFix, "-style=file", outputReplacementXml, filename
                };

                if (verbose)
                {
                    Console.WriteLine("Running: {0} {1}", "clang-format", String.Join(" ", commandArgs));
                }

                ProcessResult result = Utility.ExecuteProcess("clang-format", commandArgs, true);

                if (result.StdOut.Contains("<replacement ") && !fix)
                {
                    if (verbose)
                    {
                        // Read in the file
                        string fileContents       = File.ReadAllText(filename);
                        string[] fileContentsList = fileContents.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
                        int offsetChange          = 0;

                        // Read in the xml generated by clang-format
                        var doc = new XmlDocument();
                        doc.LoadXml(result.StdOut);

                        XmlNodeList replacements = doc.DocumentElement.ChildNodes;

                        string output = "clang-format: there are formatting errors in " + filename + "\n";

                        foreach (XmlNode replacement in replacements)
                        {
                            // Figure out offset and length for each replacement
                            if (replacement.Name.Equals("replacement"))
                            {
                                // We use offsetChange to calculate the new offset based on other formatting
                                // changes that have already been made.
                                int offset             = Int32.Parse(replacement.Attributes["offset"].Value) + offsetChange;
                                int length             = Int32.Parse(replacement.Attributes["length"].Value);
                                string replacementText = replacement.InnerText;

                                // Undo the replacements clang-format makes when it prints the xml
                                replacementText = replacementText.Replace("&#10;", "\\n");
                                replacementText = replacementText.Replace("&#13;", "\\r");
                                replacementText = replacementText.Replace("&lt;;", "<");
                                replacementText = replacementText.Replace("&amp;", "&");

                                // To calculate the cummulative amount of bytes of change we have made, we
                                // subtract the length of text that we will be replacing, and add the
                                // length of text that we will be inserting.
                                offsetChange = offsetChange - length + replacementText.Length;

                                // To calculate the line numbers, we scan to the offset in the file, and
                                // count the number of new lines we have seen. To calculate the end line
                                // number of the code snippet, we count the number of newlines up to the
                                // location of offset + length
                                var startLineNumber = fileContents.Take(offset).Count(c => c == '\n');
                                var endLineNumber   = fileContents.Take(offset + length).Count(c => c == '\n');

                                output = output + "At Line " + (startLineNumber + 1) + " Before:\n";

                                foreach (string line in fileContentsList.Skip(startLineNumber).Take(endLineNumber - startLineNumber + 1))
                                {
                                    output = output + line + "\n";
                                }

                                output = output + "After:\n";

                                // To do the replacement, we remove the old text between offset and offset + length
                                // and insert the new text
                                fileContents     = fileContents.Remove(offset, length).Insert(offset, replacementText);
                                fileContentsList = fileContents.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

                                startLineNumber = fileContents.Take(offset).Count(c => c == '\n');
                                endLineNumber   = fileContents.Take(offset + replacementText.Length).Count(c => c == '\n');

                                foreach (string line in fileContentsList.Skip(startLineNumber).Take(endLineNumber - startLineNumber + 1))
                                {
                                    output = output + line + "\n";
                                }
                            }
                        }

                        clangFormatErrors.Add(output);
                    }

                    formatOk = false;
                }
            });

            int quietErrorCount = 0;

            foreach (string failure in clangFormatErrors)
            {
                if (verbose || quietErrorCount < quietErrorLimit)
                {
                    Console.WriteLine("");
                    Console.WriteLine("{0}", failure);
                    quietErrorCount++;
                }
            }

            return(formatOk);
        }
Exemplo n.º 3
0
            private void SetPlatform()
            {
                // Extract system RID from dotnet cli
                List <string> commandArgs = new List <string> {
                    "--info"
                };

                if (_verbose)
                {
                    Console.WriteLine("Running: {0} {1}", "dotnet", String.Join(" ", commandArgs));
                }

                // Running "dotnet" (the executable, not the .cmd/.sh wrapper script) when the current
                // directory is within a runtime repo clone does not give us the information we want:
                // it is missing the "OS Platform" and "RID" lines. So, pick some other directory that
                // is expected to not be in a repo clone, and run the "dotnet" command from that directory.
                string          commandWorkingDirectory = "";
                OperatingSystem os  = Environment.OSVersion;
                PlatformID      pid = os.Platform;

                switch (pid)
                {
                case PlatformID.Win32NT:
                    commandWorkingDirectory = Environment.SystemDirectory;
                    break;

                case PlatformID.Unix:
                    commandWorkingDirectory = "/";     // Use the root directory
                    break;

                default:
                    break;
                }

                ProcessResult result = Utility.ExecuteProcess("dotnet", commandArgs, true, commandWorkingDirectory);

                if (result.ExitCode != 0)
                {
                    Console.Error.WriteLine("dotnet --info returned non-zero");
                }

                var lines = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

                foreach (var line in lines)
                {
                    Regex pattern = new Regex(@"OS Platform:([\sA-Za-z0-9\.-]*)$");
                    Match match   = pattern.Match(line);
                    if (match.Success)
                    {
                        if (match.Groups[1].Value.Trim() == "Windows")
                        {
                            _os = "Windows";
                        }
                        else if (match.Groups[1].Value.Trim() == "Darwin")
                        {
                            _os = "OSX";
                        }
                        else if (match.Groups[1].Value.Trim() == "Linux")
                        {
                            // Assuming anything other than Windows or OSX is a Linux flavor
                            _os = "Linux";
                        }
                        else
                        {
                            Console.WriteLine("Unknown operating system. Please specify with --os");
                            Environment.Exit(-1);
                        }
                    }
                }
            }