checkoff 0.4.0 → 0.5.4

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: abb481b28efc4dc6131fdc028fe0bffb8c441dc92c95474e23455f7a1fed8ede
4
- data.tar.gz: 98e270c7be0078e5efa19425affc4692c3343d093e5ab96d027eb5b643d8b141
3
+ metadata.gz: eedcba2aa1cb33274b57228b924f8871d65e6d169b90d85b8328b207245c5d80
4
+ data.tar.gz: 075bd1131ea2a329637d77e08ce41e5589889c2207751634c7fe83fe7f8935d8
5
5
  SHA512:
6
- metadata.gz: 2c6ddd7d5092290e0fbc953274f98c2b0b68262aef2201a378fa71a947152ee3c0d331c730127e5ba05616e7e9afc3261324a5d0b6babbaf63c4bd96115fcfa2
7
- data.tar.gz: 3ba297866e0c3970e12a8f31b796359f58b93d02a2d7aae5aef04dd071e68a5d4d41a4c5c4e8b3ec5f38123b0f7072f1dd2ee98217fae9bd3d1a6fb2aa843012
6
+ metadata.gz: a7aaf83addcfd2371145991bd2672e0cd2ec9307359bcdd8fe606ff4e60eff09271b5fb08e031b448c540f29a2c3b7dbbddf2127f5a75c52ff8b4beacc8b3382
7
+ data.tar.gz: 581ccb6c3e27e608abf704751f06dcfd79ceb96b37f78131e603d9659961bf4269717aa5d6fd53bbf09f8cc71116e8ca859c27d327dbb13c05583552f0353a42
@@ -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.5
73
198
 
74
199
  require:
75
200
  - rubocop-rspec
@@ -10,8 +10,13 @@ rvm:
10
10
  # checking for main() in -lstdc++... RuntimeError: The compiler failed to generate
11
11
  # https://travis-ci.com/apiology/pronto-punchlist/jobs/264907931
12
12
  # - jruby-head
13
- - ruby-head
13
+
14
+ # These are currently pending ruby-asana fixes:
15
+ #
16
+ # https://github.com/Asana/ruby-asana/pull/99
17
+ #
18
+ # - ruby-head
19
+ # - ruby-3.0
14
20
  - ruby-2.7
15
21
  - ruby-2.6
16
22
  - ruby-2.5
17
- - ruby-2.4
@@ -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.5'
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": 88.54
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
@@ -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
@@ -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
@@ -22,8 +23,11 @@ module Checkoff
22
23
  def_delegators :@projects, :client
23
24
 
24
25
  def file_task_by_section(by_section, task, project_gid)
25
- membership = task.memberships.find { |m| m.project.gid == 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
+
26
29
  current_section = membership.section.name
30
+ current_section = nil if current_section == '(no section)'
27
31
  by_section[current_section] ||= []
28
32
  by_section[current_section] << task
29
33
  end
@@ -43,6 +47,27 @@ module Checkoff
43
47
  by_section(active_tasks, project.gid)
44
48
  end
45
49
 
50
+ def legacy_file_task_by_section(current_section, by_section, task)
51
+ if task.name =~ /:$/
52
+ current_section = task.name
53
+ by_section[current_section] = []
54
+ else
55
+ by_section[current_section] ||= []
56
+ by_section[current_section] << task
57
+ end
58
+ [current_section, by_section]
59
+ end
60
+
61
+ def legacy_by_section(tasks)
62
+ current_section = nil
63
+ by_section = {}
64
+ tasks.each do |task|
65
+ current_section, by_section =
66
+ legacy_file_task_by_section(current_section, by_section, task)
67
+ end
68
+ by_section
69
+ end
70
+
46
71
  def tasks_by_section_for_project_and_assignee_status(project,
47
72
  assignee_status)
48
73
  raw_tasks = projects.tasks_from_project(project)
@@ -50,7 +75,7 @@ module Checkoff
50
75
  projects.active_tasks(raw_tasks)
51
76
  .group_by(&:assignee_status)
52
77
  active_tasks = by_assignee_status[assignee_status]
53
- by_section(active_tasks, project.gid)
78
+ legacy_by_section(active_tasks)
54
79
  end
55
80
 
56
81
  def project_or_raise(workspace_name, project_name)
@@ -64,11 +89,12 @@ module Checkoff
64
89
 
65
90
  def tasks_by_section(workspace_name, project_name)
66
91
  project = project_or_raise(workspace_name, project_name)
67
- if project_name == :my_tasks_new
92
+ case project_name
93
+ when :my_tasks_new
68
94
  tasks_by_section_for_project_and_assignee_status(project, 'inbox')
69
- elsif project_name == :my_tasks_today
95
+ when :my_tasks_today
70
96
  tasks_by_section_for_project_and_assignee_status(project, 'today')
71
- elsif project_name == :my_tasks_upcoming
97
+ when :my_tasks_upcoming
72
98
  tasks_by_section_for_project_and_assignee_status(project, 'upcoming')
73
99
  else
74
100
  tasks_by_section_for_project(project)
@@ -94,12 +120,6 @@ module Checkoff
94
120
  end
95
121
  cache_method :section_task_names, SHORT_CACHE_TIME
96
122
 
97
- # Returns all subtasks, including section headers
98
- def raw_subtasks(task)
99
- task.subtasks(projects.task_options)
100
- end
101
- cache_method :raw_subtasks, LONG_CACHE_TIME
102
-
103
123
  def task_due?(task)
104
124
  if task.due_at
105
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.4.0'
4
+ VERSION = '0.5.4'
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
- 390
1
+ 414
@@ -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.4.0
4
+ version: 0.5.4
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-17 00:00:00.000000000 Z
11
+ date: 2020-12-30 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.5'
238
239
  required_rubygems_version: !ruby/object:Gem::Requirement
239
240
  requirements:
240
241
  - - ">="