Beispiel #1
0
    def create_from_upload(self,
                           repository,
                           diff_file,
                           parent_diff_file=None,
                           request=None,
                           validate_only=False,
                           **kwargs):
        """Create a model instance from a form upload.

        This parses a diff and optional parent diff covering one or more files,
        validates, and constructs either:

        * a :py:class:`~reviewboard.diffviewer.models.diffset.DiffSet` or
        * a :py:class:`~reviewboard.diffviewer.models.diffcommit.DiffCommit`

        and the child :py:class:`FileDiffs
        <reviewboard.diffviewer.models.filediff.FileDiff>` representing the
        diff.

        This can optionally validate the diff without saving anything to the
        database. In this case, no value will be returned. Instead, callers
        should take any result as success.

        This function also accepts a number of keyword arguments when creating
        a :py:class:`~reviewboard.diffviewer.model.DiffCommit`. In that case,
        the following fields are required (except for the committer fields when
        the underlying SCM does not distinguish betwen author and committer):

        Args:
            repository (reviewboard.scmtools.models.Repository):
                The repository the diff applies to.

            diff_file (django.core.files.uploadedfile.UploadedFile):
                The diff file uploaded in the form.

            parent_diff_file (django.core.files.uploadedfile.UploadedFile,
                              optional):
                The parent diff file uploaded in the form.

            request (django.http.HttpRequest, optional):
                The current HTTP request, if any. This will result in better
                logging.

            validate_only (bool, optional):
                Whether to just validate and not save. If ``True``, then this
                won't populate the database at all and will return ``None``
                upon success. This defaults to ``False``.

            **kwargs (dict):
                Additional keyword arguments to pass to
                :py:meth:`create_from_data`.

                See :py:meth:`~DiffSetManager.create_from_data` and
                :py:meth:`DiffCommitManager.create_from_data` for acceptable
                keyword arguments.

        Returns:
            reviewboard.diffviewer.models.diffset.DiffSet:
            The resulting DiffSet stored in the database, if processing
            succeeded and ``validate_only=False``.

        Raises:
            reviewboard.diffviewer.errors.DiffParserError:
                There was an error parsing the main diff or parent diff.

            reviewboard.diffviewer.errors.DiffTooBigError:
                The diff file was too big to be uploaded, based on the
                configured maximum diff size in settings.

            reviewboard.diffviewer.errors.EmptyDiffError:
                The provided diff file did not contain any file changes.

            reviewboard.scmtools.core.FileNotFoundError:
                A file specified in the diff could not be found in the
                repository.

            reviewboard.scmtools.core.SCMError:
                There was an error talking to the repository when validating
                the existence of a file.

            reviewboard.scmtools.git.ShortSHA1Error:
                A SHA1 specified in the diff was in the short form, which
                could not be used to look up the file. This is applicable only
                to Git.
        """
        if 'save' in kwargs:
            warnings.warn(
                'The save parameter to %s.objects.create_from_upload is '
                'deprecated. Please set validate_only instead.' %
                type(self.model).__name__, RemovedInReviewBoard40Warning)
            validate_only = not kwargs.pop('save')

        check_diff_size(diff_file, parent_diff_file)

        if parent_diff_file:
            parent_diff_file_name = parent_diff_file.name
            parent_diff_file_contents = parent_diff_file.read()
        else:
            parent_diff_file_name = None
            parent_diff_file_contents = None

        return self.create_from_data(
            repository=repository,
            diff_file_name=diff_file.name,
            diff_file_contents=diff_file.read(),
            parent_diff_file_name=parent_diff_file_name,
            parent_diff_file_contents=parent_diff_file_contents,
            request=request,
            validate_only=validate_only,
            **kwargs)
Beispiel #2
0
    def validate_diff(self):
        """Validate the DiffCommit.

        This will attempt to parse the given diff (and optionally parent
        diff) into :py:class:`FileDiffs
        <reviewboard.diffviewer.models.filediff.FileDiff>`. This will not
        result in anything being committed to the database.

        Returns:
            tuple:
            A 2-tuple containing the following:

            * A list of the created FileDiffs.
            * A list of the parent FileDiffs, or ``None``.

        Raises:
            reviewboard.diffviewer.errors.DiffParserError:
                The diff could not be parsed.

            reviewboard.diffviewer.errors.DiffTooBigError:
                The diff was too big.

            reviewboard.diffviewer.errors.EmptyDiffError:
                The diff did not contain any changes.

            reviewboard.scmtools.errors.FileNotFoundError:
                A file was not found in the repository.

            reviewboard.scmtools.errors.SCMError:
                An error occurred within the SCMTool.
        """
        assert self.is_valid()

        diff_file = self.cleaned_data['diff']
        parent_diff_file = self.cleaned_data.get('parent_diff')
        validation_info = self.cleaned_data.get('validation_info')

        check_diff_size(diff_file, parent_diff_file)

        if parent_diff_file:
            parent_diff_file_contents = parent_diff_file.read()
        else:
            parent_diff_file_contents = None

        base_commit_id = self.cleaned_data['base_commit_id']

        diffset = DiffSet(name='diff',
                          revision=0,
                          basedir='',
                          repository=self.repository,
                          diffcompat=DiffCompatVersion.DEFAULT,
                          base_commit_id=base_commit_id)

        get_file_exists = partial(get_file_exists_in_history, validation_info
                                  or {}, self.repository,
                                  self.cleaned_data['parent_id'])

        return create_filediffs(
            diff_file_contents=diff_file.read(),
            parent_diff_file_contents=parent_diff_file_contents,
            repository=self.repository,
            basedir='',
            base_commit_id=base_commit_id,
            get_file_exists=get_file_exists,
            diffset=diffset,
            request=self.request,
            diffcommit=None,
            validate_only=True)
Beispiel #3
0
    def validate_diff(self):
        """Validate the DiffCommit.

        This will attempt to parse the given diff (and optionally parent
        diff) into :py:class:`FileDiffs
        <reviewboard.diffviewer.models.filediff.FileDiff>`. This will not
        result in anything being committed to the database.

        Returns:
            tuple:
            A 2-tuple containing the following:

            * A list of the created FileDiffs.
            * A list of the parent FileDiffs, or ``None``.

        Raises:
            reviewboard.diffviewer.errors.DiffParserError:
                The diff could not be parsed.

            reviewboard.diffviewer.errors.DiffTooBigError:
                The diff was too big.

            reviewboard.diffviewer.errors.EmptyDiffError:
                The diff did not contain any changes.

            reviewboard.scmtools.errors.FileNotFoundError:
                A file was not found in the repository.

            reviewboard.scmtools.errors.SCMError:
                An error occurred within the SCMTool.
        """
        assert self.is_valid()

        diff_file = self.cleaned_data['diff']
        parent_diff_file = self.cleaned_data.get('parent_diff')
        validation_info = self.cleaned_data.get('validation_info')

        check_diff_size(diff_file, parent_diff_file)

        if parent_diff_file:
            parent_diff_file_contents = parent_diff_file.read()
        else:
            parent_diff_file_contents = None

        base_commit_id = self.cleaned_data['base_commit_id']

        diffset = DiffSet(name='diff',
                          revision=0,
                          basedir='',
                          repository=self.repository,
                          diffcompat=DiffCompatVersion.DEFAULT,
                          base_commit_id=base_commit_id)

        get_file_exists = partial(get_file_exists_in_history,
                                  validation_info or {},
                                  self.repository,
                                  self.cleaned_data['parent_id'])

        return create_filediffs(
            diff_file_contents=diff_file.read(),
            parent_diff_file_contents=parent_diff_file_contents,
            repository=self.repository,
            basedir='',
            base_commit_id=base_commit_id,
            get_file_exists=get_file_exists,
            diffset=diffset,
            request=self.request,
            diffcommit=None,
            validate_only=True)
Beispiel #4
0
    def create_from_upload(self, repository, diff_file, parent_diff_file=None,
                           request=None, validate_only=False, **kwargs):
        """Create a model instance from a form upload.

        This parses a diff and optional parent diff covering one or more files,
        validates, and constructs either:

        * a :py:class:`~reviewboard.diffviewer.models.diffset.DiffSet` or
        * a :py:class:`~reviewboard.diffviewer.models.diffcommit.DiffCommit`

        and the child :py:class:`FileDiffs
        <reviewboard.diffviewer.models.filediff.FileDiff>` representing the
        diff.

        This can optionally validate the diff without saving anything to the
        database. In this case, no value will be returned. Instead, callers
        should take any result as success.

        This function also accepts a number of keyword arguments when creating
        a :py:class:`~reviewboard.diffviewer.model.DiffCommit`. In that case,
        the following fields are required (except for the committer fields when
        the underlying SCM does not distinguish betwen author and committer):

        Args:
            repository (reviewboard.scmtools.models.Repository):
                The repository the diff applies to.

            diff_file (django.core.files.uploadedfile.UploadedFile):
                The diff file uploaded in the form.

            parent_diff_file (django.core.files.uploadedfile.UploadedFile,
                              optional):
                The parent diff file uploaded in the form.

            request (django.http.HttpRequest, optional):
                The current HTTP request, if any. This will result in better
                logging.

            validate_only (bool, optional):
                Whether to just validate and not save. If ``True``, then this
                won't populate the database at all and will return ``None``
                upon success. This defaults to ``False``.

            **kwargs (dict):
                Additional keyword arguments to pass to
                :py:meth:`create_from_data`.

                See :py:meth:`~DiffSetManager.create_from_data` and
                :py:meth:`DiffCommitManager.create_from_data` for acceptable
                keyword arguments.

        Returns:
            reviewboard.diffviewer.models.diffset.DiffSet:
            The resulting DiffSet stored in the database, if processing
            succeeded and ``validate_only=False``.

        Raises:
            reviewboard.diffviewer.errors.DiffParserError:
                There was an error parsing the main diff or parent diff.

            reviewboard.diffviewer.errors.DiffTooBigError:
                The diff file was too big to be uploaded, based on the
                configured maximum diff size in settings.

            reviewboard.diffviewer.errors.EmptyDiffError:
                The provided diff file did not contain any file changes.

            reviewboard.scmtools.core.FileNotFoundError:
                A file specified in the diff could not be found in the
                repository.

            reviewboard.scmtools.core.SCMError:
                There was an error talking to the repository when validating
                the existence of a file.

            reviewboard.scmtools.git.ShortSHA1Error:
                A SHA1 specified in the diff was in the short form, which
                could not be used to look up the file. This is applicable only
                to Git.
        """
        if 'save' in kwargs:
            warnings.warn(
                'The save parameter to %s.objects.create_from_upload is '
                'deprecated. Please set validate_only instead.'
                % type(self.model).__name__,
                RemovedInReviewBoard40Warning)
            validate_only = not kwargs.pop('save')

        check_diff_size(diff_file, parent_diff_file)

        if parent_diff_file:
            parent_diff_file_name = parent_diff_file.name
            parent_diff_file_contents = parent_diff_file.read()
        else:
            parent_diff_file_name = None
            parent_diff_file_contents = None

        return self.create_from_data(
            repository=repository,
            diff_file_name=diff_file.name,
            diff_file_contents=diff_file.read(),
            parent_diff_file_name=parent_diff_file_name,
            parent_diff_file_contents=parent_diff_file_contents,
            request=request,
            validate_only=validate_only,
            **kwargs)