linear-cli 0.7.4 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80e40a55128542927047fc4469b07ca4d62e21dfa4340c842c07dfc50c9d4338
4
- data.tar.gz: 36d3481ef7b65a2bdffeb46b99d9e98ee52c47e9ad97a41fa0716219a5f0038b
3
+ metadata.gz: ed24311870484d37b861be6bfe48af2edfc58b2c248764dd31f3f82a4ba282a5
4
+ data.tar.gz: c0404fc83e9157c97b75c1afa3fe0766a1d10838ea33e9284d380de6dde1d547
5
5
  SHA512:
6
- metadata.gz: 86c6fc9b11f43136c03978add50a793d7cf615bd44eb908b71fddb8d7535d97cc4feb0cf59801b3b5803d127d8452e055bd0fbe819b115ea55658c9e5bed2008
7
- data.tar.gz: 9aab63258d4d6242a38f911c12a09a6394fdd37065ba018b2ba4c5e139d25a27e4c6f1b73cea8b977d3c3eb40fd8ba45ca323d63d3e90a2774eed90e2ddc5757
6
+ metadata.gz: 529c58e8cfa1a550e23de0ea5f3c9bb43d559f34b8c6648aa80bdc0238ee63be00282bf6166da82bf4c5be909dd5a8212e74cd74b92e42a6d1e58bc0de98e0f8
7
+ data.tar.gz: ee09439dfb8d39fbec79ec0206822a9261b340b4e9c0bc15cfb529dcc68a0e3138810833250972cbbd4a30bee1149f5e280b544193dfc414cb825aefe1c20218
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.7.5] - 2024-02-05
6
+ ### Fixed
7
+ - Fixed problem when choosing from multiple completed states (@bougyman)
8
+
5
9
  ## [0.7.3] - 2024-02-04
6
10
  ### Fixed
7
11
  - Fixed problem with issue relationship to user (@bougyman)
@@ -41,8 +45,9 @@
41
45
  ### Added
42
46
  - Added new changelog management system (changelog-rb) (@bougyman)
43
47
 
44
- [Unreleased]: https://github.com/rubyists/linear-cli/compare/0.7.3...HEAD
45
- [0.7.3]: https://github.com/rubyists/linear-cli/compare/v0.7.2...0.7.3
48
+ [Unreleased]: https://github.com/rubyists/linear-cli/compare/0.7.5...HEAD
49
+ [0.7.5]: https://github.com/rubyists/linear-cli/compare/v0.7.3...0.7.5
50
+ [0.7.3]: https://github.com/rubyists/linear-cli/compare/v0.7.2...v0.7.3
46
51
  [0.7.2]: https://github.com/rubyists/linear-cli/compare/v0.7.1...v0.7.2
47
52
  [0.7.1]: https://github.com/rubyists/linear-cli/compare/v0.7.0...v0.7.1
48
53
  [0.7.0]: https://github.com/rubyists/linear-cli/compare/v0.6.1...v0.7.0
data/Readme.adoc CHANGED
@@ -3,6 +3,8 @@
3
3
  :toclevels: 3
4
4
  :sectanchors:
5
5
  :icons: font
6
+ :tip-caption: 💡
7
+ :note-caption: 📝
6
8
  :experimental:
7
9
 
8
10
  A command line interface to https://linear.app.
@@ -59,7 +61,7 @@ You can get help/usage for any command or subcommand by using the `--help` flag.
59
61
 
60
62
  [source,sh]
61
63
  ----
62
- $ lc
64
+ $ lc --help
63
65
  $ lc [COMMAND] --help
64
66
  $ lc [COMMAND] [SUBCOMMAND] --help
65
67
  ----
@@ -78,6 +80,8 @@ $ lc w --teams
78
80
 
79
81
  `lcls` is a helper provided to list issues. It's an alias for `lc issues list`.
80
82
 
83
+ image::listings.cinema.gif[]
84
+
81
85
  [source,sh]
82
86
  ----
83
87
  $ lcls
@@ -102,7 +106,7 @@ $ lc issue take CRY-456 CRY-789
102
106
  [source,sh]
103
107
  ----
104
108
  $ lc i c --title "My new issue" --description "This is a new issue" --labels Bug,Feature --team CRY
105
- $ lc i c -t "My new issue" -T CRY -l Improvment,Feature
109
+ $ lc i c -t "My new issue" -T CRY -l Improvement,Feature
106
110
  ----
107
111
 
108
112
  NOTE: If you don't provide a title, team, labels or description, you will be prompted to enter them.
@@ -118,7 +122,7 @@ This will switch to the branch for the issue, creating the branch if it doesn't
118
122
  $ lc i dev CRY-1234
119
123
  ----
120
124
 
121
- TIP: You may pass the --dev option to the create subcommand to immediately develop the creted issue.
125
+ TIP: You may pass the --dev option to the create subcommand to immediately develop the created issue.
122
126
 
123
127
  ==== Update an issue
124
128
 
@@ -147,5 +151,5 @@ Some command aliases are available to make things easier to type.
147
151
  ----
148
152
  $ lcls
149
153
  $ lcreate --description "This is a new issue" --labels Bug,Feature --team CRY
150
- $ lclose --reason "This issues suck" CRY-1234 CRY-456
154
+ $ lclose --reason "This issue sucks" CRY-1234 CRY-456
151
155
  ----
@@ -0,0 +1,4 @@
1
+ type: Fixed
2
+ title: >
3
+ Fixed problem when choosing from multiple completed states
4
+ author: bougyman
@@ -0,0 +1 @@
1
+ date: 2024-02-05
@@ -0,0 +1,38 @@
1
+ {"version": 2, "width": 160, "height": 46, "timestamp": 1707107455, "env": {"SHELL": "/bin/zsh", "TERM": "screen-256color"}}
2
+ [0.08698, "o", "FOUND RBENV HOME\r\n"]
3
+ [0.127279, "o", "\u001b[1m\u001b[3m%\u001b[23m\u001b[1m\u001b[0m \r \r"]
4
+ [0.140171, "o", "\u001b[mdirenv: loading ~/rubyists/linear-cli/.envrc\r\n"]
5
+ [0.147537, "o", "\u001b[mdirenv: loading ~/.envrc\r\n"]
6
+ [0.189085, "o", "gpg: WARNING: server 'gpg-agent' is older than us (2.2.27 < 2.4.4)\r\n"]
7
+ [0.189626, "o", "gpg: problem with fast path key listing: IPC parameter error - ignored\r\n"]
8
+ [0.361065, "o", "direnv: export +EDITOR +GOPATH +INPUTRC +LINEAR_API_KEY +MAILNAME +PRIZE_LINK_DIRS +PRIZE_SLACK_TOKEN +RUBY_CONFIGURE_OPTS +SVDIR +YAMLFIX_SEQUENCE_STYLE ~PATH\r\n"]
9
+ [0.442465, "o", "\r\u001b[0m\u001b[23m\u001b[24m\u001b[J\u001b[48;5;232mbougyman@camazotz\u001b[49m \u001b[1m\u001b[38;5;208m~/rubyists/linear-cli\r\n\r\u001b[37m % \u001b[0m\u001b[37m\u001b[39m\u001b[49m\u001b[K\u001b[115C\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[33m-\u001b[35m[\u001b[32mmain\u001b[35m]\u001b[39m <\u001b[35mmicrok8s\u001b[39m:\u001b[34mdefault\u001b[39m> \u001b[33m22:30:55\u001b[39m\u001b[156D"]
10
+ [0.442549, "o", "\u001b[?1h\u001b=\u001b[?2004h"]
11
+ [0.952794, "o", "\u001b[32mexit\u001b[39m"]
12
+ [1.13176, "o", "\b\b\b\b\u001b[32ml\u001b[39m\u001b[39m \u001b[39m \u001b[39m \b\b\b"]
13
+ [1.593229, "o", "\b\u001b[32ms\u001b[32meq\u001b[39m 1 9 | \u001b[33mwhile\u001b[39m \u001b[32mread\u001b[39m num; \u001b[33mdo\u001b[39m \u001b[32mlc\u001b[39m i ls \u001b[33m\"CRY-\u001b[36m$num\u001b[39m\u001b[33m\"\u001b[39m -f; \u001b[32msleep\u001b[39m 2; \u001b[33mdone\u001b[39m"]
14
+ [4.51933, "o", "\u001b[?1l\u001b>"]
15
+ [4.524811, "o", "\u001b[?2004l\u001b[K\r\r\n"]
16
+ [5.666735, "o", "CRY-1 Welcome to Linear 👋 (bougyman@hey.com)\r\n---------------------------------------------------\r\nHi there. Complete these issues to learn how to use Linear and discover ✨\u001b[33;1mProTips.\u001b[0m When you’re done, delete them or move them to another team for others to view.\r\n\r\n \u001b[36;1m\u001b[33;1mTo start, type\u001b[0m \u001b[38;5;230mC\u001b[39m to \u001b[33;1mcreate your first issue.\u001b[0m\u001b[0m\r\n\r\n Create issues from any view using \u001b[38;5;230mC\u001b[39m or by clicking the \u001b[38;5;230mNew issue\u001b[39m button.\r\n\r\n 1189b618-97f2-4e2c-ae25-4f25467679e7 » \u001b[33;4mhttps://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/532d146d-bcd6-4602-bf1f-83f674b70fff/1189b618-97f2-4e2c-ae25-4f25467679e7\u001b[0m\r\n\r\n Our issue editor and comments support Markdown. You can also:\r\n\r\n \u001b[33m●\u001b[0m @mention a teammate\r\n \u001b[33m●\u001b[0m Drag & drop images or video (Loom & Youtube embed automatically)\r\n \u001b[33m●\u001b[0m Use emoji ✅\r\n\r\n\r\n"]
17
+ [9.013736, "o", "CRY-2 Try 3 ways to navigate Linear: Command line, keyboard or mouse (bougyman@hey.com)\r\n----------------------------------------------------------------------------------------------\r\n\u001b[38;5;230mCmd/Ctrl\u001b[39m \u001b[38;5;230mK\u001b[39m \u001b[33;1mis our most powerful feature.\u001b[0m\r\n\r\nUse it to search for or take any action in the app.\r\n\r\ncf798178-b3bc-4ae1-b24f-577d4871ae5d » \u001b[33;4mhttps://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/f477604b-f0d2-4ade-8a7a-571830a3b5de/cf798178-b3bc-4ae1-b24f-577d4871ae5d\u001b[0m\r\n\r\nIf you prefer to use a mouse, right click over any issue for \u001b[33;1mcontextual menus\u001b[0m. They’re a great way to learn the keyboard shortcuts, too.\r\n\r\n\u001b[90m(CleanShot 2023-07-10 at 16.03.57.png - https://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/11668d24-67e7-431d-9c7d-4bb5f409cae8/650d277b-cc1e-498b-aabd-8d04e8f57680)\u001b[0m\r\n\r\nIf you prefer \u001b[33;1mkeyboard shortcuts\u001b[0m, type \u001b[38;5;230m?\u001b[39m to view our full list.\r\n\r\n\r\n"]
18
+ [15.404919, "o", "CRY-3 Connect to Slack (bougyman@hey.com)\r\n------------------------------------------------\r\nIf your team uses Slack, enable this integration to keep your workflow and communication in sync.\r\n\r\n\u001b[33m●\u001b[0m See issue updates in a dedicated channel.\r\n\u001b[33m●\u001b[0m Use the \u001b[38;5;230m/linear\u001b[39m command to create new issues from Slack messages.\r\n\u001b[33m●\u001b[0m Sync comments between Slack and Linear.\r\n\u001b[33m●\u001b[0m Set up personal Slack notifications.\r\n\u001b[33m●\u001b[0m Import custom emoji 🥳 to your Linear workspace.\r\n\r\nConnect Slack → » \u001b[33;4mhttps://linear.app/settings/integrations/slack\u001b[0m\r\n\r\n\r\n"]
19
+ [19.624854, "o", "CRY-4 Connect GitHub or GitLab (bougyman@hey.com)\r\n--------------------------------------------------------\r\nConnect your account to link issues to pull/merge requests and automate your workflow:\r\n\r\n\u001b[33m●\u001b[0m Link Linear issues to pull requests.\r\n\u001b[33m●\u001b[0m Automatically update an issue’s status when PRs are created or merged.\r\n\u001b[33m●\u001b[0m Connect one or multiple repos.\r\n\r\nConnect GitHub or GitLab → » \u001b[33;4mhttps://linear.app/settings/integrations/github\u001b[0m\r\n\r\n \u001b[36;1mSetup tips\u001b[0m\r\n\r\n \u001b[36;1mHow to link a Linear issue to a PR\u001b[0m\r\n\r\n \u001b[33m●\u001b[0m \u001b[33;1mBranch name\u001b[0m (e.g. “LIN-123” or “username/LIN-123”). To quickly copy branch name for an issue to your clipboard, press \u001b[38;5;230mCmd/Ctrl\u001b[39m \u001b[38;5;230mShift\u001b[39m \u001b[38;5;230m.\u001b[39m\r\n \u001b[33m●\u001b[0m \u001b[33;1mPull request title\u001b[0m (e.g. “GitHub Workflow LIN-123”)\r\n \u001b[33m●\u001b[0m \u001b[33;1mPull request description\u001b[0m (e.g. \u001b[33mFixes LIN-123, Resolves LIN-123\u001b[0m) – it will not work if entered in commits o"]
20
+ [19.624988, "o", "r comments.\r\n\r\n \u001b[36;1mWhen you link a Linear issue to a PR, Linear will:\u001b[0m\r\n\r\n \u001b[33m●\u001b[0m Create a link to the PR in the Linear issue.\r\n \u001b[33m●\u001b[0m Comment on the PR with a link back to the Linear issue.\r\n \u001b[33m●\u001b[0m Once PR has been opened, Linear will change the status of the issue to “In Progress”.\r\n \u001b[33m●\u001b[0m Once PR has been merged, Linear will change the status of the issue as “Done”.\r\n\r\n \u001b[36;1mSuggested Workflow\u001b[0m\r\n\r\n \u001b[33m1.\u001b[0m Select or create the issue you want to work on next.\r\n \u001b[33m2.\u001b[0m Open the command menu (\u001b[38;5;230mCmd\u001b[39m \u001b[38;5;230mK\u001b[39m on Mac, or \u001b[38;5;230mCtrl\u001b[39m \u001b[38;5;230mK\u001b[39m on Windows) and select \u001b[33;1mCopy git branch name,\u001b[0m or use the shortcut \u001b[38;5;230mCmd/Ctrl\u001b[39m \u001b[38;5;230mShift\u001b[39m \u001b[38;5;230m.\u001b[39m\r\n \u001b[33m3.\u001b[0m This will copy the git branch name to your clipboard (e.g. \u001b[38;5;230musername/LIN-123-github-workflow\u001b[39m\r\n \u001b[33m4.\u001b[0m Paste the branch name to your git checkout command to c"]
21
+ [19.625036, "o", "reate a new branch: \u001b[38;5;230mgit checkout -b username/LIN-123-github-workflow\u001b[39m\r\n \u001b[33m5.\u001b[0m Make your changes and push the branch to GitHub and open a pull request\r\n \u001b[33m6.\u001b[0m Once the pull request is open, Linear will comment on the PR and change the issue state to \u001b[33;1mIn Progress\u001b[0m\u001b[33m.\u001b[0m\r\n \u001b[33m7.\u001b[0m Once the PR merged, Linear will change the status to Done.\r\n\r\n Read full integration instructions for GitHub » \u001b[33;4mhttps://linear.app/docs/github\u001b[0m and GitLab → » \u001b[33;4mhttps://linear.app/docs/gitlab\u001b[0m\r\n\r\n\r\n"]
22
+ [22.710372, "o", "CRY-5 Customize settings (bougyman@hey.com)\r\n--------------------------------------------------\r\nGo to settings » \u001b[33;4mhttps://linear.app/settings\u001b[0m to enable features such as Roadmap, explore features and add integrations. Use \u001b[38;5;230mG\u001b[39m then \u001b[38;5;230mS\u001b[39m to get there.\r\n\r\n\u001b[90m(image.png - https://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/558fcd30-245d-4ddf-b15b-d9f18b1f4626/image.png)\u001b[0m\r\n\r\nVisit individual team settings » \u001b[33;4mhttps://linear.app/settings/teams/\u001b[0m to customize features on a team level.\r\n\r\n\u001b[33m●\u001b[0m Configure automated issue workflows for issues linked to PRs\r\n\u001b[33m●\u001b[0m Add or edit \u001b[33mworkflow statuses\u001b[0m, and \u001b[33mlabels\u001b[0m\r\n\u001b[33m●\u001b[0m Add team Slack notifications\r\n\u001b[33m●\u001b[0m Create reusable \u001b[33mtemplates\u001b[0m. Use the keyboard shortcut \u001b[38;5;230mAlt\u001b[39m \u001b[38;5;230mC\u001b[39m to quickly create new issues from templates\r\n\u001b[33m●\u001b[0m Set your \u001b[33mestimate\u001b[0m scale and enable \u001b[33mcycles\u001b[0m\r\n\u001b[33m●\u001b[0m Configure time-saving feature"]
23
+ [22.710471, "o", "s such as \u001b[33mAuto-close\u001b[0m and \u001b[33mAuto-archive\u001b[0m\r\n\r\n\u001b[90m(image.png - https://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/9fc1632b-893e-422c-939f-0cdc9d009b37/image.png)\u001b[0m\r\n\r\n\r\n"]
24
+ [25.812849, "o", "CRY-6 Use Cycles to focus work over n–weeks\r\n--------------------------------------------------\r\nCycles are a practice to keep up your team’s momentum. They’re similar to agile flavored sprints but help focus your work without tying it to a release date or feature.\r\n\r\n\u001b[33m●\u001b[0m Customize cycles to last between 1-8 weeks.\r\n\u001b[33m●\u001b[0m Add issues manually or automatically move issues marked \u001b[33mTodo\u001b[0m to your current cycle.\r\n\u001b[33m●\u001b[0m Follow progress over time with cycle graphs.\r\n\u001b[33m●\u001b[0m Any uncompleted issues roll to the next cycle automatically.\r\n\r\n\u001b[90m(CleanShot 2023-07-10 at 16.22.23.png - https://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/29272f4b-ee87-487f-9191-2f4f2fcc14a7/ad0f609e-d9d4-45f0-870c-a0b1c1f305ab)\u001b[0m\r\n\r\n\u001b[33m┃\u001b[0m \u001b[33m✨\u001b[33;1mProTip:\u001b[0m\u001b[33m Quickly run meetings with the cycles sidebar. Filter issues by assignee and then ask each member to share updates and blockers. At Linear, we run 2-week \u001b[0m\r\n\u001b[33m┃\u001b[0m \u001b[33mcycles and follow this "]
25
+ [25.812884, "o", "format at the beginning of each cycle.\u001b[0m\r\n\r\nRead more about cycles in the Linear Guide → » \u001b[33;4mhttps://linear.app/docs/use-cycles\u001b[0m\r\n\r\n\r\n"]
26
+ [29.41905, "o", "CRY-7 Use Projects to organize work for features or releases (bougyman@hey.com)\r\n--------------------------------------------------------------------------------------\r\nProjects are meant for larger initiatives you have on your roadmap.\r\n\r\n\u001b[33m●\u001b[0m Share projects with multiple teams.\r\n\u001b[33m●\u001b[0m Set a target date.\r\n\u001b[33m●\u001b[0m View progress and estimate completion timeframe with graphs.\r\n\r\n\u001b[90m(header-projects.png - https://uploads.linear.app/fe63b3e2-bf87-46c0-8784-cd7d639287c8/3e49c9a1-8794-4740-80d9-4991c6021016/cded48fc-554a-472d-a27b-90df57550087)\u001b[0m\r\n\r\nLearn more about Projects in the Linear Guide → » \u001b[33;4mhttps://linear.app/docs/projects\u001b[0m\r\n\r\n\r\n"]
27
+ [38.231422, "o", "CRY-8 Invite your teammates (bougyman@hey.com)\r\n-----------------------------------------------------\r\nInvite others to your workspace in settings » \u001b[33;4mhttp://linear.app/settings/members\u001b[0m.\r\n\r\n\r\n"]
28
+ [41.297769, "o", "CRY-9 Next steps (bougyman@hey.com)\r\n------------------------------------------\r\nYou’re all set to use Linear.\r\n\r\n\u001b[33;1mWant to learn more?\u001b[0m\r\n\r\n\u001b[33m●\u001b[0m Check out our docs » \u001b[33;4mhttps://linear.app/docs\u001b[0m to dive into specific features\r\n\u001b[33m●\u001b[0m Learn about new features in weekly changelogs » \u001b[33;4mhttps://linear.app/changelog\u001b[0m\r\n\u001b[33m●\u001b[0m Read the Linear Method » \u001b[33;4mhttps://linear.app/linear-method\u001b[0m, our approach to software building\r\n\u001b[33m●\u001b[0m Join our Linear Customer Slack at this link » \u001b[33;4mhttp://linear.app/join-slack\u001b[0m\r\n\r\n\u001b[33;1mProTip: How to trial Linear on your team\u001b[0m\r\n\r\n\u001b[33m●\u001b[0m Use our in-app importer » \u001b[33;4mhttps://linear.app/settings/import-export\u001b[0m to add issues from Jira, Asana, Shortcut or GitHub\r\n\u001b[33m●\u001b[0m Trial it on your team. Pick a project or sprint, invite a few coworkers, add key integrations like Slack and GitHub to experience the full workflow.\r\n\r\n \u001b[36;1mHave a question?\u001b[0m\r\n\r\n Reach out to us via the Help & Support l"]
29
+ [41.297901, "o", "ink in the sidebar.\r\n\r\n\r\n"]
30
+ [43.304868, "o", "\u001b[1m\u001b[3m%\u001b[23m\u001b[1m\u001b[0m \r \r"]
31
+ [43.383925, "o", "\r\u001b[0m\u001b[23m\u001b[24m\u001b[J\u001b[48;5;232mbougyman@camazotz\u001b[49m \u001b[1m\u001b[38;5;208m~/rubyists/linear-cli\r\n\r\u001b[37m % \u001b[0m\u001b[37m\u001b[39m\u001b[49m\u001b[K\u001b[115C\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[33m-\u001b[35m[\u001b[32mmain\u001b[35m]\u001b[39m <\u001b[35mmicrok8s\u001b[39m:\u001b[34mdefault\u001b[39m> \u001b[33m22:31:38\u001b[39m\u001b[156D"]
32
+ [43.383956, "o", "\u001b[?1h\u001b=\u001b[?2004h"]
33
+ [61.66531, "o", "\u001b[4me\u001b[24m"]
34
+ [61.848614, "o", "\b\u001b[24m\u001b[32me\u001b[32mx\u001b[39m"]
35
+ [62.043272, "o", "\b\b\u001b[1m\u001b[31me\u001b[1m\u001b[31mx\u001b[1m\u001b[31mi\u001b[0m\u001b[39m"]
36
+ [62.130462, "o", "\b\b\b\u001b[0m\u001b[32me\u001b[0m\u001b[32mx\u001b[0m\u001b[32mi\u001b[32mt\u001b[39m"]
37
+ [62.529001, "o", "\u001b[?1l\u001b>"]
38
+ [62.529665, "o", "\u001b[?2004l\u001b[K\r\r\n"]
data/exe/linear-cli CHANGED
@@ -3,4 +3,11 @@
3
3
 
4
4
  require 'linear'
5
5
  Rubyists::Linear::L :cli
6
- Dry::CLI.new(Rubyists::Linear::CLI).call
6
+ begin
7
+ Dir.mktmpdir(Process.pid.to_s) do |dir|
8
+ Rubyists::Linear.tmpdir = dir
9
+ Dry::CLI.new(Rubyists::Linear::CLI).call
10
+ end
11
+ ensure
12
+ FileUtils.rm_rf(Rubyists::Linear.tmpdir) if Rubyists::Linear.tmpdir.exist?
13
+ end
@@ -54,11 +54,20 @@ module Rubyists
54
54
  prompt.ask(question)
55
55
  end
56
56
 
57
+ def cancelled_state_for(thingy)
58
+ states = thingy.cancelled_states
59
+ return states.first if states.size == 1
60
+
61
+ selection = prompt.select('Choose a cancelled state', states.to_h { |s| [s.name, s.id] })
62
+ Rubyists::Linear::WorkflowState.find selection
63
+ end
64
+
57
65
  def completed_state_for(thingy)
58
66
  states = thingy.completed_states
59
67
  return states.first if states.size == 1
60
68
 
61
- prompt.select('Choose a completed state', states.to_h { |s| [s.name, s.id] })
69
+ selection = prompt.select('Choose a completed state', states.to_h { |s| [s.name, s.id] })
70
+ Rubyists::Linear::WorkflowState.find selection
62
71
  end
63
72
 
64
73
  def description_for(description = nil)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rubyists
4
4
  module Linear
5
- VERSION = '0.7.4'
5
+ VERSION = '0.7.6'
6
6
  end
7
7
  end
@@ -27,7 +27,7 @@ module Rubyists
27
27
  logger.debug('Creating issue', options:)
28
28
  issue = make_da_issue!(**options)
29
29
  logger.debug('Issue created', issue:)
30
- prompt.yes?('Do you want to take this issue?') && gimme_da_issue!(issue.id, User.me)
30
+ prompt.yes?('Do you want to take this issue?') && gimme_da_issue!(issue.id, me: User.me)
31
31
  display issue, options
32
32
  Rubyists::Linear::CLI::Issue::Develop.new.call(issue_id: issue.id, **options) if options[:develop]
33
33
  end
@@ -18,18 +18,32 @@ module Rubyists
18
18
  include Rubyists::Linear::CLI::CommonOptions
19
19
  include Rubyists::Linear::CLI::Issue # for #gimme_da_issue! and other Issue methods
20
20
  desc 'Update an issue'
21
- argument :issue_ids, type: :array, required: true, desc: 'Issue IDs (i.e. ISS-1)'
21
+ argument :issue_ids, type: :array, required: true, desc: 'Issue IDs (i.e. CRY-1)'
22
22
  option :comment, type: :string, aliases: ['-m'], desc: 'Comment to add to the issue'
23
23
  option :pr, type: :boolean, aliases: ['--pull-request'], default: false, desc: 'Create a pull request'
24
+ option :cancel, type: :boolean, default: false, desc: 'Cancel the issue'
24
25
  option :close, type: :boolean, default: false, desc: 'Close the issue'
25
26
  option :reason, type: :string, aliases: ['--butwhy'], desc: 'Reason for closing the issue'
27
+ option :trash,
28
+ type: :boolean,
29
+ default: false,
30
+ desc: 'Also trash the issue (--close and --cancel support this option)'
31
+
32
+ example [
33
+ '--comment "This is a comment" CRY-1 CRY2 # Add a comment to multiple issues',
34
+ '--pr CRY-10 # Create a pull request for the issue',
35
+ '--close CRY-2 # Close an issue. Will be prompted for a reason',
36
+ '--close --reason "Done" CRY-1 CRY-2 # Close multiple issues with a reason',
37
+ '--cancel --trash --reason "Garbage" CRY-2 # Cancel an issue, and throw it in the trash'
38
+ ]
26
39
 
27
40
  def call(issue_ids:, **options)
28
- prompt.error('You should provide at least one issue ID') && raise(SmellsBad) if issue_ids.empty?
41
+ raise SmellsBad, 'No issue IDs provided!' if issue_ids.empty?
42
+ raise SmellsBad, 'You may only open a PR against a single issue' if options[:pr] && issue_ids.size > 1
29
43
 
30
44
  logger.debug('Updating issues', issue_ids:, options:)
31
45
  Rubyists::Linear::Issue.find_all(issue_ids).each do |issue|
32
- update_issue(issue, **options)
46
+ update_issue(issue, **options) # defined in lib/linear/commands/issue.rb
33
47
  end
34
48
  end
35
49
  end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # This is where the #reason_for, #title_for, #description_for, #team_for, and #labels_for methods are defined
4
+ # as well as other helpers which are used in multiple commands and subcommands
5
+ # This is also where the #prompt method is defined, which is used to display messages to the user and get input
3
6
  require_relative '../cli/sub_commands'
4
7
 
5
8
  module Rubyists
@@ -27,12 +30,23 @@ module Rubyists
27
30
  prompt.ok("Comment added to #{issue.identifier}")
28
31
  end
29
32
 
33
+ def cancel_issue(issue, **options)
34
+ reason = reason_for(options[:reason], four: "cancelling #{issue.identifier} - #{issue.title}")
35
+ issue_comment(issue, reason)
36
+ cancel_state = cancel_state_for(issue)
37
+ issue.close!(state: cancel_state, trash: options[:trash])
38
+ prompt.ok("#{issue.identifier} was cancelled")
39
+ end
40
+
30
41
  def close_issue(issue, **options)
31
- reason = reason_for(options[:reason], four: "closing #{issue.identifier} - #{issue.title}")
42
+ cancelled = options[:cancel]
43
+ doing = cancelled ? 'cancelling' : 'closing'
44
+ done = cancelled ? 'cancelled' : 'closed'
45
+ workflow_state = cancelled ? cancelled_state_for(issue) : completed_state_for(issue)
46
+ reason = reason_for(options[:reason], four: "#{doing} #{issue.identifier} - #{issue.title}")
32
47
  issue_comment(issue, reason)
33
- close_state = completed_state_for(issue)
34
- issue.close!(state: close_state, trash: options[:trash])
35
- prompt.ok("#{issue.identifier} was closed")
48
+ issue.close!(state: workflow_state, trash: options[:trash])
49
+ prompt.ok("#{issue.identifier} was #{done}")
36
50
  end
37
51
 
38
52
  def issue_pr(issue)
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Linear
5
+ class BaseModel
6
+ # Class methods for Linear models.
7
+ module ClassMethods
8
+ def many_to_one(relation, klass)
9
+ define_method relation do
10
+ return instance_variable_get("@#{relation}") if instance_variable_defined?("@#{relation}")
11
+ return unless (val = data[relation])
12
+
13
+ instance_variable_set("@#{relation}", Rubyists::Linear.const_get(klass).new(val))
14
+ end
15
+
16
+ define_method "#{relation}=" do |val|
17
+ hash = val.is_a?(Hash) ? val : val.data
18
+ updated_data[relation] = hash
19
+ instance_variable_set("@#{relation}", Rubyists::Linear.const_get(klass).new(hash))
20
+ end
21
+ end
22
+
23
+ alias one_to_one many_to_one
24
+
25
+ def find(id_val)
26
+ camel_name = just_name.camelize :lower
27
+ bf = base_fragment
28
+ query_data = Api.query(query { __node(camel_name, id: id_val) { ___ bf } })
29
+ new query_data[camel_name.to_sym]
30
+ end
31
+
32
+ def const_added(const)
33
+ return unless const == :Base
34
+
35
+ include MethodMagic
36
+ end
37
+
38
+ def allq(filter: nil, limit: 50, after: nil)
39
+ args = { first: limit }
40
+ args[:filter] = filter ? basic_filter.merge(filter) : basic_filter
41
+ args.delete(:filter) if args[:filter].empty?
42
+ args[:after] = after if after
43
+ all_query args, plural.to_s, base_fragment
44
+ end
45
+
46
+ def all_query(args, subject, base_fragment)
47
+ query do
48
+ __node(subject, args) do
49
+ edges do
50
+ node { ___ base_fragment }
51
+ cursor
52
+ end
53
+ ___ Fragments::PageInfo
54
+ end
55
+ end
56
+ end
57
+
58
+ def just_name
59
+ name.split('::').last
60
+ end
61
+
62
+ def base_fragment
63
+ const_get(:Base)
64
+ end
65
+
66
+ def basic_filter
67
+ return const_get(:BASIC_FILTER) if const_defined?(:BASIC_FILTER)
68
+
69
+ {}
70
+ end
71
+
72
+ def plural
73
+ return const_get(:PLURAL) if const_defined?(:PLURAL)
74
+
75
+ just_name.downcase.pluralize.to_sym
76
+ end
77
+
78
+ def gql_query(filter: nil, after: nil)
79
+ Api.query(allq(filter:, after:))
80
+ end
81
+
82
+ def all(after: nil, filter: nil, max: 100)
83
+ edges = []
84
+ moar = true
85
+ while moar
86
+ data = gql_query(filter:, after:)
87
+ subjects = data[plural]
88
+ edges += subjects[:edges]
89
+ moar = false if edges.size >= max || !subjects[:pageInfo][:hasNextPage]
90
+ after = subjects[:pageInfo][:endCursor]
91
+ end
92
+ edges.map { |edge| new edge[:node] }
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ module Linear
5
+ class BaseModel
6
+ # Methods for Linear models.
7
+ module MethodMagic
8
+ def self.included(base) # rubocop:disable Metrics/MethodLength
9
+ base.instance_eval do
10
+ base.base_fragment.__nodes.each do |node|
11
+ sym = node.__name.to_sym
12
+ define_method node.__name do
13
+ updated_data[sym]
14
+ end
15
+
16
+ define_method "#{node.__name}=" do |value|
17
+ updated_data[sym] = value
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -8,113 +8,17 @@ module Rubyists
8
8
  # Namespace for Linear
9
9
  module Linear
10
10
  L :api, :fragments
11
- # Module which provides a base model for Linear models.
11
+ M 'base_model/method_magic', 'base_model/class_methods'
12
+ # The base model for all Linear models
12
13
  class BaseModel
13
14
  extend GQLi::DSL
14
15
  include GQLi::DSL
15
16
  include SemanticLogger::Loggable
16
-
17
- # Methods for Linear models.
18
- module MethodMagic
19
- def self.included(base) # rubocop:disable Metrics/MethodLength
20
- base.instance_eval do
21
- base.base_fragment.__nodes.each do |node|
22
- sym = node.__name.to_sym
23
- define_method node.__name do
24
- updated_data[sym]
25
- end
26
-
27
- define_method "#{node.__name}=" do |value|
28
- updated_data[sym] = value
29
- end
30
- end
31
- end
32
- end
33
- end
34
-
35
- # Class methods for Linear models.
36
- class << self
37
- def one_to_one(relation, klass)
38
- define_method relation do
39
- return instance_variable_get("@#{relation}") if instance_variable_defined?("@#{relation}")
40
- return unless (val = data[relation])
41
-
42
- instance_variable_set("@#{relation}", Rubyists::Linear.const_get(klass).new(val))
43
- end
44
-
45
- define_method "#{relation}=" do |val|
46
- hash = val.is_a?(Hash) ? val : val.data
47
- updated_data[relation] = hash
48
- instance_variable_set("@#{relation}", Rubyists::Linear.const_get(klass).new(hash))
49
- end
50
- end
51
-
52
- def const_added(const)
53
- return unless const == :Base
54
-
55
- include MethodMagic
56
- end
57
-
58
- def allq(filter: nil, limit: 50, after: nil)
59
- args = { first: limit }
60
- args[:filter] = filter ? basic_filter.merge(filter) : basic_filter
61
- args.delete(:filter) if args[:filter].empty?
62
- args[:after] = after if after
63
- all_query args, plural.to_s, base_fragment
64
- end
65
-
66
- def all_query(args, subject, base_fragment)
67
- query do
68
- __node(subject, args) do
69
- edges do
70
- node { ___ base_fragment }
71
- cursor
72
- end
73
- ___ Fragments::PageInfo
74
- end
75
- end
76
- end
77
-
78
- def just_name
79
- name.split('::').last
80
- end
81
-
82
- def base_fragment
83
- const_get(:Base)
84
- end
85
-
86
- def basic_filter
87
- return const_get(:BASIC_FILTER) if const_defined?(:BASIC_FILTER)
88
-
89
- {}
90
- end
91
-
92
- def plural
93
- return const_get(:PLURAL) if const_defined?(:PLURAL)
94
-
95
- just_name.downcase.pluralize.to_sym
96
- end
97
-
98
- def gql_query(filter: nil, after: nil)
99
- Api.query(allq(filter:, after:))
100
- end
101
-
102
- def all(after: nil, filter: nil, max: 100)
103
- edges = []
104
- moar = true
105
- while moar
106
- data = gql_query(filter:, after:)
107
- subjects = data[plural]
108
- edges += subjects[:edges]
109
- moar = false if edges.size >= max || !subjects[:pageInfo][:hasNextPage]
110
- after = subjects[:pageInfo][:endCursor]
111
- end
112
- edges.map { |edge| new edge[:node] }
113
- end
114
- end
115
-
17
+ extend ClassMethods
116
18
  attr_reader :data, :updated_data
117
19
 
20
+ CANCELLED_STATES = %w[cancelled canceled].freeze
21
+
118
22
  def initialize(data)
119
23
  data.each_key { |k| raise SmellsBad, "Unknown key #{k}" unless respond_to? "#{k}=" }
120
24
  @data = data
@@ -129,6 +33,10 @@ module Rubyists
129
33
  workflow_states.select { |ws| ws.type == 'completed' }
130
34
  end
131
35
 
36
+ def cancelled_states
37
+ workflow_states.select { |ws| CANCELLED_STATES.include? ws.type }
38
+ end
39
+
132
40
  def to_h
133
41
  updated_data
134
42
  end
data/lib/linear.rb CHANGED
@@ -24,6 +24,14 @@ module Rubyists
24
24
  FEATURE_ROOT = ROOT/:features
25
25
  DEBUG_LEVELS = %i[warn info debug trace].freeze
26
26
 
27
+ def self.tmpdir=(other)
28
+ @tmpdir = other.is_a?(Pathname) ? other : Pathname(other)
29
+ end
30
+
31
+ def self.tmpdir
32
+ @tmpdir || raise('tmpdir not set')
33
+ end
34
+
27
35
  def self.L(*libraries) # rubocop:disable Naming/MethodName
28
36
  Array(libraries).each { |library| require LIBROOT/library }
29
37
  end
data/linear-cli.gemspec CHANGED
@@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
43
43
  spec.add_dependency 'semantic_logger', '~> 4.0'
44
44
  spec.add_dependency 'sequel', '~> 5.0'
45
45
  spec.add_dependency 'sqlite3', '~> 1.7'
46
+ spec.add_dependency 'tty-editor', '~> 0.7'
46
47
  spec.add_dependency 'tty-markdown', '~> 0.7'
47
48
  spec.add_dependency 'tty-prompt', '~> 0.23'
48
49
 
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linear-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tj (bougyman) Vanderpoel
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '1.7'
153
+ - !ruby/object:Gem::Dependency
154
+ name: tty-editor
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.7'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.7'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: tty-markdown
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -217,7 +231,10 @@ files:
217
231
  - changelog/0.7.2/tag.yml
218
232
  - changelog/0.7.3/fixed_problem_with_issue_relationship_to_user.yml
219
233
  - changelog/0.7.3/tag.yml
234
+ - changelog/0.7.5/fixed_problem_when_choosing_from_multiple_completed_states.yml
235
+ - changelog/0.7.5/tag.yml
220
236
  - changelog/unreleased/.gitkeep
237
+ - cinemas/listings.cinema
221
238
  - exe/lc
222
239
  - exe/lc.sh
223
240
  - exe/lclose
@@ -247,6 +264,8 @@ files:
247
264
  - lib/linear/exceptions.rb
248
265
  - lib/linear/fragments.rb
249
266
  - lib/linear/models/base_model.rb
267
+ - lib/linear/models/base_model/class_methods.rb
268
+ - lib/linear/models/base_model/method_magic.rb
250
269
  - lib/linear/models/issue.rb
251
270
  - lib/linear/models/label.rb
252
271
  - lib/linear/models/team.rb
@@ -254,6 +273,7 @@ files:
254
273
  - lib/linear/models/workflow_state.rb
255
274
  - lib/linear/version.rb
256
275
  - linear-cli.gemspec
276
+ - listings.cinema.gif
257
277
  homepage: https://github.com/rubyists/linear-cli
258
278
  licenses:
259
279
  - MIT