Skip to content

Commit f03e4cc

Browse files
authored
feat: allow project to be specified on issue create
2 parents a25d400 + 1fb7248 commit f03e4cc

6 files changed

Lines changed: 76 additions & 16 deletions

File tree

README.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,29 @@ The goal is to improve adoption of Linear.app by devs who have a heavy terminal-
88
This allows for devs to quickly create issues for new tasks they may be starting work on, and also automatically create a new local git branch for the linear issue (and switch into it).
99
This also provides an easy way to switch to git branch for a linear issue.
1010

11+
### Installation
12+
13+
- Grab pre-built binary from [here](https://github.com/pvik/linear-cli/releases).
14+
- Extract the archive
15+
16+
##### OSX
17+
18+
- Copy the binary to a location that's included in your `$PATH`
19+
- If you're using homebrew, you can copy the binary to `/opt/homebrew/bin/`
20+
- OSX requires binaries to be signed, to do this, run the following in your terminal:
21+
22+
```sh
23+
$ sudo xattr -dr com.apple.quarantine /opt/homebrew/bin/lin
24+
$ sudo codesign -s - --deep --force /opt/homebrew/bin/lin
25+
```
26+
1127
## Usage
1228

1329
### Configuration
1430

15-
XDG Config location is honored. In Linux/Mac this should be `~/.config/linear-cli/config.toml`
31+
XDG Config location is honored.
32+
In Linux this should be `~/.config/linear-cli/config.toml`
33+
In Mac this should be `~/Library/Application Data/linear-cli/config.toml`
1634

1735
This file holds your Linear.app API Key.
1836
You can create a Personal API Key in Settings > Security & access
@@ -35,6 +53,7 @@ default_team = "Engineering"
3553
team = "Engineering"
3654
priority = 3
3755
status = "Todo"
56+
project = "Data"
3857
labels = ["Backend Team"]
3958
```
4059

@@ -144,19 +163,19 @@ OPTIONS:
144163
- Create a new issue ; create a new git-branch for issue and switch to it: (all below are equivalent)
145164

146165
```
147-
lin new issue --team="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --git-create-branch
166+
lin new issue --team="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --project=Data --git-create-branch
148167
```
149168

150169
```
151-
lin touch is --tm="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --g-cb
170+
lin touch is --tm="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --prj=Data --g-cb
152171
```
153172

154173
```
155-
lin mk is --tm="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --g-cb
174+
lin mk is --tm="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --prj=Data --g-cb
156175
```
157176

158177
```
159-
lin mk i --tm="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --g-cb
178+
lin mk i --tm="Engineering" --title="test issue" --label="Backend Team" --label="Improvement" --priority=3 --status="Todo" --prj=Data --g-cb
160179
```
161180

162181

cmd/lin/cli.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ func (a App) ParseCLIParams() {
161161
&cli.StringSliceFlag{Name: "label", Value: a.ProjectConfig.DefaultIssueTemplate.Labels},
162162
&cli.IntFlag{Name: "priority", Value: a.ProjectConfig.DefaultIssueTemplate.Priority},
163163
&cli.StringFlag{Name: "status", Value: a.ProjectConfig.DefaultIssueTemplate.Status},
164+
&cli.StringFlag{Name: "project", Aliases: []string{"prj"}, Value: a.ProjectConfig.DefaultIssueTemplate.Project},
164165
&cli.BoolFlag{Name: "git-create-branch", Aliases: []string{"g-cb"}, Usage: "Create a new git branch for Issue, and switch to it."},
165166
},
166167

@@ -181,14 +182,17 @@ func (a App) ParseCLIParams() {
181182
priority := cmd.Int("priority")
182183

183184
status := cmd.String("status")
184-
if cmd.IsSet("priority") {
185-
priority = cmd.Int("priority")
186-
}
187185
stateId := ""
188186
if status != "" {
189187
stateId = a.getTeamStateId(teamId, status, true)
190188
}
191189

190+
project := cmd.String("project")
191+
projectId := ""
192+
if project != "" {
193+
projectId = a.getProjectId(project, true)
194+
}
195+
192196
labels := cmd.StringSlice("label")
193197
labelsIds := []string{}
194198
if len(labels) > 0 {
@@ -198,7 +202,7 @@ func (a App) ParseCLIParams() {
198202
myId := a.getMyId()
199203

200204
c := linear.Linear{ApiKey: a.LinearAPIToken}
201-
issue := c.CreateIssue(teamId, title, "", myId, stateId, priority, labelsIds)
205+
issue := c.CreateIssue(teamId, title, "", myId, stateId, priority, projectId, labelsIds)
202206

203207
log.Info().Msgf("Created new issue: %s", issue.Identifier)
204208
detailIssue(issue)

cmd/lin/linear_helper.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@ func (a App) getTeamStateId(teamId string, stateName string, raiseOnNotFound boo
4141
return ""
4242
}
4343

44+
func (a App) getProjectId(projectName string, raiseOnNotFound bool) string {
45+
c := linear.Linear{ApiKey: a.LinearAPIToken}
46+
projects := c.QueryProjects()
47+
48+
for _, project := range projects {
49+
if project.Name == projectName {
50+
return project.Id
51+
}
52+
}
53+
54+
if raiseOnNotFound {
55+
log.Fatal().Msg(fmt.Sprintf("Invalid Project (%s) provided.", projectName))
56+
}
57+
58+
return ""
59+
}
60+
4461
func (a App) getIssueLabelsIds(labels []string, raiseOnNotFound bool) []string {
4562
c := linear.Linear{ApiKey: a.LinearAPIToken}
4663
srvLabels := c.QueryIssueLabels(true)

internal/config/model.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type ProjectConfig struct {
1111
Team string `toml:"team"`
1212
Priority int `toml:"priority"`
1313
Status string `toml:"status"`
14+
Project string `toml:"project"`
1415
Labels []string `toml:"labels"`
1516
} `toml:"default_issue_template"`
1617
}

pkg/git/branch.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,42 @@ package git
33
import (
44
"fmt"
55
"os"
6+
"path/filepath"
67

78
"github.com/go-git/go-git/v6"
89
"github.com/go-git/go-git/v6/plumbing"
910
"github.com/rs/zerolog/log"
1011
)
1112

1213
func getCWDRepo() *git.Repository {
13-
path, err := os.Getwd()
14+
cwd, err := os.Getwd()
1415
if err != nil {
1516
log.Fatal().Err(err).Msg("Unable to get CWD")
1617
}
1718

18-
// We instantiate a new repository targeting the given path (the .git folder)
19-
r, err := git.PlainOpen(path)
20-
if err != nil {
21-
log.Fatal().Err(err).Msg("Unable to open git repo")
19+
found := false
20+
path := cwd
21+
22+
if !found {
23+
for _ = range 4 {
24+
25+
r, err := git.PlainOpen(path)
26+
if err != nil {
27+
log.Debug().Err(err).Msg("Unable to open git repo")
28+
29+
path = filepath.Join(path, "..")
30+
continue
31+
}
32+
33+
return r
34+
35+
}
2236
}
2337

24-
return r
38+
log.Fatal().Str("path", cwd).Msg("Unable to open git repo")
39+
40+
return nil
41+
2542
}
2643

2744
func getBranchRefName(branchName string) plumbing.ReferenceName {

pkg/linear/issue.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func (l Linear) CreateIssue(
4545
assigneeId string,
4646
stateId string,
4747
priority int,
48+
projectId string,
4849
labelsIds []string,
4950
) IssueDetailNode {
5051
client := l.getClient()
@@ -56,14 +57,15 @@ func (l Linear) CreateIssue(
5657
"assigneeId": assigneeId,
5758
"stateId": stateId,
5859
"priority": priority,
60+
"projectId": projectId,
5961
"labelIds": labelsIds,
6062
}
6163

6264
var mutateIssue struct {
6365
IssueCreate struct {
6466
Success bool
6567
Issue IssueDetailNode
66-
} `graphql:"issueCreate(input: {title: $title, description: $description, teamId: $teamId, assigneeId: $assigneeId, stateId: $stateId, priority: $priority, labelIds: $labelIds})"`
68+
} `graphql:"issueCreate(input: {title: $title, description: $description, teamId: $teamId, assigneeId: $assigneeId, stateId: $stateId, projectId: $projectId, priority: $priority, labelIds: $labelIds})"`
6769
}
6870

6971
err := client.WithDebug(true).Mutate(context.Background(), &mutateIssue, variables)

0 commit comments

Comments
 (0)