diff --git a/scenarios/does-not-exist.json b/scenarios/does-not-exist.json deleted file mode 100644 index ad9b9616..00000000 --- a/scenarios/does-not-exist.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "name": "requires-package-does-not-exist", - "description": "The user requires any version of package `a` which does not exist.", - "root": { - "requires": [ - "a" - ] - }, - "packages": {}, - "expected": { - "satisfiable": false - } - }, - { - "name": "requires-exact-version-does-not-exist", - "description": "The user requires an exact version of package `a` but only other versions exist", - "root": { - "requires": [ - "a==2.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "requires-greater-version-does-not-exist", - "description": "The user requires a version of `a` greater than `1.0.0` but only smaller or equal versions exist", - "root": { - "requires": [ - "a>1.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "requires-less-version-does-not-exist", - "description": "The user requires a version of `a` less than `1.0.0` but only larger versions exist", - "root": { - "requires": [ - "a<2.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "2.0.0": {}, - "3.0.0": {}, - "4.0.0": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "transitive-requires-package-does-not-exist", - "description": "The user requires package `a` but `a` requires package `b` which does not exist", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b" - ] - } - } - } - }, - "expected": { - "satisfiable": false - } - } -] diff --git a/scenarios/does_not_exist/requires-exact-version-does-not-exist.toml b/scenarios/does_not_exist/requires-exact-version-does-not-exist.toml new file mode 100644 index 00000000..fcaceaf2 --- /dev/null +++ b/scenarios/does_not_exist/requires-exact-version-does-not-exist.toml @@ -0,0 +1,10 @@ +name = "requires-exact-version-does-not-exist" +description = "The user requires an exact version of package `a` but only other versions exist" + +[root] +requires = ["a==2.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] diff --git a/scenarios/does_not_exist/requires-greater-version-does-not-exist.toml b/scenarios/does_not_exist/requires-greater-version-does-not-exist.toml new file mode 100644 index 00000000..ba1db63c --- /dev/null +++ b/scenarios/does_not_exist/requires-greater-version-does-not-exist.toml @@ -0,0 +1,12 @@ +name = "requires-greater-version-does-not-exist" +description = "The user requires a version of `a` greater than `1.0.0` but only smaller or equal versions exist" + +[root] +requires = ["a>1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."0.1.0"] + +[packages.a.versions."1.0.0"] diff --git a/scenarios/does_not_exist/requires-less-version-does-not-exist.toml b/scenarios/does_not_exist/requires-less-version-does-not-exist.toml new file mode 100644 index 00000000..b690544c --- /dev/null +++ b/scenarios/does_not_exist/requires-less-version-does-not-exist.toml @@ -0,0 +1,14 @@ +name = "requires-less-version-does-not-exist" +description = "The user requires a version of `a` less than `1.0.0` but only larger versions exist" + +[root] +requires = ["a<2.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."2.0.0"] + +[packages.a.versions."3.0.0"] + +[packages.a.versions."4.0.0"] diff --git a/scenarios/does_not_exist/requires-package-does-not-exist.toml b/scenarios/does_not_exist/requires-package-does-not-exist.toml new file mode 100644 index 00000000..001ae7b8 --- /dev/null +++ b/scenarios/does_not_exist/requires-package-does-not-exist.toml @@ -0,0 +1,10 @@ +name = "requires-package-does-not-exist" +description = "The user requires any version of package `a` which does not exist." + +[root] +requires = ["a"] + +[packages] + +[expected] +satisfiable = false diff --git a/scenarios/does_not_exist/transitive-requires-package-does-not-exist.toml b/scenarios/does_not_exist/transitive-requires-package-does-not-exist.toml new file mode 100644 index 00000000..036b0a01 --- /dev/null +++ b/scenarios/does_not_exist/transitive-requires-package-does-not-exist.toml @@ -0,0 +1,11 @@ +name = "transitive-requires-package-does-not-exist" +description = "The user requires package `a` but `a` requires package `b` which does not exist" + +[root] +requires = ["a"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["b"] diff --git a/scenarios/excluded.json b/scenarios/excluded.json deleted file mode 100644 index 13feeb30..00000000 --- a/scenarios/excluded.json +++ /dev/null @@ -1,215 +0,0 @@ -[ - { - "name": "excluded-only-version", - "description": "Only one version of the requested package is available, but the user has banned that version.", - "root": { - "requires": [ - "a!=1.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Only `a==1.0.0` is available but the user excluded it." - } - }, - { - "name": "excluded-only-compatible-version", - "description": "Only one version of the requested package `a` is compatible, but the user has banned that version.", - "root": { - "requires": [ - "a!=2.0.0", - "b>=2.0.0,<3.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==1.0.0" - ] - }, - "2.0.0": { - "requires": [ - "b==2.0.0" - ] - }, - "3.0.0": { - "requires": [ - "b==3.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {}, - "3.0.0": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Only `a==1.2.0` is available since `a==1.0.0` and `a==3.0.0` require incompatible versions of `b`. The user has excluded that version of `a` so resolution fails." - } - }, - { - "name": "dependency-excludes-range-of-compatible-versions", - "description": "There is a range of compatible versions for the requested package `a`, but another dependency `c` excludes that range.", - "root": { - "requires": [ - "a", - "b>=2.0.0,<3.0.0", - "c" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==1.0.0" - ] - }, - "2.0.0": { - "requires": [ - "b==2.0.0" - ] - }, - "2.1.0": { - "requires": [ - "b==2.0.0" - ] - }, - "2.2.0": { - "requires": [ - "b==2.0.0" - ] - }, - "2.3.0": { - "requires": [ - "b==2.0.0" - ] - }, - "3.0.0": { - "requires": [ - "b==3.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {}, - "3.0.0": {} - } - }, - "c": { - "versions": { - "1.0.0": { - "requires": [ - "a<2.0.0" - ] - }, - "2.0.0": { - "requires": [ - "a>=3.0.0" - ] - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Only the `2.x` versions of `a` are available since `a==1.0.0` and `a==3.0.0` require incompatible versions of `b`, but all available versions of `c` exclude that range of `a` so resolution fails." - } - }, - { - "name": "dependency-excludes-non-contiguous-range-of-compatible-versions", - "description": "There is a non-contiguous range of compatible versions for the requested package `a`, but another dependency `c` excludes the range. This is the same as `dependency-excludes-range-of-compatible-versions` but some of the versions of `a` are incompatible for another reason e.g. dependency on non-existent package `d`.", - "root": { - "requires": [ - "a", - "b>=2.0.0,<3.0.0", - "c" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==1.0.0" - ] - }, - "2.0.0": { - "requires": [ - "b==2.0.0" - ] - }, - "2.1.0": { - "requires": [ - "b==2.0.0", - "d" - ] - }, - "2.2.0": { - "requires": [ - "b==2.0.0" - ] - }, - "2.3.0": { - "requires": [ - "b==2.0.0", - "d" - ] - }, - "2.4.0": { - "requires": [ - "b==2.0.0" - ] - }, - "3.0.0": { - "requires": [ - "b==3.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {}, - "3.0.0": {} - } - }, - "c": { - "versions": { - "1.0.0": { - "requires": [ - "a<2.0.0" - ] - }, - "2.0.0": { - "requires": [ - "a>=3.0.0" - ] - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Only the `2.x` versions of `a` are available since `a==1.0.0` and `a==3.0.0` require incompatible versions of `b`, but all available versions of `c` exclude that range of `a` so resolution fails." - } - } -] diff --git a/scenarios/excluded/dependency-excludes-non-contiguous-range-of-compatible-versions.toml b/scenarios/excluded/dependency-excludes-non-contiguous-range-of-compatible-versions.toml new file mode 100644 index 00000000..f51a2308 --- /dev/null +++ b/scenarios/excluded/dependency-excludes-non-contiguous-range-of-compatible-versions.toml @@ -0,0 +1,42 @@ +name = "dependency-excludes-non-contiguous-range-of-compatible-versions" +description = "There is a non-contiguous range of compatible versions for the requested package `a`, but another dependency `c` excludes the range. This is the same as `dependency-excludes-range-of-compatible-versions` but some of the versions of `a` are incompatible for another reason e.g. dependency on non-existent package `d`." + +[root] +requires = ["a", "b>=2.0.0,<3.0.0", "c"] + +[expected] +satisfiable = false +explanation = "Only the `2.x` versions of `a` are available since `a==1.0.0` and `a==3.0.0` require incompatible versions of `b`, but all available versions of `c` exclude that range of `a` so resolution fails." + +[packages.a.versions."1.0.0"] +requires = ["b==1.0.0"] + +[packages.a.versions."2.0.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."2.1.0"] +requires = ["b==2.0.0", "d"] + +[packages.a.versions."2.2.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."2.3.0"] +requires = ["b==2.0.0", "d"] + +[packages.a.versions."2.4.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."3.0.0"] +requires = ["b==3.0.0"] + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] + +[packages.b.versions."3.0.0"] + +[packages.c.versions."1.0.0"] +requires = ["a<2.0.0"] + +[packages.c.versions."2.0.0"] +requires = ["a>=3.0.0"] diff --git a/scenarios/excluded/dependency-excludes-range-of-compatible-versions.toml b/scenarios/excluded/dependency-excludes-range-of-compatible-versions.toml new file mode 100644 index 00000000..1fe20d66 --- /dev/null +++ b/scenarios/excluded/dependency-excludes-range-of-compatible-versions.toml @@ -0,0 +1,39 @@ +name = "dependency-excludes-range-of-compatible-versions" +description = "There is a range of compatible versions for the requested package `a`, but another dependency `c` excludes that range." + +[root] +requires = ["a", "b>=2.0.0,<3.0.0", "c"] + +[expected] +satisfiable = false +explanation = "Only the `2.x` versions of `a` are available since `a==1.0.0` and `a==3.0.0` require incompatible versions of `b`, but all available versions of `c` exclude that range of `a` so resolution fails." + +[packages.a.versions."1.0.0"] +requires = ["b==1.0.0"] + +[packages.a.versions."2.0.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."2.1.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."2.2.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."2.3.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."3.0.0"] +requires = ["b==3.0.0"] + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] + +[packages.b.versions."3.0.0"] + +[packages.c.versions."1.0.0"] +requires = ["a<2.0.0"] + +[packages.c.versions."2.0.0"] +requires = ["a>=3.0.0"] diff --git a/scenarios/excluded/excluded-only-compatible-version.toml b/scenarios/excluded/excluded-only-compatible-version.toml new file mode 100644 index 00000000..64b45e95 --- /dev/null +++ b/scenarios/excluded/excluded-only-compatible-version.toml @@ -0,0 +1,24 @@ +name = "excluded-only-compatible-version" +description = "Only one version of the requested package `a` is compatible, but the user has banned that version." + +[root] +requires = ["a!=2.0.0", "b>=2.0.0,<3.0.0"] + +[expected] +satisfiable = false +explanation = "Only `a==1.2.0` is available since `a==1.0.0` and `a==3.0.0` require incompatible versions of `b`. The user has excluded that version of `a` so resolution fails." + +[packages.a.versions."1.0.0"] +requires = ["b==1.0.0"] + +[packages.a.versions."2.0.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."3.0.0"] +requires = ["b==3.0.0"] + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] + +[packages.b.versions."3.0.0"] diff --git a/scenarios/excluded/excluded-only-version.toml b/scenarios/excluded/excluded-only-version.toml new file mode 100644 index 00000000..bcda8275 --- /dev/null +++ b/scenarios/excluded/excluded-only-version.toml @@ -0,0 +1,11 @@ +name = "excluded-only-version" +description = "Only one version of the requested package is available, but the user has banned that version." + +[root] +requires = ["a!=1.0.0"] + +[expected] +satisfiable = false +explanation = "Only `a==1.0.0` is available but the user excluded it." + +[packages.a.versions."1.0.0"] diff --git a/scenarios/extras.json b/scenarios/extras.json deleted file mode 100644 index 43674f1d..00000000 --- a/scenarios/extras.json +++ /dev/null @@ -1,292 +0,0 @@ -[ - { - "name": "extra-required", - "description": "Optional dependencies are requested for the package.", - "root": { - "requires": [ - "a[extra]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "extra": [ - "b" - ] - } - } - } - }, - "b": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "1.0.0" - } - } - }, - { - "name": "missing-extra", - "description": "Optional dependencies are requested for the package, but the extra does not exist.", - "root": { - "requires": [ - "a[extra]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "Missing extras are ignored during resolution.", - "packages": { - "a": "1.0.0" - } - } - }, - { - "name": "multiple-extras-required", - "description": "Multiple optional dependencies are requested for the package.", - "root": { - "requires": [ - "a[extra_b,extra_c]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "extra_b": [ - "b" - ], - "extra_c": [ - "c" - ] - } - } - } - }, - "b": { - "versions": { - "1.0.0": {} - } - }, - "c": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "1.0.0", - "c": "1.0.0" - } - } - }, - { - "name": "all-extras-required", - "description": "Multiple optional dependencies are requested for the package via an 'all' extra.", - "root": { - "requires": [ - "a[all]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "all": [ - "a[extra_b]", - "a[extra_c]" - ], - "extra_b": [ - "b" - ], - "extra_c": [ - "c" - ] - } - } - } - }, - "b": { - "versions": { - "1.0.0": {} - } - }, - "c": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "1.0.0", - "c": "1.0.0" - } - } - }, - { - "name": "extra-incompatible-with-extra", - "description": "Multiple optional dependencies are requested for the package, but they have conflicting requirements with each other.", - "root": { - "requires": [ - "a[extra_b,extra_c]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "extra_b": [ - "b==1.0.0" - ], - "extra_c": [ - "b==2.0.0" - ] - } - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {} - } - } - }, - "expected": { - "explanation": "Because both `extra_b` and `extra_c` are requested and they require incompatible versions of `b`, `a` cannot be installed.", - "satisfiable": false - } - }, - { - "name": "extra-incompatible-with-extra-not-requested", - "description": "One of two incompatible optional dependencies are requested for the package.", - "root": { - "requires": [ - "a[extra_c]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "extra_b": [ - "b==1.0.0" - ], - "extra_c": [ - "b==2.0.0" - ] - } - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "Because the user does not request both extras, it is okay that one is incompatible with the other.", - "packages": { - "a": "1.0.0", - "b": "2.0.0" - } - } - }, - { - "name": "extra-incompatible-with-root", - "description": "Optional dependencies are requested for the package, but the extra is not compatible with other requested versions.", - "root": { - "requires": [ - "a[extra]", - "b==2.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "extra": [ - "b==1.0.0" - ] - } - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {} - } - } - }, - "expected": { - "explanation": "Because the user requested `b==2.0.0` but the requested extra requires `b==1.0.0`, the dependencies cannot be satisfied.", - "satisfiable": false - } - }, - { - "name": "extra-does-not-exist-backtrack", - "description": "Optional dependencies are requested for the package, the extra is only available on an older version.", - "root": { - "requires": [ - "a[extra]" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "extras": { - "extra": [ - "b==1.0.0" - ] - } - }, - "2.0.0": {}, - "3.0.0": {} - } - }, - "b": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "The resolver should not backtrack to `a==1.0.0` because missing extras are allowed during resolution. `b` should not be installed.", - "packages": { - "a": "3.0.0" - } - } - } -] diff --git a/scenarios/extras/all-extras-required.toml b/scenarios/extras/all-extras-required.toml new file mode 100644 index 00000000..013edf74 --- /dev/null +++ b/scenarios/extras/all-extras-required.toml @@ -0,0 +1,22 @@ +name = "all-extras-required" +description = "Multiple optional dependencies are requested for the package via an 'all' extra." + +[root] +requires = ["a[all]"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0" +b = "1.0.0" +c = "1.0.0" + +[packages.b.versions."1.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.a.versions."1.0.0".extras] +all = ["a[extra_b]", "a[extra_c]"] +extra_b = ["b"] +extra_c = ["c"] diff --git a/scenarios/extras/extra-does-not-exist-backtrack.toml b/scenarios/extras/extra-does-not-exist-backtrack.toml new file mode 100644 index 00000000..172aa818 --- /dev/null +++ b/scenarios/extras/extra-does-not-exist-backtrack.toml @@ -0,0 +1,21 @@ +name = "extra-does-not-exist-backtrack" +description = "Optional dependencies are requested for the package, the extra is only available on an older version." + +[root] +requires = ["a[extra]"] + +[expected] +satisfiable = true +explanation = "The resolver should not backtrack to `a==1.0.0` because missing extras are allowed during resolution. `b` should not be installed." + +[expected.packages] +a = "3.0.0" + +[packages.a.versions."2.0.0"] + +[packages.a.versions."3.0.0"] + +[packages.b.versions."1.0.0"] + +[packages.a.versions."1.0.0".extras] +extra = ["b==1.0.0"] diff --git a/scenarios/extras/extra-incompatible-with-extra-not-requested.toml b/scenarios/extras/extra-incompatible-with-extra-not-requested.toml new file mode 100644 index 00000000..915dd4d0 --- /dev/null +++ b/scenarios/extras/extra-incompatible-with-extra-not-requested.toml @@ -0,0 +1,21 @@ +name = "extra-incompatible-with-extra-not-requested" +description = "One of two incompatible optional dependencies are requested for the package." + +[root] +requires = ["a[extra_c]"] + +[expected] +satisfiable = true +explanation = "Because the user does not request both extras, it is okay that one is incompatible with the other." + +[expected.packages] +a = "1.0.0" +b = "2.0.0" + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] + +[packages.a.versions."1.0.0".extras] +extra_b = ["b==1.0.0"] +extra_c = ["b==2.0.0"] diff --git a/scenarios/extras/extra-incompatible-with-extra.toml b/scenarios/extras/extra-incompatible-with-extra.toml new file mode 100644 index 00000000..14ad87ca --- /dev/null +++ b/scenarios/extras/extra-incompatible-with-extra.toml @@ -0,0 +1,17 @@ +name = "extra-incompatible-with-extra" +description = "Multiple optional dependencies are requested for the package, but they have conflicting requirements with each other." + +[root] +requires = ["a[extra_b,extra_c]"] + +[expected] +explanation = "Because both `extra_b` and `extra_c` are requested and they require incompatible versions of `b`, `a` cannot be installed." +satisfiable = false + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] + +[packages.a.versions."1.0.0".extras] +extra_b = ["b==1.0.0"] +extra_c = ["b==2.0.0"] diff --git a/scenarios/extras/extra-incompatible-with-root.toml b/scenarios/extras/extra-incompatible-with-root.toml new file mode 100644 index 00000000..719960db --- /dev/null +++ b/scenarios/extras/extra-incompatible-with-root.toml @@ -0,0 +1,16 @@ +name = "extra-incompatible-with-root" +description = "Optional dependencies are requested for the package, but the extra is not compatible with other requested versions." + +[root] +requires = ["a[extra]", "b==2.0.0"] + +[expected] +explanation = "Because the user requested `b==2.0.0` but the requested extra requires `b==1.0.0`, the dependencies cannot be satisfied." +satisfiable = false + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] + +[packages.a.versions."1.0.0".extras] +extra = ["b==1.0.0"] diff --git a/scenarios/extras/extra-required.toml b/scenarios/extras/extra-required.toml new file mode 100644 index 00000000..9094d183 --- /dev/null +++ b/scenarios/extras/extra-required.toml @@ -0,0 +1,17 @@ +name = "extra-required" +description = "Optional dependencies are requested for the package." + +[root] +requires = ["a[extra]"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0" +b = "1.0.0" + +[packages.b.versions."1.0.0"] + +[packages.a.versions."1.0.0".extras] +extra = ["b"] diff --git a/scenarios/extras/missing-extra.toml b/scenarios/extras/missing-extra.toml new file mode 100644 index 00000000..42f065d4 --- /dev/null +++ b/scenarios/extras/missing-extra.toml @@ -0,0 +1,14 @@ +name = "missing-extra" +description = "Optional dependencies are requested for the package, but the extra does not exist." + +[root] +requires = ["a[extra]"] + +[expected] +satisfiable = true +explanation = "Missing extras are ignored during resolution." + +[expected.packages] +a = "1.0.0" + +[packages.a.versions."1.0.0"] diff --git a/scenarios/extras/multiple-extras-required.toml b/scenarios/extras/multiple-extras-required.toml new file mode 100644 index 00000000..5d396161 --- /dev/null +++ b/scenarios/extras/multiple-extras-required.toml @@ -0,0 +1,21 @@ +name = "multiple-extras-required" +description = "Multiple optional dependencies are requested for the package." + +[root] +requires = ["a[extra_b,extra_c]"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0" +b = "1.0.0" +c = "1.0.0" + +[packages.b.versions."1.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.a.versions."1.0.0".extras] +extra_b = ["b"] +extra_c = ["c"] diff --git a/scenarios/fork/allows-non-conflicting-non-overlapping-dependencies.toml b/scenarios/fork/allows-non-conflicting-non-overlapping-dependencies.toml index 68e3b3d5..12bc128c 100644 --- a/scenarios/fork/allows-non-conflicting-non-overlapping-dependencies.toml +++ b/scenarios/fork/allows-non-conflicting-non-overlapping-dependencies.toml @@ -18,10 +18,7 @@ universal = true satisfiable = true [root] -requires = [ - "a>=1 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=1 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] [packages.a.versions."2.0.0"] diff --git a/scenarios/fork/basic.toml b/scenarios/fork/basic.toml index d6f90c50..886cd54f 100644 --- a/scenarios/fork/basic.toml +++ b/scenarios/fork/basic.toml @@ -11,10 +11,7 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] [packages.a.versions."2.0.0"] diff --git a/scenarios/fork/conflict-in-fork.toml b/scenarios/fork/conflict-in-fork.toml index d153a114..d0b63ddf 100644 --- a/scenarios/fork/conflict-in-fork.toml +++ b/scenarios/fork/conflict-in-fork.toml @@ -10,27 +10,17 @@ universal = true satisfiable = false [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] -requires = [ - "b", - "c" -] +requires = ["b", "c"] [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] -requires = [ - "d==1", -] +requires = ["d==1"] [packages.c.versions."1.0.0"] -requires = [ - "d==2", -] +requires = ["d==2"] [packages.d.versions."1.0.0"] [packages.d.versions."2.0.0"] diff --git a/scenarios/fork/fork-upgrade.toml b/scenarios/fork/fork-upgrade.toml index c6d4ac5c..7cdc16f3 100644 --- a/scenarios/fork/fork-upgrade.toml +++ b/scenarios/fork/fork-upgrade.toml @@ -10,9 +10,7 @@ universal = true satisfiable = true [root] -requires = [ - "foo", -] +requires = ["foo"] [packages.foo.versions."1.0.0"] requires = [ diff --git a/scenarios/fork/incomplete-markers.toml b/scenarios/fork/incomplete-markers.toml index c870bfc2..db9ae091 100644 --- a/scenarios/fork/incomplete-markers.toml +++ b/scenarios/fork/incomplete-markers.toml @@ -24,8 +24,6 @@ requires = [ [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] -requires = [ - "c; python_version == '3.10'", -] +requires = ["c; python_version == '3.10'"] [packages.c.versions."1.0.0"] diff --git a/scenarios/fork/marker-disjoint.toml b/scenarios/fork/marker-disjoint.toml index 9652ca17..b9a54213 100644 --- a/scenarios/fork/marker-disjoint.toml +++ b/scenarios/fork/marker-disjoint.toml @@ -20,10 +20,7 @@ universal = true satisfiable = false [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'linux'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'linux'"] [packages.a.versions."1.0.0"] [packages.a.versions."2.0.0"] diff --git a/scenarios/fork/marker-inherit-combined-allowed.toml b/scenarios/fork/marker-inherit-combined-allowed.toml index acb20a30..3492a815 100644 --- a/scenarios/fork/marker-inherit-combined-allowed.toml +++ b/scenarios/fork/marker-inherit-combined-allowed.toml @@ -15,10 +15,7 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] requires = [ @@ -28,9 +25,7 @@ requires = [ [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] -requires = [ - "c ; sys_platform == 'linux' or implementation_name == 'pypy'", -] +requires = ["c ; sys_platform == 'linux' or implementation_name == 'pypy'"] [packages.b.versions."2.0.0"] [packages.c.versions."1.0.0"] diff --git a/scenarios/fork/marker-inherit-combined-disallowed.toml b/scenarios/fork/marker-inherit-combined-disallowed.toml index 281b705e..229d8c9d 100644 --- a/scenarios/fork/marker-inherit-combined-disallowed.toml +++ b/scenarios/fork/marker-inherit-combined-disallowed.toml @@ -16,10 +16,7 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] requires = [ @@ -29,9 +26,7 @@ requires = [ [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] -requires = [ - "c ; sys_platform == 'linux' or implementation_name == 'cpython'", -] +requires = ["c ; sys_platform == 'linux' or implementation_name == 'cpython'"] [packages.b.versions."2.0.0"] [packages.c.versions."1.0.0"] diff --git a/scenarios/fork/marker-inherit-combined.toml b/scenarios/fork/marker-inherit-combined.toml index 426824c1..e104f17c 100644 --- a/scenarios/fork/marker-inherit-combined.toml +++ b/scenarios/fork/marker-inherit-combined.toml @@ -17,10 +17,7 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] requires = [ @@ -30,9 +27,7 @@ requires = [ [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] -requires = [ - "c ; sys_platform == 'linux'", -] +requires = ["c ; sys_platform == 'linux'"] [packages.b.versions."2.0.0"] [packages.c.versions."1.0.0"] diff --git a/scenarios/fork/marker-inherit-isolated.toml b/scenarios/fork/marker-inherit-isolated.toml index a635c0f1..677407a7 100644 --- a/scenarios/fork/marker-inherit-isolated.toml +++ b/scenarios/fork/marker-inherit-isolated.toml @@ -15,18 +15,11 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] -requires = [ - "b ; sys_platform == 'linux'" -] +requires = ["b ; sys_platform == 'linux'"] [packages.a.versions."2.0.0"] -requires = [ - "b ; sys_platform == 'linux'" -] +requires = ["b ; sys_platform == 'linux'"] [packages.b.versions."1.0.0"] diff --git a/scenarios/fork/marker-inherit-transitive.toml b/scenarios/fork/marker-inherit-transitive.toml index 6b3cef5d..1ed33341 100644 --- a/scenarios/fork/marker-inherit-transitive.toml +++ b/scenarios/fork/marker-inherit-transitive.toml @@ -15,10 +15,7 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] requires = ["b"] diff --git a/scenarios/fork/marker-inherit.toml b/scenarios/fork/marker-inherit.toml index 272cd13f..03c3fed7 100644 --- a/scenarios/fork/marker-inherit.toml +++ b/scenarios/fork/marker-inherit.toml @@ -19,15 +19,10 @@ universal = true satisfiable = true [root] -requires = [ - "a>=2 ; sys_platform == 'linux'", - "a<2 ; sys_platform == 'darwin'", -] +requires = ["a>=2 ; sys_platform == 'linux'", "a<2 ; sys_platform == 'darwin'"] [packages.a.versions."1.0.0"] -requires = [ - "b ; sys_platform == 'linux'" -] +requires = ["b ; sys_platform == 'linux'"] [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] diff --git a/scenarios/fork/marker-limited-inherit.toml b/scenarios/fork/marker-limited-inherit.toml index 0fcd9761..fa167aaf 100644 --- a/scenarios/fork/marker-limited-inherit.toml +++ b/scenarios/fork/marker-limited-inherit.toml @@ -25,14 +25,10 @@ requires = [ ] [packages.a.versions."1.0.0"] -requires = [ - "c ; sys_platform == 'linux'" -] +requires = ["c ; sys_platform == 'linux'"] [packages.a.versions."2.0.0"] [packages.b.versions."1.0.0"] -requires = [ - "c ; sys_platform == 'linux'" -] +requires = ["c ; sys_platform == 'linux'"] [packages.c.versions."1.0.0"] diff --git a/scenarios/fork/preferences-dependent-forking-bistable.toml b/scenarios/fork/preferences-dependent-forking-bistable.toml index 9e0fa09f..735c2c62 100644 --- a/scenarios/fork/preferences-dependent-forking-bistable.toml +++ b/scenarios/fork/preferences-dependent-forking-bistable.toml @@ -23,9 +23,7 @@ universal = true satisfiable = true [root] -requires = [ - "cleaver", -] +requires = ["cleaver"] [packages.cleaver.versions."2.0.0"] requires = [ @@ -41,9 +39,7 @@ requires = [ [packages.fork-sys-platform.versions."2.0.0"] [packages.reject-cleaver2-proxy.versions."1.0.0"] -requires = [ - "reject-cleaver2==2; os_name != 'posix'" -] +requires = ["reject-cleaver2==2; os_name != 'posix'"] [packages.reject-cleaver2.versions."1.0.0"] [packages.reject-cleaver2.versions."2.0.0"] @@ -55,18 +51,14 @@ requires = [ "fork-if-not-forked-proxy; sys_platform != 'linux'", # Reject cleaver 1 if we didn't fork on sys_platform, without forking on sys_platform. "reject-cleaver1==1; sys_platform == 'linux'", - "reject-cleaver1-proxy" + "reject-cleaver1-proxy", ] [packages.fork-if-not-forked-proxy.versions."1.0.0"] -requires = [ - "fork-if-not-forked!=3" -] +requires = ["fork-if-not-forked!=3"] [packages.reject-cleaver1-proxy.versions."1.0.0"] -requires = [ - "reject-cleaver1==2; sys_platform != 'linux'", -] +requires = ["reject-cleaver1==2; sys_platform != 'linux'"] [packages.reject-cleaver1.versions."1.0.0"] [packages.reject-cleaver1.versions."2.0.0"] @@ -79,7 +71,7 @@ requires = [ # Actually provoke the fork for cleaver 1. "fork-os-name==1; os_name == 'posix'", "fork-os-name==2; os_name != 'posix'", - "reject-cleaver1-proxy" + "reject-cleaver1-proxy", ] [packages.fork-if-not-forked.versions."2.0.0"] [packages.fork-if-not-forked.versions."3.0.0"] diff --git a/scenarios/fork/preferences-dependent-forking-conflicting.toml b/scenarios/fork/preferences-dependent-forking-conflicting.toml index fab8607f..814eec72 100644 --- a/scenarios/fork/preferences-dependent-forking-conflicting.toml +++ b/scenarios/fork/preferences-dependent-forking-conflicting.toml @@ -41,7 +41,7 @@ requires = [ "cleaver", # The reporter packages. "foo", - "bar" + "bar", ] [packages.cleaver.versions."2.0.0"] @@ -55,7 +55,7 @@ requires = [ [packages.reject-cleaver-2.versions."1.0.0"] requires = [ # That's a conflict with `cleaver==2`. - "unrelated-dep==3" + "unrelated-dep==3", ] [packages.unrelated-dep.versions."1.0.0"] @@ -66,13 +66,13 @@ requires = [ requires = [ # Allow different versions when forking, but force foo 1, bar 1 in universal mode without forking. "foo==1; sys_platform == 'linux'", - "bar==1; sys_platform != 'linux'" + "bar==1; sys_platform != 'linux'", ] [packages.foo.versions."1.0.0"] requires = [ # When we selected foo 1, bar 1 in universal mode for cleaver, this causes a conflict, otherwise we select bar 2. - "bar==2" + "bar==2", ] [packages.foo.versions."2.0.0"] [packages.bar.versions."1.0.0"] diff --git a/scenarios/fork/preferences-dependent-forking-tristable.toml b/scenarios/fork/preferences-dependent-forking-tristable.toml index b0a14f56..b2162e01 100644 --- a/scenarios/fork/preferences-dependent-forking-tristable.toml +++ b/scenarios/fork/preferences-dependent-forking-tristable.toml @@ -15,11 +15,7 @@ universal = true satisfiable = true [root] -requires = [ - "cleaver", - "foo", - "bar" -] +requires = ["cleaver", "foo", "bar"] [packages.cleaver.versions."2.0.0"] requires = [ @@ -30,19 +26,13 @@ requires = [ ] [packages.a.versions."1.0.0"] -requires = [ - "unrelated-dep3==1; os_name == 'posix'" -] +requires = ["unrelated-dep3==1; os_name == 'posix'"] [packages.b.versions."1.0.0"] -requires = [ - "unrelated-dep3==2; os_name != 'posix'" -] +requires = ["unrelated-dep3==2; os_name != 'posix'"] [packages.reject-cleaver-2.versions."1.0.0"] -requires = [ - "unrelated-dep3==3" -] +requires = ["unrelated-dep3==3"] [packages.unrelated-dep.versions."1.0.0"] [packages.unrelated-dep.versions."2.0.0"] @@ -55,21 +45,21 @@ requires = [ [packages.cleaver.versions."1.0.0"] requires = [ "foo==1; sys_platform == 'linux'", - "bar==1; sys_platform != 'linux'" + "bar==1; sys_platform != 'linux'", ] [packages.foo.versions."1.0.0"] requires = [ "c!=3; sys_platform == 'linux'", "c!=2; sys_platform != 'linux'", - "reject-cleaver-1" + "reject-cleaver-1", ] [packages.foo.versions."2.0.0"] [packages.bar.versions."1.0.0"] requires = [ "c!=3; sys_platform == 'linux'", "d; sys_platform != 'linux'", - "reject-cleaver-1" + "reject-cleaver-1", ] [packages.bar.versions."2.0.0"] @@ -83,17 +73,14 @@ requires = [ [packages.unrelated-dep2.versions."2.0.0"] [packages.unrelated-dep2.versions."3.0.0"] - [packages.c.versions."1.0.0"] requires = [ "unrelated-dep2==1; os_name == 'posix'", "unrelated-dep2==2; os_name != 'posix'", - "reject-cleaver-1" + "reject-cleaver-1", ] [packages.c.versions."2.0.0"] [packages.c.versions."3.0.0"] [packages.d.versions."1.0.0"] -requires = [ - "c!=2" -] +requires = ["c!=2"] diff --git a/scenarios/fork/preferences-dependent-forking.toml b/scenarios/fork/preferences-dependent-forking.toml index 7568979c..ccea44c7 100644 --- a/scenarios/fork/preferences-dependent-forking.toml +++ b/scenarios/fork/preferences-dependent-forking.toml @@ -42,7 +42,7 @@ requires = [ "cleaver", # The reporter packages. "foo", - "bar" + "bar", ] [packages.cleaver.versions."2.0.0"] @@ -56,7 +56,7 @@ requires = [ [packages.reject-cleaver-2.versions."1.0.0"] requires = [ # That's a conflict with `cleaver==2`. - "unrelated-dep==3" + "unrelated-dep==3", ] [packages.unrelated-dep.versions."1.0.0"] @@ -67,7 +67,7 @@ requires = [ requires = [ # Allow different versions when forking, but force foo 1, bar 1 in universal mode without forking. "foo==1; sys_platform == 'linux'", - "bar==1; sys_platform != 'linux'" + "bar==1; sys_platform != 'linux'", ] [packages.foo.versions."1.0.0"] diff --git a/scenarios/fork/requires-python-full-prerelease.toml b/scenarios/fork/requires-python-full-prerelease.toml index 2fba6fdd..8e608a93 100644 --- a/scenarios/fork/requires-python-full-prerelease.toml +++ b/scenarios/fork/requires-python-full-prerelease.toml @@ -18,8 +18,6 @@ python = "3.12" [root] requires_python = ">=3.10" -requires = [ - "a==1.0.0 ; python_full_version == '3.9b1'", -] +requires = ["a==1.0.0 ; python_full_version == '3.9b1'"] [packages.a.versions."1.0.0"] diff --git a/scenarios/fork/requires-python-full.toml b/scenarios/fork/requires-python-full.toml index 1def05b8..b2e72d8f 100644 --- a/scenarios/fork/requires-python-full.toml +++ b/scenarios/fork/requires-python-full.toml @@ -18,8 +18,6 @@ python = "3.12" [root] requires_python = ">=3.10" -requires = [ - "a==1.0.0 ; python_full_version == '3.9'", -] +requires = ["a==1.0.0 ; python_full_version == '3.9'"] [packages.a.versions."1.0.0"] diff --git a/scenarios/fork/requires-python-patch-overlap.toml b/scenarios/fork/requires-python-patch-overlap.toml index dc8b9221..2bccec58 100644 --- a/scenarios/fork/requires-python-patch-overlap.toml +++ b/scenarios/fork/requires-python-patch-overlap.toml @@ -22,8 +22,6 @@ python = "3.12" [root] requires_python = ">=3.10.1" -requires = [ - "a==1.0.0 ; python_version == '3.10'", -] +requires = ["a==1.0.0 ; python_version == '3.10'"] [packages.a.versions."1.0.0"] diff --git a/scenarios/fork/requires-python.toml b/scenarios/fork/requires-python.toml index 90405b9a..47295a7d 100644 --- a/scenarios/fork/requires-python.toml +++ b/scenarios/fork/requires-python.toml @@ -15,8 +15,6 @@ python = "3.12" [root] requires_python = ">=3.10" -requires = [ - "a==1.0.0 ; python_version == '3.9'", -] +requires = ["a==1.0.0 ; python_version == '3.9'"] [packages.a.versions."1.0.0"] diff --git a/scenarios/incompatible-versions.json b/scenarios/incompatible-versions.json deleted file mode 100644 index b9ab7688..00000000 --- a/scenarios/incompatible-versions.json +++ /dev/null @@ -1,116 +0,0 @@ -[ - { - "name": "direct-incompatible-versions", - "description": "The user requires two incompatible, existing versions of package `a`", - "root": { - "requires": [ - "a==1.0.0", - "a==2.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": {}, - "2.0.0": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "transitive-incompatible-with-root-version", - "description": "The user requires packages `a` and `b` but `a` requires a different version of `b`", - "root": { - "requires": [ - "a", - "b==1.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==2.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": {}, - "2.0.0": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "transitive-incompatible-with-transitive", - "description": "The user requires package `a` and `b`; `a` and `b` require different versions of `c`", - "root": { - "requires": [ - "a", - "b" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c==1.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c==2.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "transitive-incompatible-versions", - "description": "The user requires `a`, which requires two incompatible, existing versions of package `b`", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==2.0.0", - "b==1.0.0" - ] - } - } - } - }, - "expected": { - "satisfiable": false - } - } -] diff --git a/scenarios/incompatible_versions/direct-incompatible-versions.toml b/scenarios/incompatible_versions/direct-incompatible-versions.toml new file mode 100644 index 00000000..c05bc721 --- /dev/null +++ b/scenarios/incompatible_versions/direct-incompatible-versions.toml @@ -0,0 +1,12 @@ +name = "direct-incompatible-versions" +description = "The user requires two incompatible, existing versions of package `a`" + +[root] +requires = ["a==1.0.0", "a==2.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] + +[packages.a.versions."2.0.0"] diff --git a/scenarios/incompatible_versions/transitive-incompatible-versions.toml b/scenarios/incompatible_versions/transitive-incompatible-versions.toml new file mode 100644 index 00000000..4650a461 --- /dev/null +++ b/scenarios/incompatible_versions/transitive-incompatible-versions.toml @@ -0,0 +1,11 @@ +name = "transitive-incompatible-versions" +description = "The user requires `a`, which requires two incompatible, existing versions of package `b`" + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["b==2.0.0", "b==1.0.0"] diff --git a/scenarios/incompatible_versions/transitive-incompatible-with-root-version.toml b/scenarios/incompatible_versions/transitive-incompatible-with-root-version.toml new file mode 100644 index 00000000..3dd1c147 --- /dev/null +++ b/scenarios/incompatible_versions/transitive-incompatible-with-root-version.toml @@ -0,0 +1,15 @@ +name = "transitive-incompatible-with-root-version" +description = "The user requires packages `a` and `b` but `a` requires a different version of `b`" + +[root] +requires = ["a", "b==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["b==2.0.0"] + +[packages.b.versions."1.0.0"] + +[packages.b.versions."2.0.0"] diff --git a/scenarios/incompatible_versions/transitive-incompatible-with-transitive.toml b/scenarios/incompatible_versions/transitive-incompatible-with-transitive.toml new file mode 100644 index 00000000..e4e12f84 --- /dev/null +++ b/scenarios/incompatible_versions/transitive-incompatible-with-transitive.toml @@ -0,0 +1,18 @@ +name = "transitive-incompatible-with-transitive" +description = "The user requires package `a` and `b`; `a` and `b` require different versions of `c`" + +[root] +requires = ["a", "b"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["c==1.0.0"] + +[packages.b.versions."1.0.0"] +requires = ["c==2.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0"] diff --git a/scenarios/local.json b/scenarios/local.json deleted file mode 100644 index 1c811cef..00000000 --- a/scenarios/local.json +++ /dev/null @@ -1,472 +0,0 @@ -[ - { - "name": "local-simple", - "description": "A simple version constraint should not exclude published versions with local segments.", - "root": { - "requires": [ - "a==1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3+foo" - }, - "explanation": "The version '1.2.3+foo' satisfies the constraint '==1.2.3'." - } - }, - { - "name": "local-not-used-with-sdist", - "description": "If there is a 1.2.3 version with an sdist published and no compatible wheels, then the sdist will be used.", - "root": { - "requires": [ - "a==1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3": { - "wheel_tags": [ - "py3-any-macosx_10_0_ppc64" - ], - "sdist": true - }, - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3" - }, - "explanation": "The version '1.2.3' with an sdist satisfies the constraint '==1.2.3'." - } - }, - { - "name": "local-used-without-sdist", - "description": "Even if there is a 1.2.3 version published, if it is unavailable for some reason (no sdist and no compatible wheels in this case), a 1.2.3 version with a local segment should be usable instead.", - "root": { - "requires": [ - "a==1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3": { - "wheel_tags": [ - "py3-any-macosx_10_0_ppc64" - ], - "sdist": false - }, - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3+foo" - }, - "explanation": "The version '1.2.3+foo' satisfies the constraint '==1.2.3'." - } - }, - { - "name": "local-not-latest", - "description": "Tests that we can select an older version with a local segment when newer versions are incompatible.", - "root": { - "requires": [ - "a>=1" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3": { - "wheel_tags": [ - "py3-any-macosx_10_0_ppc64" - ], - "sdist": false - }, - "1.2.2+foo": { - "wheel_tags": [ - "py3-any-macosx_10_0_ppc64" - ], - "sdist": false - }, - "1.2.1+foo": { - "sdist": true - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.1+foo" - } - } - }, - { - "name": "local-transitive", - "description": "A simple version constraint should not exclude published versions with local segments.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==2.0.0" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "2.0.0+foo" - }, - "explanation": "The version '2.0.0+foo' satisfies both ==2.0.0 and ==2.0.0+foo." - } - }, - { - "name": "local-transitive-greater-than", - "description": "A transitive constraint on a local version should not match an exclusive ordered operator.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b>2.0.0" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "local-transitive-greater-than-or-equal", - "description": "A transitive constraint on a local version should match an inclusive ordered operator.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b>=2.0.0" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "2.0.0+foo" - }, - "explanation": "The version '2.0.0+foo' satisfies both >=2.0.0 and ==2.0.0+foo." - } - }, - { - "name": "local-transitive-less-than", - "description": "A transitive constraint on a local version should not match an exclusive ordered operator.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b<2.0.0" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "local-transitive-less-than-or-equal", - "description": "A transitive constraint on a local version should match an inclusive ordered operator.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b<=2.0.0" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "2.0.0+foo" - }, - "explanation": "The version '2.0.0+foo' satisfies both <=2.0.0 and ==2.0.0+foo." - } - }, - { - "name": "local-transitive-confounding", - "description": "A transitive dependency has both a non-local and local version published, but the non-local version is unusable.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==2.0.0" - ] - } - } - }, - "b": { - "versions": { - "2.0.0": { - "wheel_tags": [ - "py3-any-macosx_10_0_ppc64" - ], - "sdist": false - }, - "2.0.0+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "2.0.0+foo" - }, - "explanation": "The version '2.0.0+foo' satisfies the constraint '==2.0.0'." - } - }, - { - "name": "local-transitive-conflicting", - "description": "A dependency depends on a conflicting local version of a direct dependency.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==2.0.0+bar" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {}, - "2.0.0+bar": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "local-transitive-backtrack", - "description": "A dependency depends on a conflicting local version of a direct dependency, but we can backtrack to a compatible version.", - "root": { - "requires": [ - "a", - "b==2.0.0+foo" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "b==2.0.0" - ] - }, - "2.0.0": { - "requires": [ - "b==2.0.0+bar" - ] - } - } - }, - "b": { - "versions": { - "2.0.0+foo": {}, - "2.0.0+bar": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "2.0.0+foo" - }, - "explanation": "Backtracking to '1.0.0' gives us compatible local versions of b." - } - }, - { - "name": "local-greater-than", - "description": "A local version should be excluded in exclusive ordered comparisons.", - "root": { - "requires": [ - "a>1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "local-greater-than-or-equal", - "description": "A local version should be included in inclusive ordered comparisons.", - "root": { - "requires": [ - "a>=1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3+foo" - }, - "explanation": "The version '1.2.3+foo' satisfies the constraint '>=1.2.3'." - } - }, - { - "name": "local-less-than", - "description": "A local version should be excluded in exclusive ordered comparisons.", - "root": { - "requires": [ - "a<1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "local-less-than-or-equal", - "description": "A local version should be included in inclusive ordered comparisons.", - "root": { - "requires": [ - "a<=1.2.3" - ] - }, - "packages": { - "a": { - "versions": { - "1.2.3+foo": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3+foo" - }, - "explanation": "The version '1.2.3+foo' satisfies the constraint '<=1.2.3'." - } - } -] diff --git a/scenarios/local/local-greater-than-or-equal.toml b/scenarios/local/local-greater-than-or-equal.toml new file mode 100644 index 00000000..c01f90fa --- /dev/null +++ b/scenarios/local/local-greater-than-or-equal.toml @@ -0,0 +1,14 @@ +name = "local-greater-than-or-equal" +description = "A local version should be included in inclusive ordered comparisons." + +[root] +requires = ["a>=1.2.3"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3+foo' satisfies the constraint '>=1.2.3'." + +[expected.packages] +a = "1.2.3+foo" + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/local/local-greater-than.toml b/scenarios/local/local-greater-than.toml new file mode 100644 index 00000000..2ffff887 --- /dev/null +++ b/scenarios/local/local-greater-than.toml @@ -0,0 +1,10 @@ +name = "local-greater-than" +description = "A local version should be excluded in exclusive ordered comparisons." + +[root] +requires = ["a>1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/local/local-less-than-or-equal.toml b/scenarios/local/local-less-than-or-equal.toml new file mode 100644 index 00000000..ae714041 --- /dev/null +++ b/scenarios/local/local-less-than-or-equal.toml @@ -0,0 +1,14 @@ +name = "local-less-than-or-equal" +description = "A local version should be included in inclusive ordered comparisons." + +[root] +requires = ["a<=1.2.3"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3+foo' satisfies the constraint '<=1.2.3'." + +[expected.packages] +a = "1.2.3+foo" + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/local/local-less-than.toml b/scenarios/local/local-less-than.toml new file mode 100644 index 00000000..0e63ea4a --- /dev/null +++ b/scenarios/local/local-less-than.toml @@ -0,0 +1,10 @@ +name = "local-less-than" +description = "A local version should be excluded in exclusive ordered comparisons." + +[root] +requires = ["a<1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/local/local-not-latest.toml b/scenarios/local/local-not-latest.toml new file mode 100644 index 00000000..324848a9 --- /dev/null +++ b/scenarios/local/local-not-latest.toml @@ -0,0 +1,22 @@ +name = "local-not-latest" +description = "Tests that we can select an older version with a local segment when newer versions are incompatible." + +[root] +requires = ["a>=1"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.2.1+foo" + +[packages.a.versions."1.2.3"] +wheel_tags = ["py3-any-macosx_10_0_ppc64"] +sdist = false + +[packages.a.versions."1.2.2+foo"] +wheel_tags = ["py3-any-macosx_10_0_ppc64"] +sdist = false + +[packages.a.versions."1.2.1+foo"] +sdist = true diff --git a/scenarios/local/local-not-used-with-sdist.toml b/scenarios/local/local-not-used-with-sdist.toml new file mode 100644 index 00000000..30f31609 --- /dev/null +++ b/scenarios/local/local-not-used-with-sdist.toml @@ -0,0 +1,18 @@ +name = "local-not-used-with-sdist" +description = "If there is a 1.2.3 version with an sdist published and no compatible wheels, then the sdist will be used." + +[root] +requires = ["a==1.2.3"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3' with an sdist satisfies the constraint '==1.2.3'." + +[expected.packages] +a = "1.2.3" + +[packages.a.versions."1.2.3"] +wheel_tags = ["py3-any-macosx_10_0_ppc64"] +sdist = true + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/local/local-simple.toml b/scenarios/local/local-simple.toml new file mode 100644 index 00000000..f1256f48 --- /dev/null +++ b/scenarios/local/local-simple.toml @@ -0,0 +1,14 @@ +name = "local-simple" +description = "A simple version constraint should not exclude published versions with local segments." + +[root] +requires = ["a==1.2.3"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3+foo' satisfies the constraint '==1.2.3'." + +[expected.packages] +a = "1.2.3+foo" + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/local/local-transitive-backtrack.toml b/scenarios/local/local-transitive-backtrack.toml new file mode 100644 index 00000000..a6f7dd52 --- /dev/null +++ b/scenarios/local/local-transitive-backtrack.toml @@ -0,0 +1,23 @@ +name = "local-transitive-backtrack" +description = "A dependency depends on a conflicting local version of a direct dependency, but we can backtrack to a compatible version." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = true +explanation = "Backtracking to '1.0.0' gives us compatible local versions of b." + +[expected.packages] +a = "1.0.0" +b = "2.0.0+foo" + +[packages.a.versions."1.0.0"] +requires = ["b==2.0.0"] + +[packages.a.versions."2.0.0"] +requires = ["b==2.0.0+bar"] + +[packages.b.versions."2.0.0+foo"] + +[packages.b.versions."2.0.0+bar"] diff --git a/scenarios/local/local-transitive-conflicting.toml b/scenarios/local/local-transitive-conflicting.toml new file mode 100644 index 00000000..ae4ca273 --- /dev/null +++ b/scenarios/local/local-transitive-conflicting.toml @@ -0,0 +1,15 @@ +name = "local-transitive-conflicting" +description = "A dependency depends on a conflicting local version of a direct dependency." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["b==2.0.0+bar"] + +[packages.b.versions."2.0.0+foo"] + +[packages.b.versions."2.0.0+bar"] diff --git a/scenarios/local/local-transitive-confounding.toml b/scenarios/local/local-transitive-confounding.toml new file mode 100644 index 00000000..44094d37 --- /dev/null +++ b/scenarios/local/local-transitive-confounding.toml @@ -0,0 +1,22 @@ +name = "local-transitive-confounding" +description = "A transitive dependency has both a non-local and local version published, but the non-local version is unusable." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "The version '2.0.0+foo' satisfies the constraint '==2.0.0'." + +[expected.packages] +a = "1.0.0" +b = "2.0.0+foo" + +[packages.a.versions."1.0.0"] +requires = ["b==2.0.0"] + +[packages.b.versions."2.0.0"] +wheel_tags = ["py3-any-macosx_10_0_ppc64"] +sdist = false + +[packages.b.versions."2.0.0+foo"] diff --git a/scenarios/local/local-transitive-greater-than-or-equal.toml b/scenarios/local/local-transitive-greater-than-or-equal.toml new file mode 100644 index 00000000..4180110e --- /dev/null +++ b/scenarios/local/local-transitive-greater-than-or-equal.toml @@ -0,0 +1,18 @@ +name = "local-transitive-greater-than-or-equal" +description = "A transitive constraint on a local version should match an inclusive ordered operator." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = true +explanation = "The version '2.0.0+foo' satisfies both >=2.0.0 and ==2.0.0+foo." + +[expected.packages] +a = "1.0.0" +b = "2.0.0+foo" + +[packages.a.versions."1.0.0"] +requires = ["b>=2.0.0"] + +[packages.b.versions."2.0.0+foo"] diff --git a/scenarios/local/local-transitive-greater-than.toml b/scenarios/local/local-transitive-greater-than.toml new file mode 100644 index 00000000..46c1d52b --- /dev/null +++ b/scenarios/local/local-transitive-greater-than.toml @@ -0,0 +1,13 @@ +name = "local-transitive-greater-than" +description = "A transitive constraint on a local version should not match an exclusive ordered operator." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["b>2.0.0"] + +[packages.b.versions."2.0.0+foo"] diff --git a/scenarios/local/local-transitive-less-than-or-equal.toml b/scenarios/local/local-transitive-less-than-or-equal.toml new file mode 100644 index 00000000..447a13a6 --- /dev/null +++ b/scenarios/local/local-transitive-less-than-or-equal.toml @@ -0,0 +1,18 @@ +name = "local-transitive-less-than-or-equal" +description = "A transitive constraint on a local version should match an inclusive ordered operator." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = true +explanation = "The version '2.0.0+foo' satisfies both <=2.0.0 and ==2.0.0+foo." + +[expected.packages] +a = "1.0.0" +b = "2.0.0+foo" + +[packages.a.versions."1.0.0"] +requires = ["b<=2.0.0"] + +[packages.b.versions."2.0.0+foo"] diff --git a/scenarios/local/local-transitive-less-than.toml b/scenarios/local/local-transitive-less-than.toml new file mode 100644 index 00000000..f5726417 --- /dev/null +++ b/scenarios/local/local-transitive-less-than.toml @@ -0,0 +1,13 @@ +name = "local-transitive-less-than" +description = "A transitive constraint on a local version should not match an exclusive ordered operator." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires = ["b<2.0.0"] + +[packages.b.versions."2.0.0+foo"] diff --git a/scenarios/local/local-transitive.toml b/scenarios/local/local-transitive.toml new file mode 100644 index 00000000..37047032 --- /dev/null +++ b/scenarios/local/local-transitive.toml @@ -0,0 +1,18 @@ +name = "local-transitive" +description = "A simple version constraint should not exclude published versions with local segments." + +[root] +requires = ["a", "b==2.0.0+foo"] + +[expected] +satisfiable = true +explanation = "The version '2.0.0+foo' satisfies both ==2.0.0 and ==2.0.0+foo." + +[expected.packages] +a = "1.0.0" +b = "2.0.0+foo" + +[packages.a.versions."1.0.0"] +requires = ["b==2.0.0"] + +[packages.b.versions."2.0.0+foo"] diff --git a/scenarios/local/local-used-without-sdist.toml b/scenarios/local/local-used-without-sdist.toml new file mode 100644 index 00000000..2c8a7f0b --- /dev/null +++ b/scenarios/local/local-used-without-sdist.toml @@ -0,0 +1,18 @@ +name = "local-used-without-sdist" +description = "Even if there is a 1.2.3 version published, if it is unavailable for some reason (no sdist and no compatible wheels in this case), a 1.2.3 version with a local segment should be usable instead." + +[root] +requires = ["a==1.2.3"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3+foo' satisfies the constraint '==1.2.3'." + +[expected.packages] +a = "1.2.3+foo" + +[packages.a.versions."1.2.3"] +wheel_tags = ["py3-any-macosx_10_0_ppc64"] +sdist = false + +[packages.a.versions."1.2.3+foo"] diff --git a/scenarios/post.json b/scenarios/post.json deleted file mode 100644 index 8bd1c2b0..00000000 --- a/scenarios/post.json +++ /dev/null @@ -1,230 +0,0 @@ -[ - { - "name": "post-simple", - "description": "A simple version constraint should not match a post-release version.", - "root": { - "requires": ["a==1.2.3"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-greater-than-or-equal", - "description": "A greater-than-or-equal version constraint should match a post-release version.", - "root": { - "requires": ["a>=1.2.3"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3.post1" - }, - "explanation": "The version '1.2.3.post1' satisfies the constraint '>=1.2.3'." - } - }, - { - "name": "post-greater-than", - "description": "A greater-than version constraint should not match a post-release version.", - "root": { - "requires": ["a>1.2.3"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-greater-than-post", - "description": "A greater-than version constraint should match a post-release version if the constraint is itself a post-release version.", - "root": { - "requires": ["a>1.2.3.post0"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post0": {}, - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3.post1" - }, - "explanation": "The version '1.2.3.post1' satisfies the constraint '>1.2.3.post0'." - } - }, - { - "name": "post-greater-than-or-equal-post", - "description": "A greater-than-or-equal version constraint should match a post-release version if the constraint is itself a post-release version.", - "root": { - "requires": ["a>=1.2.3.post0"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post0": {}, - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3.post1" - }, - "explanation": "The version '1.2.3.post1' satisfies the constraint '>=1.2.3.post0'." - } - }, - { - "name": "post-less-than-or-equal", - "description": "A less-than-or-equal version constraint should not match a post-release version.", - "root": { - "requires": ["a<=1.2.3"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-less-than", - "description": "A less-than version constraint should not match a post-release version.", - "root": { - "requires": ["a<1.2.3"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-local-greater-than", - "description": "A greater-than version constraint should not match a post-release version with a local version identifier.", - "root": { - "requires": ["a>1.2.3"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {}, - "1.2.3.post1+local": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-local-greater-than-post", - "description": "A greater-than version constraint should not match a post-release version with a local version identifier.", - "root": { - "requires": ["a>1.2.3.post1"] - }, - "packages": { - "a": { - "versions": { - "1.2.3.post1": {}, - "1.2.3.post1+local": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-equal-not-available", - "description": "An equal version constraint should not match a post-release version if the post-release version is not available.", - "root": { - "requires": ["a==1.2.3.post0"] - }, - "packages": { - "a": { - "versions": { - "1.2.3": {}, - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "post-equal-available", - "description": "An equal version constraint should match a post-release version if the post-release version is available.", - "root": { - "requires": ["a==1.2.3.post0"] - }, - "packages": { - "a": { - "versions": { - "1.2.3": {}, - "1.2.3.post0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.2.3.post0" - }, - "explanation": "The version '1.2.3.post0' satisfies the constraint '==1.2.3.post0'." - } - }, - { - "name": "post-greater-than-post-not-available", - "description": "A greater-than version constraint should not match a post-release version if the post-release version is not available.", - "root": { - "requires": ["a>1.2.3.post2"] - }, - "packages": { - "a": { - "versions": { - "1.2.3": {}, - "1.2.3.post0": {}, - "1.2.3.post1": {} - } - } - }, - "expected": { - "satisfiable": false - } - } -] diff --git a/scenarios/post/post-equal-available.toml b/scenarios/post/post-equal-available.toml new file mode 100644 index 00000000..de4957bb --- /dev/null +++ b/scenarios/post/post-equal-available.toml @@ -0,0 +1,16 @@ +name = "post-equal-available" +description = "An equal version constraint should match a post-release version if the post-release version is available." + +[root] +requires = ["a==1.2.3.post0"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3.post0' satisfies the constraint '==1.2.3.post0'." + +[expected.packages] +a = "1.2.3.post0" + +[packages.a.versions."1.2.3"] + +[packages.a.versions."1.2.3.post0"] diff --git a/scenarios/post/post-equal-not-available.toml b/scenarios/post/post-equal-not-available.toml new file mode 100644 index 00000000..e214eae6 --- /dev/null +++ b/scenarios/post/post-equal-not-available.toml @@ -0,0 +1,12 @@ +name = "post-equal-not-available" +description = "An equal version constraint should not match a post-release version if the post-release version is not available." + +[root] +requires = ["a==1.2.3.post0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3"] + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-greater-than-or-equal-post.toml b/scenarios/post/post-greater-than-or-equal-post.toml new file mode 100644 index 00000000..375b14ee --- /dev/null +++ b/scenarios/post/post-greater-than-or-equal-post.toml @@ -0,0 +1,16 @@ +name = "post-greater-than-or-equal-post" +description = "A greater-than-or-equal version constraint should match a post-release version if the constraint is itself a post-release version." + +[root] +requires = ["a>=1.2.3.post0"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3.post1' satisfies the constraint '>=1.2.3.post0'." + +[expected.packages] +a = "1.2.3.post1" + +[packages.a.versions."1.2.3.post0"] + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-greater-than-or-equal.toml b/scenarios/post/post-greater-than-or-equal.toml new file mode 100644 index 00000000..66b5e267 --- /dev/null +++ b/scenarios/post/post-greater-than-or-equal.toml @@ -0,0 +1,14 @@ +name = "post-greater-than-or-equal" +description = "A greater-than-or-equal version constraint should match a post-release version." + +[root] +requires = ["a>=1.2.3"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3.post1' satisfies the constraint '>=1.2.3'." + +[expected.packages] +a = "1.2.3.post1" + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-greater-than-post-not-available.toml b/scenarios/post/post-greater-than-post-not-available.toml new file mode 100644 index 00000000..075c869c --- /dev/null +++ b/scenarios/post/post-greater-than-post-not-available.toml @@ -0,0 +1,14 @@ +name = "post-greater-than-post-not-available" +description = "A greater-than version constraint should not match a post-release version if the post-release version is not available." + +[root] +requires = ["a>1.2.3.post2"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3"] + +[packages.a.versions."1.2.3.post0"] + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-greater-than-post.toml b/scenarios/post/post-greater-than-post.toml new file mode 100644 index 00000000..0478f089 --- /dev/null +++ b/scenarios/post/post-greater-than-post.toml @@ -0,0 +1,16 @@ +name = "post-greater-than-post" +description = "A greater-than version constraint should match a post-release version if the constraint is itself a post-release version." + +[root] +requires = ["a>1.2.3.post0"] + +[expected] +satisfiable = true +explanation = "The version '1.2.3.post1' satisfies the constraint '>1.2.3.post0'." + +[expected.packages] +a = "1.2.3.post1" + +[packages.a.versions."1.2.3.post0"] + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-greater-than.toml b/scenarios/post/post-greater-than.toml new file mode 100644 index 00000000..c62e2a96 --- /dev/null +++ b/scenarios/post/post-greater-than.toml @@ -0,0 +1,10 @@ +name = "post-greater-than" +description = "A greater-than version constraint should not match a post-release version." + +[root] +requires = ["a>1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-less-than-or-equal.toml b/scenarios/post/post-less-than-or-equal.toml new file mode 100644 index 00000000..a5d31897 --- /dev/null +++ b/scenarios/post/post-less-than-or-equal.toml @@ -0,0 +1,10 @@ +name = "post-less-than-or-equal" +description = "A less-than-or-equal version constraint should not match a post-release version." + +[root] +requires = ["a<=1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-less-than.toml b/scenarios/post/post-less-than.toml new file mode 100644 index 00000000..826d3a72 --- /dev/null +++ b/scenarios/post/post-less-than.toml @@ -0,0 +1,10 @@ +name = "post-less-than" +description = "A less-than version constraint should not match a post-release version." + +[root] +requires = ["a<1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/post/post-local-greater-than-post.toml b/scenarios/post/post-local-greater-than-post.toml new file mode 100644 index 00000000..b03335b6 --- /dev/null +++ b/scenarios/post/post-local-greater-than-post.toml @@ -0,0 +1,12 @@ +name = "post-local-greater-than-post" +description = "A greater-than version constraint should not match a post-release version with a local version identifier." + +[root] +requires = ["a>1.2.3.post1"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3.post1"] + +[packages.a.versions."1.2.3.post1+local"] diff --git a/scenarios/post/post-local-greater-than.toml b/scenarios/post/post-local-greater-than.toml new file mode 100644 index 00000000..2c93a5d8 --- /dev/null +++ b/scenarios/post/post-local-greater-than.toml @@ -0,0 +1,12 @@ +name = "post-local-greater-than" +description = "A greater-than version constraint should not match a post-release version with a local version identifier." + +[root] +requires = ["a>1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3.post1"] + +[packages.a.versions."1.2.3.post1+local"] diff --git a/scenarios/post/post-simple.toml b/scenarios/post/post-simple.toml new file mode 100644 index 00000000..199c267a --- /dev/null +++ b/scenarios/post/post-simple.toml @@ -0,0 +1,10 @@ +name = "post-simple" +description = "A simple version constraint should not match a post-release version." + +[root] +requires = ["a==1.2.3"] + +[expected] +satisfiable = false + +[packages.a.versions."1.2.3.post1"] diff --git a/scenarios/prereleases.json b/scenarios/prereleases.json deleted file mode 100644 index b40a4253..00000000 --- a/scenarios/prereleases.json +++ /dev/null @@ -1,629 +0,0 @@ -[ - { - "name": "package-only-prereleases", - "description": "The user requires any version of package `a` which only has prerelease versions available.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0a1" - }, - "explanation": "Since there are only prerelease versions of `a` available, it should be installed even though the user did not include a prerelease specifier." - } - }, - { - "name": "package-only-prereleases-in-range", - "description": "The user requires a version of package `a` which only matches prerelease versions but they did not include a prerelease specifier.", - "root": { - "requires": [ - "a>0.1.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since there are stable versions of `a` available, prerelease versions should not be selected without explicit opt-in." - } - }, - { - "name": "requires-package-only-prereleases-in-range-global-opt-in", - "description": "The user requires a version of package `a` which only matches prerelease versions. They did not include a prerelease specifier for the package, but they opted into prereleases globally.", - "resolver_options": { - "prereleases": true - }, - "root": { - "requires": [ - "a>0.1.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0a1" - } - } - }, - { - "name": "requires-package-prerelease-and-final-any", - "description": "The user requires any version of package `a` has a prerelease version available and an older non-prerelease version.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0" - }, - "explanation": "Since the user did not provide a prerelease specifier, the older stable version should be selected." - } - }, - { - "name": "package-prerelease-specified-only-final-available", - "description": "The user requires a version of `a` with a prerelease specifier and only stable releases are available.", - "root": { - "requires": [ - "a>=0.1.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "0.2.0": {}, - "0.3.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.3.0" - }, - "explanation": "The latest stable version should be selected." - } - }, - { - "name": "package-prerelease-specified-only-prerelease-available", - "description": "The user requires a version of `a` with a prerelease specifier and only prerelease releases are available.", - "root": { - "requires": [ - "a>=0.1.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0a1": {}, - "0.2.0a1": {}, - "0.3.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.3.0a1" - }, - "explanation": "The latest prerelease version should be selected." - } - }, - { - "name": "package-prerelease-specified-mixed-available", - "description": "The user requires a version of `a` with a prerelease specifier and both prerelease and stable releases are available.", - "root": { - "requires": [ - "a>=0.1.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "0.2.0a1": {}, - "0.3.0": {}, - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0a1" - }, - "explanation": "Since the user provided a prerelease specifier, the latest prerelease version should be selected." - } - }, - { - "name": "package-multiple-prereleases-kinds", - "description": "The user requires `a` which has multiple prereleases available with different labels.", - "root": { - "requires": [ - "a>=1.0.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0a1": {}, - "1.0.0b1": {}, - "1.0.0rc1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0rc1" - }, - "explanation": "Release candidates should be the highest precedence prerelease kind." - } - }, - { - "name": "package-multiple-prereleases-numbers", - "description": "The user requires `a` which has multiple alphas available.", - "root": { - "requires": [ - "a>=1.0.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0a1": {}, - "1.0.0a2": {}, - "1.0.0a3": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0a3" - }, - "explanation": "The latest alpha version should be selected." - } - }, - { - "name": "transitive-package-only-prereleases", - "description": "The user requires any version of package `a` which requires `b` which only has prerelease versions available.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": { - "requires": [ - "b" - ] - } - } - }, - "b": { - "versions": { - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0", - "b": "1.0.0a1" - }, - "explanation": "Since there are only prerelease versions of `b` available, it should be selected even though the user did not opt-in to prereleases." - } - }, - { - "name": "transitive-package-only-prereleases-in-range", - "description": "The user requires package `a` which has a dependency on a package which only matches prerelease versions but they did not include a prerelease specifier.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": { - "requires": [ - "b>0.1" - ] - } - } - }, - "b": { - "versions": { - "0.1.0": {}, - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since there are stable versions of `b` available, the prerelease version should not be selected without explicit opt-in. The available version is excluded by the range requested by the user." - } - }, - { - "name": "transitive-package-only-prereleases-in-range-opt-in", - "description": "The user requires package `a` which has a dependency on a package which only matches prerelease versions; the user has opted into allowing prereleases in `b` explicitly.", - "root": { - "requires": [ - "a", - "b>0.0.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": { - "requires": [ - "b>0.1" - ] - } - } - }, - "b": { - "versions": { - "0.1.0": {}, - "1.0.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0", - "b": "1.0.0a1" - }, - "explanation": "Since the user included a dependency on `b` with a prerelease specifier, a prerelease version can be selected." - } - }, - { - "name": "transitive-prerelease-and-stable-dependency", - "description": "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease", - "root": { - "requires": [ - "a", - "b" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c==2.0.0b1" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c>=1.0.0,<=3.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0b1": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since the user did not explicitly opt-in to a prerelease, it cannot be selected." - } - }, - { - "name": "transitive-prerelease-and-stable-dependency-opt-in", - "description": "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease. The user includes an opt-in to prereleases of the transitive dependency.", - "root": { - "requires": [ - "a", - "b", - "c>=0.0.0a1" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c==2.0.0b1" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c>=1.0.0,<=3.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0b1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "1.0.0", - "c": "2.0.0b1" - }, - "explanation": "Since the user explicitly opted-in to a prerelease for `c`, it can be installed." - } - }, - { - "name": "transitive-prerelease-and-stable-dependency-many-versions", - "description": "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease. There are many prerelease versions.", - "root": { - "requires": [ - "a", - "b" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c>=2.0.0b1" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c>=1.0.0,<=3.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0a1": {}, - "2.0.0a2": {}, - "2.0.0a3": {}, - "2.0.0a4": {}, - "2.0.0a5": {}, - "2.0.0a6": {}, - "2.0.0a7": {}, - "2.0.0a8": {}, - "2.0.0a9": {}, - "2.0.0b1": {}, - "2.0.0b2": {}, - "2.0.0b3": {}, - "2.0.0b4": {}, - "2.0.0b5": {}, - "2.0.0b6": {}, - "2.0.0b7": {}, - "2.0.0b8": {}, - "2.0.0b9": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since the user did not explicitly opt-in to a prerelease, it cannot be selected." - } - }, - { - "name": "transitive-prerelease-and-stable-dependency-many-versions-holes", - "description": "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease. There are many prerelease versions and some are excluded.", - "root": { - "requires": [ - "a", - "b" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c>1.0.0,!=2.0.0a5,!=2.0.0a6,!=2.0.0a7,!=2.0.0b1,<2.0.0b5" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c>=1.0.0,<=3.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0a1": {}, - "2.0.0a2": {}, - "2.0.0a3": {}, - "2.0.0a4": {}, - "2.0.0a5": {}, - "2.0.0a6": {}, - "2.0.0a7": {}, - "2.0.0a8": {}, - "2.0.0a9": {}, - "2.0.0b1": {}, - "2.0.0b2": {}, - "2.0.0b3": {}, - "2.0.0b4": {}, - "2.0.0b5": {}, - "2.0.0b6": {}, - "2.0.0b7": {}, - "2.0.0b8": {}, - "2.0.0b9": {} - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since the user did not explicitly opt-in to a prerelease, it cannot be selected." - } - }, - { - "name": "package-only-prereleases-boundary", - "description": "The user requires a non-prerelease version of `a` which only has prerelease versions available. There are pre-releases on the boundary of their range.", - "root": { - "requires": [ - "a<0.2.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0a1": {}, - "0.2.0a1": {}, - "0.3.0a1": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0a1" - }, - "explanation": "Since there are only prerelease versions of `a` available, a prerelease is allowed. Since the user did not explicitly request a pre-release, pre-releases at the boundary should not be selected." - } - }, - { - "name": "package-prereleases-boundary", - "description": "The user requires a non-prerelease version of `a` but has enabled pre-releases. There are pre-releases on the boundary of their range.", - "root": { - "requires": [ - "a<0.2.0" - ] - }, - "resolver_options": { - "prereleases": true - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "0.2.0a1": {}, - "0.3.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0" - }, - "explanation": "Since the user did not use a pre-release specifier, pre-releases at the boundary should not be selected even though pre-releases are allowed." - } - }, - { - "name": "package-prereleases-global-boundary", - "description": "The user requires a non-prerelease version of `a` but has enabled pre-releases. There are pre-releases on the boundary of their range.", - "root": { - "requires": [ - "a<0.2.0" - ] - }, - "resolver_options": { - "prereleases": true - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "0.2.0a1": {}, - "0.3.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0" - }, - "explanation": "Since the user did not use a pre-release specifier, pre-releases at the boundary should not be selected even though pre-releases are allowed." - } - }, - { - "name": "package-prereleases-specifier-boundary", - "description": "The user requires a prerelease version of `a`. There are pre-releases on the boundary of their range.", - "root": { - "requires": [ - "a<0.2.0a2" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "0.2.0": {}, - "0.2.0a1": {}, - "0.2.0a2": {}, - "0.2.0a3": {}, - "0.3.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.2.0a1" - }, - "explanation": "Since the user used a pre-release specifier, pre-releases at the boundary should be selected." - } - } -] diff --git a/scenarios/prereleases/package-multiple-prereleases-kinds.toml b/scenarios/prereleases/package-multiple-prereleases-kinds.toml new file mode 100644 index 00000000..28197020 --- /dev/null +++ b/scenarios/prereleases/package-multiple-prereleases-kinds.toml @@ -0,0 +1,18 @@ +name = "package-multiple-prereleases-kinds" +description = "The user requires `a` which has multiple prereleases available with different labels." + +[root] +requires = ["a>=1.0.0a1"] + +[expected] +satisfiable = true +explanation = "Release candidates should be the highest precedence prerelease kind." + +[expected.packages] +a = "1.0.0rc1" + +[packages.a.versions."1.0.0a1"] + +[packages.a.versions."1.0.0b1"] + +[packages.a.versions."1.0.0rc1"] diff --git a/scenarios/prereleases/package-multiple-prereleases-numbers.toml b/scenarios/prereleases/package-multiple-prereleases-numbers.toml new file mode 100644 index 00000000..95701722 --- /dev/null +++ b/scenarios/prereleases/package-multiple-prereleases-numbers.toml @@ -0,0 +1,18 @@ +name = "package-multiple-prereleases-numbers" +description = "The user requires `a` which has multiple alphas available." + +[root] +requires = ["a>=1.0.0a1"] + +[expected] +satisfiable = true +explanation = "The latest alpha version should be selected." + +[expected.packages] +a = "1.0.0a3" + +[packages.a.versions."1.0.0a1"] + +[packages.a.versions."1.0.0a2"] + +[packages.a.versions."1.0.0a3"] diff --git a/scenarios/prereleases/package-only-prereleases-boundary.toml b/scenarios/prereleases/package-only-prereleases-boundary.toml new file mode 100644 index 00000000..bead9a54 --- /dev/null +++ b/scenarios/prereleases/package-only-prereleases-boundary.toml @@ -0,0 +1,18 @@ +name = "package-only-prereleases-boundary" +description = "The user requires a non-prerelease version of `a` which only has prerelease versions available. There are pre-releases on the boundary of their range." + +[root] +requires = ["a<0.2.0"] + +[expected] +satisfiable = true +explanation = "Since there are only prerelease versions of `a` available, a prerelease is allowed. Since the user did not explicitly request a pre-release, pre-releases at the boundary should not be selected." + +[expected.packages] +a = "0.1.0a1" + +[packages.a.versions."0.1.0a1"] + +[packages.a.versions."0.2.0a1"] + +[packages.a.versions."0.3.0a1"] diff --git a/scenarios/prereleases/package-only-prereleases-in-range.toml b/scenarios/prereleases/package-only-prereleases-in-range.toml new file mode 100644 index 00000000..df08ab73 --- /dev/null +++ b/scenarios/prereleases/package-only-prereleases-in-range.toml @@ -0,0 +1,13 @@ +name = "package-only-prereleases-in-range" +description = "The user requires a version of package `a` which only matches prerelease versions but they did not include a prerelease specifier." + +[root] +requires = ["a>0.1.0"] + +[expected] +satisfiable = false +explanation = "Since there are stable versions of `a` available, prerelease versions should not be selected without explicit opt-in." + +[packages.a.versions."0.1.0"] + +[packages.a.versions."1.0.0a1"] diff --git a/scenarios/prereleases/package-only-prereleases.toml b/scenarios/prereleases/package-only-prereleases.toml new file mode 100644 index 00000000..407deca8 --- /dev/null +++ b/scenarios/prereleases/package-only-prereleases.toml @@ -0,0 +1,14 @@ +name = "package-only-prereleases" +description = "The user requires any version of package `a` which only has prerelease versions available." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "Since there are only prerelease versions of `a` available, it should be installed even though the user did not include a prerelease specifier." + +[expected.packages] +a = "1.0.0a1" + +[packages.a.versions."1.0.0a1"] diff --git a/scenarios/prereleases/package-prerelease-specified-mixed-available.toml b/scenarios/prereleases/package-prerelease-specified-mixed-available.toml new file mode 100644 index 00000000..f7d4bc77 --- /dev/null +++ b/scenarios/prereleases/package-prerelease-specified-mixed-available.toml @@ -0,0 +1,20 @@ +name = "package-prerelease-specified-mixed-available" +description = "The user requires a version of `a` with a prerelease specifier and both prerelease and stable releases are available." + +[root] +requires = ["a>=0.1.0a1"] + +[expected] +satisfiable = true +explanation = "Since the user provided a prerelease specifier, the latest prerelease version should be selected." + +[expected.packages] +a = "1.0.0a1" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."0.2.0a1"] + +[packages.a.versions."0.3.0"] + +[packages.a.versions."1.0.0a1"] diff --git a/scenarios/prereleases/package-prerelease-specified-only-final-available.toml b/scenarios/prereleases/package-prerelease-specified-only-final-available.toml new file mode 100644 index 00000000..97f70432 --- /dev/null +++ b/scenarios/prereleases/package-prerelease-specified-only-final-available.toml @@ -0,0 +1,18 @@ +name = "package-prerelease-specified-only-final-available" +description = "The user requires a version of `a` with a prerelease specifier and only stable releases are available." + +[root] +requires = ["a>=0.1.0a1"] + +[expected] +satisfiable = true +explanation = "The latest stable version should be selected." + +[expected.packages] +a = "0.3.0" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."0.2.0"] + +[packages.a.versions."0.3.0"] diff --git a/scenarios/prereleases/package-prerelease-specified-only-prerelease-available.toml b/scenarios/prereleases/package-prerelease-specified-only-prerelease-available.toml new file mode 100644 index 00000000..8f1bcacb --- /dev/null +++ b/scenarios/prereleases/package-prerelease-specified-only-prerelease-available.toml @@ -0,0 +1,18 @@ +name = "package-prerelease-specified-only-prerelease-available" +description = "The user requires a version of `a` with a prerelease specifier and only prerelease releases are available." + +[root] +requires = ["a>=0.1.0a1"] + +[expected] +satisfiable = true +explanation = "The latest prerelease version should be selected." + +[expected.packages] +a = "0.3.0a1" + +[packages.a.versions."0.1.0a1"] + +[packages.a.versions."0.2.0a1"] + +[packages.a.versions."0.3.0a1"] diff --git a/scenarios/prereleases/package-prereleases-boundary.toml b/scenarios/prereleases/package-prereleases-boundary.toml new file mode 100644 index 00000000..a91b0b6e --- /dev/null +++ b/scenarios/prereleases/package-prereleases-boundary.toml @@ -0,0 +1,18 @@ +name = "package-prereleases-boundary" +description = "The user requires a non-prerelease version of `a` but has enabled pre-releases. There are pre-releases on the boundary of their range." + +[root] +requires = ["a<0.2.0"] + +[expected] +satisfiable = true +explanation = "Since the user did not use a pre-release specifier, pre-releases at the boundary should not be selected even though pre-releases are allowed." + +[expected.packages] +a = "0.1.0" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."0.2.0a1"] + +[packages.a.versions."0.3.0"] diff --git a/scenarios/prereleases/package-prereleases-global-boundary.toml b/scenarios/prereleases/package-prereleases-global-boundary.toml new file mode 100644 index 00000000..2c808100 --- /dev/null +++ b/scenarios/prereleases/package-prereleases-global-boundary.toml @@ -0,0 +1,18 @@ +name = "package-prereleases-global-boundary" +description = "The user requires a non-prerelease version of `a` but has enabled pre-releases. There are pre-releases on the boundary of their range." + +[root] +requires = ["a<0.2.0"] + +[expected] +satisfiable = true +explanation = "Since the user did not use a pre-release specifier, pre-releases at the boundary should not be selected even though pre-releases are allowed." + +[expected.packages] +a = "0.1.0" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."0.2.0a1"] + +[packages.a.versions."0.3.0"] diff --git a/scenarios/prereleases/package-prereleases-specifier-boundary.toml b/scenarios/prereleases/package-prereleases-specifier-boundary.toml new file mode 100644 index 00000000..c023fa82 --- /dev/null +++ b/scenarios/prereleases/package-prereleases-specifier-boundary.toml @@ -0,0 +1,24 @@ +name = "package-prereleases-specifier-boundary" +description = "The user requires a prerelease version of `a`. There are pre-releases on the boundary of their range." + +[root] +requires = ["a<0.2.0a2"] + +[expected] +satisfiable = true +explanation = "Since the user used a pre-release specifier, pre-releases at the boundary should be selected." + +[expected.packages] +a = "0.2.0a1" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."0.2.0"] + +[packages.a.versions."0.2.0a1"] + +[packages.a.versions."0.2.0a2"] + +[packages.a.versions."0.2.0a3"] + +[packages.a.versions."0.3.0"] diff --git a/scenarios/prereleases/requires-package-only-prereleases-in-range-global-opt-in.toml b/scenarios/prereleases/requires-package-only-prereleases-in-range-global-opt-in.toml new file mode 100644 index 00000000..0f7921e1 --- /dev/null +++ b/scenarios/prereleases/requires-package-only-prereleases-in-range-global-opt-in.toml @@ -0,0 +1,15 @@ +name = "requires-package-only-prereleases-in-range-global-opt-in" +description = "The user requires a version of package `a` which only matches prerelease versions. They did not include a prerelease specifier for the package, but they opted into prereleases globally." + +[root] +requires = ["a>0.1.0"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0a1" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."1.0.0a1"] diff --git a/scenarios/prereleases/requires-package-prerelease-and-final-any.toml b/scenarios/prereleases/requires-package-prerelease-and-final-any.toml new file mode 100644 index 00000000..bff6d03e --- /dev/null +++ b/scenarios/prereleases/requires-package-prerelease-and-final-any.toml @@ -0,0 +1,16 @@ +name = "requires-package-prerelease-and-final-any" +description = "The user requires any version of package `a` has a prerelease version available and an older non-prerelease version." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "Since the user did not provide a prerelease specifier, the older stable version should be selected." + +[expected.packages] +a = "0.1.0" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."1.0.0a1"] diff --git a/scenarios/prereleases/transitive-package-only-prereleases-in-range-opt-in.toml b/scenarios/prereleases/transitive-package-only-prereleases-in-range-opt-in.toml new file mode 100644 index 00000000..9abd287e --- /dev/null +++ b/scenarios/prereleases/transitive-package-only-prereleases-in-range-opt-in.toml @@ -0,0 +1,20 @@ +name = "transitive-package-only-prereleases-in-range-opt-in" +description = "The user requires package `a` which has a dependency on a package which only matches prerelease versions; the user has opted into allowing prereleases in `b` explicitly." + +[root] +requires = ["a", "b>0.0.0a1"] + +[expected] +satisfiable = true +explanation = "Since the user included a dependency on `b` with a prerelease specifier, a prerelease version can be selected." + +[expected.packages] +a = "0.1.0" +b = "1.0.0a1" + +[packages.a.versions."0.1.0"] +requires = ["b>0.1"] + +[packages.b.versions."0.1.0"] + +[packages.b.versions."1.0.0a1"] diff --git a/scenarios/prereleases/transitive-package-only-prereleases-in-range.toml b/scenarios/prereleases/transitive-package-only-prereleases-in-range.toml new file mode 100644 index 00000000..b6dd2ae5 --- /dev/null +++ b/scenarios/prereleases/transitive-package-only-prereleases-in-range.toml @@ -0,0 +1,16 @@ +name = "transitive-package-only-prereleases-in-range" +description = "The user requires package `a` which has a dependency on a package which only matches prerelease versions but they did not include a prerelease specifier." + +[root] +requires = ["a"] + +[expected] +satisfiable = false +explanation = "Since there are stable versions of `b` available, the prerelease version should not be selected without explicit opt-in. The available version is excluded by the range requested by the user." + +[packages.a.versions."0.1.0"] +requires = ["b>0.1"] + +[packages.b.versions."0.1.0"] + +[packages.b.versions."1.0.0a1"] diff --git a/scenarios/prereleases/transitive-package-only-prereleases.toml b/scenarios/prereleases/transitive-package-only-prereleases.toml new file mode 100644 index 00000000..6ab9c671 --- /dev/null +++ b/scenarios/prereleases/transitive-package-only-prereleases.toml @@ -0,0 +1,18 @@ +name = "transitive-package-only-prereleases" +description = "The user requires any version of package `a` which requires `b` which only has prerelease versions available." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "Since there are only prerelease versions of `b` available, it should be selected even though the user did not opt-in to prereleases." + +[expected.packages] +a = "0.1.0" +b = "1.0.0a1" + +[packages.a.versions."0.1.0"] +requires = ["b"] + +[packages.b.versions."1.0.0a1"] diff --git a/scenarios/prereleases/transitive-prerelease-and-stable-dependency-many-versions-holes.toml b/scenarios/prereleases/transitive-prerelease-and-stable-dependency-many-versions-holes.toml new file mode 100644 index 00000000..8d7b7826 --- /dev/null +++ b/scenarios/prereleases/transitive-prerelease-and-stable-dependency-many-versions-holes.toml @@ -0,0 +1,53 @@ +name = "transitive-prerelease-and-stable-dependency-many-versions-holes" +description = "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease. There are many prerelease versions and some are excluded." + +[root] +requires = ["a", "b"] + +[expected] +satisfiable = false +explanation = "Since the user did not explicitly opt-in to a prerelease, it cannot be selected." + +[packages.a.versions."1.0.0"] +requires = ["c>1.0.0,!=2.0.0a5,!=2.0.0a6,!=2.0.0a7,!=2.0.0b1,<2.0.0b5"] + +[packages.b.versions."1.0.0"] +requires = ["c>=1.0.0,<=3.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0a1"] + +[packages.c.versions."2.0.0a2"] + +[packages.c.versions."2.0.0a3"] + +[packages.c.versions."2.0.0a4"] + +[packages.c.versions."2.0.0a5"] + +[packages.c.versions."2.0.0a6"] + +[packages.c.versions."2.0.0a7"] + +[packages.c.versions."2.0.0a8"] + +[packages.c.versions."2.0.0a9"] + +[packages.c.versions."2.0.0b1"] + +[packages.c.versions."2.0.0b2"] + +[packages.c.versions."2.0.0b3"] + +[packages.c.versions."2.0.0b4"] + +[packages.c.versions."2.0.0b5"] + +[packages.c.versions."2.0.0b6"] + +[packages.c.versions."2.0.0b7"] + +[packages.c.versions."2.0.0b8"] + +[packages.c.versions."2.0.0b9"] diff --git a/scenarios/prereleases/transitive-prerelease-and-stable-dependency-many-versions.toml b/scenarios/prereleases/transitive-prerelease-and-stable-dependency-many-versions.toml new file mode 100644 index 00000000..d6531c8c --- /dev/null +++ b/scenarios/prereleases/transitive-prerelease-and-stable-dependency-many-versions.toml @@ -0,0 +1,53 @@ +name = "transitive-prerelease-and-stable-dependency-many-versions" +description = "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease. There are many prerelease versions." + +[root] +requires = ["a", "b"] + +[expected] +satisfiable = false +explanation = "Since the user did not explicitly opt-in to a prerelease, it cannot be selected." + +[packages.a.versions."1.0.0"] +requires = ["c>=2.0.0b1"] + +[packages.b.versions."1.0.0"] +requires = ["c>=1.0.0,<=3.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0a1"] + +[packages.c.versions."2.0.0a2"] + +[packages.c.versions."2.0.0a3"] + +[packages.c.versions."2.0.0a4"] + +[packages.c.versions."2.0.0a5"] + +[packages.c.versions."2.0.0a6"] + +[packages.c.versions."2.0.0a7"] + +[packages.c.versions."2.0.0a8"] + +[packages.c.versions."2.0.0a9"] + +[packages.c.versions."2.0.0b1"] + +[packages.c.versions."2.0.0b2"] + +[packages.c.versions."2.0.0b3"] + +[packages.c.versions."2.0.0b4"] + +[packages.c.versions."2.0.0b5"] + +[packages.c.versions."2.0.0b6"] + +[packages.c.versions."2.0.0b7"] + +[packages.c.versions."2.0.0b8"] + +[packages.c.versions."2.0.0b9"] diff --git a/scenarios/prereleases/transitive-prerelease-and-stable-dependency-opt-in.toml b/scenarios/prereleases/transitive-prerelease-and-stable-dependency-opt-in.toml new file mode 100644 index 00000000..a2049b6b --- /dev/null +++ b/scenarios/prereleases/transitive-prerelease-and-stable-dependency-opt-in.toml @@ -0,0 +1,24 @@ +name = "transitive-prerelease-and-stable-dependency-opt-in" +description = "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease. The user includes an opt-in to prereleases of the transitive dependency." + +[root] +requires = ["a", "b", "c>=0.0.0a1"] + +[expected] +satisfiable = true +explanation = "Since the user explicitly opted-in to a prerelease for `c`, it can be installed." + +[expected.packages] +a = "1.0.0" +b = "1.0.0" +c = "2.0.0b1" + +[packages.a.versions."1.0.0"] +requires = ["c==2.0.0b1"] + +[packages.b.versions."1.0.0"] +requires = ["c>=1.0.0,<=3.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0b1"] diff --git a/scenarios/prereleases/transitive-prerelease-and-stable-dependency.toml b/scenarios/prereleases/transitive-prerelease-and-stable-dependency.toml new file mode 100644 index 00000000..fad73925 --- /dev/null +++ b/scenarios/prereleases/transitive-prerelease-and-stable-dependency.toml @@ -0,0 +1,19 @@ +name = "transitive-prerelease-and-stable-dependency" +description = "A transitive dependency has both a prerelease and a stable selector, but can only be satisfied by a prerelease" + +[root] +requires = ["a", "b"] + +[expected] +satisfiable = false +explanation = "Since the user did not explicitly opt-in to a prerelease, it cannot be selected." + +[packages.a.versions."1.0.0"] +requires = ["c==2.0.0b1"] + +[packages.b.versions."1.0.0"] +requires = ["c>=1.0.0,<=3.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0b1"] diff --git a/scenarios/requires-python.json b/scenarios/requires-python.json deleted file mode 100644 index 5f1ddb59..00000000 --- a/scenarios/requires-python.json +++ /dev/null @@ -1,464 +0,0 @@ -[ - { - "name": "python-version-does-not-exist", - "description": "The user requires a package which requires a Python version that does not exist", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.30" - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "python-less-than-current", - "description": "The user requires a package which requires a Python version less than the current version", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": "<=3.8" - } - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "We ignore the upper bound on Python requirements" - } - }, - { - "name": "python-greater-than-current", - "description": "The user requires a package which requires a Python version greater than the current version", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10" - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "python-greater-than-current-patch", - "description": "The user requires a package which requires a Python version with a patch version greater than the current patch version", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "environment": { - "python": "3.8.12" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.8.14" - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "python-greater-than-current-many", - "description": "The user requires a package which has many versions which all require a Python version greater than the current version", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "2.0.0": { - "requires_python": ">=3.10" - }, - "2.1.0": { - "requires_python": ">=3.10" - }, - "2.2.0": { - "requires_python": ">=3.10" - }, - "2.3.0": { - "requires_python": ">=3.10" - }, - "2.4.0": { - "requires_python": ">=3.10" - }, - "2.5.0": { - "requires_python": ">=3.10" - }, - "3.0.0": { - "requires_python": ">=3.11" - }, - "3.1.0": { - "requires_python": ">=3.11" - }, - "3.2.0": { - "requires_python": ">=3.11" - }, - "3.3.0": { - "requires_python": ">=3.11" - }, - "3.4.0": { - "requires_python": ">=3.11" - }, - "3.5.0": { - "requires_python": ">=3.11" - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "python-greater-than-current-backtrack", - "description": "The user requires a package where recent versions require a Python version greater than the current version, but an older version is compatible.", - "root": { - "requires": [ - "a" - ] - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.9" - }, - "2.0.0": { - "requires_python": ">=3.10" - }, - "3.0.0": { - "requires_python": ">=3.11" - }, - "4.0.0": { - "requires_python": ">=3.12" - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0" - } - } - }, - { - "name": "python-greater-than-current-excluded", - "description": "The user requires a package where recent versions require a Python version greater than the current version, but an excluded older version is compatible.", - "root": { - "requires": [ - "a>=2.0.0" - ] - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.9" - }, - "2.0.0": { - "requires_python": ">=3.10" - }, - "3.0.0": { - "requires_python": ">=3.11" - }, - "4.0.0": { - "requires_python": ">=3.12" - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "incompatible-python-compatible-override", - "description": "The user requires a package which requires a Python version greater than the current version, but they use an alternative Python version for package resolution.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.11" - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10" - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0" - } - } - }, - { - "name": "compatible-python-incompatible-override", - "description": "The user requires a package which requires a compatible Python version, but they request an incompatible Python version for package resolution.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.9" - }, - "environment": { - "python": "3.11" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10" - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "incompatible-python-compatible-override-unavailable-no-wheels", - "description": "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There are only source distributions available for the package.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.11" - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10", - "wheel": false - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since there are no wheels for the package and it is not compatible with the local installation, we cannot build the source distribution to determine its dependencies." - } - }, - { - "name": "incompatible-python-compatible-override-available-no-wheels", - "description": "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There are only source distributions available for the package. The user has a compatible Python version installed elsewhere on their system.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.11" - }, - "environment": { - "python": "3.9", - "additional_python": [ - "3.11" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10", - "wheel": false - } - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "Since there is a compatible Python version available on the system, it should be used to build the source distributions.", - "packages": { - "a": "1.0.0" - } - } - }, - { - "name": "incompatible-python-compatible-override-no-compatible-wheels", - "description": "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There is a wheel available for the package, but it does not have a compatible tag.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.11" - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10", - "wheel_tags": [ - "foo-none-any" - ] - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since there are no compatible wheels for the package and it is not compatible with the local installation, we cannot build the source distribution to determine its dependencies." - } - }, - { - "name": "incompatible-python-compatible-override-other-wheel", - "description": "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There are only source distributions available for the compatible version of the package, but there is an incompatible version with a wheel available.", - "root": { - "requires": [ - "a" - ] - }, - "resolver_options": { - "python": "3.11" - }, - "environment": { - "python": "3.9" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.10", - "wheel": false - }, - "2.0.0": { - "requires_python": ">=3.12" - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since there are no wheels for the version of the package compatible with the target and it is not compatible with the local installation, we cannot build the source distribution to determine its dependencies. The other version has wheels available, but is not compatible with the target version and cannot be used." - } - }, - { - "name": "python-patch-override-no-patch", - "description": "The user requires a package which requires a Python version with a patch version and the user provides a target version without a patch version.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.8" - }, - "environment": { - "python": "3.8.18" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.8.4" - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since the resolver is asked to solve with 3.8, the minimum compatible Python requirement is treated as 3.8.0." - } - }, - { - "name": "python-patch-override-patch-compatible", - "description": "The user requires a package which requires a Python version with a patch version and the user provides a target version with a compatible patch version.", - "root": { - "requires": [ - "a==1.0.0" - ] - }, - "resolver_options": { - "python": "3.8.0" - }, - "environment": { - "python": "3.8.18" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires_python": ">=3.8.0" - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0" - } - } - } -] diff --git a/scenarios/requires_python/compatible-python-incompatible-override.toml b/scenarios/requires_python/compatible-python-incompatible-override.toml new file mode 100644 index 00000000..48e30bf5 --- /dev/null +++ b/scenarios/requires_python/compatible-python-incompatible-override.toml @@ -0,0 +1,11 @@ +name = "compatible-python-incompatible-override" +description = "The user requires a package which requires a compatible Python version, but they request an incompatible Python version for package resolution." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" diff --git a/scenarios/requires_python/incompatible-python-compatible-override-available-no-wheels.toml b/scenarios/requires_python/incompatible-python-compatible-override-available-no-wheels.toml new file mode 100644 index 00000000..5817b6bd --- /dev/null +++ b/scenarios/requires_python/incompatible-python-compatible-override-available-no-wheels.toml @@ -0,0 +1,16 @@ +name = "incompatible-python-compatible-override-available-no-wheels" +description = "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There are only source distributions available for the package. The user has a compatible Python version installed elsewhere on their system." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = true +explanation = "Since there is a compatible Python version available on the system, it should be used to build the source distributions." + +[expected.packages] +a = "1.0.0" + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" +wheel = false diff --git a/scenarios/requires_python/incompatible-python-compatible-override-no-compatible-wheels.toml b/scenarios/requires_python/incompatible-python-compatible-override-no-compatible-wheels.toml new file mode 100644 index 00000000..7363ff29 --- /dev/null +++ b/scenarios/requires_python/incompatible-python-compatible-override-no-compatible-wheels.toml @@ -0,0 +1,13 @@ +name = "incompatible-python-compatible-override-no-compatible-wheels" +description = "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There is a wheel available for the package, but it does not have a compatible tag." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false +explanation = "Since there are no compatible wheels for the package and it is not compatible with the local installation, we cannot build the source distribution to determine its dependencies." + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" +wheel_tags = ["foo-none-any"] diff --git a/scenarios/requires_python/incompatible-python-compatible-override-other-wheel.toml b/scenarios/requires_python/incompatible-python-compatible-override-other-wheel.toml new file mode 100644 index 00000000..22844648 --- /dev/null +++ b/scenarios/requires_python/incompatible-python-compatible-override-other-wheel.toml @@ -0,0 +1,16 @@ +name = "incompatible-python-compatible-override-other-wheel" +description = "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There are only source distributions available for the compatible version of the package, but there is an incompatible version with a wheel available." + +[root] +requires = ["a"] + +[expected] +satisfiable = false +explanation = "Since there are no wheels for the version of the package compatible with the target and it is not compatible with the local installation, we cannot build the source distribution to determine its dependencies. The other version has wheels available, but is not compatible with the target version and cannot be used." + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" +wheel = false + +[packages.a.versions."2.0.0"] +requires_python = ">=3.12" diff --git a/scenarios/requires_python/incompatible-python-compatible-override-unavailable-no-wheels.toml b/scenarios/requires_python/incompatible-python-compatible-override-unavailable-no-wheels.toml new file mode 100644 index 00000000..41f4b95c --- /dev/null +++ b/scenarios/requires_python/incompatible-python-compatible-override-unavailable-no-wheels.toml @@ -0,0 +1,13 @@ +name = "incompatible-python-compatible-override-unavailable-no-wheels" +description = "The user requires a package which requires a incompatible Python version, but they request a compatible Python version for package resolution. There are only source distributions available for the package." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false +explanation = "Since there are no wheels for the package and it is not compatible with the local installation, we cannot build the source distribution to determine its dependencies." + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" +wheel = false diff --git a/scenarios/requires_python/incompatible-python-compatible-override.toml b/scenarios/requires_python/incompatible-python-compatible-override.toml new file mode 100644 index 00000000..5095adea --- /dev/null +++ b/scenarios/requires_python/incompatible-python-compatible-override.toml @@ -0,0 +1,14 @@ +name = "incompatible-python-compatible-override" +description = "The user requires a package which requires a Python version greater than the current version, but they use an alternative Python version for package resolution." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0" + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" diff --git a/scenarios/requires_python/python-greater-than-current-backtrack.toml b/scenarios/requires_python/python-greater-than-current-backtrack.toml new file mode 100644 index 00000000..d3c3cf2e --- /dev/null +++ b/scenarios/requires_python/python-greater-than-current-backtrack.toml @@ -0,0 +1,23 @@ +name = "python-greater-than-current-backtrack" +description = "The user requires a package where recent versions require a Python version greater than the current version, but an older version is compatible." + +[root] +requires = ["a"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0" + +[packages.a.versions."1.0.0"] +requires_python = ">=3.9" + +[packages.a.versions."2.0.0"] +requires_python = ">=3.10" + +[packages.a.versions."3.0.0"] +requires_python = ">=3.11" + +[packages.a.versions."4.0.0"] +requires_python = ">=3.12" diff --git a/scenarios/requires_python/python-greater-than-current-excluded.toml b/scenarios/requires_python/python-greater-than-current-excluded.toml new file mode 100644 index 00000000..e57e322d --- /dev/null +++ b/scenarios/requires_python/python-greater-than-current-excluded.toml @@ -0,0 +1,20 @@ +name = "python-greater-than-current-excluded" +description = "The user requires a package where recent versions require a Python version greater than the current version, but an excluded older version is compatible." + +[root] +requires = ["a>=2.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires_python = ">=3.9" + +[packages.a.versions."2.0.0"] +requires_python = ">=3.10" + +[packages.a.versions."3.0.0"] +requires_python = ">=3.11" + +[packages.a.versions."4.0.0"] +requires_python = ">=3.12" diff --git a/scenarios/requires_python/python-greater-than-current-many.toml b/scenarios/requires_python/python-greater-than-current-many.toml new file mode 100644 index 00000000..cf8ffecf --- /dev/null +++ b/scenarios/requires_python/python-greater-than-current-many.toml @@ -0,0 +1,44 @@ +name = "python-greater-than-current-many" +description = "The user requires a package which has many versions which all require a Python version greater than the current version" + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."2.0.0"] +requires_python = ">=3.10" + +[packages.a.versions."2.1.0"] +requires_python = ">=3.10" + +[packages.a.versions."2.2.0"] +requires_python = ">=3.10" + +[packages.a.versions."2.3.0"] +requires_python = ">=3.10" + +[packages.a.versions."2.4.0"] +requires_python = ">=3.10" + +[packages.a.versions."2.5.0"] +requires_python = ">=3.10" + +[packages.a.versions."3.0.0"] +requires_python = ">=3.11" + +[packages.a.versions."3.1.0"] +requires_python = ">=3.11" + +[packages.a.versions."3.2.0"] +requires_python = ">=3.11" + +[packages.a.versions."3.3.0"] +requires_python = ">=3.11" + +[packages.a.versions."3.4.0"] +requires_python = ">=3.11" + +[packages.a.versions."3.5.0"] +requires_python = ">=3.11" diff --git a/scenarios/requires_python/python-greater-than-current-patch.toml b/scenarios/requires_python/python-greater-than-current-patch.toml new file mode 100644 index 00000000..8d8eeaac --- /dev/null +++ b/scenarios/requires_python/python-greater-than-current-patch.toml @@ -0,0 +1,11 @@ +name = "python-greater-than-current-patch" +description = "The user requires a package which requires a Python version with a patch version greater than the current patch version" + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires_python = ">=3.8.14" diff --git a/scenarios/requires_python/python-greater-than-current.toml b/scenarios/requires_python/python-greater-than-current.toml new file mode 100644 index 00000000..d61fee21 --- /dev/null +++ b/scenarios/requires_python/python-greater-than-current.toml @@ -0,0 +1,11 @@ +name = "python-greater-than-current" +description = "The user requires a package which requires a Python version greater than the current version" + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires_python = ">=3.10" diff --git a/scenarios/requires_python/python-less-than-current.toml b/scenarios/requires_python/python-less-than-current.toml new file mode 100644 index 00000000..c948c787 --- /dev/null +++ b/scenarios/requires_python/python-less-than-current.toml @@ -0,0 +1,12 @@ +name = "python-less-than-current" +description = "The user requires a package which requires a Python version less than the current version" + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = true +explanation = "We ignore the upper bound on Python requirements" + +[packages.a.versions."1.0.0"] +requires_python = "<=3.8" diff --git a/scenarios/requires_python/python-patch-override-no-patch.toml b/scenarios/requires_python/python-patch-override-no-patch.toml new file mode 100644 index 00000000..68bb099c --- /dev/null +++ b/scenarios/requires_python/python-patch-override-no-patch.toml @@ -0,0 +1,12 @@ +name = "python-patch-override-no-patch" +description = "The user requires a package which requires a Python version with a patch version and the user provides a target version without a patch version." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false +explanation = "Since the resolver is asked to solve with 3.8, the minimum compatible Python requirement is treated as 3.8.0." + +[packages.a.versions."1.0.0"] +requires_python = ">=3.8.4" diff --git a/scenarios/requires_python/python-patch-override-patch-compatible.toml b/scenarios/requires_python/python-patch-override-patch-compatible.toml new file mode 100644 index 00000000..8956840a --- /dev/null +++ b/scenarios/requires_python/python-patch-override-patch-compatible.toml @@ -0,0 +1,14 @@ +name = "python-patch-override-patch-compatible" +description = "The user requires a package which requires a Python version with a patch version and the user provides a target version with a compatible patch version." + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = true + +[expected.packages] +a = "1.0.0" + +[packages.a.versions."1.0.0"] +requires_python = ">=3.8.0" diff --git a/scenarios/requires_python/python-version-does-not-exist.toml b/scenarios/requires_python/python-version-does-not-exist.toml new file mode 100644 index 00000000..da7219cf --- /dev/null +++ b/scenarios/requires_python/python-version-does-not-exist.toml @@ -0,0 +1,11 @@ +name = "python-version-does-not-exist" +description = "The user requires a package which requires a Python version that does not exist" + +[root] +requires = ["a==1.0.0"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +requires_python = ">=3.30" diff --git a/scenarios/tag-and-markers.json b/scenarios/tag-and-markers.json deleted file mode 100644 index d8f509e8..00000000 --- a/scenarios/tag-and-markers.json +++ /dev/null @@ -1,118 +0,0 @@ -[ - { - "name": "unreachable-package", - "description": "`c` is not reachable due to the markers, it should be excluded from the lockfile", - "root": { - "requires": [ - "a==1.0.0; sys_platform == 'win32'" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": ["b==1.0.0; sys_platform == 'linux'"] - } - } - }, - "b": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true - }, - "resolver_options": { - "universal": true - } - }, - { - "name": "unreachable-wheels", - "description": "Check that we only include wheels that match the platform markers", - "root": { - "requires": [ - "a==1.0.0; sys_platform == 'win32'", - "b==1.0.0; sys_platform == 'linux'", - "c==1.0.0; sys_platform == 'darwin'" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", - "cp312-cp312-musllinux_1_1_armv7l", - "cp312-cp312-win_amd64", - "cp312-cp312-macosx_14_0_x86_64" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", - "cp312-cp312-musllinux_1_1_armv7l", - "cp312-cp312-win_amd64", - "cp312-cp312-macosx_14_0_x86_64" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", - "cp312-cp312-musllinux_1_1_armv7l", - "cp312-cp312-win_amd64", - "cp312-cp312-macosx_14_0_x86_64" - ] - } - } - } - }, - "expected": { - "satisfiable": true - }, - "resolver_options": { - "universal": true - } - }, - { - "name": "requires-python-wheels", - "description": "Check that we only include wheels that match the required Python version", - "root": { - "requires_python": ">=3.10", - "requires": [ - "a==1.0.0" - ] - }, - "environment": { - "python": "3.12" - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "cp311-cp311-any", - "cp310-cp310-any", - "cp39-cp39-any" - ] - } - } - } - }, - "expected": { - "satisfiable": true - }, - "resolver_options": { - "universal": true - } - } -] diff --git a/scenarios/tag_and_markers/requires-python-wheels.toml b/scenarios/tag_and_markers/requires-python-wheels.toml new file mode 100644 index 00000000..45b96ddc --- /dev/null +++ b/scenarios/tag_and_markers/requires-python-wheels.toml @@ -0,0 +1,12 @@ +name = "requires-python-wheels" +description = "Check that we only include wheels that match the required Python version" + +[root] +requires_python = ">=3.10" +requires = ["a==1.0.0"] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +wheel_tags = ["cp311-cp311-any", "cp310-cp310-any", "cp39-cp39-any"] diff --git a/scenarios/tag_and_markers/unreachable-package.toml b/scenarios/tag_and_markers/unreachable-package.toml new file mode 100644 index 00000000..943de1c1 --- /dev/null +++ b/scenarios/tag_and_markers/unreachable-package.toml @@ -0,0 +1,13 @@ +name = "unreachable-package" +description = "`c` is not reachable due to the markers, it should be excluded from the lockfile" + +[root] +requires = ["a==1.0.0; sys_platform == 'win32'"] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +requires = ["b==1.0.0; sys_platform == 'linux'"] + +[packages.b.versions."1.0.0"] diff --git a/scenarios/tag_and_markers/unreachable-wheels.toml b/scenarios/tag_and_markers/unreachable-wheels.toml new file mode 100644 index 00000000..b4461ffb --- /dev/null +++ b/scenarios/tag_and_markers/unreachable-wheels.toml @@ -0,0 +1,36 @@ +name = "unreachable-wheels" +description = "Check that we only include wheels that match the platform markers" + +[root] +requires = [ + "a==1.0.0; sys_platform == 'win32'", + "b==1.0.0; sys_platform == 'linux'", + "c==1.0.0; sys_platform == 'darwin'", +] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +wheel_tags = [ + "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", + "cp312-cp312-musllinux_1_1_armv7l", + "cp312-cp312-win_amd64", + "cp312-cp312-macosx_14_0_x86_64", +] + +[packages.b.versions."1.0.0"] +wheel_tags = [ + "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", + "cp312-cp312-musllinux_1_1_armv7l", + "cp312-cp312-win_amd64", + "cp312-cp312-macosx_14_0_x86_64", +] + +[packages.c.versions."1.0.0"] +wheel_tags = [ + "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", + "cp312-cp312-musllinux_1_1_armv7l", + "cp312-cp312-win_amd64", + "cp312-cp312-macosx_14_0_x86_64", +] diff --git a/scenarios/wheels.json b/scenarios/wheels.json deleted file mode 100644 index 12e91251..00000000 --- a/scenarios/wheels.json +++ /dev/null @@ -1,265 +0,0 @@ -[ - { - "name": "specific-tag-and-default", - "description": "A wheel for a specific platform is available alongside the default.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", - "py3-none-any" - ] - } - } - } - }, - "expected": { - "satisfiable": true - } - }, - { - "name": "only-wheels", - "description": "No source distributions are available, only wheels.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "sdist": false - } - } - } - }, - "expected": { - "satisfiable": true - } - }, - { - "name": "no-wheels", - "description": "No wheels are available, only source distributions.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel": false - } - } - } - }, - "expected": { - "satisfiable": true - } - }, - { - "name": "no-wheels-with-matching-platform", - "description": "No wheels with matching platform tags are available, just source distributions.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "py3-any-macosx_10_0_ppc64" - ] - } - } - } - }, - "expected": { - "satisfiable": true - } - }, - { - "name": "no-sdist-no-wheels-with-matching-platform", - "description": "No wheels with matching platform tags are available, nor are any source distributions available", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "py3-none-macosx_10_0_ppc64" - ], - "sdist": false - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "no-sdist-no-wheels-with-matching-python", - "description": "No wheels with matching Python tags are available, nor are any source distributions available", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "jy27-none-any" - ], - "sdist": false - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "no-sdist-no-wheels-with-matching-abi", - "description": "No wheels with matching ABI tags are available, nor are any source distributions available", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel_tags": [ - "py3-MMMMMM-any" - ], - "sdist": false - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "no-wheels-no-build", - "description": "No wheels are available, only source distributions but the user has disabled builds.", - "root": { - "requires": [ - "a" - ] - }, - "resolver_options": { - "no_build": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "wheel": false - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "only-wheels-no-binary", - "description": "No source distributions are available, only wheels but the user has disabled using pre-built binaries.", - "root": { - "requires": [ - "a" - ] - }, - "resolver_options": { - "no_binary": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "sdist": false - } - } - } - }, - "expected": { - "satisfiable": false - } - }, - { - "name": "no-build", - "description": "Both wheels and source distributions are available, and the user has disabled builds.", - "root": { - "requires": [ - "a" - ] - }, - "resolver_options": { - "no_build": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "The wheel should be used for install" - } - }, - { - "name": "no-binary", - "description": "Both wheels and source distributions are available, and the user has disabled binaries.", - "root": { - "requires": [ - "a" - ] - }, - "resolver_options": { - "no_binary": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": {} - } - } - }, - "expected": { - "satisfiable": true, - "explanation": "The source distribution should be used for install" - } - } -] \ No newline at end of file diff --git a/scenarios/wheels/no-binary.toml b/scenarios/wheels/no-binary.toml new file mode 100644 index 00000000..b9f672f0 --- /dev/null +++ b/scenarios/wheels/no-binary.toml @@ -0,0 +1,11 @@ +name = "no-binary" +description = "Both wheels and source distributions are available, and the user has disabled binaries." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "The source distribution should be used for install" + +[packages.a.versions."1.0.0"] diff --git a/scenarios/wheels/no-build.toml b/scenarios/wheels/no-build.toml new file mode 100644 index 00000000..d72d4550 --- /dev/null +++ b/scenarios/wheels/no-build.toml @@ -0,0 +1,11 @@ +name = "no-build" +description = "Both wheels and source distributions are available, and the user has disabled builds." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "The wheel should be used for install" + +[packages.a.versions."1.0.0"] diff --git a/scenarios/wheels/no-sdist-no-wheels-with-matching-abi.toml b/scenarios/wheels/no-sdist-no-wheels-with-matching-abi.toml new file mode 100644 index 00000000..2ffccd70 --- /dev/null +++ b/scenarios/wheels/no-sdist-no-wheels-with-matching-abi.toml @@ -0,0 +1,12 @@ +name = "no-sdist-no-wheels-with-matching-abi" +description = "No wheels with matching ABI tags are available, nor are any source distributions available" + +[root] +requires = ["a"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +wheel_tags = ["py3-MMMMMM-any"] +sdist = false diff --git a/scenarios/wheels/no-sdist-no-wheels-with-matching-platform.toml b/scenarios/wheels/no-sdist-no-wheels-with-matching-platform.toml new file mode 100644 index 00000000..4d74a922 --- /dev/null +++ b/scenarios/wheels/no-sdist-no-wheels-with-matching-platform.toml @@ -0,0 +1,12 @@ +name = "no-sdist-no-wheels-with-matching-platform" +description = "No wheels with matching platform tags are available, nor are any source distributions available" + +[root] +requires = ["a"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +wheel_tags = ["py3-none-macosx_10_0_ppc64"] +sdist = false diff --git a/scenarios/wheels/no-sdist-no-wheels-with-matching-python.toml b/scenarios/wheels/no-sdist-no-wheels-with-matching-python.toml new file mode 100644 index 00000000..aa955744 --- /dev/null +++ b/scenarios/wheels/no-sdist-no-wheels-with-matching-python.toml @@ -0,0 +1,12 @@ +name = "no-sdist-no-wheels-with-matching-python" +description = "No wheels with matching Python tags are available, nor are any source distributions available" + +[root] +requires = ["a"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +wheel_tags = ["jy27-none-any"] +sdist = false diff --git a/scenarios/wheels/no-wheels-no-build.toml b/scenarios/wheels/no-wheels-no-build.toml new file mode 100644 index 00000000..74f2c56a --- /dev/null +++ b/scenarios/wheels/no-wheels-no-build.toml @@ -0,0 +1,11 @@ +name = "no-wheels-no-build" +description = "No wheels are available, only source distributions but the user has disabled builds." + +[root] +requires = ["a"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +wheel = false diff --git a/scenarios/wheels/no-wheels-with-matching-platform.toml b/scenarios/wheels/no-wheels-with-matching-platform.toml new file mode 100644 index 00000000..d24d42f9 --- /dev/null +++ b/scenarios/wheels/no-wheels-with-matching-platform.toml @@ -0,0 +1,11 @@ +name = "no-wheels-with-matching-platform" +description = "No wheels with matching platform tags are available, just source distributions." + +[root] +requires = ["a"] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +wheel_tags = ["py3-any-macosx_10_0_ppc64"] diff --git a/scenarios/wheels/no-wheels.toml b/scenarios/wheels/no-wheels.toml new file mode 100644 index 00000000..235eeee9 --- /dev/null +++ b/scenarios/wheels/no-wheels.toml @@ -0,0 +1,11 @@ +name = "no-wheels" +description = "No wheels are available, only source distributions." + +[root] +requires = ["a"] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +wheel = false diff --git a/scenarios/wheels/only-wheels-no-binary.toml b/scenarios/wheels/only-wheels-no-binary.toml new file mode 100644 index 00000000..3d255cd8 --- /dev/null +++ b/scenarios/wheels/only-wheels-no-binary.toml @@ -0,0 +1,11 @@ +name = "only-wheels-no-binary" +description = "No source distributions are available, only wheels but the user has disabled using pre-built binaries." + +[root] +requires = ["a"] + +[expected] +satisfiable = false + +[packages.a.versions."1.0.0"] +sdist = false diff --git a/scenarios/wheels/only-wheels.toml b/scenarios/wheels/only-wheels.toml new file mode 100644 index 00000000..cc667878 --- /dev/null +++ b/scenarios/wheels/only-wheels.toml @@ -0,0 +1,11 @@ +name = "only-wheels" +description = "No source distributions are available, only wheels." + +[root] +requires = ["a"] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +sdist = false diff --git a/scenarios/wheels/specific-tag-and-default.toml b/scenarios/wheels/specific-tag-and-default.toml new file mode 100644 index 00000000..c2eb78a3 --- /dev/null +++ b/scenarios/wheels/specific-tag-and-default.toml @@ -0,0 +1,14 @@ +name = "specific-tag-and-default" +description = "A wheel for a specific platform is available alongside the default." + +[root] +requires = ["a"] + +[expected] +satisfiable = true + +[packages.a.versions."1.0.0"] +wheel_tags = [ + "cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64", + "py3-none-any", +] diff --git a/scenarios/yanked.json b/scenarios/yanked.json deleted file mode 100644 index 7e2e1da7..00000000 --- a/scenarios/yanked.json +++ /dev/null @@ -1,293 +0,0 @@ -[ - { - "name": "package-only-yanked", - "description": "The user requires any version of package `a` which only has yanked versions available.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Yanked versions should not be installed, even if they are the only one available." - } - }, - { - "name": "package-only-yanked-in-range", - "description": "The user requires a version of package `a` which only matches yanked versions.", - "root": { - "requires": [ - "a>0.1.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since there are other versions of `a` available, yanked versions should not be selected without explicit opt-in." - } - }, - { - "name": "requires-package-yanked-and-unyanked-any", - "description": "The user requires any version of package `a` has a yanked version available and an older unyanked version.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0" - }, - "explanation": "The unyanked version should be selected." - } - }, - { - "name": "package-yanked-specified-mixed-available", - "description": "The user requires any version of `a` and both yanked and unyanked releases are available.", - "root": { - "requires": [ - "a>=0.1.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": {}, - "0.2.0": { - "yanked": true - }, - "0.3.0": {}, - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.3.0" - }, - "explanation": "The latest unyanked version should be selected." - } - }, - { - "name": "transitive-package-only-yanked", - "description": "The user requires any version of package `a` which requires `b` which only has yanked versions available.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": { - "requires": [ - "b" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Yanked versions should not be installed, even if they are the only one available." - } - }, - { - "name": "transitive-package-only-yanked-in-range", - "description": "The user requires package `a` which has a dependency on a package which only matches yanked versions.", - "root": { - "requires": [ - "a" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": { - "requires": [ - "b>0.1" - ] - } - } - }, - "b": { - "versions": { - "0.1.0": {}, - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Yanked versions should not be installed, even if they are the only valid version in a range." - } - }, - { - "name": "transitive-package-only-yanked-in-range-opt-in", - "description": "The user requires package `a` which has a dependency on a package which only matches yanked versions; the user has opted into allowing the yanked version of `b` explicitly.", - "root": { - "requires": [ - "a", - "b==1.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "0.1.0": { - "requires": [ - "b>0.1" - ] - } - } - }, - "b": { - "versions": { - "0.1.0": {}, - "1.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "0.1.0", - "b": "1.0.0" - }, - "explanation": "Since the user included a dependency on `b` with an exact specifier, the yanked version can be selected." - } - }, - { - "name": "transitive-yanked-and-unyanked-dependency", - "description": "A transitive dependency has both a yanked and an unyanked version, but can only be satisfied by a yanked version", - "root": { - "requires": [ - "a", - "b" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c==2.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c>=1.0.0,<=3.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": false, - "explanation": "Since the user did not explicitly select the yanked version, it cannot be used." - } - }, - { - "name": "transitive-yanked-and-unyanked-dependency-opt-in", - "description": "A transitive dependency has both a yanked and an unyanked version, but can only be satisfied by a yanked. The user includes an opt-in to the yanked version of the transitive dependency.", - "root": { - "requires": [ - "a", - "b", - "c==2.0.0" - ] - }, - "packages": { - "a": { - "versions": { - "1.0.0": { - "requires": [ - "c==2.0.0" - ] - } - } - }, - "b": { - "versions": { - "1.0.0": { - "requires": [ - "c>=1.0.0,<=3.0.0" - ] - } - } - }, - "c": { - "versions": { - "1.0.0": {}, - "2.0.0": { - "yanked": true - } - } - } - }, - "expected": { - "satisfiable": true, - "packages": { - "a": "1.0.0", - "b": "1.0.0", - "c": "2.0.0" - }, - "explanation": "Since the user explicitly selected the yanked version of `c`, it can be installed." - } - } -] \ No newline at end of file diff --git a/scenarios/yanked/package-only-yanked-in-range.toml b/scenarios/yanked/package-only-yanked-in-range.toml new file mode 100644 index 00000000..b529642b --- /dev/null +++ b/scenarios/yanked/package-only-yanked-in-range.toml @@ -0,0 +1,14 @@ +name = "package-only-yanked-in-range" +description = "The user requires a version of package `a` which only matches yanked versions." + +[root] +requires = ["a>0.1.0"] + +[expected] +satisfiable = false +explanation = "Since there are other versions of `a` available, yanked versions should not be selected without explicit opt-in." + +[packages.a.versions."0.1.0"] + +[packages.a.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/package-only-yanked.toml b/scenarios/yanked/package-only-yanked.toml new file mode 100644 index 00000000..c39abe82 --- /dev/null +++ b/scenarios/yanked/package-only-yanked.toml @@ -0,0 +1,12 @@ +name = "package-only-yanked" +description = "The user requires any version of package `a` which only has yanked versions available." + +[root] +requires = ["a"] + +[expected] +satisfiable = false +explanation = "Yanked versions should not be installed, even if they are the only one available." + +[packages.a.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/package-yanked-specified-mixed-available.toml b/scenarios/yanked/package-yanked-specified-mixed-available.toml new file mode 100644 index 00000000..3577b020 --- /dev/null +++ b/scenarios/yanked/package-yanked-specified-mixed-available.toml @@ -0,0 +1,22 @@ +name = "package-yanked-specified-mixed-available" +description = "The user requires any version of `a` and both yanked and unyanked releases are available." + +[root] +requires = ["a>=0.1.0"] + +[expected] +satisfiable = true +explanation = "The latest unyanked version should be selected." + +[expected.packages] +a = "0.3.0" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."0.2.0"] +yanked = true + +[packages.a.versions."0.3.0"] + +[packages.a.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/requires-package-yanked-and-unyanked-any.toml b/scenarios/yanked/requires-package-yanked-and-unyanked-any.toml new file mode 100644 index 00000000..c65b6851 --- /dev/null +++ b/scenarios/yanked/requires-package-yanked-and-unyanked-any.toml @@ -0,0 +1,17 @@ +name = "requires-package-yanked-and-unyanked-any" +description = "The user requires any version of package `a` has a yanked version available and an older unyanked version." + +[root] +requires = ["a"] + +[expected] +satisfiable = true +explanation = "The unyanked version should be selected." + +[expected.packages] +a = "0.1.0" + +[packages.a.versions."0.1.0"] + +[packages.a.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/transitive-package-only-yanked-in-range-opt-in.toml b/scenarios/yanked/transitive-package-only-yanked-in-range-opt-in.toml new file mode 100644 index 00000000..19d0fbbe --- /dev/null +++ b/scenarios/yanked/transitive-package-only-yanked-in-range-opt-in.toml @@ -0,0 +1,21 @@ +name = "transitive-package-only-yanked-in-range-opt-in" +description = "The user requires package `a` which has a dependency on a package which only matches yanked versions; the user has opted into allowing the yanked version of `b` explicitly." + +[root] +requires = ["a", "b==1.0.0"] + +[expected] +satisfiable = true +explanation = "Since the user included a dependency on `b` with an exact specifier, the yanked version can be selected." + +[expected.packages] +a = "0.1.0" +b = "1.0.0" + +[packages.a.versions."0.1.0"] +requires = ["b>0.1"] + +[packages.b.versions."0.1.0"] + +[packages.b.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/transitive-package-only-yanked-in-range.toml b/scenarios/yanked/transitive-package-only-yanked-in-range.toml new file mode 100644 index 00000000..14933ebf --- /dev/null +++ b/scenarios/yanked/transitive-package-only-yanked-in-range.toml @@ -0,0 +1,17 @@ +name = "transitive-package-only-yanked-in-range" +description = "The user requires package `a` which has a dependency on a package which only matches yanked versions." + +[root] +requires = ["a"] + +[expected] +satisfiable = false +explanation = "Yanked versions should not be installed, even if they are the only valid version in a range." + +[packages.a.versions."0.1.0"] +requires = ["b>0.1"] + +[packages.b.versions."0.1.0"] + +[packages.b.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/transitive-package-only-yanked.toml b/scenarios/yanked/transitive-package-only-yanked.toml new file mode 100644 index 00000000..f91564ed --- /dev/null +++ b/scenarios/yanked/transitive-package-only-yanked.toml @@ -0,0 +1,15 @@ +name = "transitive-package-only-yanked" +description = "The user requires any version of package `a` which requires `b` which only has yanked versions available." + +[root] +requires = ["a"] + +[expected] +satisfiable = false +explanation = "Yanked versions should not be installed, even if they are the only one available." + +[packages.a.versions."0.1.0"] +requires = ["b"] + +[packages.b.versions."1.0.0"] +yanked = true diff --git a/scenarios/yanked/transitive-yanked-and-unyanked-dependency-opt-in.toml b/scenarios/yanked/transitive-yanked-and-unyanked-dependency-opt-in.toml new file mode 100644 index 00000000..ed38f310 --- /dev/null +++ b/scenarios/yanked/transitive-yanked-and-unyanked-dependency-opt-in.toml @@ -0,0 +1,25 @@ +name = "transitive-yanked-and-unyanked-dependency-opt-in" +description = "A transitive dependency has both a yanked and an unyanked version, but can only be satisfied by a yanked. The user includes an opt-in to the yanked version of the transitive dependency." + +[root] +requires = ["a", "b", "c==2.0.0"] + +[expected] +satisfiable = true +explanation = "Since the user explicitly selected the yanked version of `c`, it can be installed." + +[expected.packages] +a = "1.0.0" +b = "1.0.0" +c = "2.0.0" + +[packages.a.versions."1.0.0"] +requires = ["c==2.0.0"] + +[packages.b.versions."1.0.0"] +requires = ["c>=1.0.0,<=3.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0"] +yanked = true diff --git a/scenarios/yanked/transitive-yanked-and-unyanked-dependency.toml b/scenarios/yanked/transitive-yanked-and-unyanked-dependency.toml new file mode 100644 index 00000000..9be759f6 --- /dev/null +++ b/scenarios/yanked/transitive-yanked-and-unyanked-dependency.toml @@ -0,0 +1,20 @@ +name = "transitive-yanked-and-unyanked-dependency" +description = "A transitive dependency has both a yanked and an unyanked version, but can only be satisfied by a yanked version" + +[root] +requires = ["a", "b"] + +[expected] +satisfiable = false +explanation = "Since the user did not explicitly select the yanked version, it cannot be used." + +[packages.a.versions."1.0.0"] +requires = ["c==2.0.0"] + +[packages.b.versions."1.0.0"] +requires = ["c>=1.0.0,<=3.0.0"] + +[packages.c.versions."1.0.0"] + +[packages.c.versions."2.0.0"] +yanked = true