checkoff 0.5.3 → 0.8.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/.envrc +2 -0
- data/.overcommit.yml +40 -0
- data/.rubocop.yml +3 -1
- data/.travis.yml +7 -2
- data/README.md +2 -0
- data/bin/checkoff +29 -0
- data/checkoff.gemspec +2 -1
- data/coverage/.last_run.json +1 -1
- data/lib/checkoff/cli.rb +5 -1
- data/lib/checkoff/config_loader.rb +43 -3
- data/lib/checkoff/projects.rb +3 -3
- data/lib/checkoff/sections.rb +48 -8
- data/lib/checkoff/tasks.rb +1 -1
- data/lib/checkoff/version.rb +1 -1
- data/lib/checkoff/workspaces.rb +4 -3
- data/metrics/bigfiles_high_water_mark +1 -1
- data/metrics/rubocop_high_water_mark +1 -1
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 834d9600b69c5f79ba30cbf22a79c66d0a277d517cafe6c2aee32de1c63bb533
|
4
|
+
data.tar.gz: 5cb97edadfd9aca288f6f1e5d95400c0e291306ffd2f3a76ad003560539b88cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83050b84c4cc44b0c5992174cfe8f837f985dd361627ed60e81466f9cb14713b87d14508c9d46d997e9887c8944557252a64bd79f3354c04285c852758fd5021
|
7
|
+
data.tar.gz: '083875c0f26f4309170d036ccec8dc3bb970ddf276916f1744ac0bd1285055de662ac7b29054bceba10fe82baba0ef319731ab32de522fb773a3af824ba687c1'
|
data/.envrc
ADDED
data/.overcommit.yml
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Use this file to configure the Overcommit hooks you wish to use. This will
|
2
|
+
# extend the default configuration defined in:
|
3
|
+
# https://github.com/sds/overcommit/blob/master/config/default.yml
|
4
|
+
#
|
5
|
+
# At the topmost level of this YAML file is a key representing type of hook
|
6
|
+
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
|
7
|
+
# customize each hook, such as whether to only run it on certain files (via
|
8
|
+
# `include`), whether to only display output if it fails (via `quiet`), etc.
|
9
|
+
#
|
10
|
+
# For a complete list of hooks, see:
|
11
|
+
# https://github.com/sds/overcommit/tree/master/lib/overcommit/hook
|
12
|
+
#
|
13
|
+
# For a complete list of options that you can use to customize hooks, see:
|
14
|
+
# https://github.com/sds/overcommit#configuration
|
15
|
+
#
|
16
|
+
# Uncomment the following lines to make the configuration take effect.
|
17
|
+
|
18
|
+
PreCommit:
|
19
|
+
RuboCop:
|
20
|
+
enabled: true
|
21
|
+
on_warn: fail # Treat all warnings as failures
|
22
|
+
#
|
23
|
+
# TrailingWhitespace:
|
24
|
+
# enabled: true
|
25
|
+
# exclude:
|
26
|
+
# - '**/db/structure.sql' # Ignore trailing whitespace in generated files
|
27
|
+
#
|
28
|
+
#PostCheckout:
|
29
|
+
# ALL: # Special hook name that customizes all hooks of this type
|
30
|
+
# quiet: true # Change all post-checkout hooks to only display output on failure
|
31
|
+
#
|
32
|
+
# IndexTags:
|
33
|
+
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
|
34
|
+
|
35
|
+
PrePush:
|
36
|
+
Minitest:
|
37
|
+
command: ['ruby', '-Ilib:test/unit:lib/checkoff', '-rbundler/setup', '-rminitest', "-e 'exit! Minitest.run'"]
|
38
|
+
include:
|
39
|
+
- 'test/unit/**/test*.rb'
|
40
|
+
enabled: true
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -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
|
-
|
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
|
data/README.md
CHANGED
data/bin/checkoff
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'checkoff' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("checkoff", "checkoff")
|
data/checkoff.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.summary = 'Command-line and gem client for Asana (unofficial)'
|
14
14
|
spec.homepage = 'http://github.com/apiology/checkoff'
|
15
15
|
spec.license = 'MIT'
|
16
|
-
spec.required_ruby_version = '>= 2.
|
16
|
+
spec.required_ruby_version = '>= 2.5'
|
17
17
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
19
|
f.match(%r{^(test|spec|features)/})
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
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 'overcommit'
|
33
34
|
spec.add_development_dependency 'quality', '~> 38'
|
34
35
|
spec.add_development_dependency 'rake', '~> 13.0'
|
35
36
|
spec.add_development_dependency 'rspec', '>=3.4'
|
data/coverage/.last_run.json
CHANGED
data/lib/checkoff/cli.rb
CHANGED
@@ -110,7 +110,11 @@ module Checkoff
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def view(workspace_name, project_name, section_name)
|
113
|
-
|
113
|
+
if project_name.nil?
|
114
|
+
stderr.puts 'Please specify a project name'
|
115
|
+
exit(1)
|
116
|
+
end
|
117
|
+
project_name = project_name[1..-1].to_sym if project_name.start_with? ':'
|
114
118
|
if section_name.nil?
|
115
119
|
run_on_project(workspace_name, project_name)
|
116
120
|
else
|
@@ -4,12 +4,52 @@ require 'yaml'
|
|
4
4
|
require 'active_support/core_ext/hash'
|
5
5
|
|
6
6
|
module Checkoff
|
7
|
+
# Use the provided config from a YAML file, and fall back to env
|
8
|
+
# variable if it's not populated for a key'
|
9
|
+
class EnvFallbackConfigLoader
|
10
|
+
def initialize(config, sym, yaml_filename)
|
11
|
+
@config = config
|
12
|
+
@envvar_prefix = sym.upcase
|
13
|
+
@yaml_filename = yaml_filename
|
14
|
+
end
|
15
|
+
|
16
|
+
def envvar_name(key)
|
17
|
+
"#{@envvar_prefix}__#{key.upcase}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](key)
|
21
|
+
config_value = @config[key]
|
22
|
+
return config_value unless config_value.nil?
|
23
|
+
|
24
|
+
ENV[envvar_name(key)]
|
25
|
+
end
|
26
|
+
|
27
|
+
def fetch(key)
|
28
|
+
out = self[key]
|
29
|
+
return out unless out.nil?
|
30
|
+
|
31
|
+
raise KeyError,
|
32
|
+
"Please configure either the #{key} key in #{@yaml_filename} or set #{envvar_name(key)}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
7
36
|
# Load configuration file
|
8
37
|
class ConfigLoader
|
9
|
-
def self.
|
38
|
+
def self.yaml_filename(sym)
|
10
39
|
file = "#{sym}.yml"
|
11
|
-
|
12
|
-
|
40
|
+
File.expand_path("~/.#{file}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.load_yaml_file(sym)
|
44
|
+
filename = yaml_filename(sym)
|
45
|
+
return {} unless File.exist?(filename)
|
46
|
+
|
47
|
+
YAML.load_file(filename).with_indifferent_access
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.load(sym)
|
51
|
+
yaml_result = load_yaml_file(sym)
|
52
|
+
EnvFallbackConfigLoader.new(yaml_result, sym, yaml_filename(sym))
|
13
53
|
end
|
14
54
|
end
|
15
55
|
end
|
data/lib/checkoff/projects.rb
CHANGED
@@ -49,8 +49,8 @@ module Checkoff
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def my_tasks(workspace_name)
|
52
|
-
my_tasks = @config
|
53
|
-
gid =
|
52
|
+
my_tasks = @config.fetch(:my_tasks)
|
53
|
+
gid = my_tasks[workspace_name] unless my_tasks.nil?
|
54
54
|
raise "Please define [:my_tasks][#{workspace_name}] in config file" if my_tasks.nil? || gid.nil?
|
55
55
|
|
56
56
|
projects.find_by_id(gid)
|
@@ -77,7 +77,7 @@ module Checkoff
|
|
77
77
|
per_page: 100,
|
78
78
|
options: {
|
79
79
|
fields: %w[name completed_at due_at due_on assignee_status tags
|
80
|
-
memberships.project.gid memberships.section.name],
|
80
|
+
memberships.project.gid memberships.section.name dependencies],
|
81
81
|
},
|
82
82
|
}
|
83
83
|
end
|
data/lib/checkoff/sections.rb
CHANGED
@@ -11,22 +11,24 @@ module Checkoff
|
|
11
11
|
|
12
12
|
extend Forwardable
|
13
13
|
|
14
|
-
attr_reader :projects, :time
|
14
|
+
attr_reader :projects, :workspaces, :time
|
15
15
|
|
16
16
|
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
17
17
|
projects: Checkoff::Projects.new(config: config),
|
18
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
18
19
|
time: Time)
|
19
20
|
@projects = projects
|
21
|
+
@workspaces = workspaces
|
20
22
|
@time = time
|
21
23
|
end
|
22
24
|
|
23
25
|
def_delegators :@projects, :client
|
24
26
|
|
25
27
|
def file_task_by_section(by_section, task, project_gid)
|
26
|
-
membership = task.memberships.find { |m| m
|
28
|
+
membership = task.memberships.find { |m| m['project']['gid'] == project_gid }
|
27
29
|
raise "Could not find task in project_gid #{project_gid}: #{task}" if membership.nil?
|
28
30
|
|
29
|
-
current_section = membership
|
31
|
+
current_section = membership['section']['name']
|
30
32
|
current_section = nil if current_section == '(no section)'
|
31
33
|
by_section[current_section] ||= []
|
32
34
|
by_section[current_section] << task
|
@@ -41,6 +43,12 @@ module Checkoff
|
|
41
43
|
end
|
42
44
|
cache_method :by_section, LONG_CACHE_TIME
|
43
45
|
|
46
|
+
def legacy_tasks_by_section_for_project(project)
|
47
|
+
raw_tasks = projects.tasks_from_project(project)
|
48
|
+
active_tasks = projects.active_tasks(raw_tasks)
|
49
|
+
legacy_by_section(active_tasks)
|
50
|
+
end
|
51
|
+
|
44
52
|
def tasks_by_section_for_project(project)
|
45
53
|
raw_tasks = projects.tasks_from_project(project)
|
46
54
|
active_tasks = projects.active_tasks(raw_tasks)
|
@@ -68,8 +76,8 @@ module Checkoff
|
|
68
76
|
by_section
|
69
77
|
end
|
70
78
|
|
71
|
-
def
|
72
|
-
|
79
|
+
def legacy_tasks_by_section_for_project_and_assignee_status(project,
|
80
|
+
assignee_status)
|
73
81
|
raw_tasks = projects.tasks_from_project(project)
|
74
82
|
by_assignee_status =
|
75
83
|
projects.active_tasks(raw_tasks)
|
@@ -87,15 +95,40 @@ module Checkoff
|
|
87
95
|
project
|
88
96
|
end
|
89
97
|
|
98
|
+
def verify_legacy_user_task_list!(workspace_name)
|
99
|
+
return unless user_task_list_migrated_to_real_sections?(workspace_name)
|
100
|
+
|
101
|
+
raise NotImplementedError, 'Section-based user task lists not yet supported'
|
102
|
+
end
|
103
|
+
|
104
|
+
ASSIGNEE_STATUS_BY_PROJECT_NAME = {
|
105
|
+
my_tasks_new: 'inbox',
|
106
|
+
my_tasks_today: 'today',
|
107
|
+
my_tasks_upcoming: 'upcoming',
|
108
|
+
}.freeze
|
109
|
+
|
110
|
+
def user_task_list_by_section(workspace_name, project_name)
|
111
|
+
verify_legacy_user_task_list!(workspace_name)
|
112
|
+
|
113
|
+
if project_name == :my_tasks
|
114
|
+
legacy_tasks_by_section_for_project(project_name)
|
115
|
+
else
|
116
|
+
legacy_tasks_by_section_for_project_and_assignee_status(project_name,
|
117
|
+
ASSIGNEE_STATUS_BY_PROJECT_NAME.fetch(project_name))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
90
121
|
def tasks_by_section(workspace_name, project_name)
|
91
122
|
project = project_or_raise(workspace_name, project_name)
|
92
123
|
case project_name
|
124
|
+
when :my_tasks
|
125
|
+
user_task_list_by_section(workspace_name, project_name)
|
93
126
|
when :my_tasks_new
|
94
|
-
|
127
|
+
user_task_list_by_section(workspace_name, project_name)
|
95
128
|
when :my_tasks_today
|
96
|
-
|
129
|
+
user_task_list_by_section(workspace_name, project_name)
|
97
130
|
when :my_tasks_upcoming
|
98
|
-
|
131
|
+
user_task_list_by_section(workspace_name, project_name)
|
99
132
|
else
|
100
133
|
tasks_by_section_for_project(project)
|
101
134
|
end
|
@@ -120,6 +153,13 @@ module Checkoff
|
|
120
153
|
end
|
121
154
|
cache_method :section_task_names, SHORT_CACHE_TIME
|
122
155
|
|
156
|
+
def user_task_list_migrated_to_real_sections?(workspace_name)
|
157
|
+
workspace = workspaces.workspace_by_name(workspace_name)
|
158
|
+
result = client.user_task_lists.get_user_task_list_for_user(user_gid: 'me',
|
159
|
+
workspace: workspace.gid)
|
160
|
+
result.migration_status != 'not_migrated'
|
161
|
+
end
|
162
|
+
|
123
163
|
def task_due?(task)
|
124
164
|
if task.due_at
|
125
165
|
Time.parse(task.due_at) <= time.now
|
data/lib/checkoff/tasks.rb
CHANGED
data/lib/checkoff/version.rb
CHANGED
data/lib/checkoff/workspaces.rb
CHANGED
@@ -11,19 +11,20 @@ module Checkoff
|
|
11
11
|
|
12
12
|
def client
|
13
13
|
@client ||= @asana_client.new do |c|
|
14
|
-
c.authentication :access_token, @config
|
14
|
+
c.authentication :access_token, @config.fetch(:personal_access_token)
|
15
15
|
c.default_headers 'asana-enable' => 'string_ids,new_sections'
|
16
|
+
c.default_headers 'asana-disable' => 'new_user_task_lists'
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
20
|
def default_workspace_gid
|
20
|
-
@config
|
21
|
+
@config.fetch(:default_workspace_gid)
|
21
22
|
end
|
22
23
|
|
23
24
|
def workspace_by_name(workspace_name)
|
24
25
|
client.workspaces.find_all.find do |workspace|
|
25
26
|
workspace.name == workspace_name
|
26
|
-
end || raise("Could not find workspace #{workspace_name}")
|
27
|
+
end || raise("Could not find workspace named [#{workspace_name}]")
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
488
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
6
|
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.8.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:
|
11
|
+
date: 2021-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: overcommit
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: quality
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,7 +187,9 @@ extensions: []
|
|
173
187
|
extra_rdoc_files: []
|
174
188
|
files:
|
175
189
|
- ".circleci/config.yml"
|
190
|
+
- ".envrc"
|
176
191
|
- ".gitignore"
|
192
|
+
- ".overcommit.yml"
|
177
193
|
- ".rubocop.yml"
|
178
194
|
- ".ruby-version"
|
179
195
|
- ".travis.yml"
|
@@ -183,6 +199,7 @@ files:
|
|
183
199
|
- Makefile
|
184
200
|
- README.md
|
185
201
|
- Rakefile
|
202
|
+
- bin/checkoff
|
186
203
|
- bin/console
|
187
204
|
- bin/setup
|
188
205
|
- checkoff.gemspec
|
@@ -235,7 +252,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
235
252
|
requirements:
|
236
253
|
- - ">="
|
237
254
|
- !ruby/object:Gem::Version
|
238
|
-
version: '2.
|
255
|
+
version: '2.5'
|
239
256
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
240
257
|
requirements:
|
241
258
|
- - ">="
|