linear-cli 0.7.5 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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