diff --git a/Setup.md b/Setup.md new file mode 100644 index 0000000..f2f3457 --- /dev/null +++ b/Setup.md @@ -0,0 +1,23 @@ + + +Instructions here are pretty good: + + https://github.com/jgitver/jgitver-maven-plugin/wiki/automatic-builds-for-maven%2C-jenkins-and-gitbucket + + +On Windows Client: + + Edit (as Administrator) C:\Windows\System32\drivers\etc\hosts + and add the following: + + 192.168.1.116 gitbucket.localdomain + 192.168.1.116 jenkins.localdomain + +On MacOSX Clients: + + sudo vi /etc/hosts + + and add as above + + + diff --git a/Setup.md b/Setup.md new file mode 100644 index 0000000..f2f3457 --- /dev/null +++ b/Setup.md @@ -0,0 +1,23 @@ + + +Instructions here are pretty good: + + https://github.com/jgitver/jgitver-maven-plugin/wiki/automatic-builds-for-maven%2C-jenkins-and-gitbucket + + +On Windows Client: + + Edit (as Administrator) C:\Windows\System32\drivers\etc\hosts + and add the following: + + 192.168.1.116 gitbucket.localdomain + 192.168.1.116 jenkins.localdomain + +On MacOSX Clients: + + sudo vi /etc/hosts + + and add as above + + + diff --git a/clang-tidy-to-junit.py b/clang-tidy-to-junit.py new file mode 100644 index 0000000..a3496a6 --- /dev/null +++ b/clang-tidy-to-junit.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import sys +import collections +import re +import logging +import itertools +from xml.sax.saxutils import escape + +# Create a `ErrorDescription` tuple with all the information we want to keep. +ErrorDescription = collections.namedtuple( + 'ErrorDescription', 'file line column error error_identifier description') + + +class ClangTidyConverter: + # All the errors encountered. + errors = [] + + # Parses the error. + # Group 1: file path + # Group 2: line + # Group 3: column + # Group 4: error message + # Group 5: error identifier + error_regex = re.compile( + r"^([\w\/\.\-\ ]+):(\d+):(\d+): (.+) (\[[\w\-,\.]+\])$") + + # This identifies the main error line (it has a [the-warning-type] at the end) + # We only create a new error when we encounter one of those. + main_error_identifier = re.compile(r'\[[\w\-,\.]+\]$') + + def __init__(self, basename): + self.basename = basename + + def print_junit_file(self, output_file): + # Write the header. + output_file.write(""" +""".format(error_count=len(self.errors))) + + sorted_errors = sorted(self.errors, key=lambda x: x.file) + + # Iterate through the errors, grouped by file. + for file, errorIterator in itertools.groupby(sorted_errors, key=lambda x: x.file): + errors = list(errorIterator) + error_count = len(errors) + + # Each file gets a test-suite + output_file.write("""\n \n""" + .format(error_count=error_count, file=file)) + for error in errors: + # Write each error as a test case. + output_file.write(""" + + +{htmldata} + + """.format(id="[{}/{}] {}".format(error.line, error.column, error.error_identifier), message=escape(error.error), + htmldata=escape(error.description))) + output_file.write("\n \n") + output_file.write("\n") + + def process_error(self, error_array): + if len(error_array) == 0: + return + + result = self.error_regex.match(error_array[0]) + if result is None: + logging.warning( + 'Could not match error_array to regex: %s', error_array) + return + + # We remove the `basename` from the `file_path` to make prettier filenames in the JUnit file. + file_path = result.group(1).replace(self.basename, "") + error = ErrorDescription(file_path, int(result.group(2)), int( + result.group(3)), result.group(4), result.group(5), "\n".join(error_array[1:])) + self.errors.append(error) + + def convert(self, input_file, output_file): + # Collect all lines related to one error. + current_error = [] + for line in input_file: + # If the line starts with a `/`, it is a line about a file. + if line[0] == '/': + # Look if it is the start of a error + if self.main_error_identifier.search(line, re.M): + # If so, process any `current_error` we might have + self.process_error(current_error) + # Initialize `current_error` with the first line of the error. + current_error = [line] + else: + # Otherwise, append the line to the error. + current_error.append(line) + elif len(current_error) > 0: + # If the line didn't start with a `/` and we have a `current_error`, we simply append + # the line as additional information. + current_error.append(line) + else: + pass + + # If we still have any current_error after we read all the lines, + # process it. + if len(current_error) > 0: + self.process_error(current_error) + + # Print the junit file. + self.print_junit_file(output_file) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + logging.error("Usage: %s base-filename-path", sys.argv[0]) + logging.error( + " base-filename-path: Removed from the filenames to make nicer paths.") + sys.exit(1) + converter = ClangTidyConverter(sys.argv[1]) + converter.convert(sys.stdin, sys.stdout) diff --git a/Setup.md b/Setup.md new file mode 100644 index 0000000..f2f3457 --- /dev/null +++ b/Setup.md @@ -0,0 +1,23 @@ + + +Instructions here are pretty good: + + https://github.com/jgitver/jgitver-maven-plugin/wiki/automatic-builds-for-maven%2C-jenkins-and-gitbucket + + +On Windows Client: + + Edit (as Administrator) C:\Windows\System32\drivers\etc\hosts + and add the following: + + 192.168.1.116 gitbucket.localdomain + 192.168.1.116 jenkins.localdomain + +On MacOSX Clients: + + sudo vi /etc/hosts + + and add as above + + + diff --git a/clang-tidy-to-junit.py b/clang-tidy-to-junit.py new file mode 100644 index 0000000..a3496a6 --- /dev/null +++ b/clang-tidy-to-junit.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import sys +import collections +import re +import logging +import itertools +from xml.sax.saxutils import escape + +# Create a `ErrorDescription` tuple with all the information we want to keep. +ErrorDescription = collections.namedtuple( + 'ErrorDescription', 'file line column error error_identifier description') + + +class ClangTidyConverter: + # All the errors encountered. + errors = [] + + # Parses the error. + # Group 1: file path + # Group 2: line + # Group 3: column + # Group 4: error message + # Group 5: error identifier + error_regex = re.compile( + r"^([\w\/\.\-\ ]+):(\d+):(\d+): (.+) (\[[\w\-,\.]+\])$") + + # This identifies the main error line (it has a [the-warning-type] at the end) + # We only create a new error when we encounter one of those. + main_error_identifier = re.compile(r'\[[\w\-,\.]+\]$') + + def __init__(self, basename): + self.basename = basename + + def print_junit_file(self, output_file): + # Write the header. + output_file.write(""" +""".format(error_count=len(self.errors))) + + sorted_errors = sorted(self.errors, key=lambda x: x.file) + + # Iterate through the errors, grouped by file. + for file, errorIterator in itertools.groupby(sorted_errors, key=lambda x: x.file): + errors = list(errorIterator) + error_count = len(errors) + + # Each file gets a test-suite + output_file.write("""\n \n""" + .format(error_count=error_count, file=file)) + for error in errors: + # Write each error as a test case. + output_file.write(""" + + +{htmldata} + + """.format(id="[{}/{}] {}".format(error.line, error.column, error.error_identifier), message=escape(error.error), + htmldata=escape(error.description))) + output_file.write("\n \n") + output_file.write("\n") + + def process_error(self, error_array): + if len(error_array) == 0: + return + + result = self.error_regex.match(error_array[0]) + if result is None: + logging.warning( + 'Could not match error_array to regex: %s', error_array) + return + + # We remove the `basename` from the `file_path` to make prettier filenames in the JUnit file. + file_path = result.group(1).replace(self.basename, "") + error = ErrorDescription(file_path, int(result.group(2)), int( + result.group(3)), result.group(4), result.group(5), "\n".join(error_array[1:])) + self.errors.append(error) + + def convert(self, input_file, output_file): + # Collect all lines related to one error. + current_error = [] + for line in input_file: + # If the line starts with a `/`, it is a line about a file. + if line[0] == '/': + # Look if it is the start of a error + if self.main_error_identifier.search(line, re.M): + # If so, process any `current_error` we might have + self.process_error(current_error) + # Initialize `current_error` with the first line of the error. + current_error = [line] + else: + # Otherwise, append the line to the error. + current_error.append(line) + elif len(current_error) > 0: + # If the line didn't start with a `/` and we have a `current_error`, we simply append + # the line as additional information. + current_error.append(line) + else: + pass + + # If we still have any current_error after we read all the lines, + # process it. + if len(current_error) > 0: + self.process_error(current_error) + + # Print the junit file. + self.print_junit_file(output_file) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + logging.error("Usage: %s base-filename-path", sys.argv[0]) + logging.error( + " base-filename-path: Removed from the filenames to make nicer paths.") + sys.exit(1) + converter = ClangTidyConverter(sys.argv[1]) + converter.convert(sys.stdin, sys.stdout) diff --git a/run-tidy.sh b/run-tidy.sh new file mode 100644 index 0000000..63ba4fa --- /dev/null +++ b/run-tidy.sh @@ -0,0 +1,6 @@ +#!/bin/bash + + +cat "$build_dir/clang-tidy-output" | ./clang-tidy-to-junit.py /srv/Jenkins/source-root-directory >"$build_dir/junit.xml" + + diff --git a/Setup.md b/Setup.md new file mode 100644 index 0000000..f2f3457 --- /dev/null +++ b/Setup.md @@ -0,0 +1,23 @@ + + +Instructions here are pretty good: + + https://github.com/jgitver/jgitver-maven-plugin/wiki/automatic-builds-for-maven%2C-jenkins-and-gitbucket + + +On Windows Client: + + Edit (as Administrator) C:\Windows\System32\drivers\etc\hosts + and add the following: + + 192.168.1.116 gitbucket.localdomain + 192.168.1.116 jenkins.localdomain + +On MacOSX Clients: + + sudo vi /etc/hosts + + and add as above + + + diff --git a/clang-tidy-to-junit.py b/clang-tidy-to-junit.py new file mode 100644 index 0000000..a3496a6 --- /dev/null +++ b/clang-tidy-to-junit.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import sys +import collections +import re +import logging +import itertools +from xml.sax.saxutils import escape + +# Create a `ErrorDescription` tuple with all the information we want to keep. +ErrorDescription = collections.namedtuple( + 'ErrorDescription', 'file line column error error_identifier description') + + +class ClangTidyConverter: + # All the errors encountered. + errors = [] + + # Parses the error. + # Group 1: file path + # Group 2: line + # Group 3: column + # Group 4: error message + # Group 5: error identifier + error_regex = re.compile( + r"^([\w\/\.\-\ ]+):(\d+):(\d+): (.+) (\[[\w\-,\.]+\])$") + + # This identifies the main error line (it has a [the-warning-type] at the end) + # We only create a new error when we encounter one of those. + main_error_identifier = re.compile(r'\[[\w\-,\.]+\]$') + + def __init__(self, basename): + self.basename = basename + + def print_junit_file(self, output_file): + # Write the header. + output_file.write(""" +""".format(error_count=len(self.errors))) + + sorted_errors = sorted(self.errors, key=lambda x: x.file) + + # Iterate through the errors, grouped by file. + for file, errorIterator in itertools.groupby(sorted_errors, key=lambda x: x.file): + errors = list(errorIterator) + error_count = len(errors) + + # Each file gets a test-suite + output_file.write("""\n \n""" + .format(error_count=error_count, file=file)) + for error in errors: + # Write each error as a test case. + output_file.write(""" + + +{htmldata} + + """.format(id="[{}/{}] {}".format(error.line, error.column, error.error_identifier), message=escape(error.error), + htmldata=escape(error.description))) + output_file.write("\n \n") + output_file.write("\n") + + def process_error(self, error_array): + if len(error_array) == 0: + return + + result = self.error_regex.match(error_array[0]) + if result is None: + logging.warning( + 'Could not match error_array to regex: %s', error_array) + return + + # We remove the `basename` from the `file_path` to make prettier filenames in the JUnit file. + file_path = result.group(1).replace(self.basename, "") + error = ErrorDescription(file_path, int(result.group(2)), int( + result.group(3)), result.group(4), result.group(5), "\n".join(error_array[1:])) + self.errors.append(error) + + def convert(self, input_file, output_file): + # Collect all lines related to one error. + current_error = [] + for line in input_file: + # If the line starts with a `/`, it is a line about a file. + if line[0] == '/': + # Look if it is the start of a error + if self.main_error_identifier.search(line, re.M): + # If so, process any `current_error` we might have + self.process_error(current_error) + # Initialize `current_error` with the first line of the error. + current_error = [line] + else: + # Otherwise, append the line to the error. + current_error.append(line) + elif len(current_error) > 0: + # If the line didn't start with a `/` and we have a `current_error`, we simply append + # the line as additional information. + current_error.append(line) + else: + pass + + # If we still have any current_error after we read all the lines, + # process it. + if len(current_error) > 0: + self.process_error(current_error) + + # Print the junit file. + self.print_junit_file(output_file) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + logging.error("Usage: %s base-filename-path", sys.argv[0]) + logging.error( + " base-filename-path: Removed from the filenames to make nicer paths.") + sys.exit(1) + converter = ClangTidyConverter(sys.argv[1]) + converter.convert(sys.stdin, sys.stdout) diff --git a/run-tidy.sh b/run-tidy.sh new file mode 100644 index 0000000..63ba4fa --- /dev/null +++ b/run-tidy.sh @@ -0,0 +1,6 @@ +#!/bin/bash + + +cat "$build_dir/clang-tidy-output" | ./clang-tidy-to-junit.py /srv/Jenkins/source-root-directory >"$build_dir/junit.xml" + + diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..d43aad9 --- /dev/null +++ b/setup.sh @@ -0,0 +1,6 @@ +#!/bin/bash + + +curl https://raw.githubusercontent.com/PSPDFKit-labs/clang-tidy-to-junit/master/clang-tidy-to-junit.py -o clang-tidy-to-junit.py + +