|
2 | 2 |
|
3 | 3 | # URL Parser - `libvcs.url`
|
4 | 4 |
|
5 |
| -VCS URL parser for python. |
| 5 | +We all love {mod}`urllib.parse`, but what about VCS systems? |
6 | 6 |
|
7 |
| -## Parsing capabilities |
| 7 | +Also, things like completions and typings being in demand, what of all these factories? Good python |
| 8 | +code, but how to we get editor support and the nice satisfaction of types snapping together? |
8 | 9 |
|
9 |
| -:::{warning} |
| 10 | +If there was a type-friendly structure - like writing our own abstract base class - or a |
| 11 | +{mod}`dataclasses` - while also being extensible to patterns and groupings, maybe we could strike a |
| 12 | +perfect balance. |
10 | 13 |
|
11 |
| -The APIs and structures themselves are still unstable APIs. If you are missing a field or use case, |
12 |
| -please file an issue. |
| 14 | +If we could make it ready-to-go out of the box, but also have framework-like extensibility, it could |
| 15 | +satisfy the niche. |
13 | 16 |
|
14 |
| -::: |
| 17 | +## Validate and detect VCS URLs |
15 | 18 |
|
16 |
| -1. Detect VCS URLs |
| 19 | +````{tab} git |
17 | 20 |
|
18 |
| - - git: {meth}`libvcs.url.git.GitURL.is_valid()` |
19 |
| - - hg: {meth}`libvcs.url.hg.HgURL.is_valid()` |
20 |
| - - svn: {meth}`libvcs.url.svn.SvnURL.is_valid()` |
| 21 | +{meth}`libvcs.url.git.GitURL.is_valid()` |
21 | 22 |
|
22 |
| -- Parse results of URL to a structure |
| 23 | +```python |
| 24 | +from libvcs.url.git import GitURL |
23 | 25 |
|
24 |
| - _Compare to {class}`urllib.parse.ParseResult`_ |
| 26 | +>>> GitURL.is_valid(url='https://github.com/vcs-python/libvcs.git') |
| 27 | +True |
| 28 | +``` |
| 29 | +
|
| 30 | +```python |
| 31 | +from libvcs.url.git import GitURL |
| 32 | +
|
| 33 | +>>> GitURL.is_valid(url='git@github.com:vcs-python/libvcs.git') |
| 34 | +True |
| 35 | +``` |
| 36 | +
|
| 37 | +```` |
| 38 | + |
| 39 | +````{tab} hg |
| 40 | +{meth}`libvcs.url.hg.HgURL.is_valid()` |
| 41 | +
|
| 42 | +```python |
| 43 | +>>> HgURL.is_valid(url='https://hg.mozilla.org/mozilla-central/mozilla-central') |
| 44 | +True |
| 45 | +``` |
| 46 | +
|
| 47 | +```python |
| 48 | +>>> HgURL.is_valid(url='hg@hg.mozilla.org:MyProject/project') |
| 49 | +True |
| 50 | +``` |
| 51 | +
|
| 52 | +```` |
| 53 | + |
| 54 | +````{tab} svn |
| 55 | +
|
| 56 | +{meth}`libvcs.url.svn.SvnURL.is_valid()` |
| 57 | +
|
| 58 | +
|
| 59 | +```python |
| 60 | +>>> SvnURL.is_valid( |
| 61 | +... url='https://svn.project.org/project-central/project-central') |
| 62 | +True |
| 63 | +``` |
| 64 | +
|
| 65 | +```python |
| 66 | +>>> SvnURL.is_valid(url='svn@svn.project.org:MyProject/project') |
| 67 | +True |
| 68 | +``` |
| 69 | +
|
| 70 | +```` |
| 71 | + |
| 72 | +## Parse VCS URLs |
25 | 73 |
|
26 |
| - - {class}`libvcs.url.git.GitURL` |
27 |
| - - {class}`libvcs.url.hg.HgURL` |
28 |
| - - {class}`libvcs.url.svn.SvnURL` |
| 74 | +_Compare to {class}`urllib.parse.ParseResult`_ |
29 | 75 |
|
30 |
| -3. Convert input VCS to _usable_ URLs |
| 76 | +````{tab} git |
31 | 77 |
|
32 |
| - - git: {meth}`libvcs.url.git.GitURL.to_url()` |
33 |
| - - hg: {meth}`libvcs.url.hg.HgURL.to_url()` |
34 |
| - - svn: {meth}`libvcs.url.svn.SvnURL.to_url()` |
| 78 | +{class}`libvcs.url.git.GitURL` |
35 | 79 |
|
36 |
| - `pip` knows what a certain URL string means, but `git clone` won't. |
| 80 | +```python |
| 81 | +>>> GitBaseURL(url='git@github.com:vcs-python/libvcs.git') |
| 82 | +GitBaseURL(url=git@github.com:vcs-python/libvcs.git, |
| 83 | + user=git, |
| 84 | + hostname=github.com, |
| 85 | + path=vcs-python/libvcs, |
| 86 | + suffix=.git, |
| 87 | + rule=core-git-scp) |
| 88 | +``` |
| 89 | +
|
| 90 | +```` |
| 91 | + |
| 92 | +````{tab} hg |
| 93 | +
|
| 94 | +{class}`libvcs.url.hg.HgURL` |
| 95 | +
|
| 96 | +```python |
| 97 | +>>> HgBaseURL( |
| 98 | +... url="http://hugin.hg.sourceforge.net:8000/hgroot/hugin/hugin") |
| 99 | +HgBaseURL(url=http://hugin.hg.sourceforge.net:8000/hgroot/hugin/hugin, |
| 100 | + scheme=http, |
| 101 | + hostname=hugin.hg.sourceforge.net, |
| 102 | + port=8000, |
| 103 | + path=hgroot/hugin/hugin, |
| 104 | + rule=core-hg) |
| 105 | +``` |
| 106 | +
|
| 107 | +```` |
| 108 | + |
| 109 | +````{tab} svn |
| 110 | +
|
| 111 | +{class}`libvcs.url.svn.SvnURL` |
| 112 | +
|
| 113 | +```python |
| 114 | +>>> SvnURL( |
| 115 | +... url='svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository') |
| 116 | +SvnURL(url=svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository, |
| 117 | + scheme=svn+ssh, |
| 118 | + hostname=svn.debian.org, |
| 119 | + path=svn/aliothproj/path/in/project/repository, |
| 120 | + rule=core-svn) |
| 121 | +``` |
| 122 | +
|
| 123 | +```` |
| 124 | + |
| 125 | +## Export usable URLs |
| 126 | + |
| 127 | +- git: {meth}`libvcs.url.git.GitURL.to_url()` |
| 128 | +- hg: {meth}`libvcs.url.hg.HgURL.to_url()` |
| 129 | +- svn: {meth}`libvcs.url.svn.SvnURL.to_url()` |
| 130 | + |
| 131 | +`pip` knows what a certain URL string means, but `git clone` won't. |
37 | 132 |
|
38 |
| - e.g. `pip install git+https://github.com/django/django.git@3.2` works great with `pip`. |
| 133 | +e.g. `pip install git+https://github.com/django/django.git@3.2` works great with `pip`. |
39 | 134 |
|
40 |
| - ```console |
41 |
| - $ pip install git+https://github.com/django/django.git@3.2 |
42 |
| - ... |
43 |
| - Successfully installed Django-3.2 |
| 135 | +```console |
| 136 | +$ pip install git+https://github.com/django/django.git@3.2 |
| 137 | +... |
| 138 | +Successfully installed Django-3.2 |
44 | 139 |
|
45 |
| - ``` |
| 140 | +``` |
46 | 141 |
|
47 |
| - but `git clone` can't use that: |
| 142 | +but `git clone` can't use that: |
48 | 143 |
|
49 |
| - ```console |
50 |
| - $ git clone git+https://github.com/django/django.git@3.2 # Fail |
51 |
| - ... |
52 |
| - Cloning into django.git@3.2''...' |
53 |
| - git: 'remote-git+https' is not a git command. See 'git --help'. |
54 |
| - ``` |
| 144 | +```console |
| 145 | +$ git clone git+https://github.com/django/django.git@3.2 # Fail |
| 146 | +... |
| 147 | +Cloning into django.git@3.2''...' |
| 148 | +git: 'remote-git+https' is not a git command. See 'git --help'. |
| 149 | +``` |
55 | 150 |
|
56 |
| - It needs something like this: |
| 151 | +It needs something like this: |
57 | 152 |
|
58 |
| - ```console |
59 |
| - $ git clone https://github.com/django/django.git --branch 3.2 |
60 |
| - ``` |
| 153 | +```console |
| 154 | +$ git clone https://github.com/django/django.git --branch 3.2 |
| 155 | +``` |
61 | 156 |
|
62 |
| - But before we get there, we don't know if we want a URL yet. We return a structure, e.g. |
63 |
| - `GitURL`. |
| 157 | +But before we get there, we don't know if we want a URL yet. We return a structure, e.g. `GitURL`. |
64 | 158 |
|
65 | 159 | - Common result primitives across VCS, e.g. `GitURL`.
|
66 | 160 |
|
@@ -101,7 +195,7 @@ The ambition for this is to build extendable parsers for package-like URLs, e.g.
|
101 | 195 |
|
102 | 196 | https://docs.npmjs.com/about-packages-and-modules#npm-package-git-url-formats
|
103 | 197 |
|
104 |
| -### Extendability |
| 198 | +## Extendability |
105 | 199 |
|
106 | 200 | Patterns can be registered. [Similar behavior](https://stackoverflow.com/a/6264214/1396928) exists
|
107 | 201 | in {mod}`urlparse` (undocumented).
|
@@ -140,11 +234,14 @@ From there, `GitURL` can be used downstream directly by other projects.
|
140 | 234 | In our case, `libvcs`s' own {ref}`cmd` and {ref}`projects`, as well as a {ref}`vcspull:index`
|
141 | 235 | configuration, will be able to detect and accept various URL patterns.
|
142 | 236 |
|
143 |
| -## Location objects |
| 237 | +### Matchers: Defaults |
| 238 | + |
| 239 | +When a match occurs, its `defaults` will fill in non-matched groups. |
| 240 | + |
| 241 | +### Matchers: First wins |
144 | 242 |
|
145 |
| -Compare to {class}`urllib.parse.ParseResult`. These are structures that break the VCS location into |
146 |
| -parse so they can be filled, replaced [^api-unstable], and exported into a URL specifier compatible |
147 |
| -with the VCS. |
| 243 | +When registering new matchers, higher `weight`s are checked first. If it's a valid regex grouping, |
| 244 | +it will be picked. |
148 | 245 |
|
149 | 246 | [^api-unstable]: Provisional API only
|
150 | 247 |
|
|
0 commit comments