checkoff 0.91.0 → 0.93.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: 35517b0881d667a3b704f6e4aca139c95e32c8cb3b10c471c80d826fb6ab063c
4
- data.tar.gz: 479341030e04f41b32a972502422d159442984dbd4c108213e376e37bd0bb6f3
3
+ metadata.gz: 49531006387df986e746c99973d425917777230710978cad819951ca8d696d7b
4
+ data.tar.gz: ef9ea84d3a708b8a47425c77a63f83241f310d2b9b0fd71e01f15ec00d5eb4d7
5
5
  SHA512:
6
- metadata.gz: d9dfe9cf496894dc305c3f6ac7f424f9dc5ea809220d193549f014ddee0c6563d6791aaa9f8df67957c4f80d73ca8da29fd6e7894ed9c34f182d5c8d8dcf0336
7
- data.tar.gz: 522e00146e8ef0d447eb31dce26cbd8ce165bf813af247e9e2aa326ccf3330d07c36dafffaba384ddcb8c2bb6958941a28613208eb0f4062161974a35e5d8d36
6
+ metadata.gz: 7d5e93cea9b3b00bb6d7622e7aa4aa93229820683118f72414ac60dd7b3fafd36fac60e1a79a16fc6091b4ba051ae3cc818b0e2f8c5a354ae57b4b849b562af0
7
+ data.tar.gz: e4f24e5b32dfce8459a3c04fc89ba0b831f0d50f61dcc780864f441b1e119f29f774f2b47503ef6653b285b60c58273bb0bca8a80aa7feacea517019ce8139c1
data/GLOSSARY.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Glossary
2
2
 
3
- * ready/due: See tasks.rb#task_ready?. Indicates a task is ready for
3
+ * ready: See tasks.rb#task_ready?. Indicates a task is ready for
4
4
  a person to work on it. This is subtly different than what is used
5
5
  by Asana to mark a date as red/green! A task is ready if it is not
6
6
  dependent on an incomplete task and one of these is true:
7
7
 
8
8
  * start is null and due on is today
9
- * start is null and due at is after now
9
+ * start is null and due at is before now
10
10
  * start on is today
11
- * start at is after now
11
+ * start at is before now
data/Gemfile.lock CHANGED
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- checkoff (0.91.0)
15
+ checkoff (0.93.0)
16
16
  activesupport
17
17
  asana (> 0.10.0)
18
18
  cache_method
@@ -33,6 +33,10 @@
33
33
  # def projects; end
34
34
  # # @return [Asana::ProxiedResourceClasses::UserTaskList]
35
35
  # def user_task_lists; end
36
+ # # @return [Asana::ProxiedResourceClasses::Portfolio]
37
+ # def portfolios; end
38
+ # # @return [Asana::ProxiedResourceClasses::User]
39
+ # def users; end
36
40
  # end
37
41
  # class Collection < Asana::Resources::Collection; end
38
42
  # module Resources
@@ -160,6 +164,35 @@
160
164
  # def get_user_task_list_for_user(client, user_gid:,
161
165
  # workspace: nil, options: {}); end
162
166
  # end
167
+ # class Portfolio
168
+ # # Returns a list of the portfolios in compact representation that are owned
169
+ # # by the current API user.
170
+ # #
171
+ # # @param workspace [Gid] The workspace or organization to filter portfolios on.
172
+ # # @param owner [String] The user who owns the portfolio. Currently, API users can only get a
173
+ # # list of portfolios that they themselves own.
174
+ # #
175
+ # # @param per_page [Integer] the number of records to fetch per page.
176
+ # # @param options [Hash] the request I/O options.
177
+ # #
178
+ # # @return [Enumerable<Asana::Resources::Portfolio>]
179
+ # def find_all(workspace: required("workspace"), owner: required("owner"), per_page: 20, options: {}); end
180
+ # # Returns the complete record for a single portfolio.
181
+ # #
182
+ # # @param id [Gid] The portfolio to get.
183
+ # # @param options [Hash] the request I/O options.
184
+ #
185
+ # # @return [Asana::Resources::Portfolio,nil]
186
+ # def find_by_id(client, id, options: {}); end
187
+ # end
188
+ # class User
189
+ # # Returns the full user record for the currently authenticated user.
190
+ # #
191
+ # # @param options [Hash] the request I/O options.
192
+ # #
193
+ # # @return [Asana::Resources::User]
194
+ # def me(options: {}); end
195
+ # end
163
196
  # end
164
197
  # end
165
198
  # rubocop:enable Layout/LineLength
@@ -8,6 +8,8 @@ underscored_plural_name="${1:?underscored plural name of entities minus .rb}"
8
8
  underscored_singular_name=$(sed -e 's/s$//g' <<< "${underscored_plural_name}")
9
9
  kabob_case_plural_name=${underscored_plural_name/_/-}
10
10
  class_name="${2:?class name without Checkoff:: prefix}"
11
+ # shellcheck disable=SC2001
12
+ asana_resource_class_name=Asana::Resources::$(sed -e 's/s$//g' <<< "${class_name}")
11
13
 
12
14
  cat > "${underscored_plural_name}.rb" << EOF
13
15
  #!/usr/bin/env ruby
@@ -20,10 +22,13 @@ require_relative 'internal/config_loader'
20
22
  require_relative 'workspaces'
21
23
  require_relative 'clients'
22
24
 
23
- # https://developers.asana.com/docs/${kabob_case_plural_name}
25
+ # https://developers.asana.com/reference/${kabob_case_plural_name}
24
26
 
25
27
  module Checkoff
26
28
  class ${class_name}
29
+ # @!parse
30
+ # extend CacheMethod::ClassMethods
31
+
27
32
  MINUTE = 60
28
33
  HOUR = MINUTE * 60
29
34
  DAY = 24 * HOUR
@@ -31,6 +36,10 @@ module Checkoff
31
36
  LONG_CACHE_TIME = MINUTE * 15
32
37
  SHORT_CACHE_TIME = MINUTE
33
38
 
39
+ # @param config [Hash]
40
+ # @param workspaces [Checkoff::Workspaces]
41
+ # @param clients [Checkoff::Clients]
42
+ # @param client [Asana::Client]
34
43
  def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
35
44
  workspaces: Checkoff::Workspaces.new(config: config),
36
45
  clients: Checkoff::Clients.new(config: config),
@@ -39,31 +48,47 @@ module Checkoff
39
48
  @client = client
40
49
  end
41
50
 
51
+ # @param workspace_name [String]
52
+ # @param ${underscored_singular_name}_name [String]
53
+ #
54
+ # @return [${asana_resource_class_name}]
42
55
  def ${underscored_singular_name}_or_raise(workspace_name, ${underscored_singular_name}_name)
43
- ${underscored_singular_name} = ${underscored_singular_name}(workspace_name, ${underscored_singular_name}_name)
44
- raise "Could not find ${underscored_singular_name} #{${underscored_singular_name}_name} under workspace #{workspace_name}." if ${underscored_singular_name}.nil?
56
+ ${underscored_singular_name}_obj = ${underscored_singular_name}(workspace_name, ${underscored_singular_name}_name)
57
+ raise "Could not find ${underscored_singular_name} #{${underscored_singular_name}_name} under workspace #{workspace_name}." if ${underscored_singular_name}_obj.nil?
45
58
 
46
- ${underscored_singular_name}
59
+ ${underscored_singular_name}_obj
47
60
  end
48
61
  cache_method :${underscored_singular_name}_or_raise, LONG_CACHE_TIME
49
62
 
63
+ # @param workspace_name [String]
64
+ # @param ${underscored_singular_name}_name [String]
65
+ #
66
+ # @return [${asana_resource_class_name},nil]
50
67
  def ${underscored_singular_name}(workspace_name, ${underscored_singular_name}_name)
51
68
  workspace = workspaces.workspace_or_raise(workspace_name)
52
- ${underscored_plural_name} = client.${underscored_plural_name}.get_${underscored_plural_name}_for_workspace(workspace_gid: workspace.gid)
53
- ${underscored_plural_name}.find { |${underscored_singular_name}| ${underscored_singular_name}.name == ${underscored_singular_name}_name }
69
+ ${underscored_singular_name}_objs = client.${underscored_plural_name}.get_${underscored_plural_name}_for_workspace(workspace_gid: workspace.gid)
70
+ ${underscored_singular_name}_objs.find { |${underscored_singular_name}_obj| ${underscored_singular_name}_obj.name == ${underscored_singular_name}_name }
54
71
  end
55
72
  cache_method :${underscored_singular_name}, LONG_CACHE_TIME
56
73
 
57
74
  private
58
75
 
59
- attr_reader :workspaces, :client
76
+ # @return [Checkoff::Workspaces]
77
+ attr_reader :workspaces
78
+
79
+ # @return [Asana::Client]
80
+ attr_reader :client
60
81
 
61
82
  # bundle exec ./${underscored_plural_name}.rb
62
83
  # :nocov:
63
84
  class << self
64
85
  # @return [void]
65
86
  def run
87
+ # @sg-ignore
88
+ # @type [String]
66
89
  workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
90
+ # @sg-ignore
91
+ # @type [String]
67
92
  ${underscored_singular_name}_name = ARGV[1] || raise('Please pass ${underscored_singular_name} name as second argument')
68
93
  ${underscored_plural_name} = Checkoff::${class_name}.new
69
94
  ${underscored_singular_name} = ${underscored_plural_name}.${underscored_singular_name}_or_raise(workspace_name, ${underscored_singular_name}_name)
@@ -72,7 +72,7 @@ module Checkoff
72
72
  end
73
73
 
74
74
  # :ready function
75
- class DuePFunctionEvaluator < FunctionEvaluator
75
+ class ReadyFunctionEvaluator < FunctionEvaluator
76
76
  def matches?
77
77
  fn?(selector, :ready)
78
78
  end
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'forwardable'
6
+ require 'cache_method'
7
+ require_relative 'internal/config_loader'
8
+ require_relative 'workspaces'
9
+ require_relative 'clients'
10
+
11
+ # https://developers.asana.com/reference/portfolios
12
+
13
+ module Checkoff
14
+ # Pull portfolios from Asana
15
+ class Portfolios
16
+ # @!parse
17
+ # extend CacheMethod::ClassMethods
18
+
19
+ MINUTE = 60
20
+ HOUR = MINUTE * 60
21
+ DAY = 24 * HOUR
22
+ REALLY_LONG_CACHE_TIME = HOUR * 1
23
+ LONG_CACHE_TIME = MINUTE * 15
24
+ SHORT_CACHE_TIME = MINUTE
25
+
26
+ # @param config [Hash]
27
+ # @param workspaces [Checkoff::Workspaces]
28
+ # @param clients [Checkoff::Clients]
29
+ # @param client [Asana::Client]
30
+ def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
31
+ workspaces: Checkoff::Workspaces.new(config: config),
32
+ clients: Checkoff::Clients.new(config: config),
33
+ client: clients.client)
34
+ @workspaces = workspaces
35
+ @client = client
36
+ end
37
+
38
+ # @param workspace_name [String]
39
+ # @param portfolio_name [String]
40
+ #
41
+ # @return [Asana::Resources::Portfolio]
42
+ def portfolio_or_raise(workspace_name, portfolio_name)
43
+ portfolio_obj = portfolio(workspace_name, portfolio_name)
44
+ raise "Could not find portfolio #{portfolio_name} under workspace #{workspace_name}." if portfolio_obj.nil?
45
+
46
+ portfolio_obj
47
+ end
48
+ cache_method :portfolio_or_raise, LONG_CACHE_TIME
49
+
50
+ # @param workspace_name [String]
51
+ # @param portfolio_name [String]
52
+ #
53
+ # @sg-ignore
54
+ # @return [Asana::Resources::Portfolio,nil]
55
+ def portfolio(workspace_name, portfolio_name)
56
+ workspace = workspaces.workspace_or_raise(workspace_name)
57
+ me = client.users.me
58
+ portfolio_objs = client.portfolios.find_all(workspace: workspace.gid,
59
+ owner: me.gid)
60
+ # @type [Asana::Resources::Portfolio, nil]
61
+ portfolio_objs.find { |portfolio_obj| portfolio_obj.name == portfolio_name }
62
+ end
63
+ cache_method :portfolio, LONG_CACHE_TIME
64
+
65
+ # Pull a specific portfolio by gid
66
+ #
67
+ # @param portfolio_gid [String]
68
+ # @param extra_fields [Array<String>]
69
+ #
70
+ # @return [Asana::Resources::Portfolio, nil]
71
+ def portfolio_by_gid(portfolio_gid,
72
+ extra_fields: [])
73
+ options = {
74
+ fields: ['name'],
75
+ }
76
+ options[:fields] += extra_fields
77
+ client.portfolios.find_by_id(portfolio_gid, options: options)
78
+ end
79
+ cache_method :portfolio_by_gid, SHORT_CACHE_TIME
80
+
81
+ private
82
+
83
+ # @return [Checkoff::Workspaces]
84
+ attr_reader :workspaces
85
+
86
+ # @return [Asana::Client]
87
+ attr_reader :client
88
+
89
+ # bundle exec ./portfolios.rb
90
+ # :nocov:
91
+ class << self
92
+ # @return [void]
93
+ def run
94
+ # @sg-ignore
95
+ # @type [String]
96
+ workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
97
+ # @sg-ignore
98
+ # @type [String]
99
+ portfolio_name = ARGV[1] || raise('Please pass portfolio name as second argument')
100
+ portfolios = Checkoff::Portfolios.new
101
+ portfolio = portfolios.portfolio_or_raise(workspace_name, portfolio_name)
102
+ puts "Results: #{portfolio}"
103
+ end
104
+ end
105
+ # :nocov:
106
+ end
107
+ end
108
+
109
+ # :nocov:
110
+ abs_program_name = File.expand_path($PROGRAM_NAME)
111
+ Checkoff::Portfolios.run if abs_program_name == File.expand_path(__FILE__)
112
+ # :nocov:
@@ -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.91.0'
6
+ VERSION = '0.93.0'
7
7
  end
data/lib/checkoff.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'checkoff/version'
4
4
  require 'checkoff/clients'
5
5
  require 'checkoff/workspaces'
6
+ require 'checkoff/portfolios'
6
7
  require 'checkoff/projects'
7
8
  require 'checkoff/sections'
8
9
  require 'checkoff/subtasks'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.91.0
4
+ version: 0.93.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vince Broz
@@ -154,6 +154,7 @@ files:
154
154
  - lib/checkoff/internal/selector_evaluator.rb
155
155
  - lib/checkoff/internal/task_selector_evaluator.rb
156
156
  - lib/checkoff/my_tasks.rb
157
+ - lib/checkoff/portfolios.rb
157
158
  - lib/checkoff/project_selectors.rb
158
159
  - lib/checkoff/projects.rb
159
160
  - lib/checkoff/section_selectors.rb