Skip to main content

worktree_io/issue/parse/
mod.rs

1mod azure;
2mod centy;
3mod gh;
4mod github;
5mod gitlab;
6mod jira;
7mod options;
8mod shorthand;
9mod worktree_url;
10
11use anyhow::{bail, Result};
12
13use super::IssueRef;
14
15impl IssueRef {
16    /// Parse any of the supported input formats:
17    /// - `https://github.com/owner/repo/issues/42`
18    /// - `worktree://open?owner=X&repo=Y&issue=42`
19    /// - `worktree://open?url=<encoded-github-url>`
20    /// - `worktree://open?owner=X&repo=Y&linear_id=<uuid>`
21    /// - `owner/repo#42`
22    /// - `owner/repo@<linear-uuid>`
23    /// - `centy:<number>` (context-aware: finds nearest `.centy/` ancestor)
24    /// - `gh:<number>` (context-aware: resolves against the `origin` GitHub remote)
25    ///
26    /// # Errors
27    ///
28    /// Returns an error if `s` does not match any supported format or if the
29    /// extracted values (e.g. issue number) are invalid.
30    pub fn parse(s: &str) -> Result<Self> {
31        let s = s.trim();
32
33        if s.starts_with("worktree://") {
34            let (issue, _opts) = worktree_url::parse_worktree_url(s)?;
35            return Ok(issue);
36        }
37
38        if s.starts_with("https://github.com") || s.starts_with("http://github.com") {
39            return github::parse_github_url(s);
40        }
41        if s.starts_with("https://dev.azure.com") || s.starts_with("http://dev.azure.com") {
42            return azure::parse_azure_devops_url(s);
43        }
44        if s.starts_with("https://gitlab.com") || s.starts_with("http://gitlab.com") {
45            return gitlab::parse_gitlab_url(s);
46        }
47
48        if s.contains(".atlassian.net/browse/") {
49            return jira::parse_jira_browse_url(s);
50        }
51
52        if s.starts_with("centy:") {
53            return centy::parse_centy(s);
54        }
55
56        if s.starts_with("gh:") {
57            return gh::parse_gh(s);
58        }
59
60        if s.starts_with("gl:") {
61            return gitlab::parse_gl(s);
62        }
63
64        if let Some(result) = shorthand::try_parse_shorthand(s) {
65            return result;
66        }
67
68        bail!(
69            "Could not parse issue reference: {s:?}\n\
70             Supported formats:\n\
71             - https://github.com/owner/repo/issues/42\n\
72             - https://gitlab.com/owner/repo/-/issues/42\n\
73             - https://dev.azure.com/org/project/_workitems/edit/42\n\
74             - worktree://open?owner=owner&repo=repo&issue=42\n\
75             - worktree://open?owner=owner&repo=repo&linear_id=<uuid>\n\
76             - worktree://open?org=org&project=project&repo=repo&work_item_id=42\n\
77             - worktree://open?jira_host=host&jira_issue_key=PROJ-42&owner=owner&repo=repo\n\
78             - worktree://open?gitlab_host=gitlab.com&owner=owner&repo=repo&issue=42\n\
79             - owner/repo#42\n\
80             - owner/repo@<linear-uuid>\n\
81             - org/project/repo!42\n\
82             - centy:<number>\n\
83             - gh:<number>\n\
84             - gl:<number>"
85        )
86    }
87}