linear_api 0.3.0

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.
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :linear do
4
+ desc 'Setup auto-tracking infrastructure (creates project and label in Linear)'
5
+ task setup: :environment do
6
+ puts 'Setting up Linear auto-tracking infrastructure...'
7
+
8
+ result = LinearApi::IssueTracker.setup!
9
+
10
+ if result[:project_id]
11
+ puts " ✓ Project 'Auto-Tracked Errors' ready (#{result[:project_id]})"
12
+ else
13
+ puts " ✗ Failed to create/find project"
14
+ end
15
+
16
+ if result[:label_id]
17
+ puts " ✓ Label 'auto:tracked' ready (#{result[:label_id]})"
18
+ else
19
+ puts " ✗ Failed to create/find label"
20
+ end
21
+
22
+ puts "\nSetup complete! Auto-tracked issues will be created in the 'Auto-Tracked Errors' project."
23
+ end
24
+
25
+ desc 'Sync all metadata from Linear API (labels, projects, states, users)'
26
+ task sync_cache: :environment do
27
+ puts 'Syncing Linear metadata from API...'
28
+
29
+ results = LinearApi::CacheSync.sync_all
30
+
31
+ results.each do |type, result|
32
+ if result[:success]
33
+ puts " ✓ #{type}: #{result[:count]} items synced"
34
+ else
35
+ puts " ✗ #{type}: #{result[:error]}"
36
+ end
37
+ end
38
+
39
+ puts "\nCache sync complete!"
40
+ puts "Total cached:"
41
+ puts " - #{LinearApi::CachedMetadata.labels.count} labels"
42
+ puts " - #{LinearApi::CachedMetadata.projects.count} projects"
43
+ puts " - #{LinearApi::CachedMetadata.states.count} states"
44
+ puts " - #{LinearApi::CachedMetadata.users.count} users"
45
+ end
46
+
47
+ desc 'Import labels/states/projects from linear.json (read-only reference data only)'
48
+ task import_json: :environment do
49
+ json_path = ENV['LINEAR_JSON_PATH'] || Rails.root.join('../linear.json')
50
+
51
+ unless File.exist?(json_path)
52
+ puts "Error: linear.json not found at #{json_path}"
53
+ puts 'Set LINEAR_JSON_PATH environment variable to specify a different path.'
54
+ exit 1
55
+ end
56
+
57
+ puts "Importing reference data from #{json_path}..."
58
+ puts "(This only imports labels, states, and users - not issues)"
59
+
60
+ counts = LinearApi::CacheSync.import_from_json(json_path)
61
+
62
+ puts "\nImport complete!"
63
+ puts " - #{counts[:labels]} labels"
64
+ puts " - #{counts[:projects]} projects (reference only)"
65
+ puts " - #{counts[:states]} states"
66
+ puts " - #{counts[:users]} users"
67
+ end
68
+
69
+ desc 'Export cached metadata to JSON file'
70
+ task export_cache: :environment do
71
+ output_path = ENV['LINEAR_EXPORT_PATH'] || Rails.root.join('linear_cache.json')
72
+
73
+ data = {
74
+ last_updated: Time.current.iso8601,
75
+ team: {
76
+ id: LinearApi.team_id,
77
+ key: 'TOS'
78
+ },
79
+ workflow_states: export_states,
80
+ labels: export_labels,
81
+ projects: export_projects,
82
+ users: export_users
83
+ }
84
+
85
+ File.write(output_path, JSON.pretty_generate(data))
86
+ puts "Exported cache to #{output_path}"
87
+ end
88
+
89
+ desc 'Refresh stale synced issues from Linear'
90
+ task refresh_issues: :environment do
91
+ stale_count = LinearApi::SyncedIssue.stale.count
92
+ puts "Refreshing #{stale_count} stale issues..."
93
+
94
+ LinearApi::SyncedIssue.refresh_stale_issues!
95
+
96
+ puts 'Done!'
97
+ end
98
+
99
+ desc 'Show cache statistics'
100
+ task stats: :environment do
101
+ puts 'Linear API Cache Statistics'
102
+ puts '=' * 40
103
+ puts "\nCached Metadata:"
104
+ puts " Labels: #{LinearApi::CachedMetadata.labels.count}"
105
+ puts " Projects: #{LinearApi::CachedMetadata.projects.count}"
106
+ puts " States: #{LinearApi::CachedMetadata.states.count}"
107
+ puts " Users: #{LinearApi::CachedMetadata.users.count}"
108
+
109
+ puts "\nSynced Issues:"
110
+ puts " Total: #{LinearApi::SyncedIssue.count}"
111
+ puts " Unresolved: #{LinearApi::SyncedIssue.unresolved.count}"
112
+ puts " Resolved: #{LinearApi::SyncedIssue.resolved.count}"
113
+ puts " Recent (7d): #{LinearApi::SyncedIssue.recent.count}"
114
+ puts " Stale: #{LinearApi::SyncedIssue.stale.count}"
115
+
116
+ puts "\nLabel Categories:"
117
+ LinearApi::CachedMetadata.labels.group(:category).count.each do |category, count|
118
+ puts " #{category || 'uncategorized'}: #{count}"
119
+ end
120
+ end
121
+
122
+ # Helper methods for export
123
+ def export_states
124
+ LinearApi::CachedMetadata.states.each_with_object({}) do |state, hash|
125
+ hash[state.key] = {
126
+ id: state.linear_id,
127
+ name: state.name,
128
+ type: state.state_type
129
+ }
130
+ end
131
+ end
132
+
133
+ def export_labels
134
+ LinearApi::CachedMetadata.labels.group_by(&:category).transform_values do |labels|
135
+ labels.each_with_object({}) do |label, hash|
136
+ key = label.key.split(':').last
137
+ hash[key] = {
138
+ id: label.linear_id,
139
+ name: label.name,
140
+ color: label.color
141
+ }
142
+ end
143
+ end
144
+ end
145
+
146
+ def export_projects
147
+ LinearApi::CachedMetadata.projects.each_with_object({}) do |project, hash|
148
+ hash[project.key] = {
149
+ id: project.linear_id,
150
+ name: project.name,
151
+ state: project.state_type
152
+ }
153
+ end
154
+ end
155
+
156
+ def export_users
157
+ LinearApi::CachedMetadata.users.each_with_object({}) do |user, hash|
158
+ hash[user.key] = {
159
+ id: user.linear_id,
160
+ name: user.name
161
+ }
162
+ end
163
+ end
164
+ end
metadata ADDED
@@ -0,0 +1,268 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: linear_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - TheOwnerStack
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '1.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '3.0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: rails
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '7.0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '7.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '2.0'
53
+ type: :development
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.0'
60
+ - !ruby/object:Gem::Dependency
61
+ name: dotenv
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '3.0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '3.0'
74
+ - !ruby/object:Gem::Dependency
75
+ name: factory_bot_rails
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '6.4'
81
+ type: :development
82
+ prerelease: false
83
+ version_requirements: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '6.4'
88
+ - !ruby/object:Gem::Dependency
89
+ name: rake
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '13.0'
95
+ type: :development
96
+ prerelease: false
97
+ version_requirements: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '13.0'
102
+ - !ruby/object:Gem::Dependency
103
+ name: rspec
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '3.12'
109
+ type: :development
110
+ prerelease: false
111
+ version_requirements: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '3.12'
116
+ - !ruby/object:Gem::Dependency
117
+ name: rspec-rails
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '6.1'
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '6.1'
130
+ - !ruby/object:Gem::Dependency
131
+ name: rubocop
132
+ requirement: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '1.50'
137
+ type: :development
138
+ prerelease: false
139
+ version_requirements: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '1.50'
144
+ - !ruby/object:Gem::Dependency
145
+ name: rubocop-rspec
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '2.20'
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '2.20'
158
+ - !ruby/object:Gem::Dependency
159
+ name: simplecov
160
+ requirement: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '0.22'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '0.22'
172
+ - !ruby/object:Gem::Dependency
173
+ name: sqlite3
174
+ requirement: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '2.1'
179
+ type: :development
180
+ prerelease: false
181
+ version_requirements: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '2.1'
186
+ - !ruby/object:Gem::Dependency
187
+ name: vcr
188
+ requirement: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - "~>"
191
+ - !ruby/object:Gem::Version
192
+ version: '6.0'
193
+ type: :development
194
+ prerelease: false
195
+ version_requirements: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - "~>"
198
+ - !ruby/object:Gem::Version
199
+ version: '6.0'
200
+ - !ruby/object:Gem::Dependency
201
+ name: webmock
202
+ requirement: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - "~>"
205
+ - !ruby/object:Gem::Version
206
+ version: '3.18'
207
+ type: :development
208
+ prerelease: false
209
+ version_requirements: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - "~>"
212
+ - !ruby/object:Gem::Version
213
+ version: '3.18'
214
+ description: A Ruby gem for interacting with the Linear project management API. Supports
215
+ creating, updating, and querying issues, projects, and labels. Includes a Rails
216
+ Engine for database-backed issue tracking and caching.
217
+ email:
218
+ - dev@theownerstack.com
219
+ executables: []
220
+ extensions: []
221
+ extra_rdoc_files: []
222
+ files:
223
+ - CHANGELOG.md
224
+ - LICENSE.txt
225
+ - README.md
226
+ - app/models/linear_api/application_record.rb
227
+ - app/models/linear_api/cached_metadata.rb
228
+ - app/models/linear_api/synced_issue.rb
229
+ - db/migrate/20260204000001_create_linear_api_cached_metadata.rb
230
+ - db/migrate/20260204000002_create_linear_api_synced_issues.rb
231
+ - lib/linear_api.rb
232
+ - lib/linear_api/cache_sync.rb
233
+ - lib/linear_api/client.rb
234
+ - lib/linear_api/engine.rb
235
+ - lib/linear_api/issue.rb
236
+ - lib/linear_api/issue_tracker.rb
237
+ - lib/linear_api/label.rb
238
+ - lib/linear_api/project.rb
239
+ - lib/linear_api/result.rb
240
+ - lib/linear_api/team.rb
241
+ - lib/linear_api/version.rb
242
+ - lib/tasks/linear_api.rake
243
+ homepage: https://github.com/dan1d/linear_api
244
+ licenses:
245
+ - MIT
246
+ metadata:
247
+ homepage_uri: https://github.com/dan1d/linear_api
248
+ source_code_uri: https://github.com/dan1d/linear_api
249
+ changelog_uri: https://github.com/dan1d/linear_api/blob/main/CHANGELOG.md
250
+ rubygems_mfa_required: 'true'
251
+ rdoc_options: []
252
+ require_paths:
253
+ - lib
254
+ required_ruby_version: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: 3.0.0
259
+ required_rubygems_version: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - ">="
262
+ - !ruby/object:Gem::Version
263
+ version: '0'
264
+ requirements: []
265
+ rubygems_version: 3.6.9
266
+ specification_version: 4
267
+ summary: Ruby client for the Linear GraphQL API with Rails Engine support
268
+ test_files: []