Store parsed requirement version in PyRequirementVersionSpec.

This commit is contained in:
Semyon Proshev
2017-05-15 22:22:22 +03:00
parent 410d10f007
commit cc2c8ad1e1
5 changed files with 234 additions and 129 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,10 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.packaging.requirement.PyRequirementRelation;
import com.jetbrains.python.packaging.requirement.PyRequirementVersion;
import com.jetbrains.python.packaging.requirement.PyRequirementVersionNormalizer;
import com.jetbrains.python.packaging.requirement.PyRequirementVersionSpec;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -271,7 +273,7 @@ public class PyRequirement {
if (o == this) return true;
if (o == null || getClass() != o.getClass()) return false;
PyRequirement that = (PyRequirement)o;
final PyRequirement that = (PyRequirement)o;
if (!myName.equals(that.myName)) return false;
if (!myVersionSpecs.equals(that.myVersionSpecs)) return false;
@@ -334,10 +336,12 @@ public class PyRequirement {
@NotNull
public static PyRequirementVersionSpec calculateVersionSpec(@NotNull String version, @NotNull PyRequirementRelation expectedRelation) {
final String normalizedVersion = PyRequirementVersionNormalizer.normalize(version);
if (expectedRelation == PyRequirementRelation.STR_EQ) return new PyRequirementVersionSpec(version);
final PyRequirementVersion normalizedVersion = PyRequirementVersionNormalizer.normalize(version);
return normalizedVersion == null ?
new PyRequirementVersionSpec(PyRequirementRelation.STR_EQ, version) :
new PyRequirementVersionSpec(version) :
new PyRequirementVersionSpec(expectedRelation, normalizedVersion);
}
@@ -412,14 +416,12 @@ public class PyRequirement {
visitedFiles.add(containingFile);
}
return splitByLinesAndCollapse(text)
.stream()
.map(line -> parseLine(line, containingFile, visitedFiles))
.flatMap(Collection::stream)
.filter(req -> req != null)
.collect(Collectors.toCollection(LinkedHashSet::new))
.stream()
.collect(Collectors.toList());
return StreamEx
.of(splitByLinesAndCollapse(text))
.flatCollection(line -> parseLine(line, containingFile, visitedFiles))
.nonNull()
.distinct()
.toList();
}
@NotNull
@@ -477,7 +479,7 @@ public class PyRequirement {
return new PyRequirement(name, Collections.singletonList(calculateVersionSpec(version, PyRequirementRelation.EQ)), installOptions);
}
@Nullable
@NotNull
private static PyRequirement createVcsRequirement(@NotNull Matcher matcher) {
final String path = matcher.group(PATH_IN_VCS_GROUP);
final String egg = getEgg(matcher);
@@ -675,13 +677,7 @@ public class PyRequirement {
if (relation != null) {
final int versionIndex = findFirstNotWhiteSpaceAfter(versionSpec, relation.toString().length());
final String version = versionSpec.substring(versionIndex);
if (relation == PyRequirementRelation.STR_EQ) {
return new PyRequirementVersionSpec(relation, version);
}
return calculateVersionSpec(version, relation);
return calculateVersionSpec(versionSpec.substring(versionIndex), relation);
}
return null;
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.packaging.requirement
data class PyRequirementVersion(val epoch: String? = null,
val release: String,
val pre: String? = null,
val post: String? = null,
val dev: String? = null,
val local: String? = null) {
companion object {
@JvmStatic
fun release(release: String): PyRequirementVersion = PyRequirementVersion(release = release)
}
val presentableText: String
get() =
sequenceOf(epochPresentable(), release, pre, postPresentable(), devPresentable(), localPresentable())
.filterNotNull()
.joinToString(separator = "") { it }
private fun epochPresentable() = if (epoch == null) null else "$epoch!"
private fun postPresentable() = if (post == null) null else ".$post"
private fun devPresentable() = if (dev == null) null else ".$dev"
private fun localPresentable() = if (local == null) null else "+$local"
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.jetbrains.python.packaging.requirement;
import com.intellij.openapi.util.text.StringUtil;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -103,71 +104,88 @@ public final class PyRequirementVersionNormalizer {
Pattern.CASE_INSENSITIVE);
@Nullable
public static String normalize(@NotNull String version) {
public static PyRequirementVersion normalize(@NotNull String version) {
final Matcher matcher = VERSION.matcher(version);
if (matcher.matches()) {
final StringBuilder sb = new StringBuilder();
return new PyRequirementVersion(
normalizeEpoch(matcher),
normalizeRelease(matcher),
normalizePre(matcher),
normalizePost(matcher),
normalizeDev(matcher),
normalizeLocal(matcher)
);
}
final String epoch = matcher.group(EPOCH_GROUP);
if (epoch != null) {
final String normalizedEpoch = normalizeNumber(epoch.substring(0, epoch.length() - 1));
sb
.append(normalizedEpoch)
.append('!');
}
return null;
}
for (String releasePart : StringUtil.tokenize(matcher.group(RELEASE_GROUP), ".")) {
sb
.append(releasePart.equals("*") ? "*" : normalizeNumber(releasePart))
.append('.');
}
@Nullable
private static String normalizeEpoch(@NotNull Matcher matcher) {
final String epoch = matcher.group(EPOCH_GROUP);
if (epoch != null) {
return normalizeNumber(epoch.substring(0, epoch.length() - 1));
}
if (sb.charAt(sb.length() - 1) == '.') {
sb.setLength(sb.length() - 1);
}
return null;
}
final String preReleaseType = matcher.group(PRE_RELEASE_TYPE_GROUP);
if (preReleaseType != null) {
final String preReleaseNumber = matcher.group(PRE_RELEASE_NUMBER_GROUP);
final String normalizedPreReleaseNumber = preReleaseNumber == null ? "0" : normalizeNumber(preReleaseNumber);
@NotNull
private static String normalizeRelease(@NotNull Matcher matcher) {
return StreamEx
.of(StringUtil.tokenize(matcher.group(RELEASE_GROUP), ".").iterator())
.map(releasePart -> releasePart.equals("*") ? "*" : normalizeNumber(releasePart))
.joining(".");
}
sb
.append(normalizePreReleaseType(preReleaseType))
.append(normalizedPreReleaseNumber);
}
@Nullable
private static String normalizePre(@NotNull Matcher matcher) {
final String preReleaseType = matcher.group(PRE_RELEASE_TYPE_GROUP);
if (preReleaseType != null) {
final String preReleaseNumber = matcher.group(PRE_RELEASE_NUMBER_GROUP);
final String normalizedPreReleaseNumber = preReleaseNumber == null ? "0" : normalizeNumber(preReleaseNumber);
final String postReleaseType = matcher.group(POST_RELEASE_TYPE_GROUP);
if (postReleaseType != null) {
final String postReleaseNumber = matcher.group(POST_RELEASE_NUMBER_GROUP);
final String normalizedPostReleaseNumber = postReleaseNumber == null ? "0" : normalizeNumber(postReleaseNumber);
return normalizePreReleaseType(preReleaseType) + normalizedPreReleaseNumber;
}
sb
.append(".post")
.append(normalizeNumber(normalizedPostReleaseNumber));
}
return null;
}
final String implicitPostReleaseNumber = matcher.group(IMPLICIT_POST_RELEASE_NUMBER_GROUP);
if (implicitPostReleaseNumber != null) {
sb
.append(".post")
.append(normalizeNumber(implicitPostReleaseNumber));
}
@Nullable
private static String normalizePost(@NotNull Matcher matcher) {
final String postReleaseType = matcher.group(POST_RELEASE_TYPE_GROUP);
if (postReleaseType != null) {
final String postReleaseNumber = matcher.group(POST_RELEASE_NUMBER_GROUP);
final String normalizedPostReleaseNumber = postReleaseNumber == null ? "0" : normalizeNumber(postReleaseNumber);
if (matcher.group(DEV_RELEASE_TYPE_GROUP) != null) {
final String devReleaseNumber = matcher.group(DEV_RELEASE_NUMBER_GROUP);
final String normalizedDevReleaseNumber = devReleaseNumber == null ? "0" : normalizeNumber(devReleaseNumber);
return "post" + normalizeNumber(normalizedPostReleaseNumber);
}
sb
.append(".dev")
.append(normalizedDevReleaseNumber);
}
final String implicitPostReleaseNumber = matcher.group(IMPLICIT_POST_RELEASE_NUMBER_GROUP);
if (implicitPostReleaseNumber != null) {
return "post" + normalizeNumber(implicitPostReleaseNumber);
}
final String localVersion = matcher.group(LOCAL_VERSION_GROUP);
if (localVersion != null) {
sb.append(normalizeLocalVersion(localVersion));
}
return null;
}
return sb.toString();
@Nullable
private static String normalizeDev(@NotNull Matcher matcher) {
if (matcher.group(DEV_RELEASE_TYPE_GROUP) != null) {
final String devReleaseNumber = matcher.group(DEV_RELEASE_NUMBER_GROUP);
final String normalizedDevReleaseNumber = devReleaseNumber == null ? "0" : normalizeNumber(devReleaseNumber);
return "dev" + normalizedDevReleaseNumber;
}
return null;
}
@Nullable
private static String normalizeLocal(@NotNull Matcher matcher) {
final String localVersion = matcher.group(LOCAL_VERSION_GROUP);
if (localVersion != null) {
return localVersion.substring(1).replaceAll("[-_]", ".");
}
return null;
@@ -190,9 +208,4 @@ public final class PyRequirementVersionNormalizer {
return "rc";
}
}
@NotNull
private static String normalizeLocalVersion(@NotNull String localVersion) {
return localVersion.replaceAll("[-_]", ".");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,11 @@
package com.jetbrains.python.packaging.requirement;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import static com.intellij.webcore.packaging.PackageVersionComparator.VERSION_COMPARATOR;
@@ -25,11 +29,21 @@ public class PyRequirementVersionSpec {
@NotNull
private final PyRequirementRelation myRelation;
@Nullable
private final PyRequirementVersion myParsedVersion;
@NotNull
private final String myVersion;
public PyRequirementVersionSpec(@NotNull PyRequirementRelation relation, @NotNull String version) {
public PyRequirementVersionSpec(@NotNull PyRequirementRelation relation, @NotNull PyRequirementVersion version) {
myRelation = relation;
myParsedVersion = version;
myVersion = myParsedVersion.getPresentableText();
}
public PyRequirementVersionSpec(@NotNull String version) {
myRelation = PyRequirementRelation.STR_EQ;
myParsedVersion = null;
myVersion = version;
}
@@ -73,7 +87,9 @@ public class PyRequirementVersionSpec {
case GTE:
return VERSION_COMPARATOR.compare(version, myVersion) >= 0;
case EQ:
final Pair<String, String> publicAndLocalVersions = splitIntoPublicAndLocalVersions(myVersion);
Objects.requireNonNull(myParsedVersion);
final Pair<String, String> publicAndLocalVersions = splitIntoPublicAndLocalVersions(myParsedVersion);
final Pair<String, String> otherPublicAndLocalVersions = splitIntoPublicAndLocalVersions(version);
final boolean publicVersionsAreSame =
VERSION_COMPARATOR.compare(otherPublicAndLocalVersions.first, publicAndLocalVersions.first) == 0;
@@ -91,6 +107,15 @@ public class PyRequirementVersionSpec {
}
}
@NotNull
private static Pair<String, String> splitIntoPublicAndLocalVersions(@NotNull PyRequirementVersion version) {
final PyRequirementVersion withoutLocal =
new PyRequirementVersion(version.getEpoch(), version.getRelease(), version.getPre(), version.getPost(), version.getDev(), null);
return Pair.createNonNull(withoutLocal.getPresentableText(), StringUtil.notNullize(version.getLocal()));
}
@NotNull
private static Pair<String, String> splitIntoPublicAndLocalVersions(@NotNull String version) {
final String[] publicAndLocalVersions = version.split("\\+", 2);
@@ -21,6 +21,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.packaging.requirement.PyRequirementRelation;
import com.jetbrains.python.packaging.requirement.PyRequirementVersion;
import com.jetbrains.python.packaging.requirement.PyRequirementVersionSpec;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -2093,34 +2094,47 @@ public class PyRequirementTest extends PyTestCase {
final String name = "django_compressor";
final String version = "dev";
final String line = name + "==" + version;
final List<PyRequirementVersionSpec> versionSpecs = Collections.singletonList(new PyRequirementVersionSpec(PyRequirementRelation.STR_EQ,
version));
final List<PyRequirementVersionSpec> versionSpecs = Collections.singletonList(new PyRequirementVersionSpec(version));
assertEquals(new PyRequirement(name, versionSpecs, Collections.singletonList(line)), PyRequirement.fromLine(line));
}
// https://www.python.org/dev/peps/pep-0440/#version-specifiers
public void testRequirementRelation() {
doRequirementRelationTest(PyRequirementRelation.LT, "1.4");
doRequirementRelationTest(PyRequirementRelation.LTE, "1.4");
doRequirementRelationTest(PyRequirementRelation.NE, "1.4");
doRequirementRelationTest(PyRequirementRelation.EQ, "1.4");
doRequirementRelationTest(PyRequirementRelation.GT, "1.4");
doRequirementRelationTest(PyRequirementRelation.GTE, "1.4");
doRequirementRelationTest(PyRequirementRelation.COMPATIBLE, "1.*");
doRequirementRelationTest(PyRequirementRelation.STR_EQ, "version");
doRequirementRelationTest(PyRequirementRelation.LT, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(PyRequirementRelation.LTE, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(PyRequirementRelation.NE, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(PyRequirementRelation.EQ, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(PyRequirementRelation.GT, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(PyRequirementRelation.GTE, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(PyRequirementRelation.COMPATIBLE, PyRequirementVersion.release("1.*"));
doRequirementRelationTest(PyRequirementRelation.STR_EQ, PyRequirementVersion.release("version"));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.EQ), Arrays.asList("2.8.1", "2.8.*"));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GTE), Arrays.asList("1.4", "1.3.1"));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.EQ),
Arrays.asList(PyRequirementVersion.release("2.8.1"), PyRequirementVersion.release("2.8.*")));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GTE),
Arrays.asList(PyRequirementVersion.release("1.4"), PyRequirementVersion.release("1.3.1")));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GT, PyRequirementRelation.NE,
PyRequirementRelation.LT, PyRequirementRelation.EQ),
Arrays.asList("1.6", "1.9", "1.9.6", "2.0a0", "2.4rc1"));
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.LT,
PyRequirementRelation.GT,
PyRequirementRelation.NE,
PyRequirementRelation.LT,
PyRequirementRelation.EQ),
Arrays.asList(PyRequirementVersion.release("1.6"),
PyRequirementVersion.release("1.9"),
PyRequirementVersion.release("1.9.6"),
new PyRequirementVersion(null, "2.0", "a0", null, null, null),
new PyRequirementVersion(null, "2.4", "rc1", null, null, null)));
// PY-14583
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.LTE, PyRequirementRelation.GTE,
doRequirementRelationTest(Arrays.asList(PyRequirementRelation.GTE,
PyRequirementRelation.LTE,
PyRequirementRelation.GTE,
PyRequirementRelation.LTE),
Arrays.asList("0.8.4", "0.8.99", "0.9.7", "0.9.99"));
Arrays.asList(PyRequirementVersion.release("0.8.4"),
PyRequirementVersion.release("0.8.99"),
PyRequirementVersion.release("0.9.7"),
PyRequirementVersion.release("0.9.99")));
}
// https://www.python.org/dev/peps/pep-0508/#extras
@@ -2128,7 +2142,7 @@ public class PyRequirementTest extends PyTestCase {
public void testRequirementExtras() {
final String name = "MyProject1";
final List<PyRequirementRelation> relations = Collections.emptyList();
final List<String> versions = Collections.emptyList();
final List<PyRequirementVersion> versions = Collections.emptyList();
doRequirementRelationTest(name, "[PDF]", relations, versions);
doRequirementRelationTest(name, " [extra1, extra2]", relations, versions);
@@ -2147,29 +2161,49 @@ public class PyRequirementTest extends PyTestCase {
final String extras3 = " [security,tests]";
final String name3 = "requests";
doRequirementRelationTest(name1, extras1, PyRequirementRelation.LT, "1.4");
doRequirementRelationTest(name2, extras2, PyRequirementRelation.LTE, "1.4");
doRequirementRelationTest(name3, extras3, PyRequirementRelation.NE, "1.4");
doRequirementRelationTest(name1, extras1, PyRequirementRelation.EQ, "1.4");
doRequirementRelationTest(name2, extras2, PyRequirementRelation.GT, "1.4");
doRequirementRelationTest(name3, extras3, PyRequirementRelation.GTE, "1.4");
doRequirementRelationTest(name1, extras1, PyRequirementRelation.COMPATIBLE, "1.*");
doRequirementRelationTest(name2, extras2, PyRequirementRelation.STR_EQ, "version");
doRequirementRelationTest(name1, extras1, PyRequirementRelation.LT, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(name2, extras2, PyRequirementRelation.LTE, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(name3, extras3, PyRequirementRelation.NE, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(name1, extras1, PyRequirementRelation.EQ, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(name2, extras2, PyRequirementRelation.GT, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(name3, extras3, PyRequirementRelation.GTE, PyRequirementVersion.release("1.4"));
doRequirementRelationTest(name1, extras1, PyRequirementRelation.COMPATIBLE, PyRequirementVersion.release("1.*"));
doRequirementRelationTest(name2, extras2, PyRequirementRelation.STR_EQ, PyRequirementVersion.release("version"));
doRequirementRelationTest(name3, extras3, Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.EQ),
Arrays.asList("2.8.1", "2.8.*"));
doRequirementRelationTest(name3,
extras3,
Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.EQ),
Arrays.asList(PyRequirementVersion.release("2.8.1"), PyRequirementVersion.release("2.8.*")));
doRequirementRelationTest(name1, extras1, Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GTE),
Arrays.asList("1.4", "1.3.1"));
doRequirementRelationTest(name1,
extras1,
Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GTE),
Arrays.asList(PyRequirementVersion.release("1.4"), PyRequirementVersion.release("1.3.1")));
doRequirementRelationTest(name2, extras2, Arrays.asList(PyRequirementRelation.LT, PyRequirementRelation.GT, PyRequirementRelation.NE,
PyRequirementRelation.LT, PyRequirementRelation.EQ),
Arrays.asList("1.6", "1.9", "1.9.6", "2.0a0", "2.4rc1"));
doRequirementRelationTest(name2,
extras2,
Arrays.asList(PyRequirementRelation.LT,
PyRequirementRelation.GT,
PyRequirementRelation.NE,
PyRequirementRelation.LT,
PyRequirementRelation.EQ),
Arrays.asList(PyRequirementVersion.release("1.6"),
PyRequirementVersion.release("1.9"),
PyRequirementVersion.release("1.9.6"),
new PyRequirementVersion(null, "2.0", "a0", null, null, null),
new PyRequirementVersion(null, "2.4", "rc1", null, null, null)));
// PY-14583
doRequirementRelationTest(name3, extras3, Arrays.asList(PyRequirementRelation.GTE, PyRequirementRelation.LTE, PyRequirementRelation.GTE,
PyRequirementRelation.LTE),
Arrays.asList("0.8.4", "0.8.99", "0.9.7", "0.9.99"));
doRequirementRelationTest(name3,
extras3,
Arrays.asList(PyRequirementRelation.GTE,
PyRequirementRelation.LTE,
PyRequirementRelation.GTE,
PyRequirementRelation.LTE),
Arrays.asList(PyRequirementVersion.release("0.8.4"),
PyRequirementVersion.release("0.8.99"),
PyRequirementVersion.release("0.9.7"),
PyRequirementVersion.release("0.9.99")));
}
// https://pip.pypa.io/en/stable/reference/pip_install/#per-requirement-overrides
@@ -2179,7 +2213,7 @@ public class PyRequirementTest extends PyTestCase {
final String linePrefix = name + " >= " + version;
final List<PyRequirementVersionSpec> versionSpecs =
Collections.singletonList(new PyRequirementVersionSpec(PyRequirementRelation.GTE, version));
Collections.singletonList(new PyRequirementVersionSpec(PyRequirementRelation.GTE, PyRequirementVersion.release(version)));
final List<String> installOptions1 = Arrays.asList(linePrefix,
"--global-option", "--no-user-cfg",
@@ -2202,7 +2236,7 @@ public class PyRequirementTest extends PyTestCase {
final String textPrefix = name + " >= " + version;
final List<PyRequirementVersionSpec> versionSpecs =
Collections.singletonList(new PyRequirementVersionSpec(PyRequirementRelation.GTE, version));
Collections.singletonList(new PyRequirementVersionSpec(PyRequirementRelation.GTE, PyRequirementVersion.release(version)));
final String text = textPrefix + " " +
"--global-option=\"--no-user-cfg\" \\\n" +
@@ -2383,44 +2417,41 @@ public class PyRequirementTest extends PyTestCase {
doTest(name, version, line.substring(0, line.lastIndexOf('#') - 1));
}
private static void doRequirementRelationTest(@NotNull PyRequirementRelation relation, @NotNull String version) {
private static void doRequirementRelationTest(@NotNull PyRequirementRelation relation, @NotNull PyRequirementVersion version) {
doRequirementRelationTest("Django", null, Collections.singletonList(relation), Collections.singletonList(version));
}
private static void doRequirementRelationTest(@NotNull List<PyRequirementRelation> relations, @NotNull List<String> versions) {
private static void doRequirementRelationTest(@NotNull List<PyRequirementRelation> relations,
@NotNull List<PyRequirementVersion> versions) {
doRequirementRelationTest("Django", null, relations, versions);
}
private static void doRequirementRelationTest(@NotNull String name,
@Nullable String extras,
@NotNull PyRequirementRelation relation,
@NotNull String version) {
@NotNull PyRequirementVersion version) {
doRequirementRelationTest(name, extras, Collections.singletonList(relation), Collections.singletonList(version));
}
private static void doRequirementRelationTest(@NotNull String name,
@Nullable String extras,
@NotNull List<PyRequirementRelation> relations,
@NotNull List<String> versions) {
@NotNull List<PyRequirementVersion> versions) {
assertEquals(versions.size(), relations.size());
final StringBuilder sb = new StringBuilder(name);
final List<PyRequirementVersionSpec> expectedVersionSpecs = new ArrayList<>();
if (extras != null) sb.append(extras);
final int initialLength = sb.length();
for (Pair<PyRequirementRelation, String> pair : ContainerUtil.zip(relations, versions)) {
for (Pair<PyRequirementRelation, PyRequirementVersion> pair : ContainerUtil.zip(relations, versions)) {
final PyRequirementRelation relation = pair.getFirst();
final String version = pair.getSecond();
final PyRequirementVersion version = pair.getSecond();
sb.append(relation).append(version).append(",");
expectedVersionSpecs.add(new PyRequirementVersionSpec(relation, version));
}
if (sb.length() != initialLength) {
sb.setLength(sb.length() - 1);
}
sb.append(StringUtil.join(expectedVersionSpecs, ","));
final String options = sb.toString();