Esempio n. 1
0
def get_config(repo_root):
    """ Gets the configuration file either from the repository, the user
        ``.gitlint`` directory or the default.
    """
    config = None
    if repo_root:
        repo_config = os.path.join(repo_root, '.gitlint.yaml')
        if os.path.exists(repo_config):
            config = repo_config

    if not config:
        home_folder = os.path.expanduser('~')
        user_config = os.path.join(home_folder, '.git-lint', 'config.yaml')
        if os.path.exists(user_config):
            config = os.path.join(home_folder, '.git-lint', 'config.yaml')

    if not config:
        config = os.path.join(
            os.path.dirname(__file__), 'configs', 'config.yaml')

    with open(config) as f:
        # We have to read the content first as yaml hangs up when reading from
        # MockOpen
        content = f.read()
        # Yaml.load will return None when the input is empty.
        if not content:
            yaml_config = {}
        else:
            yaml_config = yaml.load(content)

    return linters.parse_yaml_config(yaml_config, repo_root)
Esempio n. 2
0
 def test_parse_yaml_config_requirements_not_in_path(self):
     yaml_config = {
         'linter': {
             'arguments': [],
             'command':
             'ls',
             'requirements': [
                 'some_unexistent_command_one',
                 'ls',
                 'some_unexistent_command_two',
             ],
             'extensions': ['.foo'],
             'filter':
             '.*',
             'installation':
             'Run apt-get install command_one command_two',
         }
     }
     config = linters.parse_yaml_config(yaml_config, '')
     self.assertEqual({
         'filename': {
             'skipped': [
                 'some_unexistent_command_one, ' +
                 'some_unexistent_command_two are not '
                 'installed. Run apt-get install command_one ' +
                 'command_two'
             ]
         }
     }, config['.foo'][0]('filename', []))
Esempio n. 3
0
 def test_parse_yaml_config_requirements_not_in_path(self):
     yaml_config = {
         'linter': {
             'arguments': [],
             'command':
             'ls',
             'requirements': [
                 'some_unexistent_command_one',
                 'ls',
                 'some_unexistent_command_two',
             ],
             'extensions': ['.foo'],
             'filter':
             '.*',
             'installation':
             'Run apt-get install command_one command_two',
         }
     }
     config = linters.parse_yaml_config(yaml_config, '')
     self.assertEqual(
         {
             'filename': {
                 'skipped': [
                     'some_unexistent_command_one, ' +
                     'some_unexistent_command_two are not '
                     'installed. Run apt-get install command_one ' +
                     'command_two'
                 ]
             }
         }, config['extensions']['.foo'][0]('filename', []))
Esempio n. 4
0
    def test_parse_yaml_config_with_variables(self):
        yaml_config_with_vars = {
            'linter': {
                'arguments': ['--config', '{DEFAULT_CONFIGS}/foo.config'],
                'command': '{REPO_HOME}/bin/linter',
                'requirements': [
                    '{REPO_HOME}/bin/dep1',
                ],
                'extensions': ['.foo'],
                'filter': '.*',
                'installation': 'install',
            }
        }
        variables = {
            'DEFAULT_CONFIGS':
            os.path.join(os.path.dirname(gitlint.__file__), 'configs'),
            'REPO_HOME':
            '/usr/home/repo',
        }
        yaml_config_no_vars = {
            'linter': {
                'arguments': [
                    '--config',
                    '{DEFAULT_CONFIGS}/foo.config'.format(**variables),
                ],
                'command':
                '{REPO_HOME}/bin/linter'.format(**variables),
                'requirements': [
                    '{REPO_HOME}/bin/dep1'.format(**variables),
                ],
                'extensions': ['.foo'],
                'filter':
                '.*',
                'installation':
                'install',
            }
        }

        with mock.patch('gitlint.utils.which', return_value=['lint']):
            config_with_vars = linters.parse_yaml_config(
                yaml_config_with_vars, variables['REPO_HOME'])
            config_no_vars = linters.parse_yaml_config(yaml_config_no_vars,
                                                       variables['REPO_HOME'])

            self.assertEqual(config_with_vars, config_no_vars)
Esempio n. 5
0
    def test_parse_yaml_config_with_variables(self):
        yaml_config_with_vars = {
            'linter': {
                'arguments': ['--config', '{DEFAULT_CONFIGS}/foo.config'],
                'command': '{REPO_HOME}/bin/linter',
                'requirements': [
                    '{REPO_HOME}/bin/dep1',
                ],
                'extensions': ['.foo'],
                'filter': '.*',
                'installation': 'install',
            }
        }
        variables = {
            'DEFAULT_CONFIGS':
            os.path.join(os.path.dirname(gitlint.__file__), 'configs'),
            'REPO_HOME':
            '/usr/home/repo',
        }
        yaml_config_no_vars = {
            'linter': {
                'arguments': [
                    '--config',
                    '{DEFAULT_CONFIGS}/foo.config'.format(**variables),
                ],
                'command':
                '{REPO_HOME}/bin/linter'.format(**variables),
                'requirements': [
                    '{REPO_HOME}/bin/dep1'.format(**variables),
                ],
                'extensions': ['.foo'],
                'filter':
                '.*',
                'installation':
                'install',
            }
        }

        with mock.patch('gitlint.utils.which', return_value=['lint']):
            config_with_vars = linters.parse_yaml_config(
                yaml_config_with_vars, variables['REPO_HOME'])
            config_no_vars = linters.parse_yaml_config(yaml_config_no_vars,
                                                       variables['REPO_HOME'])

            self.assertEqual(config_with_vars, config_no_vars)
Esempio n. 6
0
def get_config(repo_root):
    """Gets the configuration file either from the repository or the default."""
    config = os.path.join(os.path.dirname(__file__), 'configs', 'config.yaml')

    if repo_root:
        repo_config = os.path.join(repo_root, '.gitlint.yaml')
        if os.path.exists(repo_config):
            config = repo_config

    with open(config) as f:
        # We have to read the content first as yaml hangs up when reading from
        # MockOpen
        content = f.read()
        # Yaml.load will return None when the input is empty.
        if not content:
            yaml_config = {}
        else:
            yaml_config = yaml.load(content)

    return linters.parse_yaml_config(yaml_config, repo_root)
Esempio n. 7
0
def get_config(repo_root):
    """Gets the configuration file either from the repository or the default."""
    config = os.path.join(os.path.dirname(__file__), 'configs', 'config.yaml')

    if repo_root:
        repo_config = os.path.join(repo_root, '.gitlint.yaml')
        if os.path.exists(repo_config):
            config = repo_config

    with open(config) as f:
        # We have to read the content first as yaml hangs up when reading from
        # MockOpen
        content = f.read()
        # Yaml.load will return None when the input is empty.
        if not content:
            yaml_config = {}
        else:
            yaml_config = yaml.load(content, Loader=yaml.FullLoader)

    return linters.parse_yaml_config(yaml_config, repo_root)
Esempio n. 8
0
 def test_parse_yaml_config_command_not_in_path(self):
     yaml_config = {
         'linter': {
             'arguments': [],
             'command': 'some_unexistent_program_name',
             'extensions': ['.foo'],
             'filter': '.*',
             'installation': ('Go to some_unexistent_program_name.com to ' +
                              'install it.'),
         }
     }
     config = linters.parse_yaml_config(yaml_config, '')
     self.assertEqual(
         {
             'filename': {
                 'skipped': ['some_unexistent_program_name is not ' +
                             'installed. Go to some_unexistent_program_' +
                             'name.com to install it.']
             }
         },
         config['.foo'][0]('filename', []))
Esempio n. 9
0
 def test_parse_yaml_config_command_not_in_path(self):
     yaml_config = {
         'linter': {
             'arguments': [],
             'command':
             'some_unexistent_program_name',
             'extensions': ['.foo'],
             'filter':
             '.*',
             'installation':
             ('Go to some_unexistent_program_name.com to ' + 'install it.'),
         }
     }
     config = linters.parse_yaml_config(yaml_config, '')
     self.assertEqual(
         {
             'filename': {
                 'skipped': [
                     'some_unexistent_program_name is not ' +
                     'installed. Go to some_unexistent_program_' +
                     'name.com to install it.'
                 ]
             }
         }, config['extensions']['.foo'][0]('filename', []))
Esempio n. 10
0
def main(argv, stdout=sys.stdout, stderr=sys.stderr):
    """Main gitlint routine. To be called from scripts."""
    # Wrap sys stdout for python 2, so print can understand unicode.
    linesep = os.linesep
    if sys.version_info[0] < 3:
        if stdout == sys.stdout:
            stdout = codecs.getwriter("utf-8")(stdout)
        if stderr == sys.stderr:
            stderr = codecs.getwriter("utf-8")(stderr)
        linesep = unicode(os.linesep)  # pylint: disable=undefined-variable

    arguments = docopt.docopt(
        __doc__, argv=argv[1:], version='git-lint v%s' % __VERSION__)

    json_output = arguments['--json']

    vcs, repository_root = get_vcs_root()

    if vcs is None:
        stderr.write('fatal: Not a git repository' + linesep)
        return 128

    commit = None
    mode = arguments['--mode']
    if not mode or mode == 'merge-base':
        commit = vcs.merge_base_commit()
    elif mode == 'last-commit':
        commit = vcs.last_commit()
    elif mode != 'local':
        raise ValueError(
            'Invalid mode. Valid modes are: merge-base, local, or last-commit.')

    config = get_config(repository_root)

    if arguments['FILENAME']:
        invalid_filenames = find_invalid_filenames(arguments['FILENAME'],
                                                   repository_root)
        if invalid_filenames:
            invalid_filenames.append(('', ''))
            stderr.write(
                linesep.join(invalid[1] for invalid in invalid_filenames))
            return 2

        changed_files = vcs.modified_files(
            repository_root, tracked_only=arguments['--tracked'], commit=commit)
        modified_files = {}
        for filename in arguments['FILENAME']:
            normalized_filename = os.path.abspath(filename)
            modified_files[normalized_filename] = changed_files.get(
                normalized_filename)
    else:
        modified_files = vcs.modified_files(
            repository_root, tracked_only=arguments['--tracked'], commit=commit)
        if config.get('ignore-regex'):
            regex_list = [
                '(%s)' % r for r in config.get('ignore-regex').split()
            ]
            regex = re.compile('|'.join(regex_list))
            modified_files = {
                k: v for k, v in modified_files.items() if not regex.match(k)
            }

    linter_not_found = False
    files_with_problems = 0
    linter_config = linters.parse_yaml_config(
        config.get('linters', {}), repository_root, not arguments['--no-cache'])
    fixer_config = fixers.parse_yaml_config(config.get('fixers', {}), repository_root, arguments['--fix-linexp'])
    json_result = {}

    with futures.ThreadPoolExecutor(max_workers=multiprocessing.cpu_count())\
            as executor:
        processfile = functools.partial(process_file, vcs, commit,
                                        arguments['--force'], linter_config,
                                        fixer_config, arguments['--fix'], arguments['--fix-all'])
        for filename, result in executor.map(
                processfile, [(filename, modified_files[filename])
                              for filename in sorted(modified_files.keys())]):

            rel_filename = os.path.relpath(filename)

            if not json_output:
                stdout.write('Processing file: %s%s' % (termcolor.colored(
                    rel_filename, attrs=('bold',)), linesep))

            output_lines = []
            if result.get('error'):
                output_lines.extend('%s: %s' % (ERROR, reason)
                                    for reason in result.get('error'))
                linter_not_found = True
            if result.get('skipped'):
                output_lines.extend('%s: %s' % (SKIPPED, reason)
                                    for reason in result.get('skipped'))
            if not result.get('comments', []):
                if not output_lines:
                    output_lines.append(OK)
            else:
                files_with_problems += 1
                for data in result['comments']:
                    formatted_message = format_comment(data)
                    output_lines.append(formatted_message)
                    data['formatted_message'] = formatted_message

            if json_output:
                json_result[filename] = result
            else:
                output = linesep.join(output_lines)
                stdout.write(output)
                stdout.write(linesep + linesep)

    if json_output:
        # Hack to convert to unicode, Python3 returns unicode, wheres Python2
        # returns str.
        stdout.write(
            json.dumps(json_result,
                       ensure_ascii=False).encode('utf-8').decode('utf-8'))

    if files_with_problems > 0:
        return 1
    if linter_not_found:
        return 4
    return 0