checkoff 0.92.0 → 0.94.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 +1 -1
 - data/config/definitions.rb +33 -0
 - data/lib/checkoff/create-entity.sh +32 -7
 - data/lib/checkoff/internal/selector_classes/task.rb +1 -1
 - data/lib/checkoff/internal/task_timing.rb +31 -0
 - data/lib/checkoff/portfolios.rb +112 -0
 - data/lib/checkoff/tasks.rb +18 -31
 - data/lib/checkoff/version.rb +1 -1
 - data/lib/checkoff.rb +1 -0
 - metadata +4 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3728a0da90fb49dedd232b05722fbb87f03789d3bf9bc15513e4fa4b88f9e6fc
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 16ce81c8b51905620414ff21f9469ce83c100a61985f355b8a27de20b7234b3c
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d73466d69b7b116eb8c58c0053b7cf13cedf288477e7cc8862de091fdd183e5a84355e19841e09df003da9b44d2b87ac90a459845c9186737069002f5312e455
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 207d7d34ecdc3435892afe3b96860df2373e36067f8c75866f7b87d5a6f0aac0ebe89b0889b45d6a31ddec1ac6211f592fce4b657aa70ffad5e5c504deeea773
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/config/definitions.rb
    CHANGED
    
    | 
         @@ -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/ 
     | 
| 
      
 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 
     | 
    
         
            -
                  ${ 
     | 
| 
       53 
     | 
    
         
            -
                  ${ 
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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)
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Checkoff
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Internal
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Utility methods for working with task dates and times
         
     | 
| 
      
 6 
     | 
    
         
            +
                class TaskTiming
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # @param time_class [Class<Time>]
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def initialize(time_class: Time)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @time_class = time_class
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # @param task [Asana::Resources::Task]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @return [Time, nil]
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def start_time(task)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    return @time_class.parse(task.start_at) if task.start_at
         
     | 
| 
      
 16 
     | 
    
         
            +
                    return @time_class.parse(task.start_on) if task.start_on
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # @param task [Asana::Resources::Task]
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # @return [Time, nil]
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def due_time(task)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    return @time_class.parse(task.due_at) if task.due_at
         
     | 
| 
      
 25 
     | 
    
         
            +
                    return @time_class.parse(task.due_on) if task.due_on
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            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:
         
     | 
    
        data/lib/checkoff/tasks.rb
    CHANGED
    
    | 
         @@ -5,6 +5,7 @@ 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require_relative 'sections'
         
     | 
| 
       6 
6 
     | 
    
         
             
            require_relative 'workspaces'
         
     | 
| 
       7 
7 
     | 
    
         
             
            require_relative 'internal/config_loader'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'internal/task_timing'
         
     | 
| 
       8 
9 
     | 
    
         
             
            require 'asana'
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
            module Checkoff
         
     | 
| 
         @@ -57,8 +58,8 @@ module Checkoff 
     | 
|
| 
       57 
58 
     | 
    
         
             
                def task_ready?(task, ignore_dependencies: false)
         
     | 
| 
       58 
59 
     | 
    
         
             
                  return false if !ignore_dependencies && incomplete_dependencies?(task)
         
     | 
| 
       59 
60 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                  start = start_time(task)
         
     | 
| 
       61 
     | 
    
         
            -
                  due = due_time(task)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  start = task_timing.start_time(task)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  due = task_timing.due_time(task)
         
     | 
| 
       62 
63 
     | 
    
         | 
| 
       63 
64 
     | 
    
         
             
                  return true if start.nil? && due.nil?
         
     | 
| 
       64 
65 
     | 
    
         | 
| 
         @@ -79,12 +80,12 @@ module Checkoff 
     | 
|
| 
       79 
80 
     | 
    
         
             
                         only_uncompleted: true,
         
     | 
| 
       80 
81 
     | 
    
         
             
                         extra_fields: [])
         
     | 
| 
       81 
82 
     | 
    
         
             
                  # @sg-ignore
         
     | 
| 
       82 
     | 
    
         
            -
                   
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                   
     | 
| 
      
 83 
     | 
    
         
            +
                  t = tasks(workspace_name,
         
     | 
| 
      
 84 
     | 
    
         
            +
                            project_name,
         
     | 
| 
      
 85 
     | 
    
         
            +
                            section_name: section_name,
         
     | 
| 
      
 86 
     | 
    
         
            +
                            only_uncompleted: only_uncompleted,
         
     | 
| 
      
 87 
     | 
    
         
            +
                            extra_fields: extra_fields)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  t.find { |task| task.name == task_name }
         
     | 
| 
       88 
89 
     | 
    
         
             
                end
         
     | 
| 
       89 
90 
     | 
    
         
             
                cache_method :task, SHORT_CACHE_TIME
         
     | 
| 
       90 
91 
     | 
    
         | 
| 
         @@ -146,16 +147,20 @@ module Checkoff 
     | 
|
| 
       146 
147 
     | 
    
         | 
| 
       147 
148 
     | 
    
         
             
                private
         
     | 
| 
       148 
149 
     | 
    
         | 
| 
      
 150 
     | 
    
         
            +
                # @return [Checkoff::Internal::TaskTiming]
         
     | 
| 
      
 151 
     | 
    
         
            +
                def task_timing
         
     | 
| 
      
 152 
     | 
    
         
            +
                  @task_timing ||= Checkoff::Internal::TaskTiming.new(time_class: @time_class)
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
       149 
155 
     | 
    
         
             
                # @param workspace_name [String]
         
     | 
| 
       150 
156 
     | 
    
         
             
                # @param project_name [String, Symbol]
         
     | 
| 
       151 
     | 
    
         
            -
                # @param section_name [String, nil,  
     | 
| 
      
 157 
     | 
    
         
            +
                # @param section_name [String, nil, Symbol<:unspecified>]
         
     | 
| 
       152 
158 
     | 
    
         
             
                # @param only_uncompleted [Boolean]
         
     | 
| 
       153 
159 
     | 
    
         
             
                # @param extra_fields [Array<String>]
         
     | 
| 
      
 160 
     | 
    
         
            +
                #
         
     | 
| 
       154 
161 
     | 
    
         
             
                # @return [Enumerable<Asana::Resources::Task>]
         
     | 
| 
       155 
     | 
    
         
            -
                def  
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
                                       only_uncompleted:,
         
     | 
| 
       158 
     | 
    
         
            -
                                       extra_fields:)
         
     | 
| 
      
 162 
     | 
    
         
            +
                def tasks(workspace_name, project_name,
         
     | 
| 
      
 163 
     | 
    
         
            +
                          only_uncompleted:, extra_fields:, section_name: :unspecified)
         
     | 
| 
       159 
164 
     | 
    
         
             
                  if section_name == :unspecified
         
     | 
| 
       160 
165 
     | 
    
         
             
                    project = projects.project_or_raise(workspace_name, project_name)
         
     | 
| 
       161 
166 
     | 
    
         
             
                    projects.tasks_from_project(project,
         
     | 
| 
         @@ -182,23 +187,5 @@ module Checkoff 
     | 
|
| 
       182 
187 
     | 
    
         
             
                def default_assignee_gid
         
     | 
| 
       183 
188 
     | 
    
         
             
                  @config.fetch(:default_assignee_gid)
         
     | 
| 
       184 
189 
     | 
    
         
             
                end
         
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
                # @param task [Asana::Resources::Task]
         
     | 
| 
       187 
     | 
    
         
            -
                # @return [Time, nil]
         
     | 
| 
       188 
     | 
    
         
            -
                def start_time(task)
         
     | 
| 
       189 
     | 
    
         
            -
                  return @time_class.parse(task.start_at) if task.start_at
         
     | 
| 
       190 
     | 
    
         
            -
                  return @time_class.parse(task.start_on) if task.start_on
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                  nil
         
     | 
| 
       193 
     | 
    
         
            -
                end
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
                # @param task [Asana::Resources::Task]
         
     | 
| 
       196 
     | 
    
         
            -
                # @return [Time, nil]
         
     | 
| 
       197 
     | 
    
         
            -
                def due_time(task)
         
     | 
| 
       198 
     | 
    
         
            -
                  return @time_class.parse(task.due_at) if task.due_at
         
     | 
| 
       199 
     | 
    
         
            -
                  return @time_class.parse(task.due_on) if task.due_on
         
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
                  nil
         
     | 
| 
       202 
     | 
    
         
            -
                end
         
     | 
| 
       203 
190 
     | 
    
         
             
              end
         
     | 
| 
       204 
191 
     | 
    
         
             
            end
         
     | 
    
        data/lib/checkoff/version.rb
    CHANGED
    
    
    
        data/lib/checkoff.rb
    CHANGED
    
    
    
        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.94.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-10- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-10-23 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: activesupport
         
     | 
| 
         @@ -153,7 +153,9 @@ files: 
     | 
|
| 
       153 
153 
     | 
    
         
             
            - lib/checkoff/internal/selector_classes/task/function_evaluator.rb
         
     | 
| 
       154 
154 
     | 
    
         
             
            - lib/checkoff/internal/selector_evaluator.rb
         
     | 
| 
       155 
155 
     | 
    
         
             
            - lib/checkoff/internal/task_selector_evaluator.rb
         
     | 
| 
      
 156 
     | 
    
         
            +
            - lib/checkoff/internal/task_timing.rb
         
     | 
| 
       156 
157 
     | 
    
         
             
            - lib/checkoff/my_tasks.rb
         
     | 
| 
      
 158 
     | 
    
         
            +
            - lib/checkoff/portfolios.rb
         
     | 
| 
       157 
159 
     | 
    
         
             
            - lib/checkoff/project_selectors.rb
         
     | 
| 
       158 
160 
     | 
    
         
             
            - lib/checkoff/projects.rb
         
     | 
| 
       159 
161 
     | 
    
         
             
            - lib/checkoff/section_selectors.rb
         
     |