checkoff 0.227.0 → 0.229.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.
- checksums.yaml +4 -4
- data/checkoff.gemspec +7 -7
- data/lib/checkoff/cli.rb +71 -1
- data/lib/checkoff/clients.rb +1 -1
- data/lib/checkoff/custom_fields.rb +3 -3
- data/lib/checkoff/events.rb +3 -3
- data/lib/checkoff/internal/asana_event_enrichment.rb +13 -14
- data/lib/checkoff/internal/config_loader.rb +4 -2
- data/lib/checkoff/internal/logging.rb +3 -0
- data/lib/checkoff/internal/project_selector_evaluator.rb +5 -2
- data/lib/checkoff/internal/project_timing.rb +0 -2
- data/lib/checkoff/internal/search_url/custom_field_param_converter.rb +12 -12
- data/lib/checkoff/internal/search_url/custom_field_variant.rb +19 -18
- data/lib/checkoff/internal/search_url/date_param_converter.rb +9 -9
- data/lib/checkoff/internal/search_url/parser.rb +20 -30
- data/lib/checkoff/internal/search_url/results_merger.rb +4 -6
- data/lib/checkoff/internal/search_url/simple_param_converter.rb +19 -11
- data/lib/checkoff/internal/section_selector_evaluator.rb +7 -3
- data/lib/checkoff/internal/selector_classes/common/function_evaluator.rb +3 -2
- data/lib/checkoff/internal/selector_classes/common.rb +5 -6
- data/lib/checkoff/internal/selector_classes/function_evaluator.rb +2 -3
- data/lib/checkoff/internal/selector_classes/project/function_evaluator.rb +3 -2
- data/lib/checkoff/internal/selector_classes/section/function_evaluator.rb +2 -2
- data/lib/checkoff/internal/selector_classes/section.rb +2 -2
- data/lib/checkoff/internal/selector_classes/task/function_evaluator.rb +3 -2
- data/lib/checkoff/internal/selector_classes/task.rb +1 -2
- data/lib/checkoff/internal/selector_evaluator.rb +2 -2
- data/lib/checkoff/internal/task_hashes.rb +3 -3
- data/lib/checkoff/internal/task_selector_evaluator.rb +3 -0
- data/lib/checkoff/internal/task_timing.rb +0 -2
- data/lib/checkoff/internal/thread_local.rb +5 -4
- data/lib/checkoff/my_tasks.rb +4 -4
- data/lib/checkoff/portfolios.rb +1 -1
- data/lib/checkoff/project_selectors.rb +4 -4
- data/lib/checkoff/projects.rb +6 -6
- data/lib/checkoff/resources.rb +5 -3
- data/lib/checkoff/section_selectors.rb +4 -4
- data/lib/checkoff/sections.rb +18 -15
- data/lib/checkoff/subtasks.rb +2 -2
- data/lib/checkoff/tags.rb +7 -3
- data/lib/checkoff/task_searches.rb +9 -9
- data/lib/checkoff/task_selectors.rb +10 -6
- data/lib/checkoff/tasks.rb +5 -5
- data/lib/checkoff/timelines.rb +0 -1
- data/lib/checkoff/timing.rb +5 -4
- data/lib/checkoff/version.rb +1 -1
- data/lib/checkoff/workspaces.rb +1 -1
- data/rbi/checkoff.rbi +342 -305
- data/sig/checkoff.rbs +327 -279
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f57a81625b3c25ed144505d114057cd46d6282436a8a44e5b597b75b35938fc
|
4
|
+
data.tar.gz: f48a21ca0f749f54111e0e38c6d0b410a322a5a5ab5172f3a8e3a2099cffce89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8f4325f1043ea9478fe19fbeaa640aca3b6aa017761a1e97cfedba663a2d4e3c94aa67c562a7f12d0b7d72953bf1e96351486620b3016c810f56a3fdd1f6c4b
|
7
|
+
data.tar.gz: 363ead40190b064f57cd0eee22de909c00960667aa6dfcf23aca938f406375a61983c731fcf6d9929892ee69327aefcbbf2cf70663bedbc8aff67fb297de3ec6
|
data/checkoff.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.summary = 'Command-line and gem client for Asana (unofficial)'
|
14
14
|
spec.homepage = 'https://github.com/apiology/checkoff'
|
15
15
|
spec.license = 'MIT license'
|
16
|
-
spec.required_ruby_version = '>= 3.
|
16
|
+
spec.required_ruby_version = '>= 3.2'
|
17
17
|
|
18
18
|
spec.files = Dir['README.md',
|
19
19
|
'Rakefile',
|
@@ -29,12 +29,12 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ['lib']
|
31
31
|
|
32
|
-
spec.
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
spec.
|
36
|
-
spec.
|
37
|
-
spec.
|
32
|
+
spec.add_dependency 'activesupport'
|
33
|
+
spec.add_dependency 'asana', '>0.10.0'
|
34
|
+
spec.add_dependency 'cache_method'
|
35
|
+
spec.add_dependency 'gli'
|
36
|
+
spec.add_dependency 'mime-types'
|
37
|
+
spec.add_dependency 'sorbet-runtime'
|
38
38
|
|
39
39
|
spec.metadata = {
|
40
40
|
'rubygems_mfa_required' => 'false',
|
data/lib/checkoff/cli.rb
CHANGED
@@ -14,6 +14,10 @@ require_relative 'sections'
|
|
14
14
|
module Checkoff
|
15
15
|
# Move tasks from one place to another
|
16
16
|
class MvSubcommand
|
17
|
+
# @param from_workspace_arg [Symbol,String]
|
18
|
+
# @param from_project_arg [Symbol,String]
|
19
|
+
# @param from_section_arg [nil,String]
|
20
|
+
# @return [void]
|
17
21
|
def validate_and_assign_from_location(from_workspace_arg, from_project_arg, from_section_arg)
|
18
22
|
if from_workspace_arg == :default_workspace
|
19
23
|
# Figure out what to do here - we accept a default
|
@@ -28,6 +32,9 @@ module Checkoff
|
|
28
32
|
@from_section_name = from_section_arg
|
29
33
|
end
|
30
34
|
|
35
|
+
# @param to_project_arg [Symbol, String]
|
36
|
+
#
|
37
|
+
# @return [String, Symbol]
|
31
38
|
def create_to_project_name(to_project_arg)
|
32
39
|
if to_project_arg == :source_project
|
33
40
|
from_project_name
|
@@ -36,6 +43,9 @@ module Checkoff
|
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
46
|
+
# @param to_section_arg [Symbol, String, nil] :source_section
|
47
|
+
#
|
48
|
+
# @return [nil, String, Symbol]
|
39
49
|
def create_to_section_name(to_section_arg)
|
40
50
|
if to_section_arg == :source_section
|
41
51
|
from_section_name
|
@@ -44,6 +54,10 @@ module Checkoff
|
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
57
|
+
# @param to_workspace_arg [Symbol, String]
|
58
|
+
# @param to_project_arg [Symbol, String]
|
59
|
+
# @param to_section_arg [Symbol, String, nil] :source_section
|
60
|
+
# @return [void]
|
47
61
|
def validate_and_assign_to_location(to_workspace_arg, to_project_arg, to_section_arg)
|
48
62
|
@to_workspace_name = to_workspace_arg
|
49
63
|
@to_workspace_name = from_workspace_name if to_workspace_arg == :source_workspace
|
@@ -55,6 +69,17 @@ module Checkoff
|
|
55
69
|
raise NotImplementedError, 'Not implemented: Teach me how to move tasks between workspaces'
|
56
70
|
end
|
57
71
|
|
72
|
+
# @param from_workspace_arg [Symbol, String]
|
73
|
+
# @param from_project_arg [Symbol, String]
|
74
|
+
# @param from_section_arg [nil, String]
|
75
|
+
# @param to_workspace_arg [Symbol, String]
|
76
|
+
# @param to_project_arg [Symbol, String]
|
77
|
+
# @param to_section_arg [Symbol, String, nil] :source_section
|
78
|
+
# @param config [Checkoff::Internal::EnvFallbackConfigLoader, Hash]
|
79
|
+
# @param projects [Checkoff::Projects]
|
80
|
+
# @param sections [Checkoff::Sections]
|
81
|
+
# @param logger [IO]
|
82
|
+
# @return [void]
|
58
83
|
def initialize(from_workspace_arg:,
|
59
84
|
from_project_arg:,
|
60
85
|
from_section_arg:,
|
@@ -73,15 +98,23 @@ module Checkoff
|
|
73
98
|
@logger = logger
|
74
99
|
end
|
75
100
|
|
101
|
+
# @param tasks [Enumerable<Asana::Resources::Task>]
|
102
|
+
# @param to_project [Asana::Resources::Project]
|
103
|
+
# @param to_section [Asana::Resources::Section]
|
104
|
+
# @return [void]
|
76
105
|
def move_tasks(tasks, to_project, to_section)
|
77
106
|
tasks.each do |task|
|
78
|
-
# a. check if already in correct project and section (
|
107
|
+
# a. check if already in correct project and section (future)
|
79
108
|
# b. if not, put it there
|
80
109
|
@logger.puts "Moving #{task.name} to #{to_section.name}..."
|
81
110
|
task.add_project(project: to_project.gid, section: to_section.gid)
|
82
111
|
end
|
83
112
|
end
|
84
113
|
|
114
|
+
# @param from_workspace_name [String]
|
115
|
+
# @param from_project_name [String, Symbol]
|
116
|
+
# @param from_section_name [String, Symbol]
|
117
|
+
# @return [Enumerable<Asana::Resources::Task>]
|
85
118
|
def fetch_tasks(from_workspace_name, from_project_name, from_section_name)
|
86
119
|
if from_section_name == :all_sections
|
87
120
|
raise NotImplementedError, 'Not implemented: Teach me how to move all sections of a project'
|
@@ -90,6 +123,7 @@ module Checkoff
|
|
90
123
|
sections.tasks(from_workspace_name, from_project_name, from_section_name)
|
91
124
|
end
|
92
125
|
|
126
|
+
# @return [void]
|
93
127
|
def run
|
94
128
|
# 0. Look up project and section gids
|
95
129
|
to_project = projects.project_or_raise(to_workspace_name, to_project_name)
|
@@ -109,6 +143,8 @@ module Checkoff
|
|
109
143
|
:to_workspace_name, :to_project_name, :to_section_name,
|
110
144
|
:projects, :sections
|
111
145
|
|
146
|
+
# @param project_arg [String]
|
147
|
+
# @return [Symbol, String]
|
112
148
|
def project_arg_to_name(project_arg)
|
113
149
|
if project_arg.start_with? ':'
|
114
150
|
project_arg[1..].to_sym
|
@@ -120,6 +156,15 @@ module Checkoff
|
|
120
156
|
|
121
157
|
# CLI subcommand that shows tasks in JSON form
|
122
158
|
class ViewSubcommand
|
159
|
+
# @param workspace_name [String]
|
160
|
+
# @param project_name [String, Symbol]
|
161
|
+
# @param section_name [String, Symbol, nil]
|
162
|
+
# @param task_name [String, Symbol, nil]
|
163
|
+
# @param config [Checkoff::Internal::EnvFallbackConfigLoader, Hash]
|
164
|
+
# @param projects [Checkoff::Projects]
|
165
|
+
# @param sections [Checkoff::Sections]
|
166
|
+
# @param tasks [Checkoff::Tasks]
|
167
|
+
# @param stderr [IO]
|
123
168
|
def initialize(workspace_name, project_name, section_name,
|
124
169
|
task_name,
|
125
170
|
config: Checkoff::Internal::ConfigLoader.load(:asana),
|
@@ -138,6 +183,7 @@ module Checkoff
|
|
138
183
|
@tasks = tasks
|
139
184
|
end
|
140
185
|
|
186
|
+
# @return [void]
|
141
187
|
def run
|
142
188
|
if section_name.nil?
|
143
189
|
run_on_project(workspace_name, project_name)
|
@@ -150,6 +196,8 @@ module Checkoff
|
|
150
196
|
|
151
197
|
private
|
152
198
|
|
199
|
+
# @param project_name [String]
|
200
|
+
# @return [String, Symbol]
|
153
201
|
def validate_and_assign_project_name(project_name)
|
154
202
|
@project_name = if project_name.start_with? ':'
|
155
203
|
project_name[1..].to_sym
|
@@ -158,6 +206,9 @@ module Checkoff
|
|
158
206
|
end
|
159
207
|
end
|
160
208
|
|
209
|
+
# @param workspace [String, Symbol]
|
210
|
+
# @param project [String, Symbol]
|
211
|
+
# @return [String]
|
161
212
|
def run_on_project(workspace, project)
|
162
213
|
tasks_by_section =
|
163
214
|
sections.tasks_by_section(workspace, project)
|
@@ -167,18 +218,29 @@ module Checkoff
|
|
167
218
|
tasks_by_section.to_json
|
168
219
|
end
|
169
220
|
|
221
|
+
# @param workspace [String, Symbol]
|
222
|
+
# @param project [String, Symbol]
|
223
|
+
# @param section [String, Symbol, nil]
|
224
|
+
# @return [String]
|
170
225
|
def run_on_section(workspace, project, section)
|
171
226
|
section = nil if section == ''
|
172
227
|
tasks = sections.tasks(workspace, project, section) || []
|
173
228
|
tasks_to_hash(tasks).to_json
|
174
229
|
end
|
175
230
|
|
231
|
+
# @param workspace [String, Symbol]
|
232
|
+
# @param project [String, Symbol]
|
233
|
+
# @param section [String, Symbol, nil]
|
234
|
+
# @param task_name [String]
|
235
|
+
# @return [String]
|
176
236
|
def run_on_task(workspace, project, section, task_name)
|
177
237
|
section = nil if section == ''
|
178
238
|
task = tasks.task(workspace, project, task_name, section_name: section)
|
179
239
|
task_to_hash(task).to_json
|
180
240
|
end
|
181
241
|
|
242
|
+
# @param task [Asana::Resources::Task]
|
243
|
+
# @return [Hash{Symbol => undefined}]
|
182
244
|
def task_to_hash(task)
|
183
245
|
task_out = {
|
184
246
|
name: task.name,
|
@@ -191,6 +253,8 @@ module Checkoff
|
|
191
253
|
task_out
|
192
254
|
end
|
193
255
|
|
256
|
+
# @param tasks [Enumerable<Asana::Resources::Task>]
|
257
|
+
# @return [Array<Hash>]
|
194
258
|
def tasks_to_hash(tasks)
|
195
259
|
tasks.map { |task| task_to_hash(task) }
|
196
260
|
end
|
@@ -200,6 +264,11 @@ module Checkoff
|
|
200
264
|
|
201
265
|
# CLI subcommand that creates a task
|
202
266
|
class QuickaddSubcommand
|
267
|
+
# @param workspace_name [String]
|
268
|
+
# @param task_name [String]
|
269
|
+
# @param config [Internal::EnvFallbackConfigLoader, Hash]
|
270
|
+
# @param workspaces [Checkoff::Workspaces]
|
271
|
+
# @param tasks [Checkoff::Tasks]
|
203
272
|
def initialize(workspace_name, task_name,
|
204
273
|
config: Checkoff::Internal::ConfigLoader.load(:asana),
|
205
274
|
workspaces: Checkoff::Workspaces.new(config:),
|
@@ -210,6 +279,7 @@ module Checkoff
|
|
210
279
|
@tasks = tasks
|
211
280
|
end
|
212
281
|
|
282
|
+
# @return [void]
|
213
283
|
def run
|
214
284
|
workspace = @workspaces.workspace_or_raise(workspace_name)
|
215
285
|
@tasks.add_task(task_name,
|
data/lib/checkoff/clients.rb
CHANGED
@@ -19,7 +19,7 @@ module Checkoff
|
|
19
19
|
LONG_CACHE_TIME = MINUTE * 15
|
20
20
|
SHORT_CACHE_TIME = MINUTE
|
21
21
|
|
22
|
-
# @param config [Checkoff::Internal::EnvFallbackConfigLoader]
|
22
|
+
# @param config [Hash, Checkoff::Internal::EnvFallbackConfigLoader]
|
23
23
|
# @param asana_client_class [Class<Asana::Client>]
|
24
24
|
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
25
25
|
asana_client_class: Asana::Client)
|
@@ -24,7 +24,7 @@ module Checkoff
|
|
24
24
|
LONG_CACHE_TIME = MINUTE * 15
|
25
25
|
SHORT_CACHE_TIME = MINUTE
|
26
26
|
|
27
|
-
# @param config [Checkoff::Internal::EnvFallbackConfigLoader]
|
27
|
+
# @param config [Hash, Checkoff::Internal::EnvFallbackConfigLoader]
|
28
28
|
# @param workspaces [Checkoff::Workspaces]
|
29
29
|
# @param clients [Checkoff::Clients]
|
30
30
|
# @param client [Asana::Client]
|
@@ -93,7 +93,7 @@ module Checkoff
|
|
93
93
|
end
|
94
94
|
|
95
95
|
# @sg-ignore
|
96
|
-
# @param
|
96
|
+
# @param resource [Asana::Resources::Task,Asana::Resources::Project]
|
97
97
|
# @param custom_field_name [String]
|
98
98
|
# @return [Hash, nil]
|
99
99
|
def resource_custom_field_by_name(resource, custom_field_name)
|
@@ -144,7 +144,7 @@ module Checkoff
|
|
144
144
|
|
145
145
|
private
|
146
146
|
|
147
|
-
# @param custom_field [Hash{String =>
|
147
|
+
# @param custom_field [Hash{String => Hash,Array<Hash>}]
|
148
148
|
#
|
149
149
|
# @sg-ignore
|
150
150
|
# @return [Array<Hash>]
|
data/lib/checkoff/events.rb
CHANGED
@@ -33,7 +33,7 @@ module Checkoff
|
|
33
33
|
SHORT_CACHE_TIME = MINUTE
|
34
34
|
private_constant :SHORT_CACHE_TIME
|
35
35
|
|
36
|
-
# @param config [Checkoff::Internal::EnvFallbackConfigLoader]
|
36
|
+
# @param config [Checkoff::Internal::EnvFallbackConfigLoader,Hash]
|
37
37
|
# @param workspaces [Checkoff::Workspaces]
|
38
38
|
# @param tasks [Checkoff::Tasks]
|
39
39
|
# @param sections [Checkoff::Sections]
|
@@ -79,9 +79,9 @@ module Checkoff
|
|
79
79
|
asana_event_enrichment.enrich_event(asana_event)
|
80
80
|
end
|
81
81
|
|
82
|
-
# @param filter [Hash
|
82
|
+
# @param filter [Hash{String => String, Array<String>}]
|
83
83
|
#
|
84
|
-
# @return [Hash
|
84
|
+
# @return [Hash{String => String, Array<String>}]
|
85
85
|
def enrich_filter(filter)
|
86
86
|
asana_event_enrichment.enrich_filter(filter)
|
87
87
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'forwardable'
|
@@ -22,7 +22,6 @@ module Checkoff
|
|
22
22
|
# @param resources [Checkoff::Resources]
|
23
23
|
# @param clients [Checkoff::Clients]
|
24
24
|
# @param client [Asana::Client]
|
25
|
-
# @param asana_event_enrichment [Checkoff::Internal::AsanaEventEnrichment]
|
26
25
|
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
27
26
|
workspaces: Checkoff::Workspaces.new(config:),
|
28
27
|
tasks: Checkoff::Tasks.new(config:),
|
@@ -53,9 +52,9 @@ module Checkoff
|
|
53
52
|
asana_event
|
54
53
|
end
|
55
54
|
|
56
|
-
# @param filter [Hash
|
55
|
+
# @param filter [Hash{String => String, Array<String>}]
|
57
56
|
#
|
58
|
-
# @return [Hash
|
57
|
+
# @return [Hash{String => String, Array<String>}]
|
59
58
|
def enrich_filter(filter)
|
60
59
|
filter = filter.dup
|
61
60
|
enrich_filter_section!(filter)
|
@@ -64,7 +63,7 @@ module Checkoff
|
|
64
63
|
filter
|
65
64
|
end
|
66
65
|
|
67
|
-
# @param webhook_subscription [Hash] Hash of the request made to
|
66
|
+
# @param webhook_subscription [Hash, nil] Hash of the request made to
|
68
67
|
# webhook POST endpoint - https://app.asana.com/api/1.0/webhooks
|
69
68
|
# https://developers.asana.com/reference/createwebhook
|
70
69
|
#
|
@@ -88,27 +87,26 @@ module Checkoff
|
|
88
87
|
# @param gid [String]
|
89
88
|
# @param resource_type [String,nil]
|
90
89
|
#
|
91
|
-
# @return [Array
|
90
|
+
# @return [Array([String, nil], [String, nil])]
|
92
91
|
def enrich_gid(gid, resource_type: nil)
|
93
92
|
# @sg-ignore
|
94
93
|
resource, resource_type = resources.resource_by_gid(gid, resource_type:)
|
95
94
|
[resource&.name, resource_type]
|
96
95
|
end
|
97
96
|
|
98
|
-
# @param filter [Hash{String => String}]
|
97
|
+
# @param filter [Hash{String => String, Array<String>}]
|
99
98
|
#
|
100
99
|
# @return [String, nil]
|
101
100
|
def enrich_filter_parent_gid!(filter)
|
102
101
|
parent_gid = filter['checkoff:parent.gid']
|
103
102
|
return unless parent_gid
|
104
103
|
|
105
|
-
# @sg-ignore
|
106
104
|
name, resource_type = enrich_gid(parent_gid)
|
107
105
|
filter['checkoff:enriched:parent.name'] = name if name
|
108
106
|
filter['checkoff:enriched:parent.resource_type'] = resource_type if resource_type
|
109
107
|
end
|
110
108
|
|
111
|
-
# @param filter [Hash{String => String}]
|
109
|
+
# @param filter [Hash{String => String, Array<String>}]
|
112
110
|
#
|
113
111
|
# @return [void]
|
114
112
|
def enrich_filter_resource!(filter)
|
@@ -117,14 +115,15 @@ module Checkoff
|
|
117
115
|
return unless resource_gid
|
118
116
|
|
119
117
|
task = tasks.task_by_gid(resource_gid)
|
120
|
-
|
118
|
+
task_name = task&.name
|
119
|
+
filter['checkoff:enriched:resource.name'] = task_name if task_name
|
121
120
|
end
|
122
121
|
|
123
|
-
# @param filter [Hash{String =>
|
122
|
+
# @param filter [Hash{String => String, Array<String>}]
|
124
123
|
#
|
125
124
|
# @return [void]
|
126
125
|
def enrich_filter_section!(filter)
|
127
|
-
section_gid = filter['checkoff:fetched.section.gid']
|
126
|
+
section_gid = T.cast(filter['checkoff:fetched.section.gid'], T.nilable(String))
|
128
127
|
return unless section_gid
|
129
128
|
|
130
129
|
section = sections.section_by_gid(section_gid)
|
@@ -156,8 +155,8 @@ module Checkoff
|
|
156
155
|
#
|
157
156
|
# @return [void]
|
158
157
|
def enrich_event_resource!(asana_event)
|
159
|
-
# @type [Hash{String => String
|
160
|
-
resource = asana_event['resource']
|
158
|
+
# @type [Hash{String => String}]
|
159
|
+
resource = T.cast(asana_event['resource'], T::Hash[String, String])
|
161
160
|
# @type [String]
|
162
161
|
resource_type = resource.fetch('resource_type')
|
163
162
|
|
@@ -9,7 +9,7 @@ module Checkoff
|
|
9
9
|
# Use the provided config from a YAML file, and fall back to env
|
10
10
|
# variable if it's not populated for a key'
|
11
11
|
class EnvFallbackConfigLoader
|
12
|
-
# @param config [Hash
|
12
|
+
# @param config [Hash{Symbol => undefined}]
|
13
13
|
# @param sym [Symbol]
|
14
14
|
# @param yaml_filename [String]
|
15
15
|
def initialize(config, sym, yaml_filename)
|
@@ -50,6 +50,8 @@ module Checkoff
|
|
50
50
|
# Load configuration file
|
51
51
|
class ConfigLoader
|
52
52
|
class << self
|
53
|
+
# @param sym [Symbol]
|
54
|
+
#
|
53
55
|
# @return [EnvFallbackConfigLoader]
|
54
56
|
def load(sym)
|
55
57
|
yaml_result = load_yaml_file(sym)
|
@@ -59,7 +61,7 @@ module Checkoff
|
|
59
61
|
private
|
60
62
|
|
61
63
|
# @param sym [Symbol]
|
62
|
-
# @return [Hash
|
64
|
+
# @return [Hash{Symbol => undefined}]
|
63
65
|
def load_yaml_file(sym)
|
64
66
|
filename = yaml_filename(sym)
|
65
67
|
return {} unless File.exist?(filename)
|
@@ -5,11 +5,14 @@ require 'logger'
|
|
5
5
|
|
6
6
|
# include this to add ability to log at different levels
|
7
7
|
module Logging
|
8
|
+
# @sg-ignore
|
8
9
|
# @return [::Logger]
|
9
10
|
def logger
|
11
|
+
# @type [::Logger]
|
10
12
|
# @sg-ignore
|
11
13
|
@logger ||= if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
|
12
14
|
# @sg-ignore
|
15
|
+
# @type [::Logger]
|
13
16
|
Rails.logger
|
14
17
|
else
|
15
18
|
::Logger.new($stdout, level: log_level)
|
@@ -26,17 +26,20 @@ module Checkoff
|
|
26
26
|
super()
|
27
27
|
end
|
28
28
|
|
29
|
-
private
|
30
|
-
|
31
29
|
COMMON_FUNCTION_EVALUATORS = (Checkoff::SelectorClasses::Common.constants.map do |const|
|
32
30
|
Checkoff::SelectorClasses::Common.const_get(const)
|
33
31
|
end - [Checkoff::SelectorClasses::Common::FunctionEvaluator]).freeze
|
32
|
+
private_constant :COMMON_FUNCTION_EVALUATORS
|
34
33
|
|
35
34
|
PROJECT_FUNCTION_EVALUATORS = (Checkoff::SelectorClasses::Project.constants.map do |const|
|
36
35
|
Checkoff::SelectorClasses::Project.const_get(const)
|
37
36
|
end - [Checkoff::SelectorClasses::Project::FunctionEvaluator]).freeze
|
37
|
+
private_constant :PROJECT_FUNCTION_EVALUATORS
|
38
38
|
|
39
39
|
FUNCTION_EVALUTORS = (COMMON_FUNCTION_EVALUATORS + PROJECT_FUNCTION_EVALUATORS).freeze
|
40
|
+
private_constant :FUNCTION_EVALUTORS
|
41
|
+
|
42
|
+
private
|
40
43
|
|
41
44
|
# @return [Array<Class<Checkoff::SelectorClasses::Project::FunctionEvaluator>>]
|
42
45
|
def function_evaluators
|
@@ -20,7 +20,6 @@ module Checkoff
|
|
20
20
|
end
|
21
21
|
|
22
22
|
# @param project [Asana::Resources::Project]
|
23
|
-
# @param field_name [Symbol]
|
24
23
|
#
|
25
24
|
# @sg-ignore
|
26
25
|
# @return [Date, nil]
|
@@ -31,7 +30,6 @@ module Checkoff
|
|
31
30
|
end
|
32
31
|
|
33
32
|
# @param project [Asana::Resources::Project]
|
34
|
-
# @param field_name [Symbol]
|
35
33
|
#
|
36
34
|
# @sg-ignore
|
37
35
|
# @return [Date, nil]
|
@@ -10,16 +10,16 @@ module Checkoff
|
|
10
10
|
# Convert custom field parameters from an Asana search URL into
|
11
11
|
# API search arguments and Checkoff task selectors
|
12
12
|
class CustomFieldParamConverter
|
13
|
-
# @param custom_field_params [Hash
|
13
|
+
# @param custom_field_params [Hash{String => Array<String>}]
|
14
14
|
def initialize(custom_field_params:)
|
15
15
|
@custom_field_params = custom_field_params
|
16
16
|
end
|
17
17
|
|
18
|
-
# @return [Array(Hash
|
18
|
+
# @return [Array(Hash{String => String}, Array<Symbol, Array>)]
|
19
19
|
def convert
|
20
|
-
# @type args [Hash
|
20
|
+
# @type args [Hash{String => String}]
|
21
21
|
args = {}
|
22
|
-
# @type task_selector [Array<
|
22
|
+
# @type task_selector [Array<Symbol, Array>]
|
23
23
|
task_selector = []
|
24
24
|
by_custom_field.each do |gid, single_custom_field_params|
|
25
25
|
# @sg-ignore
|
@@ -37,14 +37,14 @@ module Checkoff
|
|
37
37
|
private
|
38
38
|
|
39
39
|
# @sg-ignore
|
40
|
-
# @return [Hash
|
40
|
+
# @return [Hash{String => Hash}]
|
41
41
|
def by_custom_field
|
42
42
|
custom_field_params.group_by do |key, _value|
|
43
43
|
gid_from_custom_field_key(key)
|
44
44
|
end.transform_values(&:to_h)
|
45
45
|
end
|
46
46
|
|
47
|
-
# @type [Hash
|
47
|
+
# @type [Hash{String => Class<CustomFieldVariant>}]
|
48
48
|
VARIANTS = {
|
49
49
|
'is' => CustomFieldVariant::Is,
|
50
50
|
'no_value' => CustomFieldVariant::NoValue,
|
@@ -57,22 +57,22 @@ module Checkoff
|
|
57
57
|
'contains_any' => CustomFieldVariant::ContainsAny,
|
58
58
|
'contains_all' => CustomFieldVariant::ContainsAll,
|
59
59
|
}.freeze
|
60
|
+
private_constant :VARIANTS
|
60
61
|
|
61
62
|
# @param gid [String]
|
62
|
-
# @param single_custom_field_params [Hash
|
63
|
+
# @param single_custom_field_params [Hash{String => Array<String>}]
|
63
64
|
# @sg-ignore
|
64
|
-
# @return [Array(Hash
|
65
|
+
# @return [Array(Hash{String => String}, Array<Symbol, Array>)]
|
65
66
|
def convert_single_custom_field_params(gid, single_custom_field_params)
|
66
67
|
variant_key = "custom_field_#{gid}.variant"
|
67
68
|
variant = single_custom_field_params.fetch(variant_key)
|
68
69
|
remaining_params = single_custom_field_params.reject { |k, _v| k == variant_key }
|
69
70
|
raise "Teach me how to handle #{variant_key} = #{variant}" unless variant.length == 1
|
70
71
|
|
71
|
-
# @
|
72
|
-
# @type variant_class [Class<CustomFieldVariant>]
|
72
|
+
# @type [Class<CustomFieldVariant>]
|
73
73
|
variant_class = VARIANTS[variant[0]]
|
74
|
-
# @type [Array(Hash<String, String>, Array<[Symbol, Array]>)]
|
75
74
|
# @sg-ignore
|
75
|
+
# @type [Array(Hash{String => String}, Array<Symbol, Array>)]
|
76
76
|
return variant_class.new(gid, remaining_params).convert unless variant_class.nil?
|
77
77
|
|
78
78
|
raise "Teach me how to handle #{variant_key} = #{variant}"
|
@@ -84,7 +84,7 @@ module Checkoff
|
|
84
84
|
key.split('_')[2].split('.')[0]
|
85
85
|
end
|
86
86
|
|
87
|
-
# @return [Hash
|
87
|
+
# @return [Hash{String => Array<String>}]
|
88
88
|
attr_reader :custom_field_params
|
89
89
|
end
|
90
90
|
end
|