# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# URL to file bug reports for repo tool issues.
BUG_REPORT_URL = 'https://bugs.chromium.org/p/gerrit/issues/entry?template=Repo+tool+issue'


class ManifestParseError(Exception):
  """Failed to parse the manifest file.
  """


class ManifestInvalidRevisionError(Exception):
  """The revision value in a project is incorrect.
  """


class ManifestInvalidPathError(Exception):
  """A path used in <copyfile> or <linkfile> is incorrect.
  """


class NoManifestException(Exception):
  """The required manifest does not exist.
  """

  def __init__(self, path, reason):
    super(NoManifestException, self).__init__()
    self.path = path
    self.reason = reason

  def __str__(self):
    return self.reason


class EditorError(Exception):
  """Unspecified error from the user's text editor.
  """

  def __init__(self, reason):
    super(EditorError, self).__init__()
    self.reason = reason

  def __str__(self):
    return self.reason


class GitError(Exception):
  """Unspecified internal error from git.
  """

  def __init__(self, command):
    super(GitError, self).__init__()
    self.command = command

  def __str__(self):
    return self.command


class UploadError(Exception):
  """A bundle upload to Gerrit did not succeed.
  """

  def __init__(self, reason):
    super(UploadError, self).__init__()
    self.reason = reason

  def __str__(self):
    return self.reason


class DownloadError(Exception):
  """Cannot download a repository.
  """

  def __init__(self, reason):
    super(DownloadError, self).__init__()
    self.reason = reason

  def __str__(self):
    return self.reason


class NoSuchProjectError(Exception):
  """A specified project does not exist in the work tree.
  """

  def __init__(self, name=None):
    super(NoSuchProjectError, self).__init__()
    self.name = name

  def __str__(self):
    if self.name is None:
      return 'in current directory'
    return self.name


class InvalidProjectGroupsError(Exception):
  """A specified project is not suitable for the specified groups
  """

  def __init__(self, name=None):
    super(InvalidProjectGroupsError, self).__init__()
    self.name = name

  def __str__(self):
    if self.name is None:
      return 'in current directory'
    return self.name


class RepoChangedException(Exception):
  """Thrown if 'repo sync' results in repo updating its internal
     repo or manifest repositories.  In this special case we must
     use exec to re-execute repo with the new code and manifest.
  """

  def __init__(self, extra_args=None):
    super(RepoChangedException, self).__init__()
    self.extra_args = extra_args or []


class HookError(Exception):
  """Thrown if a 'repo-hook' could not be run.

  The common case is that the file wasn't present when we tried to run it.
  """
