You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 line
4.8KB

  1. Error: Dependency Resolution Failure
  2. ####################################
  3. .. note::
  4. ``dds`` implements the `Pubgrub`_ dependency resolution algorithm.
  5. .. _Pubgrub: https://github.com/dart-lang/pub/blob/master/doc/solver.md
  6. If you receive this error, it indicates that the requested dependencies create
  7. one or more conflicts. ``dds`` will do its best to emit a useful explanation of
  8. how this conflict was formed that can hopefully be used to find the original
  9. basis for the conflict.
  10. Every package can have some number of dependencies, which are other packages
  11. that are required for the dependent package to be used. Beyond just a package
  12. name, a dependency will also have a *compatible version range*.
  13. Resolution Example
  14. ******************
  15. For example, let us suppose a package ``Widgets@4.2.8`` may have a *dependency*
  16. on ``Gadgets^2.4.4`` and ``Gizmos^3.2.0``.
  17. .. note::
  18. The ``@4.2.8`` suffix on ``Widgets`` means that ``4.2.8`` is the *exact*
  19. version of ``Widgets``, while the ``^2.4.4`` is a *version range* on
  20. ``Gadgets`` which starts at ``2.4.4`` and includes every version until (but
  21. not including) ``3.0.0``. ``^3.2.0`` is a version range on ``Gizmos`` that
  22. starts at ``3.2.0`` and includes every version until (but not including)
  23. ``4.0.0``.
  24. Now let us suppose the following versions of ``Gadgets`` and ``Gizmos`` are
  25. available:
  26. ``Gadgets``:
  27. - ``2.4.0``
  28. - ``2.4.3``
  29. - ``2.4.4``
  30. - ``2.5.0``
  31. - ``2.6.0``
  32. - ``3.1.0``
  33. ``Gizmos``:
  34. - ``2.1.0``
  35. - ``3.2.0``
  36. - ``3.5.6``
  37. - ``4.5.0``
  38. We can immediately rule out some candidates of ``Gadgets``: for the dependency
  39. ``Gadgets^2.4.4``, ``2.4.0`` and ``2.4.3`` are *too old*, while ``3.1.0`` is
  40. *too new*. This leaves us with ``2.4.4``, ``2.5.0``, and ``2.6.0``.
  41. We'll first look at ``Gadgets@2.4.4``. We need to recursively solve its
  42. dependencies. Suppose that it declares a dependency of ``Gizmos^2.1.0``. We
  43. have already established that we *require* ``Gizmos^3.2.0``, and because
  44. ``^2.1.0`` and ``^3.2.0`` are *disjoint* (they share no common versions) we can
  45. say that ``Gizmos^3.2.0`` is *incompatible* with our existing partial solution,
  46. and that its dependent, ``Gadgets@2.4.4`` is *transitively incompatible* with
  47. the partial solution. Thus, ``Gadgets@2.4.4`` is out of the running.
  48. This doesn't mean we're immediately broken, though. We still have two more
  49. versions of ``Gadgets`` to inspect. We'll start with the next version in line:
  50. ``Gadgets@2.5.0``. Suppose that it has a dependency on ``Gizmos^3.4.0``. We
  51. have already established a requirement of ``Gizmos^3.2.0``, so we must find
  52. a candidate for ``Gizmos`` that satisfies both dependencies. Fortunately, we
  53. have exactly one: ``Gizmos@3.5.6`` satisfies *both* ``Gizmos^3.2.0`` *and*
  54. ``Gizmos^3.4.0``.
  55. Suppose that ``Gizmos@3.5.6`` has no further dependencies. At this point, we
  56. have inspected all dependencies and have resolutions for every named package:
  57. Thus, we have a valid solution of ``Widgets@4.2.8``, ``Gadgets@2.5.0``, and
  58. ``Gizmos@2.6.0``! We didn't even need to inspect ``Gadgets@2.6.0``.
  59. In this case, ``dds`` will not produce an error, and the given package solution
  60. will be used.
  61. Breaking the Solution
  62. =====================
  63. Now suppose the same case, except that ``Gadgets@2.5.0`` is not available.
  64. We'll instead move to check ``Gadgets@2.6.0``.
  65. Suppose that ``Gadgets@2.6.0`` has a dependency on ``Gizmos^4.0.6``. While we
  66. *do* have a candidate thereof, we've already declared a requriement on
  67. ``Gizmos^3.2.0``. Because ``^4.0.6`` and ``^3.2.0`` are disjoint, then there is
  68. no possible satisfier for both ranges. This means that ``Gizmos^4.0.6`` is
  69. incompatible in the partial solution, and that ``Gadgets@2.6.0`` is
  70. transitively incompatible as well. It is no longer a candidate.
  71. We've exhausted the available candidates for ``Gadgets^2.4.4``, so we must now
  72. conclude that ``Gadgets^2.4.4`` is *also incompatible*. Transitively, this also
  73. means that ``Widgets@4.2.8`` is incompatible as well.
  74. We've reached a problem, though: ``Widgets@4.2.8`` is our original requirement!
  75. There is nothing left to invalidate in our partial solution, so we rule that
  76. our original requirements are *unsatisfiable*.
  77. At this point, ``dds`` will raise the error that *dependency resolution has
  78. failed*. It will attempt its best to reconstruct the logic that we have used
  79. above in order to explain what has gone wrong.
  80. Fixing the Problem
  81. ******************
  82. There is no strict process for fixing these conflicts.
  83. Fixing a dependency conflict is a manual process. It will require reviewing the
  84. available versions and underlying reasons that the dependency maintainers have
  85. chosen their compatibility ranges statements.
  86. Your own dependency statements will often need to be changed, and sometimes
  87. even code will have to be revised to reach compatibility with newer or older
  88. dependency versions.