# 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.


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.
  """
