checkoff 0.36.1 → 0.38.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/Gemfile.lock +2 -16
- data/checkoff.gemspec +0 -1
- data/config/definitions.rb +52 -0
- data/lib/checkoff/internal/search_url/parser.rb +6 -0
- data/lib/checkoff/internal/search_url/simple_param_converter.rb +34 -1
- data/lib/checkoff/projects.rb +33 -5
- data/lib/checkoff/task_searches.rb +11 -0
- data/lib/checkoff/tasks.rb +28 -1
- data/lib/checkoff/version.rb +1 -1
- data/lib/checkoff/workspaces.rb +19 -7
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb28394467995eb9df10b9fa896614dca20ef97b0759c2945bb3baaf98ba0d56
|
4
|
+
data.tar.gz: 3b565699736d8956d83a94e8c93d910ecfac4f7f65280e27303d0da8dd3fd6ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cfeaa16ebe32cda3959dfce64b72382e743d5dcf40a2d1771c2b2d725594f8d505f094139163bca7e6059908b02d5811260c75b7670126a1bcdf22fb306c9f6
|
7
|
+
data.tar.gz: 9066df52dadb002a5b8bd34a7a1fc852d1e45b4543202e21995dee9e491703357ba305b612c5772d5c9c0153e5c7245c9304988e0f5751b608bfbe03e420d214
|
data/Gemfile.lock
CHANGED
@@ -12,7 +12,7 @@ GIT
|
|
12
12
|
PATH
|
13
13
|
remote: .
|
14
14
|
specs:
|
15
|
-
checkoff (0.
|
15
|
+
checkoff (0.38.0)
|
16
16
|
activesupport
|
17
17
|
asana (> 0.10.0)
|
18
18
|
cache_method
|
@@ -22,7 +22,7 @@ PATH
|
|
22
22
|
GEM
|
23
23
|
remote: https://rubygems.org/
|
24
24
|
specs:
|
25
|
-
activesupport (7.0.
|
25
|
+
activesupport (7.0.5)
|
26
26
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
27
27
|
i18n (>= 1.6, < 2)
|
28
28
|
minitest (>= 5.1)
|
@@ -145,19 +145,6 @@ GEM
|
|
145
145
|
reverse_markdown (2.1.1)
|
146
146
|
nokogiri
|
147
147
|
rexml (3.2.5)
|
148
|
-
rspec (3.11.0)
|
149
|
-
rspec-core (~> 3.11.0)
|
150
|
-
rspec-expectations (~> 3.11.0)
|
151
|
-
rspec-mocks (~> 3.11.0)
|
152
|
-
rspec-core (3.11.0)
|
153
|
-
rspec-support (~> 3.11.0)
|
154
|
-
rspec-expectations (3.11.1)
|
155
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
156
|
-
rspec-support (~> 3.11.0)
|
157
|
-
rspec-mocks (3.11.1)
|
158
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
159
|
-
rspec-support (~> 3.11.0)
|
160
|
-
rspec-support (3.11.1)
|
161
148
|
rubocop (1.36.0)
|
162
149
|
json (~> 2.3)
|
163
150
|
parallel (~> 1.10)
|
@@ -239,7 +226,6 @@ DEPENDENCIES
|
|
239
226
|
punchlist
|
240
227
|
rake (~> 13.0)
|
241
228
|
rbs (> 3.0.3)
|
242
|
-
rspec (>= 3.4)
|
243
229
|
rubocop (~> 1.36, < 1.44)
|
244
230
|
rubocop-minitest
|
245
231
|
rubocop-rake
|
data/checkoff.gemspec
CHANGED
@@ -46,7 +46,6 @@ Gem::Specification.new do |spec|
|
|
46
46
|
spec.add_development_dependency 'rake', '~> 13.0'
|
47
47
|
# ensure recent definitions
|
48
48
|
spec.add_development_dependency 'rbs', ['>3.0.3']
|
49
|
-
spec.add_development_dependency 'rspec', '>=3.4'
|
50
49
|
# I haven't adapted things to Gemspec/DevelopmentDependencies yet,
|
51
50
|
# which arrives in 1.44
|
52
51
|
spec.add_development_dependency 'rubocop', ['~> 1.36', '<1.44']
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# @!parse
|
4
|
+
# class Time
|
5
|
+
# class << self
|
6
|
+
# # @param date [String]
|
7
|
+
# # @return [Time]
|
8
|
+
# def parse(date); end
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
# module Asana
|
12
|
+
# class Client
|
13
|
+
# # @return [Asana::ProxiedResourceClasses::Task]
|
14
|
+
# def tasks; end
|
15
|
+
# # @return [Asana::ProxiedResourceClasses::Workspace]
|
16
|
+
# def workspaces; end
|
17
|
+
# end
|
18
|
+
# module Resources
|
19
|
+
# class Task
|
20
|
+
# # @return [String, nil]
|
21
|
+
# def html_notes; end
|
22
|
+
# class << self
|
23
|
+
# # @return [Asana::Resources::Task]
|
24
|
+
# def create(client, assignee:, workspace:, name:); end
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# module Resources
|
29
|
+
# class Workspace
|
30
|
+
# # @return [String, nil]
|
31
|
+
# def html_notes; end
|
32
|
+
# class << self
|
33
|
+
# # @return [Asana::Resources::Workspace]
|
34
|
+
# def find_by_id(client, id, options: {}); end
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
# module ProxiedResourceClasses
|
39
|
+
# class Task
|
40
|
+
# # Returns the complete task record for a single task.
|
41
|
+
# #
|
42
|
+
# # @param id [String] The task to get.
|
43
|
+
# # @param options [Hash] the request I/O options.
|
44
|
+
# # @return [Asana::Resources::Task]
|
45
|
+
# def find_by_id(id, options: {}); end
|
46
|
+
# end
|
47
|
+
# class Workspace
|
48
|
+
# # @return [Array<Asana::Resources::Workspace>]
|
49
|
+
# def find_all; end
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
|
+
require 'cgi'
|
6
|
+
require 'uri'
|
5
7
|
require_relative 'simple_param_converter'
|
6
8
|
require_relative 'custom_field_param_converter'
|
7
9
|
|
@@ -17,7 +19,9 @@ module Checkoff
|
|
17
19
|
|
18
20
|
def convert_params(url)
|
19
21
|
url_params = CGI.parse(URI.parse(url).query)
|
22
|
+
# @sg-ignore
|
20
23
|
custom_field_params, simple_url_params = partition_url_params(url_params)
|
24
|
+
# @sg-ignore
|
21
25
|
custom_field_args, task_selector = convert_custom_field_params(custom_field_params)
|
22
26
|
simple_url_args = convert_simple_params(simple_url_params)
|
23
27
|
[custom_field_args.merge(simple_url_args), task_selector]
|
@@ -33,6 +37,8 @@ module Checkoff
|
|
33
37
|
CustomFieldParamConverter.new(custom_field_params: custom_field_params).convert
|
34
38
|
end
|
35
39
|
|
40
|
+
# @param url_params [Hash<String, String>]
|
41
|
+
# @return [Array(Hash<String, String>, Hash<String, String>)]
|
36
42
|
def partition_url_params(url_params)
|
37
43
|
url_params.to_a.partition do |key, _values|
|
38
44
|
key.start_with? 'custom_field_'
|
@@ -11,6 +11,8 @@ module Checkoff
|
|
11
11
|
module SimpleParam
|
12
12
|
# base class for handling different types of search url params
|
13
13
|
class SimpleParam
|
14
|
+
# @param key [String] the name of the search url param
|
15
|
+
# @param values [Array<String>] the values of the search url param
|
14
16
|
def initialize(key:, values:)
|
15
17
|
@key = key
|
16
18
|
@values = values
|
@@ -18,10 +20,13 @@ module Checkoff
|
|
18
20
|
|
19
21
|
private
|
20
22
|
|
23
|
+
# @sg-ignore
|
24
|
+
# @return [String] the single value of the search url param
|
21
25
|
def single_value
|
22
26
|
@single_value ||= begin
|
23
27
|
raise "Teach me how to handle #{key} = #{values}" if values.length != 1
|
24
28
|
|
29
|
+
# @type [String]
|
25
30
|
values.fetch(0)
|
26
31
|
end
|
27
32
|
end
|
@@ -34,6 +39,7 @@ module Checkoff
|
|
34
39
|
# 123~456 means "abc" and "def" projects
|
35
40
|
def parse_projects_and_sections(projects, sections)
|
36
41
|
single_value.split('~').each do |project_section_pair|
|
42
|
+
# @sg-ignore
|
37
43
|
project, section = project_section_pair.split('_column_')
|
38
44
|
if section.nil?
|
39
45
|
projects << project
|
@@ -106,15 +112,32 @@ module Checkoff
|
|
106
112
|
['tags.any', tag_ids.join(',')]
|
107
113
|
end
|
108
114
|
end
|
115
|
+
|
116
|
+
# Handle 'sort' search url param
|
117
|
+
class Sort < SimpleParam
|
118
|
+
def convert
|
119
|
+
# https://developers.asana.com/reference/searchtasksforworkspace
|
120
|
+
conversion = {
|
121
|
+
'last_modified' => 'modified_at',
|
122
|
+
'due_date' => 'due_date',
|
123
|
+
'creation_time' => 'created_at',
|
124
|
+
'completion_time' => 'completed_at',
|
125
|
+
'likes' => 'likes',
|
126
|
+
}
|
127
|
+
['sort_by', conversion.fetch(single_value)]
|
128
|
+
end
|
129
|
+
end
|
109
130
|
end
|
110
131
|
|
111
132
|
# Convert simple parameters - ones where the param name itself
|
112
133
|
# doesn't encode any parameters'
|
113
134
|
class SimpleParamConverter
|
135
|
+
# @param simple_url_params [Hash<String, Array<String>>] the simple params
|
114
136
|
def initialize(simple_url_params:)
|
115
137
|
@simple_url_params = simple_url_params
|
116
138
|
end
|
117
139
|
|
140
|
+
# @return [Hash<String, String>] the converted params
|
118
141
|
def convert
|
119
142
|
simple_url_params.to_a.flat_map do |key, values|
|
120
143
|
convert_arg(key, values).each_slice(2).to_a
|
@@ -123,6 +146,7 @@ module Checkoff
|
|
123
146
|
|
124
147
|
private
|
125
148
|
|
149
|
+
# @type [Hash<String, Class<SimpleParam::SimpleParam>>] the mapping from param name to class
|
126
150
|
ARGS = {
|
127
151
|
'any_projects.ids' => SimpleParam::AnyProjectsIds,
|
128
152
|
'not_projects.ids' => SimpleParam::NotProjectsIds,
|
@@ -130,12 +154,21 @@ module Checkoff
|
|
130
154
|
'not_tags.ids' => SimpleParam::NotTagsIds,
|
131
155
|
'any_tags.ids' => SimpleParam::AnyTagsIds,
|
132
156
|
'subtask' => SimpleParam::Subtask,
|
157
|
+
'sort' => SimpleParam::Sort,
|
133
158
|
}.freeze
|
134
159
|
|
135
160
|
# https://developers.asana.com/docs/search-tasks-in-a-workspace
|
161
|
+
# @sg-ignore
|
162
|
+
# @param key [String] the name of the search url param
|
163
|
+
# @param values [Array<String>] the values of the search url param
|
164
|
+
# @return [Hash<String, String>] the converted params
|
136
165
|
def convert_arg(key, values)
|
166
|
+
# @type [Class<SimpleParam::SimpleParam>]
|
137
167
|
clazz = ARGS.fetch(key)
|
138
|
-
|
168
|
+
# @type [SimpleParam::SimpleParam]
|
169
|
+
obj = clazz.new(key: key, values: values)
|
170
|
+
# @sg-ignore
|
171
|
+
obj.convert
|
139
172
|
end
|
140
173
|
|
141
174
|
attr_reader :simple_url_params
|
data/lib/checkoff/projects.rb
CHANGED
@@ -17,12 +17,19 @@ module Checkoff
|
|
17
17
|
# Work with projects in Asana
|
18
18
|
class Projects
|
19
19
|
MINUTE = 60
|
20
|
+
# @sg-ignore
|
20
21
|
HOUR = MINUTE * 60
|
21
22
|
DAY = 24 * HOUR
|
23
|
+
# @sg-ignore
|
22
24
|
REALLY_LONG_CACHE_TIME = HOUR * 1
|
25
|
+
# @sg-ignore
|
23
26
|
LONG_CACHE_TIME = MINUTE * 15
|
24
27
|
SHORT_CACHE_TIME = MINUTE
|
25
28
|
|
29
|
+
# @!parse
|
30
|
+
# extend CacheMethod::ClassMethods
|
31
|
+
|
32
|
+
# @param client [Asana::Client]
|
26
33
|
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
27
34
|
client: Checkoff::Clients.new(config: config).client,
|
28
35
|
workspaces: Checkoff::Workspaces.new(config: config,
|
@@ -33,7 +40,7 @@ module Checkoff
|
|
33
40
|
end
|
34
41
|
|
35
42
|
# Default options used in Asana API to pull taskso
|
36
|
-
# @return [Hash]
|
43
|
+
# @return [Hash<Symbol, Object>]
|
37
44
|
def task_options
|
38
45
|
{
|
39
46
|
per_page: 100,
|
@@ -45,6 +52,9 @@ module Checkoff
|
|
45
52
|
end
|
46
53
|
|
47
54
|
# pulls an Asana API project class given a name
|
55
|
+
# @param [String] workspace_name
|
56
|
+
# @param [String] project_name
|
57
|
+
# @return [Asana::Resources::Project, nil]
|
48
58
|
def project(workspace_name, project_name)
|
49
59
|
if project_name.is_a?(Symbol) && project_name.to_s.start_with?('my_tasks')
|
50
60
|
my_tasks(workspace_name)
|
@@ -57,21 +67,30 @@ module Checkoff
|
|
57
67
|
end
|
58
68
|
cache_method :project, LONG_CACHE_TIME
|
59
69
|
|
60
|
-
# @
|
70
|
+
# @param workspace_name [String]
|
71
|
+
# @param project_name [String]
|
72
|
+
# @return [Asana::Resources::Project]
|
61
73
|
def project_or_raise(workspace_name, project_name)
|
62
|
-
|
63
|
-
raise "Could not find project #{project_name} under workspace #{workspace_name}." if
|
74
|
+
p = project(workspace_name, project_name)
|
75
|
+
raise "Could not find project #{project_name} under workspace #{workspace_name}." if p.nil?
|
64
76
|
|
65
|
-
|
77
|
+
p
|
66
78
|
end
|
67
79
|
cache_method :project_or_raise, LONG_CACHE_TIME
|
68
80
|
|
69
81
|
# find uncompleted tasks in a list
|
82
|
+
# @param [Array<Asana::Resources::Task>] tasks
|
83
|
+
# @return [Array<Asana::Resources::Task>]
|
70
84
|
def active_tasks(tasks)
|
71
85
|
tasks.select { |task| task.completed_at.nil? }
|
72
86
|
end
|
73
87
|
|
74
88
|
# pull task objects from a named project
|
89
|
+
# @sg-ignore
|
90
|
+
# @param [Asana::Resources::Project] project
|
91
|
+
# @param [Boolean] only_uncompleted
|
92
|
+
# @param [Array<String>] extra_fields
|
93
|
+
# @return [Array<Asana::Resources::Task>]
|
75
94
|
def tasks_from_project(project, only_uncompleted: true, extra_fields: [])
|
76
95
|
options = task_options
|
77
96
|
options[:completed_since] = '9999-12-01' if only_uncompleted
|
@@ -85,11 +104,15 @@ module Checkoff
|
|
85
104
|
|
86
105
|
attr_reader :client
|
87
106
|
|
107
|
+
# @sg-ignore
|
88
108
|
def projects
|
89
109
|
client.projects
|
90
110
|
end
|
91
111
|
cache_method :projects, LONG_CACHE_TIME
|
92
112
|
|
113
|
+
# @sg-ignore
|
114
|
+
# @param [String] workspace_name
|
115
|
+
# @return [Array<Asana::Resources::Project>]
|
93
116
|
def projects_by_workspace_name(workspace_name)
|
94
117
|
workspace = @workspaces.workspace_or_raise(workspace_name)
|
95
118
|
raise "Could not find workspace named #{workspace_name}" unless workspace
|
@@ -97,8 +120,13 @@ module Checkoff
|
|
97
120
|
projects.find_by_workspace(workspace: workspace.gid)
|
98
121
|
end
|
99
122
|
|
123
|
+
# @sg-ignore
|
124
|
+
# @param [String] workspace_name
|
125
|
+
# @return [Asana::Resources::Project]
|
100
126
|
def my_tasks(workspace_name)
|
101
127
|
workspace = @workspaces.workspace_or_raise(workspace_name)
|
128
|
+
# @sg-ignore
|
129
|
+
# @type [Asana::Resources::UserTaskList]
|
102
130
|
result = client.user_task_lists.get_user_task_list_for_user(user_gid: 'me',
|
103
131
|
workspace: workspace.gid)
|
104
132
|
gid = result.gid
|
@@ -19,9 +19,12 @@ module Checkoff
|
|
19
19
|
# Run task searches against the Asana API
|
20
20
|
class TaskSearches
|
21
21
|
MINUTE = 60
|
22
|
+
# @sg-ignore
|
22
23
|
HOUR = MINUTE * 60
|
23
24
|
DAY = 24 * HOUR
|
25
|
+
# @sg-ignore
|
24
26
|
REALLY_LONG_CACHE_TIME = HOUR * 1
|
27
|
+
# @sg-ignore
|
25
28
|
LONG_CACHE_TIME = MINUTE * 15
|
26
29
|
SHORT_CACHE_TIME = MINUTE
|
27
30
|
|
@@ -59,11 +62,15 @@ module Checkoff
|
|
59
62
|
client: client)
|
60
63
|
tasks.select { |task| task_selectors.filter_via_task_selector(task, task_selector) }
|
61
64
|
end
|
65
|
+
# @sg-ignore
|
62
66
|
cache_method :task_search, LONG_CACHE_TIME
|
63
67
|
|
64
68
|
private
|
65
69
|
|
70
|
+
# @param [Array<String>] extra_fields
|
71
|
+
# @return [Hash<Symbol, Object>]
|
66
72
|
def calculate_api_options(extra_fields)
|
73
|
+
# @type [Hash<Symbol, Object>]
|
67
74
|
options = projects.task_options[:options]
|
68
75
|
options[:fields] += ['custom_fields']
|
69
76
|
options[:fields] += extra_fields
|
@@ -74,7 +81,11 @@ module Checkoff
|
|
74
81
|
# :nocov:
|
75
82
|
class << self
|
76
83
|
def run
|
84
|
+
# @sg-ignore
|
85
|
+
# @type [String]
|
77
86
|
workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
|
87
|
+
# @sg-ignore
|
88
|
+
# @type [String]
|
78
89
|
url = ARGV[1] || raise('Please pass task search URL as second argument')
|
79
90
|
task_searches = Checkoff::TaskSearches.new
|
80
91
|
task_search = task_searches.task_search(workspace_name, url)
|
data/lib/checkoff/tasks.rb
CHANGED
@@ -3,21 +3,30 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
require_relative 'sections'
|
6
|
+
require_relative 'workspaces'
|
6
7
|
require 'asana'
|
7
8
|
|
8
9
|
module Checkoff
|
9
10
|
# Pull tasks from Asana
|
10
11
|
class Tasks
|
11
12
|
MINUTE = 60
|
13
|
+
# @sg-ignore
|
12
14
|
HOUR = MINUTE * 60
|
13
15
|
DAY = 24 * HOUR
|
14
16
|
REALLY_LONG_CACHE_TIME = HOUR
|
17
|
+
# @sg-ignore
|
15
18
|
LONG_CACHE_TIME = MINUTE * 15
|
19
|
+
# @sg-ignore
|
16
20
|
SHORT_CACHE_TIME = MINUTE * 5
|
17
21
|
|
22
|
+
# @param client [Asana::Client]
|
23
|
+
# @param workspaces [Checkoff::Workspaces]
|
24
|
+
# @param time_class [Class<Time>]
|
18
25
|
# @param sections [Checkoff::Sections]
|
19
26
|
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
20
27
|
client: Checkoff::Clients.new(config: config).client,
|
28
|
+
workspaces: Checkoff::Workspaces.new(config: config,
|
29
|
+
client: client),
|
21
30
|
sections: Checkoff::Sections.new(config: config,
|
22
31
|
client: client),
|
23
32
|
time_class: Time,
|
@@ -27,6 +36,7 @@ module Checkoff
|
|
27
36
|
@time_class = time_class
|
28
37
|
@asana_task = asana_task
|
29
38
|
@client = client
|
39
|
+
@workspaces = workspaces
|
30
40
|
end
|
31
41
|
|
32
42
|
def task_ready?(task)
|
@@ -53,9 +63,22 @@ module Checkoff
|
|
53
63
|
tasks.find { |task| task.name == task_name }
|
54
64
|
end
|
55
65
|
|
66
|
+
# Pull a specific task by name
|
67
|
+
# @return [Asana::Resources::Task, nil]
|
68
|
+
def task_by_gid(task_gid,
|
69
|
+
only_uncompleted: true,
|
70
|
+
extra_fields: [])
|
71
|
+
options = projects.task_options
|
72
|
+
options[:options][:fields] += extra_fields
|
73
|
+
options[:completed_since] = '9999-12-01' if only_uncompleted
|
74
|
+
client.tasks.find_by_id(task_gid, options: options)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @param workspace_gid [String]
|
78
|
+
# @param assignee_gid [String]
|
56
79
|
# @return [Asana::Resources::Task]
|
57
80
|
def add_task(name,
|
58
|
-
workspace_gid: default_workspace_gid,
|
81
|
+
workspace_gid: @workspaces.default_workspace_gid,
|
59
82
|
assignee_gid: default_assignee_gid)
|
60
83
|
@asana_task.create(client,
|
61
84
|
assignee: assignee_gid,
|
@@ -93,11 +116,14 @@ module Checkoff
|
|
93
116
|
@projects ||= @sections.projects
|
94
117
|
end
|
95
118
|
|
119
|
+
# @sg-ignore
|
96
120
|
# @return [String]
|
97
121
|
def default_assignee_gid
|
98
122
|
@config.fetch(:default_assignee_gid)
|
99
123
|
end
|
100
124
|
|
125
|
+
# @param task [Asana::Resources::Task]
|
126
|
+
# @return [Time, nil]
|
101
127
|
def due_time(task)
|
102
128
|
return @time_class.parse(task.due_at) if task.due_at
|
103
129
|
return @time_class.parse(task.due_on) if task.due_on
|
@@ -117,6 +143,7 @@ module Checkoff
|
|
117
143
|
# @sg-ignore
|
118
144
|
# @type [Array<Asana::Resources::Task>, nil]
|
119
145
|
already_fetched_dependencies = task.instance_variable_get(:@dependencies)
|
146
|
+
# @sg-ignore
|
120
147
|
return false unless already_fetched_dependencies.nil? || already_fetched_dependencies.size.positive?
|
121
148
|
|
122
149
|
task.dependencies.any? do |parent_task_info|
|
data/lib/checkoff/version.rb
CHANGED
data/lib/checkoff/workspaces.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'asana'
|
3
4
|
require 'forwardable'
|
4
5
|
require 'cache_method'
|
5
6
|
require_relative 'internal/config_loader'
|
@@ -11,12 +12,16 @@ module Checkoff
|
|
11
12
|
# Query different workspaces of Asana projects
|
12
13
|
class Workspaces
|
13
14
|
MINUTE = 60
|
15
|
+
# @sg-ignore
|
14
16
|
HOUR = MINUTE * 60
|
15
17
|
DAY = 24 * HOUR
|
18
|
+
# @sg-ignore
|
16
19
|
REALLY_LONG_CACHE_TIME = HOUR * 1
|
20
|
+
# @sg-ignore
|
17
21
|
LONG_CACHE_TIME = MINUTE * 15
|
18
22
|
SHORT_CACHE_TIME = MINUTE
|
19
23
|
|
24
|
+
# @param client [Asana::Client]
|
20
25
|
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
21
26
|
client: Checkoff::Clients.new(config: config).client,
|
22
27
|
asana_workspace: Asana::Resources::Workspace)
|
@@ -26,29 +31,36 @@ module Checkoff
|
|
26
31
|
end
|
27
32
|
|
28
33
|
# Pulls an Asana workspace object
|
34
|
+
# @param [String] workspace_name
|
35
|
+
# @return [Asana::Resources::Workspace, nil]
|
29
36
|
def workspace(workspace_name)
|
30
37
|
client.workspaces.find_all.find do |workspace|
|
31
38
|
workspace.name == workspace_name
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
42
|
+
# @return [Asana::Resources::Workspace]
|
35
43
|
def default_workspace
|
36
44
|
@asana_workspace.find_by_id(client, default_workspace_gid)
|
37
45
|
end
|
38
46
|
|
47
|
+
# @param [String] workspace_name
|
48
|
+
# @return [Asana::Resources::Workspace]
|
39
49
|
def workspace_or_raise(workspace_name)
|
40
|
-
|
41
|
-
raise "Could not find workspace #{workspace_name}" if
|
50
|
+
w = workspace(workspace_name)
|
51
|
+
raise "Could not find workspace #{workspace_name}" if w.nil?
|
42
52
|
|
43
|
-
|
53
|
+
w
|
44
54
|
end
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
attr_reader :client
|
49
|
-
|
56
|
+
# @sg-ignore
|
57
|
+
# @return [String]
|
50
58
|
def default_workspace_gid
|
51
59
|
@config.fetch(:default_workspace_gid)
|
52
60
|
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
attr_reader :client
|
53
65
|
end
|
54
66
|
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.
|
4
|
+
version: 0.38.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-05-
|
11
|
+
date: 2023-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -254,20 +254,6 @@ dependencies:
|
|
254
254
|
- - ">"
|
255
255
|
- !ruby/object:Gem::Version
|
256
256
|
version: 3.0.3
|
257
|
-
- !ruby/object:Gem::Dependency
|
258
|
-
name: rspec
|
259
|
-
requirement: !ruby/object:Gem::Requirement
|
260
|
-
requirements:
|
261
|
-
- - ">="
|
262
|
-
- !ruby/object:Gem::Version
|
263
|
-
version: '3.4'
|
264
|
-
type: :development
|
265
|
-
prerelease: false
|
266
|
-
version_requirements: !ruby/object:Gem::Requirement
|
267
|
-
requirements:
|
268
|
-
- - ">="
|
269
|
-
- !ruby/object:Gem::Version
|
270
|
-
version: '3.4'
|
271
257
|
- !ruby/object:Gem::Dependency
|
272
258
|
name: rubocop
|
273
259
|
requirement: !ruby/object:Gem::Requirement
|
@@ -425,6 +411,7 @@ files:
|
|
425
411
|
- bin/solargraph
|
426
412
|
- bin/yard
|
427
413
|
- checkoff.gemspec
|
414
|
+
- config/definitions.rb
|
428
415
|
- docs/cookiecutter_input.json
|
429
416
|
- docs/example_project.png
|
430
417
|
- exe/checkoff
|