checkoff 0.41.0 → 0.43.0

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: ca8318553efc488d88a70b394e290ec8030f532ac9b3d4fa4fc67eb60849270a
4
- data.tar.gz: cd86cc76ca2f74bed8e35212da234f5cbcad358db6a08d181f702fda149e785a
3
+ metadata.gz: af9b4c58d6440cc99eab9508632a3140d3f1519ad32fdf5f21b65833291999ba
4
+ data.tar.gz: 8d32790e9071087f948f9c1e3a3f3870f2de3dd0a1ab835e2b3727b7725d69e0
5
5
  SHA512:
6
- metadata.gz: ecde71759c34fe1cee589084e7c06577726af223cc207f3cb4236f02d3d4fba75662bf622d69de7cabc7f22acb6f041cd8ddfeb142f60aba07051b35a3ac9e00
7
- data.tar.gz: bb87fb6a83333fc0efffcd4ce5a37da55689bd617642a15dbbb4b4a1c94cb8511aa9a2e9d11e4fc16fc6ec6631d8191976e125156a1241b8f27367fb0afd4d27
6
+ metadata.gz: cf699102f03d8d6169e317f94aa88229537626ea74ec3b17446396e35fcf7e9d758d1b881d3c0d4fade4324a52e4ec64ed60d6540cac736e11440a9b4fbb1ca4
7
+ data.tar.gz: ea3952f4603dcb3344b856df43f11686589f8341763bb360d467bb99c852922b8480c3a41a86829dd25a79d3874561675e4ac4d98e09dddbc059720d86577583
data/Gemfile.lock CHANGED
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- checkoff (0.41.0)
15
+ checkoff (0.43.0)
16
16
  activesupport
17
17
  asana (> 0.10.0)
18
18
  cache_method
@@ -8,19 +8,27 @@ module Checkoff
8
8
  # Use the provided config from a YAML file, and fall back to env
9
9
  # variable if it's not populated for a key'
10
10
  class EnvFallbackConfigLoader
11
+ # @param config [Hash<Symbol, Object>]
12
+ # @param sym [Symbol]
13
+ # @param yaml_filename [String]
11
14
  def initialize(config, sym, yaml_filename)
12
15
  @config = config
13
16
  @envvar_prefix = sym.upcase
14
17
  @yaml_filename = yaml_filename
15
18
  end
16
19
 
20
+ # @param key [Symbol]
21
+ # @return [Object]
17
22
  def [](key)
18
23
  config_value = @config[key]
19
24
  return config_value unless config_value.nil?
20
25
 
26
+ # @sg-ignore
21
27
  ENV.fetch(envvar_name(key), nil)
22
28
  end
23
29
 
30
+ # @param key [Symbol]
31
+ # @return [Object]
24
32
  def fetch(key)
25
33
  out = self[key]
26
34
  return out unless out.nil?
@@ -31,6 +39,8 @@ module Checkoff
31
39
 
32
40
  private
33
41
 
42
+ # @param key [Symbol]
43
+ # @return [String]
34
44
  def envvar_name(key)
35
45
  "#{@envvar_prefix}__#{key.upcase}"
36
46
  end
@@ -39,7 +49,8 @@ module Checkoff
39
49
  # Load configuration file
40
50
  class ConfigLoader
41
51
  class << self
42
- # @return EnvFallbackConfigLoader
52
+ # @sg-ignore
53
+ # @return [Hash<Symbol, Object>]
43
54
  def load(sym)
44
55
  yaml_result = load_yaml_file(sym)
45
56
  EnvFallbackConfigLoader.new(yaml_result, sym, yaml_filename(sym))
@@ -47,13 +58,18 @@ module Checkoff
47
58
 
48
59
  private
49
60
 
61
+ # @param sym [Symbol]
62
+ # @return [Hash<[String, Symbol], Object>]
50
63
  def load_yaml_file(sym)
51
64
  filename = yaml_filename(sym)
52
65
  return {} unless File.exist?(filename)
53
66
 
67
+ # @sg-ignore
54
68
  YAML.load_file(filename).with_indifferent_access
55
69
  end
56
70
 
71
+ # @param sym [Symbol]
72
+ # @return [String]
57
73
  def yaml_filename(sym)
58
74
  file = "#{sym}.yml"
59
75
  File.expand_path("~/.#{file}")
@@ -3,7 +3,7 @@
3
3
  module Checkoff
4
4
  # Base class to evaluate a task selector function given fully evaluated arguments
5
5
  class FunctionEvaluator
6
- # @param task_selector [Array<(Symbol, Array)>]
6
+ # @param task_selector [Array<(Symbol, Array)>,String]
7
7
  # @param tasks [Checkoff::Tasks]
8
8
  def initialize(task_selector:,
9
9
  tasks:)
@@ -101,7 +101,7 @@ module Checkoff
101
101
  def pull_custom_field_by_name(task, custom_field_name)
102
102
  custom_fields = task.custom_fields
103
103
  if custom_fields.nil?
104
- raise "custom fields not found on task - did you add 'custom_field' in your extra_fields argument?"
104
+ raise "custom fields not found on task - did you add 'custom_fields' in your extra_fields argument?"
105
105
  end
106
106
 
107
107
  # @sg-ignore
@@ -165,6 +165,21 @@ module Checkoff
165
165
  end
166
166
  end
167
167
 
168
+ # :equals? function
169
+ class EqualsPFunctionEvaluator < FunctionEvaluator
170
+ def matches?
171
+ fn?(task_selector, :equals?)
172
+ end
173
+
174
+ # @param _task [Asana::Resources::Task]
175
+ # @param lhs [Object]
176
+ # @param rhs [Object]
177
+ # @return [Boolean]
178
+ def evaluate(_task, lhs, rhs)
179
+ lhs == rhs
180
+ end
181
+ end
182
+
168
183
  # :tag function
169
184
  class TagPFunctionEvaluator < FunctionEvaluator
170
185
  def matches?
@@ -324,6 +339,20 @@ module Checkoff
324
339
  end
325
340
  end
326
341
 
342
+ # String literals
343
+ class StringLiteralEvaluator < FunctionEvaluator
344
+ def matches?
345
+ task_selector.is_a?(String)
346
+ end
347
+
348
+ # @sg-ignore
349
+ # @param _task [Asana::Resources::Task]
350
+ # @return [String]
351
+ def evaluate(_task)
352
+ task_selector
353
+ end
354
+ end
355
+
327
356
  # Evaluator task selectors against a task
328
357
  class TaskSelectorEvaluator
329
358
  # @param task [Asana::Resources::Task]
@@ -337,6 +366,7 @@ module Checkoff
337
366
  FUNCTION_EVALUTORS = [
338
367
  NotFunctionEvaluator,
339
368
  NilPFunctionEvaluator,
369
+ EqualsPFunctionEvaluator,
340
370
  TagPFunctionEvaluator,
341
371
  CustomFieldValueFunctionEvaluator,
342
372
  CustomFieldGidValueFunctionEvaluator,
@@ -346,6 +376,7 @@ module Checkoff
346
376
  DuePFunctionEvaluator,
347
377
  DueDateSetPFunctionEvaluator,
348
378
  CustomFieldLessThanNDaysFromNowFunctionEvaluator,
379
+ StringLiteralEvaluator,
349
380
  ].freeze
350
381
 
351
382
  # @param task_selector [Array]
@@ -375,13 +406,18 @@ module Checkoff
375
406
  # @param evaluator [FunctionEvaluator]
376
407
  # @return [Boolean, Object, nil]
377
408
  def try_this_evaluator(task_selector, evaluator)
378
- evaluated_args = task_selector[1..].map.with_index do |item, index|
379
- if evaluator.evaluate_arg?(index)
380
- evaluate(item)
381
- else
382
- item
383
- end
384
- end
409
+ # if task_selector is an array
410
+ evaluated_args = if task_selector.is_a?(Array)
411
+ task_selector[1..].map.with_index do |item, index|
412
+ if evaluator.evaluate_arg?(index)
413
+ evaluate(item)
414
+ else
415
+ item
416
+ end
417
+ end
418
+ else
419
+ []
420
+ end
385
421
 
386
422
  evaluator.evaluate(task, *evaluated_args)
387
423
  end
@@ -27,6 +27,17 @@ module Checkoff
27
27
 
28
28
  include Asana::Resources::ResponseHelper
29
29
 
30
+ # @!parse
31
+ # extend CacheMethod::ClassMethods
32
+
33
+ # @param config [Hash<Symbol, Object>]
34
+ # @param workspaces [Checkoff::Workspaces]
35
+ # @param task_selectors [Checkoff::TaskSelectors]
36
+ # @param projects [Checkoff::Projects]
37
+ # @param clients [Checkoff::Clients]
38
+ # @param client [Asana::Client]
39
+ # @param search_url_parser [Checkoff::Internal::SearchUrl::Parser]
40
+ # @param asana_resources_collection_class [Class<Asana::Resources::Collection>]
30
41
  def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
31
42
  workspaces: Checkoff::Workspaces.new(config: config),
32
43
  task_selectors: Checkoff::TaskSelectors.new(config: config),
@@ -49,6 +60,7 @@ module Checkoff
49
60
  # @return [Array<Asana::Resources::Task>]
50
61
  def task_search(workspace_name, url, extra_fields: [])
51
62
  workspace = workspaces.workspace_or_raise(workspace_name)
63
+ # @sg-ignore
52
64
  api_params, task_selector = @search_url_parser.convert_params(url)
53
65
  path = "/workspaces/#{workspace.gid}/tasks/search"
54
66
  options = calculate_api_options(extra_fields)
@@ -76,8 +88,13 @@ module Checkoff
76
88
  # bundle exec ./task_searches.rb
77
89
  # :nocov:
78
90
  class << self
91
+ # @return [void]
79
92
  def run
93
+ # @sg-ignore
94
+ # @type [String]
80
95
  workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
96
+ # @sg-ignore
97
+ # @type [String]
81
98
  url = ARGV[1] || raise('Please pass task search URL as second argument')
82
99
  task_searches = Checkoff::TaskSearches.new
83
100
  task_search = task_searches.task_search(workspace_name, url)
@@ -86,7 +103,14 @@ module Checkoff
86
103
  end
87
104
  # :nocov:
88
105
 
89
- attr_reader :task_selectors, :projects, :workspaces, :client
106
+ # @return [Checkoff::TaskSelectors]
107
+ attr_reader :task_selectors
108
+ # @return [Checkoff::Projects]
109
+ attr_reader :projects
110
+ # @return [Checkoff::Workspaces]
111
+ attr_reader :workspaces
112
+ # @return [Asana::Client]
113
+ attr_reader :client
90
114
  end
91
115
  end
92
116
 
@@ -4,25 +4,25 @@
4
4
 
5
5
  require_relative 'sections'
6
6
  require_relative 'workspaces'
7
+ require_relative 'internal/config_loader'
7
8
  require 'asana'
8
9
 
9
10
  module Checkoff
10
11
  # Pull tasks from Asana
11
12
  class Tasks
12
13
  MINUTE = 60
13
- # @sg-ignore
14
14
  HOUR = MINUTE * 60
15
15
  DAY = 24 * HOUR
16
16
  REALLY_LONG_CACHE_TIME = HOUR
17
- # @sg-ignore
18
17
  LONG_CACHE_TIME = MINUTE * 15
19
- # @sg-ignore
20
18
  SHORT_CACHE_TIME = MINUTE * 5
21
19
 
20
+ # @param config [Hash<Symbol, Object>]
22
21
  # @param client [Asana::Client]
23
22
  # @param workspaces [Checkoff::Workspaces]
24
- # @param time_class [Class<Time>]
25
23
  # @param sections [Checkoff::Sections]
24
+ # @param time_class [Class<Time>]
25
+ # @param asana_task [Class<Asana::Resources::Task>]
26
26
  def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
27
27
  client: Checkoff::Clients.new(config: config).client,
28
28
  workspaces: Checkoff::Workspaces.new(config: config,
@@ -39,8 +39,10 @@ module Checkoff
39
39
  @workspaces = workspaces
40
40
  end
41
41
 
42
- def task_ready?(task)
43
- return false if incomplete_dependencies?(task)
42
+ # @param task [Asana::Resources::Task]
43
+ # @param ignore_dependencies [Boolean]
44
+ def task_ready?(task, ignore_dependencies: false)
45
+ return false if !ignore_dependencies && incomplete_dependencies?(task)
44
46
 
45
47
  due = due_time(task)
46
48
 
@@ -50,11 +52,19 @@ module Checkoff
50
52
  end
51
53
 
52
54
  # Pull a specific task by name
55
+ # @param workspace_name [String]
56
+ # @param project_name [String, Symbol]
57
+ # @param section_name [String, nil, Symbol]
58
+ # @param task_name [String]
59
+ # @param only_uncompleted [Boolean]
60
+ # @param extra_fields [Array<String>]
61
+ # @sg-ignore
53
62
  # @return [Asana::Resources::Task, nil]
54
63
  def task(workspace_name, project_name, task_name,
55
64
  section_name: :unspecified,
56
65
  only_uncompleted: true,
57
66
  extra_fields: [])
67
+ # @sg-ignore
58
68
  tasks = tasks_from_section(workspace_name,
59
69
  project_name,
60
70
  section_name: section_name,
@@ -74,6 +84,7 @@ module Checkoff
74
84
  client.tasks.find_by_id(task_gid, options: options)
75
85
  end
76
86
 
87
+ # @param name [String]
77
88
  # @param workspace_gid [String]
78
89
  # @param assignee_gid [String]
79
90
  # @return [Asana::Resources::Task]
@@ -85,13 +96,19 @@ module Checkoff
85
96
  workspace: workspace_gid, name: name)
86
97
  end
87
98
 
88
- # Return an end-user URL to the task in question
99
+ # @param task [Asana::Resources::Task]
100
+ # @return [String] end-user URL to the task in question
89
101
  def url_of_task(task)
90
102
  "https://app.asana.com/0/0/#{task.gid}/f"
91
103
  end
92
104
 
93
105
  private
94
106
 
107
+ # @param workspace_name [String]
108
+ # @param project_name [String, Symbol]
109
+ # @param section_name [String, nil, :unspecified]
110
+ # @param only_uncompleted [Boolean]
111
+ # @param extra_fields [Array<String>]
95
112
  # @return [Array<Asana::Resources::Task>]
96
113
  def tasks_from_section(workspace_name, project_name,
97
114
  section_name:,
@@ -109,6 +126,7 @@ module Checkoff
109
126
  end
110
127
  end
111
128
 
129
+ # @return [Asana::Client]
112
130
  attr_reader :client
113
131
 
114
132
  # @return [Checkoff::Projects]
@@ -131,6 +149,7 @@ module Checkoff
131
149
  nil
132
150
  end
133
151
 
152
+ # @param task [Asana::Resources::Task]
134
153
  def incomplete_dependencies?(task)
135
154
  # Avoid a redundant fetch. Unfortunately, Ruby SDK allows
136
155
  # dependencies to be fetched along with other attributes--but
@@ -3,5 +3,5 @@
3
3
  # Command-line and gem client for Asana (unofficial)
4
4
  module Checkoff
5
5
  # Version of library
6
- VERSION = '0.41.0'
6
+ VERSION = '0.43.0'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.41.0
4
+ version: 0.43.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vince Broz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-19 00:00:00.000000000 Z
11
+ date: 2023-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport