diff --git a/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java b/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java index b8cfb0160a3d..698bb1debc96 100644 --- a/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java +++ b/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java @@ -65,10 +65,18 @@ public class PyRequirement { private static final String REVISION_REGEXP = "(@[^#\\s]+)?"; @NotNull - private static final String EGG_GROUP = "egg"; + private static final String EGG_BEFORE_SUBDIR_GROUP = "eggb"; @NotNull - private static final String EGG_REGEXP = "(#egg=(?<" + EGG_GROUP + ">\\S+))?"; + private static final String EGG_AFTER_SUBDIR_GROUP = "egga"; + + @NotNull + private static final String PARAMS_REGEXP = + "(" + + "(#egg=(?<" + EGG_BEFORE_SUBDIR_GROUP + ">[^&\\s]+)(&subdirectory=\\S+)?)" + + "|" + + "(#subdirectory=[^&\\s]+&egg=(?<" + EGG_AFTER_SUBDIR_GROUP + ">\\S+))" + + ")?"; @NotNull private static final String COMMENT_REGEXP = "(" + LINE_WS_REGEXP + "+#.*)?"; @@ -91,7 +99,7 @@ public class PyRequirement { private static final Pattern GIT_PROJECT_URL = Pattern.compile(SRC_BEFORE_REGEXP + EDITABLE_REGEXP + "git\\+" + USER_AT_REGEXP + "[^:\\s]+:" + - PATH_REGEXP + REVISION_REGEXP + EGG_REGEXP + + PATH_REGEXP + REVISION_REGEXP + PARAMS_REGEXP + SRC_AFTER_REGEXP + COMMENT_REGEXP); // supports: bzr+lp:... @@ -99,7 +107,7 @@ public class PyRequirement { private static final Pattern BZR_PROJECT_URL = Pattern.compile(SRC_BEFORE_REGEXP + EDITABLE_REGEXP + "bzr\\+lp:" + - PATH_REGEXP + REVISION_REGEXP + EGG_REGEXP + + PATH_REGEXP + REVISION_REGEXP + PARAMS_REGEXP + SRC_AFTER_REGEXP + COMMENT_REGEXP); // supports: (bzr|git|hg|svn)(+smth)?://... @@ -107,7 +115,7 @@ public class PyRequirement { private static final Pattern VCS_PROJECT_URL = Pattern.compile(SRC_BEFORE_REGEXP + EDITABLE_REGEXP + "(bzr|git|hg|svn)(\\+[A-Za-z]+)?://?[^/]+/" + - PATH_REGEXP + REVISION_REGEXP + EGG_REGEXP + + PATH_REGEXP + REVISION_REGEXP + PARAMS_REGEXP + SRC_AFTER_REGEXP + COMMENT_REGEXP); // PEP-508 + PEP-440 @@ -391,7 +399,7 @@ public class PyRequirement { @Nullable private static PyRequirement createVcsRequirement(@NotNull String line, @NotNull Matcher matcher) { final String path = matcher.group(PATH_GROUP); - final String egg = matcher.group(EGG_GROUP); + final String egg = getEgg(matcher); final String project = extractProject(dropTrunk(dropRevision(path))); final Pair nameAndVersion = @@ -420,10 +428,12 @@ public class PyRequirement { for (String line : StringUtil.splitByLines(text)) { if (line.endsWith("\\") && !line.endsWith("\\\\")) { sb.append(line.substring(0, line.length() - 1)); - } else { + } + else { if (sb.length() == 0) { result.add(line); - } else { + } + else { sb.append(line); result.add(sb.toString()); @@ -461,6 +471,13 @@ public class PyRequirement { return versionParts.isEmpty() ? null : normalizeVersion(StringUtil.join(versionParts, "-")); } + @Nullable + private static String getEgg(@NotNull Matcher matcher) { + final String beforeSubdir = matcher.group(EGG_BEFORE_SUBDIR_GROUP); + + return beforeSubdir == null ? matcher.group(EGG_AFTER_SUBDIR_GROUP) : beforeSubdir; + } + @NotNull private static String extractProject(@NotNull String path) { final int end = path.endsWith("/") ? path.length() - 1 : path.length(); diff --git a/python/testSrc/com/jetbrains/python/packaging/PyRequirementTest.java b/python/testSrc/com/jetbrains/python/packaging/PyRequirementTest.java index eae7c39ffdd0..e962d0870439 100644 --- a/python/testSrc/com/jetbrains/python/packaging/PyRequirementTest.java +++ b/python/testSrc/com/jetbrains/python/packaging/PyRequirementTest.java @@ -79,7 +79,6 @@ public class PyRequirementTest extends PyTestCase { } // VCS - // TODO: subdirectory // PY-6328 public void testGit() { doTest("git://git.myproject.org/MyProject#egg=MyProject1"); @@ -137,6 +136,117 @@ public class PyRequirementTest extends PyTestCase { doTest("git+user@git.myproject.org:/path/MyProject.git/#egg=MyProject1"); } + // PY-19544 + public void testGitWithSubdirectory() { + doTest("git://git.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/path/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git://git.myproject.org/path/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + + doTest("git+git://git.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/path/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+git://git.myproject.org/path/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + + doTest("git+https://git.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/path/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+https://git.myproject.org/path/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + + doTest("git+ssh://git.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/path/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://git.myproject.org/path/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + + doTest("git+ssh://user@git.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/path/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+ssh://user@git.myproject.org/path/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + + doTest("git+user@git.myproject.org:MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:/path/MyProject.git#egg=MyProject1&subdirectory=clients/python"); + doTest("git+user@git.myproject.org:/path/MyProject.git/#egg=MyProject1&subdirectory=clients/python"); + + doTest("git://git.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/path/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git://git.myproject.org/path/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + + doTest("git+git://git.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/path/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+git://git.myproject.org/path/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + + doTest("git+https://git.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/path/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+https://git.myproject.org/path/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + + doTest("git+ssh://git.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/path/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://git.myproject.org/path/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + + doTest("git+ssh://user@git.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/path/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+ssh://user@git.myproject.org/path/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + + doTest("git+user@git.myproject.org:MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:/path/MyProject.git#subdirectory=clients/python&egg=MyProject1"); + doTest("git+user@git.myproject.org:/path/MyProject.git/#subdirectory=clients/python&egg=MyProject1"); + } + public void testEditableGit() { doTest("-e git://git.myproject.org/MyProject#egg=MyProject1"); doTest("-e git://git.myproject.org/MyProject/#egg=MyProject1"); @@ -659,6 +769,49 @@ public class PyRequirementTest extends PyTestCase { doTest("hg+ssh://user@hg.myproject.org/path/MyProject/#egg=MyProject1"); } + // PY-19544 + public void testMercurialWithSubdirectory() { + doTest("hg+http://hg.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+http://hg.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+http://hg.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+http://hg.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("hg+https://hg.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+https://hg.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+https://hg.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+https://hg.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("hg+ssh://hg.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+ssh://hg.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+ssh://hg.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+ssh://hg.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("hg+ssh://user@hg.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+ssh://user@hg.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+ssh://user@hg.myproject.org/path/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("hg+ssh://user@hg.myproject.org/path/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("hg+http://hg.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+http://hg.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+http://hg.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+http://hg.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + + doTest("hg+https://hg.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+https://hg.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+https://hg.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+https://hg.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + + doTest("hg+ssh://hg.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+ssh://hg.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+ssh://hg.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+ssh://hg.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + + doTest("hg+ssh://user@hg.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+ssh://user@hg.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+ssh://user@hg.myproject.org/path/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("hg+ssh://user@hg.myproject.org/path/MyProject/#subdirectory=clients/python&egg=MyProject1"); + } + public void testEditableMercurial() { doTest("-e hg+http://hg.myproject.org/MyProject#egg=MyProject1"); doTest("-e hg+http://hg.myproject.org/MyProject/#egg=MyProject1"); @@ -883,6 +1036,69 @@ public class PyRequirementTest extends PyTestCase { doTest("svn+svn://user@svn.myproject.org/svn/MyProject/#egg=MyProject1"); } + // PY-19544 + public void testSubversionWithSubdirectory() { + doTest("svn+http://svn.myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+http://svn.myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+http://svn.myproject.org/svn/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+http://svn.myproject.org/svn/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("svn+https://svn.myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+https://svn.myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+https://svn.myproject.org/svn/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+https://svn.myproject.org/svn/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("svn+ssh://svn.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+ssh://svn.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+ssh://svn.myproject.org/svn/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+ssh://svn.myproject.org/svn/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("svn+ssh://user@svn.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+ssh://user@svn.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+ssh://user@svn.myproject.org/svn/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+ssh://user@svn.myproject.org/svn/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("svn+svn://svn.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+svn://svn.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+svn://svn.myproject.org/svn/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+svn://svn.myproject.org/svn/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("svn+svn://user@svn.myproject.org/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+svn://user@svn.myproject.org/MyProject/#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+svn://user@svn.myproject.org/svn/MyProject#egg=MyProject1&subdirectory=clients/python"); + doTest("svn+svn://user@svn.myproject.org/svn/MyProject/#egg=MyProject1&subdirectory=clients/python"); + + doTest("svn+http://svn.myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+http://svn.myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+http://svn.myproject.org/svn/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+http://svn.myproject.org/svn/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("svn+https://svn.myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+https://svn.myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+https://svn.myproject.org/svn/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+https://svn.myproject.org/svn/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("svn+ssh://svn.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+ssh://svn.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+ssh://svn.myproject.org/svn/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+ssh://svn.myproject.org/svn/MyProject/#subdirectory=clients/python&egg=MyProject1"); + + doTest("svn+ssh://user@svn.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+ssh://user@svn.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+ssh://user@svn.myproject.org/svn/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+ssh://user@svn.myproject.org/svn/MyProject/#subdirectory=clients/python&egg=MyProject1"); + + doTest("svn+svn://svn.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+svn://svn.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+svn://svn.myproject.org/svn/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+svn://svn.myproject.org/svn/MyProject/#subdirectory=clients/python&egg=MyProject1"); + + doTest("svn+svn://user@svn.myproject.org/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+svn://user@svn.myproject.org/MyProject/#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+svn://user@svn.myproject.org/svn/MyProject#subdirectory=clients/python&egg=MyProject1"); + doTest("svn+svn://user@svn.myproject.org/svn/MyProject/#subdirectory=clients/python&egg=MyProject1"); + } + public void testEditableSubversion() { doTest("-e svn+http://svn.myproject.org/MyProject/trunk#egg=MyProject1"); doTest("-e svn+http://svn.myproject.org/MyProject/trunk/#egg=MyProject1"); @@ -1209,6 +1425,93 @@ public class PyRequirementTest extends PyTestCase { doTest("bzr+lp:MyProject#egg=MyProject1"); } + // PY-19544 + public void testBazaarWithSubdirectory() { + doTest("bzr+http://bzr.myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+http://bzr.myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+http://bzr.myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+http://bzr.myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+https://bzr.myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+https://bzr.myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+https://bzr.myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+https://bzr.myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+sftp://myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+sftp://myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+sftp://myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+sftp://myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+sftp://user@myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+sftp://user@myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+sftp://user@myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+sftp://user@myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+ssh://myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ssh://myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ssh://myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ssh://myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+ssh://user@myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ssh://user@myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ssh://user@myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ssh://user@myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+ftp://myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ftp://myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ftp://myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ftp://myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+ftp://user@myproject.org/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ftp://user@myproject.org/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ftp://user@myproject.org/path/MyProject/trunk#egg=MyProject1&subdirectory=clients/python"); + doTest("bzr+ftp://user@myproject.org/path/MyProject/trunk/#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+lp:MyProject#egg=MyProject1&subdirectory=clients/python"); + + doTest("bzr+http://bzr.myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+http://bzr.myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+http://bzr.myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+http://bzr.myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+https://bzr.myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+https://bzr.myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+https://bzr.myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+https://bzr.myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+sftp://myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+sftp://myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+sftp://myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+sftp://myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+sftp://user@myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+sftp://user@myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+sftp://user@myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+sftp://user@myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+ssh://myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ssh://myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ssh://myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ssh://myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+ssh://user@myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ssh://user@myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ssh://user@myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ssh://user@myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+ftp://myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ftp://myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ftp://myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ftp://myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+ftp://user@myproject.org/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ftp://user@myproject.org/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ftp://user@myproject.org/path/MyProject/trunk#subdirectory=clients/python&egg=MyProject1"); + doTest("bzr+ftp://user@myproject.org/path/MyProject/trunk/#subdirectory=clients/python&egg=MyProject1"); + + doTest("bzr+lp:MyProject#subdirectory=clients/python&egg=MyProject1"); + } + public void testEditableBazaar() { doTest("-e bzr+http://bzr.myproject.org/MyProject/trunk#egg=MyProject1"); doTest("-e bzr+http://bzr.myproject.org/MyProject/trunk/#egg=MyProject1");