checkoff 0.3.2 → 0.5.3

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: 7b60fa3a74c9081153ae5c0f489da64684033ae6f675129d07aaf401dcc43170
4
- data.tar.gz: a382e7ad7163e6465e561eb427f2ddc5c73c5039de45028d306aec082212995a
3
+ metadata.gz: 7c4947b2573662cc82bf0fd8652c9efc13169326fb70952e3794aecd3a071a1c
4
+ data.tar.gz: 97d4f7ec0a0781a62750462fc0a7428980f06a6d084c029b832897f854fd3d32
5
5
  SHA512:
6
- metadata.gz: a3599189037cb4bc794f1acb098e927b8556d88bde21c49591e6e79b6cd203c74befad345c883a4c28e07edc73ca467601099a93f99b8b8abf4f28150df4aed6
7
- data.tar.gz: 747a97c032b4e40ead6c6e2d76ec6e571b0b37e2ec7e66cf7ed706d95061ef90e0c2666f3d974199801b98c4f5083d772e76ddacd0460d549c326dcbb036b791
6
+ metadata.gz: 02e3a309b680887411309fa3f33d8f14a325889f1bfbf5c18790cec9ab20aa80a0e71ab38fdcfa7eefe523474dd2a56bf0443b3523fc0cb0bd90719dd380fcf9
7
+ data.tar.gz: 22f2339cda88ee9ee63d6009e945d29bf2a7d9b552b0eae3d2a39892bc1f85e3ce373afd341fde97d24719ad89fbf804250fd4450761a4920ab00bc0e17b465d
@@ -67,9 +67,134 @@ Style/StringLiterals:
67
67
  - double_quotes
68
68
  ConsistentQuotesInMultiline: true
69
69
 
70
- AllCops:
71
- TargetRubyVersion: 2.4
70
+ Layout/BeginEndAlignment: # (new in 0.91)
71
+ Enabled: true
72
+ Layout/EmptyLinesAroundAttributeAccessor: # (new in 0.83)
73
+ Enabled: true
74
+ Layout/SpaceAroundMethodCallOperator: # (new in 0.82)
75
+ Enabled: true
76
+ Lint/BinaryOperatorWithIdenticalOperands: # (new in 0.89)
77
+ Enabled: true
78
+ Lint/ConstantDefinitionInBlock: # (new in 0.91)
79
+ Enabled: true
80
+ Lint/DeprecatedOpenSSLConstant: # (new in 0.84)
81
+ Enabled: true
82
+ Lint/DuplicateElsifCondition: # (new in 0.88)
83
+ Enabled: true
84
+ Lint/DuplicateRequire: # (new in 0.90)
85
+ Enabled: true
86
+ Lint/DuplicateRescueException: # (new in 0.89)
87
+ Enabled: true
88
+ Lint/EmptyConditionalBody: # (new in 0.89)
89
+ Enabled: true
90
+ Lint/EmptyFile: # (new in 0.90)
91
+ Enabled: true
92
+ Lint/FloatComparison: # (new in 0.89)
93
+ Enabled: true
94
+ Lint/IdentityComparison: # (new in 0.91)
95
+ Enabled: true
96
+ Lint/MissingSuper: # (new in 0.89)
97
+ Enabled: true
98
+ Lint/MixedRegexpCaptureTypes: # (new in 0.85)
99
+ Enabled: true
100
+ Lint/OutOfRangeRegexpRef: # (new in 0.89)
101
+ Enabled: true
102
+ Lint/RaiseException: # (new in 0.81)
103
+ Enabled: true
104
+ Lint/SelfAssignment: # (new in 0.89)
105
+ Enabled: true
106
+ Lint/StructNewOverride: # (new in 0.81)
107
+ Enabled: true
108
+ Lint/TopLevelReturnWithArgument: # (new in 0.89)
109
+ Enabled: true
110
+ Lint/TrailingCommaInAttributeDeclaration: # (new in 0.90)
111
+ Enabled: true
112
+ Lint/UnreachableLoop: # (new in 0.89)
113
+ Enabled: true
114
+ Lint/UselessMethodDefinition: # (new in 0.90)
115
+ Enabled: true
116
+ Lint/UselessTimes: # (new in 0.91)
117
+ Enabled: true
118
+ Style/AccessorGrouping: # (new in 0.87)
119
+ Enabled: true
120
+ Style/BisectedAttrAccessor: # (new in 0.87)
121
+ Enabled: true
122
+ Style/CaseLikeIf: # (new in 0.88)
123
+ Enabled: true
124
+ Style/CombinableLoops: # (new in 0.90)
125
+ Enabled: true
126
+ Style/ExplicitBlockArgument: # (new in 0.89)
127
+ Enabled: true
128
+ Style/ExponentialNotation: # (new in 0.82)
129
+ Enabled: true
130
+ Style/GlobalStdStream: # (new in 0.89)
131
+ Enabled: true
132
+ Style/HashAsLastArrayItem: # (new in 0.88)
133
+ Enabled: true
134
+ Style/HashEachMethods: # (new in 0.80)
135
+ Enabled: true
136
+ Style/HashLikeCase: # (new in 0.88)
137
+ Enabled: true
138
+ Style/HashTransformKeys: # (new in 0.80)
139
+ Enabled: true
140
+ Style/HashTransformValues: # (new in 0.80)
141
+ Enabled: true
142
+ Style/KeywordParametersOrder: # (new in 0.90)
143
+ Enabled: true
144
+ Style/OptionalBooleanParameter: # (new in 0.89)
145
+ Enabled: true
146
+ Style/RedundantAssignment: # (new in 0.87)
147
+ Enabled: true
148
+ Style/RedundantFetchBlock: # (new in 0.86)
149
+ Enabled: true
150
+ Style/RedundantFileExtensionInRequire: # (new in 0.88)
151
+ Enabled: true
152
+ Style/RedundantRegexpCharacterClass: # (new in 0.85)
153
+ Enabled: true
154
+ Style/RedundantRegexpEscape: # (new in 0.85)
155
+ Enabled: true
156
+ Style/RedundantSelfAssignment: # (new in 0.90)
157
+ Enabled: true
158
+ Style/SingleArgumentDig: # (new in 0.89)
159
+ Enabled: true
160
+ Style/SlicingWithRange: # (new in 0.83)
161
+ Enabled: true
162
+ Style/SoleNestedConditional: # (new in 0.89)
163
+ Enabled: true
164
+ Style/StringConcatenation: # (new in 0.89)
165
+ Enabled: true
166
+ Minitest/AssertInDelta: # (new in 0.10)
167
+ Enabled: true
168
+ Minitest/AssertionInLifecycleHook: # (new in 0.10)
169
+ Enabled: true
170
+ Minitest/AssertKindOf: # (new in 0.10)
171
+ Enabled: true
172
+ Minitest/AssertOutput: # (new in 0.10)
173
+ Enabled: true
174
+ Minitest/AssertPathExists: # (new in 0.10)
175
+ Enabled: true
176
+ Minitest/AssertSilent: # (new in 0.10)
177
+ Enabled: true
178
+ Minitest/LiteralAsActualArgument: # (new in 0.10)
179
+ Enabled: true
180
+ Minitest/MultipleAssertions: # (new in 0.10)
181
+ Enabled: true
182
+ Minitest/RefuteInDelta: # (new in 0.10)
183
+ Enabled: true
184
+ Minitest/RefuteKindOf: # (new in 0.10)
185
+ Enabled: true
186
+ Minitest/RefutePathExists: # (new in 0.10)
187
+ Enabled: true
188
+ Minitest/TestMethodName: # (new in 0.10)
189
+ # This gives false positives when non-test methods exist...
190
+ Enabled: false
191
+ Minitest/UnspecifiedException: # (new in 0.10)
192
+ Enabled: true
193
+ RSpec/StubbedMock: # (new in 1.44)
194
+ Enabled: true
72
195
 
196
+ AllCops:
197
+ TargetRubyVersion: 2.6
73
198
 
74
199
  require:
75
200
  - rubocop-rspec
@@ -10,12 +10,12 @@ Gem::Specification.new do |spec|
10
10
  spec.version = Checkoff::VERSION
11
11
  spec.authors = ['Vince Broz']
12
12
  spec.email = ['vince@broz.cc']
13
-
14
13
  spec.summary = 'Command-line and gem client for Asana (unofficial)'
15
14
  spec.homepage = 'http://github.com/apiology/checkoff'
16
15
  spec.license = 'MIT'
16
+ spec.required_ruby_version = '>= 2.6'
17
17
 
18
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
19
  f.match(%r{^(test|spec|features)/})
20
20
  end
21
21
  spec.bindir = 'exe'
@@ -23,14 +23,14 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ['lib']
24
24
 
25
25
  spec.add_runtime_dependency 'activesupport'
26
- spec.add_runtime_dependency 'asana'
26
+ spec.add_runtime_dependency 'asana', '>0.10.0'
27
27
  spec.add_runtime_dependency 'cache_method'
28
28
  spec.add_runtime_dependency 'dalli'
29
29
 
30
30
  spec.add_development_dependency 'bundler'
31
31
  spec.add_development_dependency 'minitest-profile'
32
32
  spec.add_development_dependency 'mocha'
33
- spec.add_development_dependency 'quality', '~> 37'
33
+ spec.add_development_dependency 'quality', '~> 38'
34
34
  spec.add_development_dependency 'rake', '~> 13.0'
35
35
  spec.add_development_dependency 'rspec', '>=3.4'
36
36
  spec.add_development_dependency 'simplecov'
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "result": {
3
- "covered_percent": 98.65
3
+ "covered_percent": 83.74
4
4
  }
5
5
  }
@@ -4,4 +4,5 @@ require 'checkoff/version'
4
4
  require 'checkoff/workspaces'
5
5
  require 'checkoff/projects'
6
6
  require 'checkoff/sections'
7
+ require 'checkoff/subtasks'
7
8
  require 'checkoff/tasks'
@@ -15,11 +15,13 @@ module Checkoff
15
15
  class CLI
16
16
  attr_reader :sections, :stderr
17
17
 
18
- def initialize(workspaces: Checkoff::Workspaces.new,
19
- projects: Checkoff::Projects.new,
20
- sections: Checkoff::Sections.new(projects: projects),
21
- tasks: Checkoff::Tasks.new,
22
- stderr: STDERR,
18
+ def initialize(config: Checkoff::ConfigLoader.load(:asana),
19
+ workspaces: Checkoff::Workspaces.new(config: config),
20
+ projects: Checkoff::Projects.new(config: config),
21
+ sections: Checkoff::Sections.new(config: config,
22
+ projects: projects),
23
+ tasks: Checkoff::Tasks.new(config: config),
24
+ stderr: $stderr,
23
25
  kernel: Kernel)
24
26
  @workspaces = workspaces
25
27
  @projects = projects
@@ -87,9 +89,10 @@ module Checkoff
87
89
  def parse_args(args)
88
90
  mode = args[0]
89
91
  subargs = OpenStruct.new
90
- if mode == 'view'
92
+ case mode
93
+ when 'view'
91
94
  parse_view_args(subargs, args)
92
- elsif mode == 'quickadd'
95
+ when 'quickadd'
93
96
  parse_quickadd_args(subargs, args)
94
97
  else
95
98
  raise
@@ -107,7 +110,7 @@ module Checkoff
107
110
  end
108
111
 
109
112
  def view(workspace_name, project_name, section_name)
110
- project_name = project_name[1..-1].to_sym if project_name.start_with? ':'
113
+ project_name = project_name[1..].to_sym if project_name.start_with? ':'
111
114
  if section_name.nil?
112
115
  run_on_project(workspace_name, project_name)
113
116
  else
@@ -118,9 +121,10 @@ module Checkoff
118
121
  def run(args)
119
122
  validate_args!(args)
120
123
  command, subargs = parse_args(args)
121
- if command == 'view'
124
+ case command
125
+ when 'view'
122
126
  view(subargs.workspace, subargs.project, subargs.section)
123
- elsif command == 'quickadd'
127
+ when 'quickadd'
124
128
  quickadd(subargs.workspace, subargs.task_name)
125
129
  else
126
130
  raise
@@ -3,7 +3,6 @@
3
3
  require 'yaml'
4
4
  require 'active_support/core_ext/hash'
5
5
 
6
- # frozen_string_literal: true
7
6
  module Checkoff
8
7
  # Load configuration file
9
8
  class ConfigLoader
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'config_loader'
2
4
 
3
- # frozen_string_literal: true
4
5
  require 'cache_method'
5
6
  require 'asana'
6
7
 
@@ -25,7 +26,7 @@ module Checkoff
25
26
 
26
27
  def initialize(config: Checkoff::ConfigLoader.load(:asana),
27
28
  asana_client: Asana::Client,
28
- workspaces: Checkoff::Workspaces.new)
29
+ workspaces: Checkoff::Workspaces.new(config: config))
29
30
  @config = config
30
31
  @asana_client = asana_client
31
32
  @workspaces = workspaces
@@ -50,9 +51,7 @@ module Checkoff
50
51
  def my_tasks(workspace_name)
51
52
  my_tasks = @config[:my_tasks]
52
53
  gid = @config[:my_tasks][workspace_name] unless my_tasks.nil?
53
- if my_tasks.nil? || gid.nil?
54
- raise "Please define [:my_tasks][#{workspace_name}] in config file"
55
- end
54
+ raise "Please define [:my_tasks][#{workspace_name}] in config file" if my_tasks.nil? || gid.nil?
56
55
 
57
56
  projects.find_by_id(gid)
58
57
  end
@@ -77,7 +76,8 @@ module Checkoff
77
76
  {
78
77
  per_page: 100,
79
78
  options: {
80
- fields: %w[name completed_at due_at due_on assignee_status tags],
79
+ fields: %w[name completed_at due_at due_on assignee_status tags
80
+ memberships.project.gid memberships.section.name],
81
81
  },
82
82
  }
83
83
  end
@@ -87,7 +87,7 @@ module Checkoff
87
87
  options[:completed_since] = '9999-12-01' if only_uncompleted
88
88
  options[:project] = project.gid
89
89
  options[:options][:fields] += extra_fields
90
- client.tasks.find_all(options).to_a
90
+ client.tasks.find_all(**options).to_a
91
91
  end
92
92
  cache_method :tasks_from_project, SHORT_CACHE_TIME
93
93
  end
@@ -13,7 +13,8 @@ module Checkoff
13
13
 
14
14
  attr_reader :projects, :time
15
15
 
16
- def initialize(projects: Checkoff::Projects.new,
16
+ def initialize(config: Checkoff::ConfigLoader.load(:asana),
17
+ projects: Checkoff::Projects.new(config: config),
17
18
  time: Time)
18
19
  @projects = projects
19
20
  @time = time
@@ -21,7 +22,32 @@ module Checkoff
21
22
 
22
23
  def_delegators :@projects, :client
23
24
 
24
- def file_task_by_section(current_section, by_section, task)
25
+ def file_task_by_section(by_section, task, project_gid)
26
+ membership = task.memberships.find { |m| m.project.gid == project_gid }
27
+ raise "Could not find task in project_gid #{project_gid}: #{task}" if membership.nil?
28
+
29
+ current_section = membership.section.name
30
+ current_section = nil if current_section == '(no section)'
31
+ by_section[current_section] ||= []
32
+ by_section[current_section] << task
33
+ end
34
+
35
+ def by_section(tasks, project_gid)
36
+ by_section = {}
37
+ tasks.each do |task|
38
+ file_task_by_section(by_section, task, project_gid)
39
+ end
40
+ by_section
41
+ end
42
+ cache_method :by_section, LONG_CACHE_TIME
43
+
44
+ def tasks_by_section_for_project(project)
45
+ raw_tasks = projects.tasks_from_project(project)
46
+ active_tasks = projects.active_tasks(raw_tasks)
47
+ by_section(active_tasks, project.gid)
48
+ end
49
+
50
+ def legacy_file_task_by_section(current_section, by_section, task)
25
51
  if task.name =~ /:$/
26
52
  current_section = task.name
27
53
  by_section[current_section] = []
@@ -32,22 +58,15 @@ module Checkoff
32
58
  [current_section, by_section]
33
59
  end
34
60
 
35
- def by_section(tasks)
61
+ def legacy_by_section(tasks)
36
62
  current_section = nil
37
63
  by_section = {}
38
64
  tasks.each do |task|
39
- current_section, by_section = file_task_by_section(current_section,
40
- by_section, task)
65
+ current_section, by_section =
66
+ legacy_file_task_by_section(current_section, by_section, task)
41
67
  end
42
68
  by_section
43
69
  end
44
- cache_method :by_section, LONG_CACHE_TIME
45
-
46
- def tasks_by_section_for_project(project)
47
- raw_tasks = projects.tasks_from_project(project)
48
- active_tasks = projects.active_tasks(raw_tasks)
49
- by_section(active_tasks)
50
- end
51
70
 
52
71
  def tasks_by_section_for_project_and_assignee_status(project,
53
72
  assignee_status)
@@ -56,7 +75,7 @@ module Checkoff
56
75
  projects.active_tasks(raw_tasks)
57
76
  .group_by(&:assignee_status)
58
77
  active_tasks = by_assignee_status[assignee_status]
59
- by_section(active_tasks)
78
+ legacy_by_section(active_tasks)
60
79
  end
61
80
 
62
81
  def project_or_raise(workspace_name, project_name)
@@ -70,11 +89,12 @@ module Checkoff
70
89
 
71
90
  def tasks_by_section(workspace_name, project_name)
72
91
  project = project_or_raise(workspace_name, project_name)
73
- if project_name == :my_tasks_new
92
+ case project_name
93
+ when :my_tasks_new
74
94
  tasks_by_section_for_project_and_assignee_status(project, 'inbox')
75
- elsif project_name == :my_tasks_today
95
+ when :my_tasks_today
76
96
  tasks_by_section_for_project_and_assignee_status(project, 'today')
77
- elsif project_name == :my_tasks_upcoming
97
+ when :my_tasks_upcoming
78
98
  tasks_by_section_for_project_and_assignee_status(project, 'upcoming')
79
99
  else
80
100
  tasks_by_section_for_project(project)
@@ -100,12 +120,6 @@ module Checkoff
100
120
  end
101
121
  cache_method :section_task_names, SHORT_CACHE_TIME
102
122
 
103
- # Returns all subtasks, including section headers
104
- def raw_subtasks(task)
105
- task.subtasks(projects.task_options)
106
- end
107
- cache_method :raw_subtasks, LONG_CACHE_TIME
108
-
109
123
  def task_due?(task)
110
124
  if task.due_at
111
125
  Time.parse(task.due_at) <= time.now
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Checkoff
6
+ # Query different subtasks of Asana tasks
7
+ class Subtasks
8
+ MINUTE = 60
9
+ LONG_CACHE_TIME = MINUTE * 15
10
+ SHORT_CACHE_TIME = MINUTE * 5
11
+
12
+ extend Forwardable
13
+
14
+ def file_task_by_section(current_section, by_section, task)
15
+ if task.name =~ /:$/
16
+ current_section = task.name
17
+ by_section[current_section] = []
18
+ else
19
+ by_section[current_section] ||= []
20
+ by_section[current_section] << task
21
+ end
22
+ [current_section, by_section]
23
+ end
24
+
25
+ def by_section(tasks)
26
+ current_section = nil
27
+ by_section = {}
28
+ tasks.each do |task|
29
+ current_section, by_section = file_task_by_section(current_section,
30
+ by_section, task)
31
+ end
32
+ by_section
33
+ end
34
+
35
+ # Returns all subtasks, including section headers
36
+ def raw_subtasks(task)
37
+ task.subtasks(projects.task_options)
38
+ end
39
+ cache_method :raw_subtasks, LONG_CACHE_TIME
40
+ end
41
+ end
@@ -15,7 +15,7 @@ module Checkoff
15
15
  SHORT_CACHE_TIME = MINUTE * 5
16
16
 
17
17
  def initialize(config: Checkoff::ConfigLoader.load(:asana),
18
- sections: Checkoff::Sections.new,
18
+ sections: Checkoff::Sections.new(config: config),
19
19
  asana_task: Asana::Resources::Task)
20
20
  @config = config
21
21
  @sections = sections
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Checkoff
4
- VERSION = '0.3.2'
4
+ VERSION = '0.5.3'
5
5
  end
@@ -3,7 +3,7 @@
3
3
  require 'quality/rake/task'
4
4
 
5
5
  Quality::Rake::Task.new do |task|
6
- task.skip_tools = ['reek']
6
+ task.skip_tools = %w[reek cane eslint jscs pycodestyle rails_best_practices flake8]
7
7
  task.output_dir = 'metrics'
8
- task.exclude_files = ['docs/example_project.png']
8
+ task.exclude_files = ['docs/example_project.png', '.rubocop.yml']
9
9
  end
@@ -1 +1 @@
1
- 457
1
+ 414
@@ -1 +1 @@
1
- 10
1
+ 3
@@ -1 +1 @@
1
- 2
1
+ 4
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.3.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vince Broz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-11 00:00:00.000000000 Z
11
+ date: 2020-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: asana
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - ">"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 0.10.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - ">"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.10.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cache_method
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '37'
117
+ version: '38'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '37'
124
+ version: '38'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rake
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -194,6 +194,7 @@ files:
194
194
  - lib/checkoff/config_loader.rb
195
195
  - lib/checkoff/projects.rb
196
196
  - lib/checkoff/sections.rb
197
+ - lib/checkoff/subtasks.rb
197
198
  - lib/checkoff/tasks.rb
198
199
  - lib/checkoff/version.rb
199
200
  - lib/checkoff/workspaces.rb
@@ -234,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
235
  requirements:
235
236
  - - ">="
236
237
  - !ruby/object:Gem::Version
237
- version: '0'
238
+ version: '2.6'
238
239
  required_rubygems_version: !ruby/object:Gem::Requirement
239
240
  requirements:
240
241
  - - ">="