def create_clang_default_rules(rules): # defaults clang error (not associated with any activation switch) rule_key = "clang-diagnostic-error" rule_name = "clang-diagnostic-error" rule_type = DIAG_CLASS["CLASS_ERROR"]["sonarqube_type"] rule_severity = SEVERITY["SEV_Remark"]["sonarqube_severity"] rule_description = "<p>Diagnostic text: compiler error, e.g header file not found</p>" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity et.SubElement(rule, 'type').text = rule_type rules.append(rule) # defaults clang warning (not associated with any activation switch) rule_key = "clang-diagnostic-warning" rule_name = "clang-diagnostic-warning" rule_type = DIAG_CLASS["CLASS_WARNING"]["sonarqube_type"] rule_severity = SEVERITY["SEV_Warning"]["sonarqube_severity"] rule_description = "<p>Diagnostic text: default compiler warnings</p>" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity et.SubElement(rule, 'type').text = rule_type rules.append(rule)
def rstfile_to_rule(path, fix_urls): rule = et.Element('rule') filename_with_extension = os.path.basename(path) filename = os.path.splitext(filename_with_extension)[0] key = filename name = filename description = rstfile_to_description(path, filename, fix_urls) default_issue_type = "CODE_SMELL" default_issue_severity = "INFO" et.SubElement(rule, 'key').text = key et.SubElement(rule, 'name').text = name cdata = CDATA(description) et.SubElement(rule, 'description').append(cdata) custom_severity = SEVERITY_MAP.get(key, None) if custom_severity: default_issue_severity = custom_severity["severity"] default_issue_type = custom_severity["type"] et.SubElement(rule, 'severity').text = default_issue_severity et.SubElement(rule, 'type').text = default_issue_type if default_issue_severity != 'INFO': et.SubElement(rule, 'remediationFunction').text = 'LINEAR' et.SubElement(rule, 'remediationFunctionGapMultiplier').text = '5min' return rule
def rstfile_to_rule(path, fix_urls): rule = et.Element('rule') filename_with_extension = os.path.basename(path) filename = os.path.splitext(filename_with_extension)[0] key = filename name = filename description = rstfile_to_description(path, filename, fix_urls) default_issue_type = "CODE_SMELL" default_issue_severity = "MAJOR" et.SubElement(rule, 'key').text = key et.SubElement(rule, 'name').text = name cdata = CDATA(description) et.SubElement(rule, 'description').append(cdata) custom_severity = SEVERITY_MAP.get(key, None) if custom_severity is None: et.SubElement(rule, 'severity').text = default_issue_severity et.SubElement(rule, 'type').text = default_issue_type else: et.SubElement(rule, 'severity').text = custom_severity["severity"] et.SubElement(rule, 'type').text = custom_severity["type"] return rule
def create_clang_default_rules(rules): # defaults clang error (not associated with any activation switch): error, fatal error rule_key = "clang-diagnostic-error" rule_name = "clang-diagnostic-error" rule_type = DIAG_CLASS["CLASS_ERROR"]["sonarqube_type"] rule_severity = SEVERITY["SEV_Remark"]["sonarqube_severity"] rule_description = "<p>Default compiler diagnostic for errors without an explicit check name. Compiler error, e.g header file not found.</p>" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity et.SubElement(rule, 'type').text = rule_type rules.append(rule) # defaults clang warning (not associated with any activation switch): warning rule_key = "clang-diagnostic-warning" rule_name = "clang-diagnostic-warning" rule_type = DIAG_CLASS["CLASS_WARNING"]["sonarqube_type"] rule_severity = SEVERITY["SEV_Warning"]["sonarqube_severity"] rule_description = "<p>Default compiler diagnostic for warnings without an explicit check name.</p>" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity et.SubElement(rule, 'type').text = rule_type rules.append(rule) # defaults clang issue (not associated with any activation switch): all other levels rule_key = "clang-diagnostic-unknown" rule_name = "clang-diagnostic-unknown" rule_type = DIAG_CLASS["CLASS_REMARK"]["sonarqube_type"] rule_severity = SEVERITY["SEV_Remark"]["sonarqube_severity"] rule_description = "<p>(Unkown) compiler diagnostic without an explicit check name.</p>" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity et.SubElement(rule, 'type').text = rule_type rules.append(rule)
def diagnostics_to_rules_xml(json_file): rules = et.Element('rules') # add a template rule create_template_rules(rules) # add clang default warnings create_clang_default_rules(rules) with open(json_file) as f: data = json.load(f) diag_groups = data["!instanceof"]["DiagGroup"] for diag_group_id in sorted(diag_groups): if not data[diag_group_id]["GroupName"]: continue # colleact all Diagnostics included into this DiagGroup warnings_in_group = [] collect_warnings(data, diag_group_id, warnings_in_group) if not warnings_in_group: continue # for each DiagGroup calculate the rule type and severity rule_type, rule_severity = calculate_rule_type_and_severity( warnings_in_group) group_name_escaped = data[diag_group_id]["GroupName"].replace( "++", "-").replace("#", "-").replace("--", "-") rule_name = "clang-diagnostic-" + data[diag_group_id]["GroupName"] rule_key = "clang-diagnostic-" + data[diag_group_id]["GroupName"] rule_description = generate_description(group_name_escaped, warnings_in_group) rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity et.SubElement(rule, 'type').text = rule_type if rule_severity != 'INFO': et.SubElement(rule, 'remediationFunction').text = 'LINEAR' et.SubElement(rule, 'remediationFunctionGapMultiplier').text = '5min' rules.append(rule) write_rules_xml(rules, sys.stdout)
def create_rules(warnings, rules): """ Add warnings as rules to XML. - default 'type' is 'CODE_SMELL' - default 'severity' is 'INFO' - if not 'INFO' / 'CODE_SMELL' set: - 'remediationFunction' to 'LINEAR' - - 'remediationFunctionGapMultiplier' to '5min' """ for _key, data in warnings.items(): rule = et.Element('rule') # mandatory et.SubElement(rule, 'key').text = data['key'] et.SubElement(rule, 'name').text = data['name'] cdata = CDATA(description(data)) et.SubElement(rule, 'description').append(cdata) # optional if 'tag' in data: for tag in data['tag'].split(','): et.SubElement(rule, 'tag').text = tag if 'internalKey' in data: et.SubElement(rule, 'internalKey').text = data['internalKey'] if 'severity' in data: et.SubElement(rule, 'severity').text = data['severity'] else: et.SubElement(rule, 'severity').text = 'INFO' if 'type' in data: et.SubElement(rule, 'type').text = data['type'] else: et.SubElement(rule, 'type').text = 'CODE_SMELL' if ('remediationFunction' in data) and ('remediationFunctionGapMultiplier' in data): et.SubElement(rule, 'remediationFunction').text = data['remediationFunction'] et.SubElement(rule, 'remediationFunctionGapMultiplier').text = data['remediationFunctionGapMultiplier'] else: if ('severity' in data) and ('type' in data) and not ( (data['severity'] == 'INFO') and (data['type'] == 'CODE_SMELL')): et.SubElement(rule, 'remediationFunction').text = 'LINEAR' et.SubElement(rule, 'remediationFunctionGapMultiplier').text = '5min' rules.append(rule)
def get_clang_warnings_rule(): rule = et.Element('rule') et.SubElement(rule,'key').text = 'clang-diagnostic-warning' et.SubElement(rule,'name').text = 'clang-diagnostic-warning' description = """ <div class="title"> <p>clang-tidy - clang-diagnostic-warning</p> </div> <h1 id="clang-diagnostic-warning">clang-diagnostic-warning</h1> <p>Any warnings output by CLANG not toggable via activation switches are captured by this rule.</p> """ cdata = CDATA(description) et.SubElement(rule, 'description').append(cdata) et.SubElement(rule, 'severity').text = "MAJOR" et.SubElement(rule, 'type').text = "BUG" return rule
def error_to_rule(error): rule = et.Element('rule') errId = error.attrib["id"] errMsg = error.attrib["msg"] errDetails = error.attrib["verbose"] errSeverity = error.attrib["severity"] sonarQubeIssueType = SEVERITY_TO_SONARQUBE[errSeverity]["type"] sonarQubeIssueSeverity = SEVERITY_TO_SONARQUBE[errSeverity]["priority"] et.SubElement(rule, 'key').text = errId et.SubElement( rule, 'name').text = errMsg if not errMsg.endswith(".") else errMsg[:-1] cweNr = None if "cwe" in error.attrib: cweNr = error.attrib["cwe"] elif errId.endswith("Called") and errSeverity == "style": # there is no CWE number, but such checks come from libraries and # warn about obsolete or not thread-safe functions cweNr = 477 if cweNr is not None: errDetails = message_with_cwe_reference(errDetails, cweNr) # encode description tag always as CDATA cdata = CDATA(errDetails) et.SubElement(rule, 'description').append(cdata) if cweNr is not None: et.SubElement(rule, 'tag').text = "cwe" if sonarQubeIssueType == "BUG": et.SubElement(rule, 'tag').text = "bug" et.SubElement(rule, 'internalKey').text = errId et.SubElement(rule, 'severity').text = sonarQubeIssueSeverity et.SubElement(rule, 'type').text = sonarQubeIssueType et.SubElement(rule, 'remediationFunction').text = "LINEAR" et.SubElement(rule, 'remediationFunctionGapMultiplier').text = "5min" return rule
def create_template_rules(rules): rule_key = "CustomRuleTemplate" rule_name = "Template for custom Custom rules" rule_severity = SEVERITY["SEV_Warning"]["sonarqube_severity"] rule_description = """<p>Follow these steps to make your custom Custom rules available in SonarQube:</p> <ol> <ol> <li>Create a new rule in SonarQube by "copying" this rule template and specify the <code>CheckId</code> of your custom rule, a title, a description, and a default severity.</li> <li>Enable the newly created rule in your quality profile</li> </ol> <li>Relaunch an analysis on your projects, et voila, your custom rules are executed!</li> </ol>""" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'cardinality').text = "MULTIPLE" name = et.SubElement(rule, 'name').text = rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity rules.append(rule)
def add_template_rules(rules): """ Add template rule(s) to XML. """ rule_key = 'CustomRuleTemplate' rule_name = 'Template for custom Custom rules' rule_severity = 'MAJOR' # pylint: disable=line-too-long rule_description = """<p>Follow these steps to make your custom Custom rules available in SonarQube:</p> <ol> <ol> <li>Create a new rule in SonarQube by "copying" this rule template and specify the <code>CheckId</code> of your custom rule, a title, a description, and a default severity.</li> <li>Enable the newly created rule in your quality profile</li> </ol> <li>Relaunch an analysis on your projects, et voilà, your custom rules are executed!</li> </ol>""" rule = et.Element('rule') et.SubElement(rule, 'key').text = rule_key et.SubElement(rule, 'cardinality').text = "MULTIPLE" et.SubElement(rule, 'name').text=rule_name et.SubElement(rule, 'description').append(CDATA(rule_description)) et.SubElement(rule, 'severity').text = rule_severity rules.append(rule)