Esempio n. 1
0
def get_file_dict(filename_list, log_printer, allow_raw_files=False):
    """
    Reads all files into a dictionary.

    :param filename_list:   List of names of paths to files to get contents of.
    :param log_printer:     The logger which logs errors.
    :param allow_raw_files: Allow the usage of raw files (non text files),
                            disabled by default
    :return:                Reads the content of each file into a dictionary
                            with filenames as keys.
    """
    file_dict = {}
    for filename in filename_list:
        try:
            with open(filename, 'r',
                      encoding=detect_encoding(filename)) as _file:
                file_dict[filename] = tuple(_file.readlines())
        except UnicodeDecodeError:
            if allow_raw_files:
                file_dict[filename] = None
                continue
            log_printer.warn("Failed to read file '{}'. It seems to contain "
                             'non-unicode characters. Leaving it '
                             'out.'.format(filename))
        except OSError as exception:
            log_printer.log_exception("Failed to read file '{}' because of "
                                      'an unknown error. Leaving it '
                                      'out.'.format(filename),
                                      exception,
                                      log_level=LOG_LEVEL.WARNING)

    log_printer.debug('Files that will be checked:\n' +
                      '\n'.join(file_dict.keys()))
    return file_dict
Esempio n. 2
0
 def get_disk_contents(self):
     """
     :return:
         Returns the contents of a copy of the file
         on the disk. It might not be in sync with
         the editor version of the file.
     """
     with open(self.filename, 'r',
               encoding=detect_encoding(self.filename)) as disk:
         return disk.read()
Esempio n. 3
0
 def get_disk_contents(self):
     """
     :return:
         Returns the contents of a copy of the file
         on the disk. It might not be in sync with
         the editor version of the file.
     """
     with open(self.filename, 'r',
               encoding=detect_encoding(self.filename)) as disk:
         return disk.read()
Esempio n. 4
0
    def apply(self, result, original_file_dict, file_diff_dict, editor: str):
        """
        (O)pen file

        :param editor: The editor to open the file with.
        """
        try:
            editor_info = KNOWN_EDITORS[editor.strip()]
        except KeyError:
            # If the editor is unknown fall back to just passing
            # the filenames and emit a warning
            logging.warning(
                'The editor "{editor}" is unknown to coala. Files won\'t be'
                ' opened at the correct positions and other quirks might'
                ' occur. Consider opening an issue at'
                ' https://github.com/coala/coala/issues so we'
                ' can add support for this editor.'
                ' Supported editors are: {supported}'.format(
                    editor=editor, supported=', '.join(
                        sorted(KNOWN_EDITORS.keys())
                    )
                )
            )
            editor_info = {
                'file_arg_template': '{filename}',
                'gui': False
            }

        # Use dict to remove duplicates
        filenames = {
            src.file: {
                'filename': src.renamed_file(file_diff_dict),
                'line': src.start.line or 1,
                'column': src.start.column or 1
            }
            for src in result.affected_code
        }

        call_args = self.build_editor_call_args(editor, editor_info, filenames)

        if editor_info.get('gui', True):
            subprocess.call(call_args, stdout=subprocess.PIPE)
        else:
            subprocess.call(call_args)

        for original_name, file_info in filenames.items():
            filename = file_info['filename']
            with open(filename, encoding=detect_encoding(filename)) as file:
                file_diff_dict[original_name] = Diff.from_string_arrays(
                    original_file_dict[original_name], file.readlines(),
                    rename=False if original_name == filename else filename)

        return file_diff_dict
Esempio n. 5
0
    def apply(self,
              result,
              original_file_dict,
              file_diff_dict,
              no_orig: bool = False):
        """
        (A)pply patch

        :param no_orig: Whether or not to create .orig backup files
        """
        for filename in result.diffs:
            pre_patch_filename = filename
            if filename in file_diff_dict:
                diff = file_diff_dict[filename]
                pre_patch_filename = (diff.rename
                                      if diff.rename is not False
                                      else filename)
                file_diff_dict[filename] += result.diffs[filename]
            else:
                file_diff_dict[filename] = result.diffs[filename]

                # Backup original file, only if there was no previous patch
                # from this run though!
                if not no_orig and isfile(pre_patch_filename):
                    shutil.copy2(pre_patch_filename,
                                 pre_patch_filename + '.orig')

            diff = file_diff_dict[filename]

            if not diff.delete:
                new_filename = (diff.rename
                                if diff.rename is not False
                                else filename)
                with open(new_filename, mode='w',
                          encoding=detect_encoding(pre_patch_filename)) as file:
                    file.writelines(diff.modified)

            if diff.delete or diff.rename:
                if diff.rename != pre_patch_filename and isfile(
                        pre_patch_filename):
                    remove(pre_patch_filename)

        return file_diff_dict
Esempio n. 6
0
    def apply(self,
              result,
              original_file_dict,
              file_diff_dict,
              no_orig: bool=False):
        """
        (A)pply patch

        :param no_orig: Whether or not to create .orig backup files
        """
        for filename in result.diffs:
            pre_patch_filename = filename
            if filename in file_diff_dict:
                diff = file_diff_dict[filename]
                pre_patch_filename = (diff.rename
                                      if diff.rename is not False
                                      else filename)
                file_diff_dict[filename] += result.diffs[filename]
            else:
                file_diff_dict[filename] = result.diffs[filename]

                # Backup original file, only if there was no previous patch
                # from this run though!
                if not no_orig and isfile(pre_patch_filename):
                    shutil.copy2(pre_patch_filename,
                                 pre_patch_filename + '.orig')

            diff = file_diff_dict[filename]

            if not diff.delete:
                new_filename = (diff.rename
                                if diff.rename is not False
                                else filename)
                with open(new_filename, mode='w',
                          encoding=detect_encoding(pre_patch_filename)) as file:
                    file.writelines(diff.modified)

            if diff.delete or diff.rename:
                if diff.rename != pre_patch_filename and isfile(
                        pre_patch_filename):
                    remove(pre_patch_filename)

        return file_diff_dict
    def apply(self,
              result,
              original_file_dict,
              file_diff_dict,
              language: str,
              no_orig: bool = False):
        """
        Add (I)gnore comment
        """

        ignore_comment = self.get_ignore_comment(result.origin, language)

        if not ignore_comment:
            return file_diff_dict

        source_range = next(
            filter(lambda sr: exists(sr.file), result.affected_code))
        filename = source_range.file

        ignore_diff = Diff(original_file_dict[filename])
        ignore_diff.change_line(
            source_range.start.line,
            original_file_dict[filename][source_range.start.line - 1],
            original_file_dict[filename][source_range.start.line - 1].rstrip()
            + '  ' + ignore_comment)

        if filename in file_diff_dict:
            ignore_diff = file_diff_dict[filename] + ignore_diff
        else:
            if not no_orig and isfile(filename):
                shutil.copy2(filename, filename + '.orig')

        file_diff_dict[filename] = ignore_diff

        new_filename = ignore_diff.rename if ignore_diff.rename else filename
        with open(new_filename,
                  mode='w',
                  encoding=detect_encoding(new_filename)) as file:
            file.writelines(ignore_diff.modified)

        return file_diff_dict
Esempio n. 8
0
    def from_file(cls, filename, workspace, binary=False):
        """
        Construct a FileProxy instance from an existing
        file on the drive.

        :param filename:
            The name of the file to be represented by
            the proxy instance.
        :param workspace:
            The workspace the file belongs to. This can
            be none representing that the the directory
            server is currently serving from is the workspace.
        :return:
            Returns a FileProxy instance of the file with
            the content synced from a disk copy.
        """
        if not binary:
            with open(filename, 'r',
                      encoding=detect_encoding(filename)) as reader:
                return cls(filename, workspace, reader.read())
        else:
            with open(filename, 'rb') as reader:
                return cls(filename, workspace, reader.read())
Esempio n. 9
0
    def from_file(cls, filename, workspace, binary=False):
        """
        Construct a FileProxy instance from an existing
        file on the drive.

        :param filename:
            The name of the file to be represented by
            the proxy instance.
        :param workspace:
            The workspace the file belongs to. This can
            be none representing that the the directory
            server is currently serving from is the workspace.
        :return:
            Returns a FileProxy instance of the file with
            the content synced from a disk copy.
        """
        if not binary:
            with open(filename, 'r',
                      encoding=detect_encoding(filename)) as reader:
                return cls(filename, workspace, reader.read())
        else:
            with open(filename, 'rb') as reader:
                return cls(filename, workspace, reader.read())
Esempio n. 10
0
    def apply(self, result, original_file_dict, file_diff_dict, language: str,
              no_orig: bool=False):
        """
        Add (I)gnore comment
        """

        ignore_comment = self.get_ignore_comment(result.origin, language)

        if not ignore_comment:
            return file_diff_dict

        source_range = next(filter(lambda sr: exists(sr.file),
                                   result.affected_code))
        filename = source_range.file

        ignore_diff = Diff(original_file_dict[filename])
        ignore_diff.change_line(
            source_range.start.line,
            original_file_dict[filename][source_range.start.line-1],
            original_file_dict[filename][source_range.start.line-1].rstrip() +
            '  ' + ignore_comment)

        if filename in file_diff_dict:
            ignore_diff = file_diff_dict[filename] + ignore_diff
        else:
            if not no_orig and isfile(filename):
                shutil.copy2(filename, filename + '.orig')

        file_diff_dict[filename] = ignore_diff

        new_filename = ignore_diff.rename if ignore_diff.rename else filename
        with open(new_filename, mode='w',
                  encoding=detect_encoding(new_filename)) as file:
            file.writelines(ignore_diff.modified)

        return file_diff_dict