checkoff 0.2.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 117a1e63ffe4109064607e746bc4c48b42d923d6
4
- data.tar.gz: 4d428edd63053d7b021ad32d8c479b7f5fb54931
2
+ SHA256:
3
+ metadata.gz: a75e010929b7dcb752bf9cffd0f424039cb4c54da94e44af30a8b8627f13eefb
4
+ data.tar.gz: f2410a5287cf99a90f23ed7052a18f09553a652b87b575a2b665e7717c0193fa
5
5
  SHA512:
6
- metadata.gz: 96086eddeb94cfa9f01c37d9df640a71698f591ef1281f9a7ba1fcc40ab5e6a31f06bf40f7c987b741b64dbffa67f6dc63c3962f4434c3eea40e679fab9755a5
7
- data.tar.gz: 320d92a0cc339558fabaf5372476764f721c73cbf5ace1a3366c3fb2c09ec52e38e2a7aef7c6d3e31957bdf21a594006cd579bbf6843764226b54dcf0dbd49a8
6
+ metadata.gz: b7f458362faa147dc0c6d6097b4c3e912ce73c9a5de729fdfedd61bb691b7f0825b35dbce99ad5e06e7b82a1945a576fde09455fb94655a4748995d251da62e2
7
+ data.tar.gz: 3e47840ed4da82d9859876773436ad678f44b02e9b8aa1de34ed7f2de6b0a1ea4cb4b25738c627bc2d7bca1de27ced995e9b57e6f6af3e52badf499bdf5f4cd5
@@ -0,0 +1,17 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ working_directory: ~/checkoff
5
+ docker:
6
+ - image: apiology/circleci-ruby:latest
7
+ steps:
8
+ - checkout
9
+ - type: cache-restore
10
+ key: checkoff-{{ checksum "checkoff.gemspec" }}-{{ checksum "Gemfile" }}
11
+ - run: gem install --no-document bundler
12
+ - run: bundle install --path vendor/bundle --jobs=4
13
+ - type: cache-save
14
+ key: checkoff-{{ checksum "checkoff.gemspec" }}-{{ checksum "Gemfile" }}
15
+ paths:
16
+ - "vendor/bundle"
17
+ - run: bundle exec rake --jobs=4 ci
@@ -1,27 +1,27 @@
1
- # I like trailing commas in maps. They let me insert new elements and
1
+ # I like trailing commas in hashes. They let me insert new elements and
2
2
  # see them as one line in a diff, not two.
3
- Style/TrailingCommaInLiteral:
3
+ Style/TrailingCommaInHashLiteral:
4
+ EnforcedStyleForMultiline: comma
5
+
6
+ Style/TrailingCommaInArrayLiteral:
4
7
  EnforcedStyleForMultiline: comma
5
8
 
6
9
  # I use keyword arguments for a poor man's dependency injection to cut
7
10
  # down on the magic in my tests.
8
- ParameterLists:
11
+ Metrics/ParameterLists:
9
12
  CountKeywordArgs: false
10
13
 
11
- # If i'm using one function name and returning the contents of an
14
+ # If I'm using one function name and returning the contents of an
12
15
  # attribute, that's OK. The alternative would be this, which I find
13
16
  # confusing and often not really what I mean:
14
17
  #
15
18
  # attr_reader :something_else
16
19
  # alias_method :something, :something_else
17
- TrivialAccessors:
20
+ Style/TrivialAccessors:
18
21
  ExactNameMatch: true
19
22
 
20
- Layout/MultilineMethodCallIndentation:
21
- EnforcedStyle: indented
22
-
23
23
  #
24
- # Add 'XXX' to the standard list
24
+ # Add 'XX X' to the standard list
25
25
  #
26
26
  Style/CommentAnnotation:
27
27
  Keywords:
@@ -37,3 +37,41 @@ Style/CommentAnnotation:
37
37
  W"
38
38
  - "XX\
39
39
  X"
40
+
41
+ # https://stackoverflow.com/questions/40934345/rubocop-25-line-block-size-and-rspec-tests
42
+ Metrics/BlockLength:
43
+ # Exclude DSLs
44
+ Exclude:
45
+ - 'Rakefile'
46
+ - '*.gemspec'
47
+ - '**/*.rake'
48
+ - 'spec/**/*.rb'
49
+ - 'feature/**/*.rb'
50
+
51
+ # http://www.betterspecs.org/#single
52
+ #
53
+ # > in tests that are not isolated (e.g. ones that integrate with a
54
+ # > DB, an external webservice, or end-to-end-tests), you take a
55
+ # > massive performance hit to do the same setup over and over again,
56
+ # > just to set a different expectation in each test. In these sorts
57
+ # > of slower tests, I think it's fine to specify more than one
58
+ # > isolated behavior.
59
+ RSpec/MultipleExpectations:
60
+ Exclude:
61
+ - 'feature/**/*.rb'
62
+
63
+ Style/StringLiterals:
64
+ EnforcedStyle: single_quotes
65
+ SupportedStyles:
66
+ - single_quotes
67
+ - double_quotes
68
+ ConsistentQuotesInMultiline: true
69
+
70
+ AllCops:
71
+ TargetRubyVersion: 2.4
72
+
73
+
74
+ require:
75
+ - rubocop-rspec
76
+ - rubocop-minitest
77
+ - rubocop-rake
@@ -1 +1 @@
1
- ruby-2.3.6
1
+ 2.6.6
@@ -1,11 +1,17 @@
1
+ language: ruby
2
+ cache: bundler
1
3
  before_install:
4
+ # https://bundler.io/blog/2019/05/14/
5
+ # solutions-for-cant-find-gem-bundler-with-executable-bundle.html
6
+ - gem update --system
2
7
  - gem install bundler
3
- language: ruby
4
8
  rvm:
5
- - ruby-2.5.0
6
- - ruby-2.4.3
7
- - ruby-2.3.6
8
- - ruby-2.2.9
9
- # - jruby-head # see https://github.com/apiology/quality/issues/59
10
- # - jruby-9.0 # see https://github.com/apiology/quality/issues/59
11
- # - ruby-head # Upstream bug - see https://travis-ci.org/apiology/checkoff/jobs/138626934
9
+ # JRuby error with native code build - possibly can be overcome?
10
+ # checking for main() in -lstdc++... RuntimeError: The compiler failed to generate
11
+ # https://travis-ci.com/apiology/pronto-punchlist/jobs/264907931
12
+ # - jruby-head
13
+ - ruby-head
14
+ - ruby-2.7
15
+ - ruby-2.6
16
+ - ruby-2.5
17
+ - ruby-2.4
@@ -0,0 +1,27 @@
1
+ .PHONY: spec feature
2
+
3
+ all: localtest
4
+
5
+ localtest:
6
+ @bundle exec rake localtest
7
+
8
+ feature:
9
+ @bundle exec rake feature
10
+
11
+ spec:
12
+ @bundle exec rake spec
13
+
14
+ rubocop:
15
+ @bundle exec rake rubocop
16
+
17
+ punchlist:
18
+ @bundle exec rake punchlist
19
+
20
+ pronto:
21
+ @bundle exec rake pronto
22
+
23
+ bigfiles:
24
+ @bundle exec rake bigfiles
25
+
26
+ quality:
27
+ @bundle exec rake quality
data/README.md CHANGED
@@ -75,7 +75,7 @@ And even gather counts for project metrics:
75
75
  ```bash
76
76
  $ checkoff view 'Personal Projects' 'Create demo' | jq 'to_entries | map(.value) | flatten | map(.name) | length'
77
77
  4
78
- $
78
+ $
79
79
  ```
80
80
 
81
81
  ## Caching
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: true
2
1
  # coding: ascii
2
+ # frozen_string_literal: true
3
3
 
4
- lib = File.expand_path('../lib', __FILE__)
4
+ lib = File.expand_path('lib', __dir__)
5
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
  require 'checkoff/version'
7
7
 
@@ -27,11 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.add_runtime_dependency 'cache_method'
28
28
  spec.add_runtime_dependency 'dalli'
29
29
 
30
- spec.add_development_dependency 'bundler', '~> 1.12'
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'
34
- spec.add_development_dependency 'rake', '~> 10.0'
33
+ spec.add_development_dependency 'quality', '~> 37'
34
+ spec.add_development_dependency 'rake', '~> 13.0'
35
35
  spec.add_development_dependency 'rspec', '>=3.4'
36
36
  spec.add_development_dependency 'simplecov'
37
37
  end
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "result": {
3
- "covered_percent": 98.65
3
+ "covered_percent": 85.99
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'
@@ -63,7 +63,7 @@ module Checkoff
63
63
  def quickadd(workspace_name, task_name)
64
64
  workspace = @workspaces.workspace_by_name(workspace_name)
65
65
  @tasks.add_task(task_name,
66
- workspace_id: workspace.id)
66
+ workspace_gid: workspace.gid)
67
67
  end
68
68
 
69
69
  def validate_args!(args)
@@ -103,7 +103,7 @@ module Checkoff
103
103
  stderr.puts " #{$PROGRAM_NAME} quickadd workspace task_name"
104
104
  stderr.puts
105
105
  stderr.puts "'project' can be set to a project name, or :my_tasks, " \
106
- ':my_tasks_upcoming, :my_tasks_new, or :my_tasks_today'
106
+ ":my_tasks_upcoming, :my_tasks_new, or :my_tasks_today"
107
107
  end
108
108
 
109
109
  def view(workspace_name, project_name, section_name)
@@ -10,7 +10,7 @@ module Checkoff
10
10
  def self.load(sym)
11
11
  file = "#{sym}.yml"
12
12
  YAML.load_file(File.expand_path("~/.#{file}"))
13
- .with_indifferent_access
13
+ .with_indifferent_access
14
14
  end
15
15
  end
16
16
  end
@@ -43,16 +43,18 @@ module Checkoff
43
43
  def projects_by_workspace_name(workspace_name)
44
44
  workspace = @workspaces.workspace_by_name(workspace_name)
45
45
  raise "Could not find workspace named #{workspace_name}" unless workspace
46
- projects.find_by_workspace(workspace: workspace.id)
46
+
47
+ projects.find_by_workspace(workspace: workspace.gid)
47
48
  end
48
49
 
49
50
  def my_tasks(workspace_name)
50
51
  my_tasks = @config[:my_tasks]
51
- id = @config[:my_tasks][workspace_name] unless my_tasks.nil?
52
- if my_tasks.nil? || id.nil?
52
+ gid = @config[:my_tasks][workspace_name] unless my_tasks.nil?
53
+ if my_tasks.nil? || gid.nil?
53
54
  raise "Please define [:my_tasks][#{workspace_name}] in config file"
54
55
  end
55
- projects.find_by_id(id)
56
+
57
+ projects.find_by_id(gid)
56
58
  end
57
59
 
58
60
  def project(workspace_name, project_name)
@@ -75,7 +77,8 @@ module Checkoff
75
77
  {
76
78
  per_page: 100,
77
79
  options: {
78
- fields: %w[name completed_at due_at due_on assignee_status tags],
80
+ fields: %w[name completed_at due_at due_on assignee_status tags
81
+ memberships.project.gid memberships.section.name],
79
82
  },
80
83
  }
81
84
  end
@@ -83,10 +86,10 @@ module Checkoff
83
86
  def tasks_from_project(project, only_uncompleted: true, extra_fields: [])
84
87
  options = task_options
85
88
  options[:completed_since] = '9999-12-01' if only_uncompleted
86
- options[:project] = project.id
89
+ options[:project] = project.gid
87
90
  options[:options][:fields] += extra_fields
88
- client.tasks.find_all(options).to_a
91
+ client.tasks.find_all(**options).to_a
89
92
  end
90
- cache_method :tasks_from_project, LONG_CACHE_TIME
93
+ cache_method :tasks_from_project, SHORT_CACHE_TIME
91
94
  end
92
95
  end
@@ -21,23 +21,17 @@ module Checkoff
21
21
 
22
22
  def_delegators :@projects, :client
23
23
 
24
- def file_task_by_section(current_section, by_section, task)
25
- if task.name =~ /:$/
26
- current_section = task.name
27
- by_section[current_section] = []
28
- else
29
- by_section[current_section] ||= []
30
- by_section[current_section] << task
31
- end
32
- [current_section, by_section]
24
+ def file_task_by_section(by_section, task, project_gid)
25
+ membership = task.memberships.find { |m| m.project.gid == project_gid }
26
+ current_section = membership.section.name
27
+ by_section[current_section] ||= []
28
+ by_section[current_section] << task
33
29
  end
34
30
 
35
- def by_section(tasks)
36
- current_section = nil
31
+ def by_section(tasks, project_gid)
37
32
  by_section = {}
38
33
  tasks.each do |task|
39
- current_section, by_section = file_task_by_section(current_section,
40
- by_section, task)
34
+ file_task_by_section(by_section, task, project_gid)
41
35
  end
42
36
  by_section
43
37
  end
@@ -46,7 +40,7 @@ module Checkoff
46
40
  def tasks_by_section_for_project(project)
47
41
  raw_tasks = projects.tasks_from_project(project)
48
42
  active_tasks = projects.active_tasks(raw_tasks)
49
- by_section(active_tasks)
43
+ by_section(active_tasks, project.gid)
50
44
  end
51
45
 
52
46
  def tasks_by_section_for_project_and_assignee_status(project,
@@ -54,9 +48,9 @@ module Checkoff
54
48
  raw_tasks = projects.tasks_from_project(project)
55
49
  by_assignee_status =
56
50
  projects.active_tasks(raw_tasks)
57
- .group_by(&:assignee_status)
51
+ .group_by(&:assignee_status)
58
52
  active_tasks = by_assignee_status[assignee_status]
59
- by_section(active_tasks)
53
+ by_section(active_tasks, project.gid)
60
54
  end
61
55
 
62
56
  def project_or_raise(workspace_name, project_name)
@@ -100,12 +94,6 @@ module Checkoff
100
94
  end
101
95
  cache_method :section_task_names, SHORT_CACHE_TIME
102
96
 
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
97
  def task_due?(task)
110
98
  if task.due_at
111
99
  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
@@ -42,15 +42,15 @@ module Checkoff
42
42
  end
43
43
 
44
44
  def add_task(name,
45
- workspace_id: default_workspace_id,
46
- assignee_id: default_assignee_id)
45
+ workspace_gid: default_workspace_gid,
46
+ assignee_gid: default_assignee_gid)
47
47
  @asana_task.create(client,
48
- assignee: assignee_id,
49
- workspace: workspace_id, name: name)
48
+ assignee: assignee_gid,
49
+ workspace: workspace_gid, name: name)
50
50
  end
51
51
 
52
- def default_assignee_id
53
- @config[:default_assignee_id]
52
+ def default_assignee_gid
53
+ @config[:default_assignee_gid]
54
54
  end
55
55
  end
56
56
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Checkoff
4
- VERSION = '0.2.0'
4
+ VERSION = '0.5.0'
5
5
  end
@@ -12,11 +12,12 @@ module Checkoff
12
12
  def client
13
13
  @client ||= @asana_client.new do |c|
14
14
  c.authentication :access_token, @config[:personal_access_token]
15
+ c.default_headers 'asana-enable' => 'string_ids,new_sections'
15
16
  end
16
17
  end
17
18
 
18
- def default_workspace_id
19
- @config[:default_workspace_id]
19
+ def default_workspace_gid
20
+ @config[:default_workspace_gid]
20
21
  end
21
22
 
22
23
  def workspace_by_name(workspace_name)
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ desc 'Run tasks to be done during a continuous integration (CI) build'
3
4
  task ci: :localtest
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ desc 'Rebaseline quality thresholds to last commit'
3
4
  task :clear_metrics do |_t|
4
5
  ret =
5
6
  system('git checkout coverage/.last_run.json metrics/*_high_water_mark')
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ desc 'Standard build when running on a workstation'
3
4
  task localtest: %i[clear_metrics test quality]
@@ -1 +1 @@
1
- 459
1
+ 389
@@ -1 +1 @@
1
- 8
1
+ 7
@@ -1,2 +1 @@
1
- 11
2
-
1
+ 3
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.2.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vince Broz
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-26 00:00:00.000000000 Z
11
+ date: 2020-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.12'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.12'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: minitest-profile
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -112,30 +112,30 @@ dependencies:
112
112
  name: quality
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '37'
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: '0'
124
+ version: '37'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rake
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '10.0'
131
+ version: '13.0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '10.0'
138
+ version: '13.0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rspec
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -164,7 +164,7 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- description:
167
+ description:
168
168
  email:
169
169
  - vince@broz.cc
170
170
  executables:
@@ -172,6 +172,7 @@ executables:
172
172
  extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
+ - ".circleci/config.yml"
175
176
  - ".gitignore"
176
177
  - ".rubocop.yml"
177
178
  - ".ruby-version"
@@ -179,12 +180,12 @@ files:
179
180
  - CODE_OF_CONDUCT.md
180
181
  - Gemfile
181
182
  - LICENSE.txt
183
+ - Makefile
182
184
  - README.md
183
185
  - Rakefile
184
186
  - bin/console
185
187
  - bin/setup
186
188
  - checkoff.gemspec
187
- - circle.yml
188
189
  - coverage/.last_run.json
189
190
  - docs/example_project.png
190
191
  - exe/checkoff
@@ -193,6 +194,7 @@ files:
193
194
  - lib/checkoff/config_loader.rb
194
195
  - lib/checkoff/projects.rb
195
196
  - lib/checkoff/sections.rb
197
+ - lib/checkoff/subtasks.rb
196
198
  - lib/checkoff/tasks.rb
197
199
  - lib/checkoff/version.rb
198
200
  - lib/checkoff/workspaces.rb
@@ -216,6 +218,7 @@ files:
216
218
  - metrics/mdl_high_water_mark
217
219
  - metrics/pep8_high_water_mark
218
220
  - metrics/punchlist_high_water_mark
221
+ - metrics/pycodestyle_high_water_mark
219
222
  - metrics/rails_best_practices_high_water_mark
220
223
  - metrics/rubocop_high_water_mark
221
224
  - metrics/scalastyle_high_water_mark
@@ -224,7 +227,7 @@ homepage: http://github.com/apiology/checkoff
224
227
  licenses:
225
228
  - MIT
226
229
  metadata: {}
227
- post_install_message:
230
+ post_install_message:
228
231
  rdoc_options: []
229
232
  require_paths:
230
233
  - lib
@@ -239,9 +242,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
242
  - !ruby/object:Gem::Version
240
243
  version: '0'
241
244
  requirements: []
242
- rubyforge_project:
243
- rubygems_version: 2.6.14
244
- signing_key:
245
+ rubygems_version: 3.0.3
246
+ signing_key:
245
247
  specification_version: 4
246
248
  summary: Command-line and gem client for Asana (unofficial)
247
249
  test_files: []
data/circle.yml DELETED
@@ -1,6 +0,0 @@
1
- test:
2
- override:
3
- - bundle exec rake localtest
4
- general:
5
- artifacts:
6
- - "coverage"