Skip to main content

worktree_io/issue/
mod.rs

1use std::path::PathBuf;
2
3mod parse;
4
5#[cfg(test)]
6mod tests;
7
8#[cfg(test)]
9mod linear_tests;
10
11/// Options extracted from a `worktree://` deep link.
12#[derive(Debug, Clone, Default)]
13pub struct DeepLinkOptions {
14    /// Editor override from the `editor` query param. May be a symbolic name
15    /// (`cursor`, `code`, `zed`, `nvim`, etc.) or a raw percent-decoded command.
16    pub editor: Option<String>,
17}
18
19/// A reference to an issue that identifies a workspace.
20#[derive(Debug, Clone, PartialEq)]
21pub enum IssueRef {
22    GitHub {
23        owner: String,
24        repo: String,
25        number: u64,
26    },
27    /// A Linear issue identified by its UUID, paired with the GitHub repo that
28    /// hosts the code for that project.
29    Linear {
30        owner: String,
31        repo: String,
32        id: String,
33    },
34}
35
36impl IssueRef {
37    /// Directory name used inside the bare clone for this worktree.
38    pub fn workspace_dir_name(&self) -> String {
39        match self {
40            Self::GitHub { number, .. } => format!("issue-{number}"),
41            Self::Linear { id, .. } => format!("linear-{id}"),
42        }
43    }
44
45    /// Git branch name for this issue worktree.
46    pub fn branch_name(&self) -> String {
47        self.workspace_dir_name()
48    }
49
50    /// HTTPS clone URL for the repository.
51    pub fn clone_url(&self) -> String {
52        match self {
53            Self::GitHub { owner, repo, .. } | Self::Linear { owner, repo, .. } => {
54                format!("https://github.com/{owner}/{repo}.git")
55            }
56        }
57    }
58
59    /// Path to the worktree checkout: `~/worktrees/github/owner/repo/issue-N`
60    pub fn temp_path(&self) -> PathBuf {
61        self.bare_clone_path().join(self.workspace_dir_name())
62    }
63
64    /// Path to the bare clone: `~/worktrees/github/owner/repo`
65    pub fn bare_clone_path(&self) -> PathBuf {
66        match self {
67            Self::GitHub { owner, repo, .. } | Self::Linear { owner, repo, .. } => {
68                dirs::home_dir()
69                    .expect("could not determine home directory")
70                    .join("worktrees")
71                    .join("github")
72                    .join(owner)
73                    .join(repo)
74            }
75        }
76    }
77}
78