linear-cli 0.7.5 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -2
  3. data/Readme.adoc +11 -3
  4. data/changelog/0.7.7/added_ability_to_attach_project_to_command.yml +4 -0
  5. data/changelog/0.7.7/added_issue_pr_command.yml +4 -0
  6. data/changelog/0.7.7/added_lcomment_alias_to_add_comments_to_issues.yml +4 -0
  7. data/changelog/0.7.7/tag.yml +1 -0
  8. data/exe/lc +5 -1
  9. data/exe/lclose +1 -0
  10. data/exe/lcls +1 -0
  11. data/exe/lcomment +1 -0
  12. data/exe/lcreate +1 -0
  13. data/exe/linear-cli +8 -1
  14. data/exe/{lc.sh → scripts/lc.sh} +4 -3
  15. data/exe/scripts/lcls.sh +2 -0
  16. data/exe/scripts/lcomment.sh +2 -0
  17. data/lib/linear/api.rb +1 -1
  18. data/lib/linear/cli/caller.rb +6 -1
  19. data/lib/linear/cli/sub_commands.rb +5 -59
  20. data/lib/linear/cli/version.rb +1 -1
  21. data/lib/linear/cli/what_for.rb +143 -0
  22. data/lib/linear/cli.rb +8 -1
  23. data/lib/linear/commands/issue/create.rb +1 -0
  24. data/lib/linear/commands/issue/pr.rb +38 -0
  25. data/lib/linear/commands/issue/update.rb +21 -6
  26. data/lib/linear/commands/issue.rb +54 -21
  27. data/lib/linear/models/base_model/class_methods.rb +129 -0
  28. data/lib/linear/models/base_model/method_magic.rb +23 -0
  29. data/lib/linear/models/base_model.rb +9 -108
  30. data/lib/linear/models/issue/class_methods.rb +44 -0
  31. data/lib/linear/models/issue.rb +23 -38
  32. data/lib/linear/models/project.rb +47 -0
  33. data/lib/linear/models/team.rb +6 -9
  34. data/lib/linear.rb +8 -0
  35. data/linear-cli.gemspec +2 -1
  36. metadata +33 -10
  37. data/exe/lclose +0 -4
  38. data/exe/lcls +0 -4
  39. data/exe/lcls.sh +0 -2
  40. data/exe/lcreate +0 -4
  41. /data/exe/{lclose.sh → scripts/lclose.sh} +0 -0
  42. /data/exe/{lcreate.sh → scripts/lcreate.sh} +0 -0
@@ -0,0 +1,129 @@
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 setter!(relation, klass)
9
+ define_method "#{relation}=" do |val|
10
+ hash = val.is_a?(Hash) ? val : val.updated_data
11
+ updated_data[relation] = hash
12
+ instance_variable_set("@#{relation}", Rubyists::Linear.const_get(klass).new(hash))
13
+ end
14
+ end
15
+
16
+ def getter!(relation)
17
+ define_method relation do
18
+ return instance_variable_get("@#{relation}") if instance_variable_defined?("@#{relation}")
19
+
20
+ return unless (val = updated_data[relation])
21
+
22
+ send("#{relation}=", val)
23
+ end
24
+ end
25
+
26
+ def many_to_one(relation, klass = nil)
27
+ klass ||= relation.to_s.camelize.to_sym
28
+ getter! relation
29
+ setter! relation, klass
30
+ end
31
+
32
+ alias one_to_one many_to_one
33
+
34
+ def many_setter!(relation, klass)
35
+ define_method "#{relation}=" do |val|
36
+ vals = if val&.key?(:nodes)
37
+ val[:nodes]
38
+ else
39
+ Array(val)
40
+ end
41
+ updated_data[relation] = vals.map { |v| v.is_a?(Hash) ? v : v.updated_data }
42
+ new_relations = vals.map { |v| v.is_a?(Hash) ? Rubyists::Linear.const_get(klass).new(v) : v }
43
+ instance_variable_set("@#{relation}", new_relations)
44
+ end
45
+ end
46
+
47
+ def one_to_many(relation, klass = nil)
48
+ klass ||= relation.to_s.singularize.camelize.to_sym
49
+ getter! relation
50
+ many_setter! relation, klass
51
+ end
52
+
53
+ def find(id_val)
54
+ camel_name = just_name.camelize :lower
55
+ ff = full_fragment
56
+ query_data = Api.query(query { __node(camel_name, id: id_val) { ___ ff } })
57
+ new query_data[camel_name.to_sym]
58
+ end
59
+
60
+ def const_added(const)
61
+ return unless const == :Base
62
+
63
+ include MethodMagic
64
+ end
65
+
66
+ def allq(filter: nil, limit: 50, after: nil)
67
+ args = { first: limit }
68
+ args[:filter] = filter ? basic_filter.merge(filter) : basic_filter
69
+ args.delete(:filter) if args[:filter].empty?
70
+ args[:after] = after if after
71
+ all_query args, plural.to_s, base_fragment
72
+ end
73
+
74
+ def all_query(args, subject, base_fragment)
75
+ query do
76
+ __node(subject, args) do
77
+ edges do
78
+ node { ___ base_fragment }
79
+ cursor
80
+ end
81
+ ___ Fragments::PageInfo
82
+ end
83
+ end
84
+ end
85
+
86
+ def just_name
87
+ name.split('::').last
88
+ end
89
+
90
+ def base_fragment
91
+ const_get(:Base)
92
+ end
93
+
94
+ def full_fragment
95
+ base_fragment
96
+ end
97
+
98
+ def basic_filter
99
+ return const_get(:BASIC_FILTER) if const_defined?(:BASIC_FILTER)
100
+
101
+ {}
102
+ end
103
+
104
+ def plural
105
+ return const_get(:PLURAL) if const_defined?(:PLURAL)
106
+
107
+ just_name.downcase.pluralize.to_sym
108
+ end
109
+
110
+ def gql_query(filter: nil, after: nil)
111
+ Api.query(allq(filter:, after:))
112
+ end
113
+
114
+ def all(after: nil, filter: nil, max: 100)
115
+ edges = []
116
+ moar = true
117
+ while moar
118
+ data = gql_query(filter:, after:)
119
+ subjects = data[plural]
120
+ edges += subjects[:edges]
121
+ moar = false if edges.size >= max || !subjects[:pageInfo][:hasNextPage]
122
+ after = subjects[:pageInfo][:endCursor]
123
+ end
124
+ edges.map { |edge| new edge[:node] }
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,23 @@
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/AbcSize
9
+ base.instance_eval do
10
+ base.base_fragment.__nodes.each do |node|
11
+ sym = node.__name.to_sym
12
+ define_method(sym) { updated_data[sym] } unless instance_methods.include? sym
13
+ esym = :"#{sym}="
14
+ next if instance_methods.include? esym
15
+
16
+ define_method(esym) { |value| updated_data[sym] = value }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,120 +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 find(id_val)
53
- camel_name = just_name.camelize :lower
54
- bf = base_fragment
55
- query_data = Api.query(query { __node(camel_name, id: id_val) { ___ bf } })
56
- new query_data[camel_name.to_sym]
57
- end
58
-
59
- def const_added(const)
60
- return unless const == :Base
61
-
62
- include MethodMagic
63
- end
64
-
65
- def allq(filter: nil, limit: 50, after: nil)
66
- args = { first: limit }
67
- args[:filter] = filter ? basic_filter.merge(filter) : basic_filter
68
- args.delete(:filter) if args[:filter].empty?
69
- args[:after] = after if after
70
- all_query args, plural.to_s, base_fragment
71
- end
72
-
73
- def all_query(args, subject, base_fragment)
74
- query do
75
- __node(subject, args) do
76
- edges do
77
- node { ___ base_fragment }
78
- cursor
79
- end
80
- ___ Fragments::PageInfo
81
- end
82
- end
83
- end
84
-
85
- def just_name
86
- name.split('::').last
87
- end
88
-
89
- def base_fragment
90
- const_get(:Base)
91
- end
92
-
93
- def basic_filter
94
- return const_get(:BASIC_FILTER) if const_defined?(:BASIC_FILTER)
95
-
96
- {}
97
- end
98
-
99
- def plural
100
- return const_get(:PLURAL) if const_defined?(:PLURAL)
101
-
102
- just_name.downcase.pluralize.to_sym
103
- end
104
-
105
- def gql_query(filter: nil, after: nil)
106
- Api.query(allq(filter:, after:))
107
- end
108
-
109
- def all(after: nil, filter: nil, max: 100)
110
- edges = []
111
- moar = true
112
- while moar
113
- data = gql_query(filter:, after:)
114
- subjects = data[plural]
115
- edges += subjects[:edges]
116
- moar = false if edges.size >= max || !subjects[:pageInfo][:hasNextPage]
117
- after = subjects[:pageInfo][:endCursor]
118
- end
119
- edges.map { |edge| new edge[:node] }
120
- end
121
- end
122
-
17
+ extend ClassMethods
123
18
  attr_reader :data, :updated_data
124
19
 
20
+ CANCELLED_STATES = %w[cancelled canceled].freeze
21
+
125
22
  def initialize(data)
126
23
  data.each_key { |k| raise SmellsBad, "Unknown key #{k}" unless respond_to? "#{k}=" }
127
24
  @data = data
@@ -136,6 +33,10 @@ module Rubyists
136
33
  workflow_states.select { |ws| ws.type == 'completed' }
137
34
  end
138
35
 
36
+ def cancelled_states
37
+ workflow_states.select { |ws| CANCELLED_STATES.include? ws.type }
38
+ end
39
+
139
40
  def to_h
140
41
  updated_data
141
42
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubyists
4
+ # Namespace for Linear
5
+ module Linear
6
+ M :user, :team
7
+ # The Issue class represents a Linear issue.
8
+ class Issue
9
+ # Class methods for Issue
10
+ module ClassMethods
11
+ def base_fragment
12
+ @base_fragment ||= fragment('BaseIssue', 'Issue') do
13
+ ___ Base
14
+ assignee { ___ User.base_fragment }
15
+ team { ___ Team.base_fragment }
16
+ end
17
+ end
18
+
19
+ def full_fragment
20
+ @full_fragment ||= fragment('FullIssue', 'Issue') do
21
+ ___ Base
22
+ assignee { ___ User.full_fragment }
23
+ team { ___ Team.full_fragment }
24
+ end
25
+ end
26
+
27
+ def find_all(*slugs)
28
+ slugs.flatten.map { |slug| find(slug) }
29
+ end
30
+
31
+ def create(title:, description:, team:, project:, labels: [])
32
+ team_id = team.id
33
+ label_ids = labels.map(&:id)
34
+ input = { title:, description:, teamId: team_id }
35
+ input[:labelIds] = label_ids unless label_ids.empty?
36
+ input[:projectId] = project.id if project
37
+ m = mutation { issueCreate(input:) { issue { ___ Issue.base_fragment } } }
38
+ query_data = Api.query(m)
39
+ new query_data.dig(:issueCreate, :issue)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -5,13 +5,15 @@ require 'gqli'
5
5
  module Rubyists
6
6
  # Namespace for Linear
7
7
  module Linear
8
- M :base_model, :user
8
+ M :base_model
9
9
  Issue = Class.new(BaseModel)
10
+ M 'issue/class_methods'
10
11
  # The Issue class represents a Linear issue.
11
- class Issue # rubocop:disable Metrics/ClassLength
12
+ class Issue
12
13
  include SemanticLogger::Loggable
13
- one_to_one :assignee, :User
14
- one_to_one :team, :Team
14
+ extend ClassMethods
15
+ many_to_one :assignee, :User
16
+ many_to_one :team, :Team
15
17
 
16
18
  BASIC_FILTER = { completedAt: { null: true } }.freeze
17
19
 
@@ -25,38 +27,6 @@ module Rubyists
25
27
  updatedAt
26
28
  end
27
29
 
28
- class << self
29
- def base_fragment
30
- @base_fragment ||= fragment('IssueWithTeams', 'Issue') do
31
- ___ Base
32
- assignee { ___ User.base_fragment }
33
- team { ___ Team.base_fragment }
34
- end
35
- end
36
-
37
- def find(slug)
38
- q = query { issue(id: slug) { ___ Issue.base_fragment } }
39
- data = Api.query(q)
40
- raise NotFoundError, "Issue not found: #{slug}" if data.nil?
41
-
42
- new(data[:issue])
43
- end
44
-
45
- def find_all(*slugs)
46
- slugs.flatten.map { |slug| find(slug) }
47
- end
48
-
49
- def create(title:, description:, team:, labels: [])
50
- team_id = team.id
51
- label_ids = labels.map(&:id)
52
- input = { title:, description:, teamId: team_id }
53
- input[:labelIds] = label_ids unless label_ids.empty?
54
- m = mutation { issueCreate(input:) { issue { ___ Issue.base_fragment } } }
55
- query_data = Api.query(m)
56
- new query_data.dig(:issueCreate, :issue)
57
- end
58
- end
59
-
60
30
  def comment_fragment
61
31
  @comment_fragment ||= fragment('Comment', 'Comment') do
62
32
  id
@@ -65,6 +35,21 @@ module Rubyists
65
35
  end
66
36
  end
67
37
 
38
+ def update!(input)
39
+ id_for_this = identifier
40
+ m = mutation { issueUpdate(id: id_for_this, input:) { issue { ___ Issue.full_fragment } } }
41
+ query_data = Api.query(m)
42
+ updated = query_data.dig(:issueUpdate, :issue)
43
+ raise SmellsBad, "Unknown response for issue update: #{data} (should have :issueUpdate key)" if updated.nil?
44
+
45
+ @data = @updated_data = updated
46
+ self
47
+ end
48
+
49
+ def attach_to_project(project)
50
+ update!({ projectId: project.id })
51
+ end
52
+
68
53
  # Reference for this mutation:
69
54
  # https://studio.apollographql.com/public/Linear-API/variant/current/schema/reference/inputs/CommentCreateInput
70
55
  def add_comment(comment)
@@ -81,7 +66,7 @@ module Rubyists
81
66
  id_for_this = identifier
82
67
  input = { stateId: close_state.id }
83
68
  input[:trash] = true if trash
84
- mutation { issueUpdate(id: id_for_this, input:) { issue { ___ Issue.base_fragment } } }
69
+ mutation { issueUpdate(id: id_for_this, input:) { issue { ___ Issue.full_fragment } } }
85
70
  end
86
71
 
87
72
  def close!(state: nil, trash: false)
@@ -97,7 +82,7 @@ module Rubyists
97
82
 
98
83
  def assign!(user)
99
84
  this_id = identifier
100
- m = mutation { issueUpdate(id: this_id, input: { assigneeId: user.id }) { issue { ___ Issue.base_fragment } } }
85
+ m = mutation { issueUpdate(id: this_id, input: { assigneeId: user.id }) { issue { ___ Issue.full_fragment } } }
101
86
  query_data = Api.query(m)
102
87
  updated = query_data.dig(:issueUpdate, :issue)
103
88
  raise SmellsBad, "Unknown response for issue update: #{data} (should have :issueUpdate key)" if updated.nil?
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gqli'
4
+
5
+ module Rubyists
6
+ # Namespace for Linear
7
+ module Linear
8
+ M :base_model
9
+ Project = Class.new(BaseModel)
10
+ # The Project class represents a Linear workflow state.
11
+ class Project
12
+ include SemanticLogger::Loggable
13
+
14
+ Base = fragment('BaseProject', 'Project') do
15
+ id
16
+ name
17
+ content
18
+ slugId
19
+ description
20
+ url
21
+ createdAt
22
+ updatedAt
23
+ end
24
+
25
+ def slug
26
+ File.basename(url).sub("-#{slugId}", '')
27
+ end
28
+
29
+ def match_score?(string)
30
+ downed = string.downcase
31
+ return 100 if downed.split.join('-') == slug || downed == name.downcase
32
+ return 75 if name.include?(string) || slug.include?(downed)
33
+ return 50 if description.downcase.include?(downed)
34
+
35
+ 0
36
+ end
37
+
38
+ def to_s
39
+ format('%<name>-12s %<url>s', name:, url:)
40
+ end
41
+
42
+ def inspection
43
+ format('name: "%<name>s" type: "%<url>s"', name:, url:)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -5,11 +5,12 @@ require 'gqli'
5
5
  module Rubyists
6
6
  # Namespace for Linear
7
7
  module Linear
8
- M :base_model, :issue, :user, :workflow_state
8
+ M :base_model, :issue, :project, :workflow_state, :user
9
9
  Team = Class.new(BaseModel)
10
10
  # The Issue class represents a Linear issue.
11
11
  class Team
12
12
  include SemanticLogger::Loggable
13
+ one_to_many :projects
13
14
 
14
15
  # TODO: Make this configurable
15
16
  BaseFilter = { # rubocop:disable Naming/ConstantName
@@ -29,15 +30,11 @@ module Rubyists
29
30
  updatedAt
30
31
  end
31
32
 
32
- def self.find(key)
33
- q = query do
34
- team(id: key) { ___ Base }
33
+ def self.full_fragment
34
+ @full_fragment ||= fragment('WholeTeam', 'Team') do
35
+ ___ Base
36
+ projects { nodes { ___ Project.base_fragment } }
35
37
  end
36
- data = Api.query(q)
37
- hash = data[:team]
38
- raise NotFoundError, "Team not found: #{key}" unless hash
39
-
40
- new hash
41
38
  end
42
39
 
43
40
  def self.mine
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
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  end
30
30
  end
31
31
  spec.bindir = 'exe'
32
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }.reject { |f| f.end_with?('.sh') }
33
33
  spec.require_paths = ['lib']
34
34
 
35
35
  # Uncomment to register a new dependency of your gem
@@ -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
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linear-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.7.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tj (bougyman) Vanderpoel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-05 00:00:00.000000000 Z
11
+ date: 2024-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -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
@@ -183,13 +197,10 @@ email:
183
197
  - tj@rubyists.com
184
198
  executables:
185
199
  - lc
186
- - lc.sh
187
200
  - lclose
188
- - lclose.sh
189
201
  - lcls
190
- - lcls.sh
202
+ - lcomment
191
203
  - lcreate
192
- - lcreate.sh
193
204
  - linear-cli
194
205
  extensions: []
195
206
  extra_rdoc_files: []
@@ -219,17 +230,23 @@ files:
219
230
  - changelog/0.7.3/tag.yml
220
231
  - changelog/0.7.5/fixed_problem_when_choosing_from_multiple_completed_states.yml
221
232
  - changelog/0.7.5/tag.yml
233
+ - changelog/0.7.7/added_ability_to_attach_project_to_command.yml
234
+ - changelog/0.7.7/added_issue_pr_command.yml
235
+ - changelog/0.7.7/added_lcomment_alias_to_add_comments_to_issues.yml
236
+ - changelog/0.7.7/tag.yml
222
237
  - changelog/unreleased/.gitkeep
223
238
  - cinemas/listings.cinema
224
239
  - exe/lc
225
- - exe/lc.sh
226
240
  - exe/lclose
227
- - exe/lclose.sh
228
241
  - exe/lcls
229
- - exe/lcls.sh
242
+ - exe/lcomment
230
243
  - exe/lcreate
231
- - exe/lcreate.sh
232
244
  - exe/linear-cli
245
+ - exe/scripts/lc.sh
246
+ - exe/scripts/lclose.sh
247
+ - exe/scripts/lcls.sh
248
+ - exe/scripts/lcomment.sh
249
+ - exe/scripts/lcreate.sh
233
250
  - lib/linear.rb
234
251
  - lib/linear/api.rb
235
252
  - lib/linear/cli.rb
@@ -238,10 +255,12 @@ files:
238
255
  - lib/linear/cli/sub_commands.rb
239
256
  - lib/linear/cli/version.rb
240
257
  - lib/linear/cli/watcher.rb
258
+ - lib/linear/cli/what_for.rb
241
259
  - lib/linear/commands/issue.rb
242
260
  - lib/linear/commands/issue/create.rb
243
261
  - lib/linear/commands/issue/develop.rb
244
262
  - lib/linear/commands/issue/list.rb
263
+ - lib/linear/commands/issue/pr.rb
245
264
  - lib/linear/commands/issue/take.rb
246
265
  - lib/linear/commands/issue/update.rb
247
266
  - lib/linear/commands/team.rb
@@ -250,8 +269,12 @@ files:
250
269
  - lib/linear/exceptions.rb
251
270
  - lib/linear/fragments.rb
252
271
  - lib/linear/models/base_model.rb
272
+ - lib/linear/models/base_model/class_methods.rb
273
+ - lib/linear/models/base_model/method_magic.rb
253
274
  - lib/linear/models/issue.rb
275
+ - lib/linear/models/issue/class_methods.rb
254
276
  - lib/linear/models/label.rb
277
+ - lib/linear/models/project.rb
255
278
  - lib/linear/models/team.rb
256
279
  - lib/linear/models/user.rb
257
280
  - lib/linear/models/workflow_state.rb
data/exe/lclose DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- exec File.join(__dir__, 'lclose.sh'), *ARGV
data/exe/lcls DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- exec File.join(__dir__, 'lcls.sh'), *ARGV
data/exe/lcls.sh DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env bash
2
- exec linear-cli issue list "$@"
data/exe/lcreate DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- exec File.join(__dir__, 'lcreate.sh'), *ARGV
File without changes
File without changes