# 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(ManifestParseError):
  """The revision value in a project is incorrect.
  """


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


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

  def __init__(self, path, reason):
    super().__init__(path, reason)
    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().__init__(reason)
    self.reason = reason

  def __str__(self):
    return self.reason


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

  def __init__(self, command):
    super().__init__(command)
    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().__init__(reason)
    self.reason = reason

  def __str__(self):
    return self.reason


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

  def __init__(self, reason):
    super().__init__(reason)
    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().__init__(name)
    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().__init__(name)
    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().__init__(extra_args)
    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.
  """
