<commit_before># -*- coding: utf-8 -*-
import os
import subprocess

import hglib
from parsepatch.patch import Patch

from cli_common.log import get_logger
from static_analysis_bot import CLANG_FORMAT
from static_analysis_bot import Issue
from static_analysis_bot import stats
from static_analysis_bot.config import settings
from static_analysis_bot.revisions import Revision

logger = get_logger(__name__)

ISSUE_MARKDOWN = '''
## clang-format

- **Path**: {path}
- **Lines**: from {line}, on {nb_lines} lines
- **Is new**: {is_new}
'''


class ClangFormat(object):
    '''
    Clang Format direct Runner
    List potential issues on modified files
    from a patch
    '''
    def __init__(self):
        self.diff = ''

    @stats.api.timed('runtime.clang-format')
    def run(self, revision):
        '''
        Run ./mach clang-format on the current patch
        '''
        assert isinstance(revision, Revision)

        # Commit the current revision for `./mach clang-format` to reformat its changes

        cmd = [
            'gecko-env',
            './mach', '--log-no-times', 'clang-format',
        ]
        logger.info('Running ./mach clang-format', cmd=' '.join(cmd))

        # Run command
        clang_output = subprocess.check_output(cmd, cwd=settings.repo_dir).decode('utf-8')

        # Dump raw clang-format output as a Taskcluster artifact (for debugging)
        clang_output_path = os.path.join(
            settings.taskcluster.results_dir,
            '{}-clang-format.txt'.format(repr(revision)),
        )
        with open(clang_output_path, 'w') as f:
            f.write(clang_output)

        # Look for any fixes `./mach clang-format` may have found
        client = hglib.open(settings.repo_dir)
        self.diff = client.diff(unified=8).decode('utf-8')

        if not self.diff:
            return [], None

        # Generate a reverse diff for `parsepatch` (in order to get original
        # line numbers from the dev's patch instead of new line numbers)
        reverse_diff = client.diff(unified=8, reverse=True).decode('utf-8')

        # Store that diff as an improvement sent to devs
        revision.add_improvement_patch('clang-format', reverse_diff)

        # List all the lines that were fixed by `./mach clang-format`
        patch = Patch.parse_patch(reverse_diff, skip_comments=False)
        assert patch != {}, \
            'Empty patch'

        # Build `ClangFormatIssue`s
        issues = []
        for filename, diff in patch.items():
            lines = sorted(diff.get('touched', []) + diff.get('added', []))<commit_msg>staticanalysis/bot: Fix dummy leftover bug (#1631)<commit_after># -*- coding: utf-8 -*-
import os
import subprocess

import hglib
from parsepatch.patch import Patch

from cli_common.log import get_logger
from static_analysis_bot import CLANG_FORMAT
from static_analysis_bot import Issue
from static_analysis_bot import stats
from static_analysis_bot.config import settings
from static_analysis_bot.revisions import Revision

logger = get_logger(__name__)

ISSUE_MARKDOWN = '''
## clang-format

- **Path**: {path}
- **Lines**: from {line}, on {nb_lines} lines
- **Is new**: {is_new}
'''


class ClangFormat(object):
    '''
    Clang Format direct Runner
    List potential issues on modified files
    from a patch
    '''
    def __init__(self):
        self.diff = ''

    @stats.api.timed('runtime.clang-format')
    def run(self, revision):
        '''
        Run ./mach clang-format on the current patch
        '''
        assert isinstance(revision, Revision)

        # Commit the current revision for `./mach clang-format` to reformat its changes
        cmd = [
            'gecko-env',
            './mach', '--log-no-times', 'clang-format',
        ]
        logger.info('Running ./mach clang-format', cmd=' '.join(cmd))

        # Run command
        clang_output = subprocess.check_output(cmd, cwd=settings.repo_dir).decode('utf-8')

        # Dump raw clang-format output as a Taskcluster artifact (for debugging)
        clang_output_path = os.path.join(
            settings.taskcluster.results_dir,
            '{}-clang-format.txt'.format(repr(revision)),
        )
        with open(clang_output_path, 'w') as f:
            f.write(clang_output)

        # Look for any fixes `./mach clang-format` may have found
        client = hglib.open(settings.repo_dir)
        self.diff = client.diff(unified=8).decode('utf-8')

        if not self.diff:
            return []

        # Generate a reverse diff for `parsepatch` (in order to get original
        # line numbers from the dev's patch instead of new line numbers)
        reverse_diff = client.diff(unified=8, reverse=True).decode('utf-8')

        # Store that diff as an improvement sent to devs
        revision.add_improvement_patch('clang-format', reverse_diff)

        # List all the lines that were fixed by `./mach clang-format`
        patch = Patch.parse_patch(reverse_diff, skip_comments=False)
        assert patch != {}, \
            'Empty patch'

        # Build `ClangFormatIssue`s
        issues = []
        for filename, diff in patch.items():
            lines = sorted(diff.get('touched', []) + diff.get('added', []))
{'fraction_non_alphanumeric': 0.11452728670253651, 'fraction_numerical': 0.0030745580322828594, 'mean_word_length': 2.6221294363256784, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2650341', 'n_tokens_mistral': 1573, 'n_tokens_neox': 1523, 'n_words': 428}