|
1 |
| -# git-url-parse |
2 |
| - |
3 | 1 | [](https://crates.io/crates/git-url-parse)
|
4 |
| - |
| 2 | +[](https://crates.io/crates/git-url-parse) |
| 3 | + |
5 | 4 | [](https://github.com/tjtelan/git-url-parse-rs/actions/workflows/ci.yml)
|
6 | 5 | [](https://docs.rs/git-url-parse/)
|
7 | 6 | [](LICENSE)
|
8 | 7 | 
|
9 | 8 |
|
10 |
| -Supports common protocols as specified by the [Pro Git book](https://git-scm.com/book/en/v2) |
| 9 | +--- |
11 | 10 |
|
12 |
| -See: [4.1 Git on the Server - The Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) |
| 11 | +<!-- cargo-rdme start --> |
13 | 12 |
|
14 |
| -Supports parsing SSH/HTTPS repo urls for: |
15 |
| -* Github |
16 |
| -* Bitbucket |
17 |
| -* Azure Devops |
| 13 | +# Git Url Parse |
18 | 14 |
|
19 |
| -See [tests/parse.rs](tests/parse.rs) for expected output for a variety of inputs. |
| 15 | +Parses url used by git (e.g. `git clone <url>`) |
20 | 16 |
|
21 |
| ---- |
| 17 | +## Features |
| 18 | + |
| 19 | +- 🔍 Parses `git clone` compatible urls into [`GitUrl`](https://docs.rs/git-url-parse/latest/git_url_parse/types/struct.GitUrl.html) |
| 20 | + - Supports multiple Git URL schemes (SSH, HTTP, HTTPS, File) |
| 21 | + - Inspired by [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) with adaptations to support Git urls |
| 22 | + |
| 23 | +- 🏗️ Host provider info extraction |
| 24 | + - Easy to implement trait [`GitProvider`](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/trait.GitProvider.html) for custom provider parsing |
| 25 | + - Built-in support for multiple Git hosting providers |
| 26 | + * [Generic](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.GenericProvider.html) (`git@host:owner/repo.git` style urls) |
| 27 | + * [GitLab](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.GitLabProvider.html) |
| 28 | + * [Azure DevOps](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.AzureDevOpsProvider.html) |
| 29 | + |
| 30 | +## Quick Example |
| 31 | + |
| 32 | +```rust |
| 33 | +use git_url_parse::{GitUrl, GitUrlParseError}; |
| 34 | +use git_url_parse::types::provider::GitProvider; |
| 35 | +use git_url_parse::types::provider::GenericProvider; |
| 36 | + |
| 37 | +fn main() -> Result<(), git_url_parse::GitUrlParseError> { |
| 38 | + let http_url = GitUrl::parse("https://github.com/tjtelan/git-url-parse-rs.git")?; |
| 39 | + |
| 40 | + // Extract basic URL components |
| 41 | + assert_eq!(http_url.host(), Some("github.com")); |
| 42 | + assert_eq!(http_url.path(), "/tjtelan/git-url-parse-rs.git"); |
| 43 | + |
| 44 | + // Support ssh-based urls as well |
| 45 | + let ssh_url = GitUrl::parse( "[email protected]:tjtelan/git-url-parse-rs.git") ?; |
| 46 | + |
| 47 | + assert_eq!(ssh_url.scheme(), Some("ssh")); |
| 48 | + assert_eq!(ssh_url.host(), Some("github.com")); |
| 49 | + assert_eq!(ssh_url.path(), "tjtelan/git-url-parse-rs.git"); |
| 50 | + |
| 51 | + // Extract provider-specific information |
| 52 | + // Built-in support for Github (Generic), Gitlab, Azure Devops style urls |
| 53 | + let provider : GenericProvider = ssh_url.provider_info()?; |
| 54 | + assert_eq!(provider.owner(), "tjtelan"); |
| 55 | + assert_eq!(provider.repo(), "git-url-parse-rs"); |
| 56 | + |
| 57 | + // Implement your own provider |
| 58 | + #[derive(Debug, Clone, PartialEq, Eq)] |
| 59 | + struct CustomProvider; |
| 60 | + |
| 61 | + impl GitProvider<GitUrl<'_>, GitUrlParseError> for CustomProvider { |
| 62 | + fn from_git_url(_url: &GitUrl) -> Result<Self, GitUrlParseError> { |
| 63 | + // Your custom provider parsing here |
| 64 | + Ok(Self) |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + let custom_provider: CustomProvider = ssh_url.provider_info()?; |
| 69 | + let expected = CustomProvider; |
| 70 | + assert_eq!(custom_provider, expected); |
| 71 | + |
| 72 | + Ok(()) |
| 73 | +} |
| 74 | +``` |
22 | 75 |
|
23 |
| -URLs that use the `ssh://` protocol (implicitly or explicitly) undergo a small normalization process in order to be parsed. |
| 76 | +## Limitations |
24 | 77 |
|
25 |
| -Internally uses `Url::parse()` from the [Url](https://crates.io/crates/url) crate after normalization. |
| 78 | + Intended only for git repo urls. Url spec [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) is not fully implemented. |
26 | 79 |
|
27 |
| -## Examples |
| 80 | +- No support for: |
| 81 | + - Query parameters |
| 82 | + - Fragment identifiers |
| 83 | + - Percent-encoding |
| 84 | + - Complex IP address formats |
28 | 85 |
|
29 |
| -### Run example with debug output |
| 86 | +## Install |
30 | 87 |
|
31 | 88 | ```shell
|
32 |
| -$ RUST_LOG=git_url_parse cargo run --example multi |
33 |
| -$ RUST_LOG=git_url_parse cargo run --example trim_auth |
| 89 | +cargo add git-url-parse |
34 | 90 | ```
|
35 | 91 |
|
36 |
| -### Simple usage and output |
| 92 | +### Cargo Features |
37 | 93 |
|
38 |
| -```bash |
39 |
| -$ cargo run --example readme |
40 |
| -``` |
| 94 | +#### `log` |
| 95 | +Enable for internal `debug!` output from [log](https://docs.rs/log/latest) |
| 96 | +#### `serde` |
| 97 | +Enable for [serde](https://docs.rs/serde/latest/) `Serialize`/`Deserialize` on [`GitUrl`](https://docs.rs/git-url-parse/latest/git_url_parse/types/struct.GitUrl.html) |
| 98 | +#### `url` |
| 99 | +(**enabled by default**) |
41 | 100 |
|
42 |
| -```rust |
43 |
| -use git_url_parse::GitUrl; |
| 101 | +Uses [url](https://docs.rs/url/latest/) during parsing for full url validation |
44 | 102 |
|
45 |
| -fn main() { |
46 |
| - println!( "SSH: {:#?}", GitUrl::parse( "[email protected]:tjtelan/git-url-parse-rs.git")); |
47 |
| - println!("HTTPS: {:#?}", GitUrl::parse("https://github.com/tjtelan/git-url-parse-rs")); |
48 |
| -} |
49 |
| -``` |
| 103 | +<!-- cargo-rdme end --> |
| 104 | + |
| 105 | +## Migration from 0.4.x and earlier |
| 106 | + |
| 107 | +This crate was one of my first serious projects in Rust. Because I was still learning, it had some maintenance problems and was a bit awkward to use. In version 0.5, I rewrote most of it to fix those issues. |
| 108 | + |
| 109 | +The [`GitUrl`](https://docs.rs/git-url-parse/latest/git_url_parse/types/struct.GitUrl.html) struct is only meant to handle parsing urls used by `git`, which the [url](https://docs.rs/url/latest/url) crate doesn't handle. The recent updates make it so the input string is parsed and internally stored into a simple string slice (`&str`). And, instead of exposing all the internal fields of the struct, those details are hidden, and we use methods to interact with it. |
| 110 | + |
| 111 | +The [`GitProvider`](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/trait.GitProvider.html) trait helps extract common pieces of information that are often found in different url patterns using the [`GitUrl::provider_info`](https://docs.rs/git-url-parse/latest/git_url_parse/types/struct.GitUrl.html#method.provider_info) method. Several example provider parsers are included to show how this works. The result of [`GitUrl::parse`](https://docs.rs/git-url-parse/latest/git_url_parse/types/struct.GitUrl.html#method.parse) is more straightforward to use, but the internal details are hidden, and working with provider-specific information at the git host level is more specialized. |
| 112 | + |
| 113 | +The most common pattern for git url paths, like `/owner/repo.git`, is handled by [`GenericProvider`](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.GenericProvider.html). |
| 114 | + |
| 115 | +There's also [`AzureDevOpsProvider`](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.AzureDevOpsProvider.html), which is designed for Azure DevOps urls that follow the `org`, `project`, `repo` pattern. |
50 | 116 |
|
51 |
| -### Example Output |
52 |
| -```bash |
53 |
| -SSH: Ok( |
54 |
| - GitUrl { |
55 |
| - host: Some( |
56 |
| - "github.com", |
57 |
| - ), |
58 |
| - name: "git-url-parse-rs", |
59 |
| - owner: Some( |
60 |
| - "tjtelan", |
61 |
| - ), |
62 |
| - organization: None, |
63 |
| - fullname: "tjtelan/git-url-parse-rs", |
64 |
| - scheme: Ssh, |
65 |
| - user: Some( |
66 |
| - "git", |
67 |
| - ), |
68 |
| - token: None, |
69 |
| - port: None, |
70 |
| - path: "tjtelan/git-url-parse-rs.git", |
71 |
| - git_suffix: true, |
72 |
| - scheme_prefix: false, |
73 |
| - }, |
74 |
| -) |
75 |
| -HTTPS: Ok( |
76 |
| - GitUrl { |
77 |
| - host: Some( |
78 |
| - "github.com", |
79 |
| - ), |
80 |
| - name: "git-url-parse-rs", |
81 |
| - owner: Some( |
82 |
| - "tjtelan", |
83 |
| - ), |
84 |
| - organization: None, |
85 |
| - fullname: "tjtelan/git-url-parse-rs", |
86 |
| - scheme: Https, |
87 |
| - user: None, |
88 |
| - token: None, |
89 |
| - port: None, |
90 |
| - path: "/tjtelan/git-url-parse-rs", |
91 |
| - git_suffix: false, |
92 |
| - scheme_prefix: true, |
93 |
| - }, |
94 |
| -) |
95 |
| -``` |
| 117 | +Finally, there's a new supported provider called [`GitLabProvider`](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.GitLabProvider.html), which is for GitLab urls. It supports the common `owner/repo` pattern shared with [`GenericProvider`](https://docs.rs/git-url-parse/latest/git_url_parse/types/provider/struct.GenericProvider.html), and also handles GitLab’s subgroups. |
0 commit comments