Skip to main content

worktree_io/issue/
impls.rs

1use super::IssueRef;
2
3impl IssueRef {
4    /// Directory name used inside the bare clone for this worktree.
5    #[must_use]
6    pub fn workspace_dir_name(&self) -> String {
7        match self {
8            Self::GitHub { number, .. } | Self::GitLab { number, .. } => {
9                format!("issue-{number}")
10            }
11            Self::Adhoc { name, .. } => name.clone(),
12            Self::Linear { id, .. } => format!("linear-{id}"),
13            Self::AzureDevOps { id, .. } => format!("workitem-{id}"),
14            Self::Jira { issue_key, .. } => format!("jira-{}", issue_key.to_lowercase()),
15            Self::Local { display_number, .. } => format!("issue-{display_number}"),
16            Self::RemoteBranch { branch, .. } => branch.clone(),
17        }
18    }
19
20    /// Git branch name for this issue worktree.
21    #[must_use]
22    pub fn branch_name(&self) -> String {
23        self.workspace_dir_name()
24    }
25
26    /// HTTPS clone URL for the repository.
27    ///
28    /// # Panics
29    ///
30    /// Always panics for `IssueRef::Local` — local repos are never cloned.
31    #[must_use]
32    pub fn clone_url(&self) -> String {
33        match self {
34            Self::GitHub { owner, repo, .. }
35            | Self::Linear { owner, repo, .. }
36            | Self::Jira { owner, repo, .. }
37            | Self::Adhoc { owner, repo, .. } => {
38                format!("https://github.com/{owner}/{repo}.git")
39            }
40            Self::GitLab { owner, repo, .. } => {
41                format!("https://gitlab.com/{owner}/{repo}.git")
42            }
43            Self::AzureDevOps {
44                org, project, repo, ..
45            } => {
46                format!("https://dev.azure.com/{org}/{project}/_git/{repo}")
47            }
48            Self::Local { .. } => {
49                unreachable!("clone_url is never called for IssueRef::Local")
50            }
51            Self::RemoteBranch {
52                host, owner, repo, ..
53            } => match host.as_str() {
54                "gitlab" => format!("https://gitlab.com/{owner}/{repo}.git"),
55                _ => format!("https://github.com/{owner}/{repo}.git"),
56            },
57        }
58    }
59
60    /// Subdirectory name within a multi-workspace root: `<repo>-<id>`.
61    ///
62    /// For example, `GitHub { repo: "backend", number: 7 }` → `"backend-7"`.
63    ///
64    /// # Panics
65    ///
66    /// Panics for `IssueRef::Local` — local issues are not supported in
67    /// multi-workspace mode.
68    #[must_use]
69    pub fn multi_dir_name(&self) -> String {
70        match self {
71            Self::GitHub { repo, number, .. } | Self::GitLab { repo, number, .. } => {
72                format!("{repo}-{number}")
73            }
74            Self::Adhoc { repo, name, .. } => format!("{repo}-{name}"),
75            Self::Linear { repo, id, .. } => format!("{repo}-{id}"),
76            Self::AzureDevOps { repo, id, .. } => format!("{repo}-{id}"),
77            Self::Jira {
78                repo, issue_key, ..
79            } => {
80                format!("{repo}-{}", issue_key.to_lowercase())
81            }
82            Self::Local { .. } => {
83                unreachable!("multi_dir_name is not supported for IssueRef::Local")
84            }
85            Self::RemoteBranch { .. } => {
86                unreachable!("multi_dir_name is not supported for RemoteBranch")
87            }
88        }
89    }
90}