Ejemplo n.º 1
0
    def add_file(self, name, filename, content, mimetype=None):
        """Add an uploaded file for the request.

        Args:
            name (bytes or unicode):
                The name of the field representing the file.

            filename (bytes or unicode):
                The filename.

            content (bytes or unicode):
                The contents of the file.

            mimetype (bytes or unicode, optional):
                The optional mimetype of the content. If not provided, it
                will be guessed.
        """
        mimetype = force_bytes(
            mimetypes.guess_type(force_unicode(filename))[0]
            or b'application/octet-stream')

        self._files[force_bytes(name)] = {
            'filename': force_bytes(filename),
            'content': force_bytes(content),
            'mimetype': mimetype,
        }
Ejemplo n.º 2
0
    def add_field(self, name, value):
        """Add a form-data field for the request.

        Args:
            name (bytes or unicode):
                The name of the field.

            value (bytes or unicode):
                The value to send for the field.

                For backwards-compatibility, other values will be
                converted to strings. This may turn into a warning in
                future releases. Callers are encouraged to only send
                strings.
        """
        if not isinstance(value, (bytes, six.text_type)):
            value = str(value)

        self._fields[force_bytes(name)] = force_bytes(value)
Ejemplo n.º 3
0
    def _output_patches(self, patches):
        """Output the contents of the patches to the console.

        Args:
            patches (list of dict):
                The list of patches that would be applied.
        """
        for patch_data in patches:
            diff_body = patch_data['diff']

            if isinstance(diff_body, bytes):
                if six.PY3:
                    diff_body = force_bytes(diff_body)
                    sys.stdout.buffer.write(diff_body)
                    print()
                else:
                    print(diff_body.decode('utf-8'))
            else:
                print(diff_body)
Ejemplo n.º 4
0
    def main(self, *args):
        """Print the diff to terminal."""
        # The 'args' tuple must be made into a list for some of the
        # SCM Clients code. See comment in post.
        args = list(args)

        if self.options.revision_range:
            raise CommandError(
                'The --revision-range argument has been removed. To create a '
                'diff for one or more specific revisions, pass those '
                'revisions as arguments. For more information, see the '
                'RBTools 0.6 Release Notes.')

        if self.options.svn_changelist:
            raise CommandError(
                'The --svn-changelist argument has been removed. To use a '
                'Subversion changelist, pass the changelist name as an '
                'additional argument after the command.')

        repository_info, tool = self.initialize_scm_tool(
            client_name=self.options.repository_type)
        server_url = self.get_server_url(repository_info, tool)
        api_client, api_root = self.get_api(server_url)
        self.setup_tool(tool, api_root=api_root)

        try:
            revisions = tool.parse_revision_spec(args)
            extra_args = None
        except InvalidRevisionSpecError:
            if not tool.supports_diff_extra_args:
                raise

            revisions = None
            extra_args = args

        if (self.options.exclude_patterns
                and not tool.supports_diff_exclude_patterns):

            raise CommandError(
                'The %s backend does not support excluding files via the '
                '-X/--exclude commandline options or the EXCLUDE_PATTERNS '
                '.reviewboardrc option.' % tool.name)

        diff_kwargs = {}

        if self.options.no_renames:
            if not tool.supports_no_renames:
                raise CommandError(
                    'The %s SCM tool does not support diffs '
                    'without renames.', tool.type)

            diff_kwargs['no_renames'] = True

        if self.options.git_find_renames_threshold is not None:
            diff_kwargs['git_find_renames_threshold'] = \
                self.options.git_find_renames_threshold

        diff_info = tool.diff(revisions=revisions,
                              include_files=self.options.include_files or [],
                              exclude_patterns=self.options.exclude_patterns
                              or [],
                              extra_args=extra_args,
                              **diff_kwargs)

        diff = diff_info['diff']

        if diff:
            if six.PY2:
                print(diff)
            else:
                # Write the non-decoded binary diff to standard out
                diff = force_bytes(diff)
                sys.stdout.buffer.write(diff)
                print()
Ejemplo n.º 5
0
    def apply_patch(self,
                    diff_file_path,
                    base_dir,
                    patch_num,
                    total_patches,
                    revert=False):
        """Apply a patch to the tree.

        Args:
            diff_file_path (unicode):
                The file path of the diff being applied.

            base_dir (unicode):
                The base directory within which to apply the patch.

            patch_num (int):
                The 1-based index of the patch being applied.

            total_patches (int):
                The total number of patches being applied.

            revert (bool, optional):
                Whether the patch is being reverted.

        Returns:
            bool:
            ``True`` if the patch was applied/reverted successfully.
            ``False`` if the patch was partially applied/reverted but there
            were conflicts.

        Raises:
            rbtools.command.CommandError:
                There was an error applying or reverting the patch.
        """
        # If we're working with more than one patch, show the patch number
        # we're applying or reverting. If we're only working with one, the
        # previous log from _apply_patches() will suffice.
        if total_patches > 1:
            if revert:
                msg = _('Reverting patch %(num)d/%(total)d...')
            else:
                msg = _('Applying patch %(num)d/%(total)d...')

            logger.info(msg, {
                'num': patch_num,
                'total': total_patches,
            })

        result = self._tool.apply_patch(
            patch_file=diff_file_path,
            base_path=self._repository_info.base_path,
            base_dir=base_dir,
            p=self.options.px,
            revert=revert)

        if result.patch_output:
            print()

            patch_output = result.patch_output.strip()

            if six.PY2:
                print(patch_output)
            else:
                patch_output = force_bytes(patch_output)
                sys.stdout.buffer.write(patch_output)
                print()

            print()

        if not result.applied:
            if revert:
                raise CommandError(
                    'Unable to revert the patch. The patch may be invalid, or '
                    'there may be conflicts that could not be resolved.')
            else:
                raise CommandError(
                    'Unable to apply the patch. The patch may be invalid, or '
                    'there may be conflicts that could not be resolved.')

        if result.has_conflicts:
            if result.conflicting_files:
                if revert:
                    print('The patch was partially reverted, but there were '
                          'conflicts in:')
                else:
                    print('The patch was partially applied, but there were '
                          'conflicts in:')

                print()

                for filename in result.conflicting_files:
                    print('    %s' % filename)

                print()
            elif revert:
                print('The patch was partially reverted, but there were '
                      'conflicts.')
            else:
                print('The patch was partially applied, but there were '
                      'conflicts.')

            return False

        return True