checkoff 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.envrc +1 -1
- data/.gitignore +0 -1
- data/.markdownlint_style.rb +3 -0
- data/.mdlrc +1 -0
- data/CONTRIBUTING.rst +75 -0
- data/DEVELOPMENT.md +9 -0
- data/Gemfile.lock +26 -7
- data/LICENSE +1 -2
- data/Makefile +3 -0
- data/README.md +8 -12
- data/checkoff.gemspec +1 -0
- data/coverage/.last_run.json +2 -2
- data/fix.sh +4 -9
- data/lib/checkoff/cli.rb +3 -3
- data/lib/checkoff/clients.rb +2 -2
- data/lib/checkoff/create-entity.sh +2 -2
- data/lib/checkoff/custom_fields.rb +2 -2
- data/lib/checkoff/internal/config_loader.rb +63 -0
- data/lib/checkoff/internal/create-class.sh +22 -0
- data/lib/checkoff/my_tasks.rb +1 -1
- data/lib/checkoff/projects.rb +2 -2
- data/lib/checkoff/sections.rb +1 -1
- data/lib/checkoff/subtasks.rb +2 -2
- data/lib/checkoff/tags.rb +2 -2
- data/lib/checkoff/task_selectors.rb +102 -0
- data/lib/checkoff/tasks.rb +1 -1
- data/lib/checkoff/version.rb +2 -1
- data/lib/checkoff/workspaces.rb +2 -2
- data/lib/checkoff.rb +1 -0
- data/rakelib/console.rake +9 -0
- metadata +22 -3
- data/lib/checkoff/config_loader.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebf4493d6d8ae139dcc63fa7178ed04f1aa596b2b6b4c82d16f512daac2d19e0
|
4
|
+
data.tar.gz: b6116733287bc50b94aaadd541b1d9789cd3a17f0ff82e0d2fc645a4c279070f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 408c57bfb26c63a750c8eb38723eb27b4b33fdf283b99b8890f84d59515a0cea2274226059e4c4cd848e5cef5b73c99a1d9bdb78746210ec06aef0ff6dd60aaf
|
7
|
+
data.tar.gz: 29e6d4ebfccf6b1bee268d0cf1e753f70402be79c63def06610e13a0b426ed9e534db230f32b13385831c473ae56cb21feb0d4812f3bfa2c70ab0b187c884111
|
data/.envrc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
# shellcheck shell=bash
|
2
2
|
PATH_add bin
|
3
|
-
export ASANA__PERSONAL_ACCESS_TOKEN="op://Private/Asana access token - VLD read-write/token" ASANA__DEFAULT_ASSIGNEE_GID="op://Private/Asana access token - VLD read-write/default_workspace_gid"
|
3
|
+
export ASANA__PERSONAL_ACCESS_TOKEN="op://Private/Asana access token - VLD read-write/token" ASANA__DEFAULT_ASSIGNEE_GID="op://Private/Asana access token - VLD read-write/default_workspace_gid" ASANA__DEFAULT_WORKSPACE_GID="op://Private/Asana access token - VLD read-write/default_workspace_gid"
|
4
4
|
direnv_load with-op op run --cache -- direnv dump
|
data/.gitignore
CHANGED
data/.mdlrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
style ".markdownlint_style.rb"
|
data/CONTRIBUTING.rst
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
============
|
2
|
+
Contributing
|
3
|
+
============
|
4
|
+
|
5
|
+
Contributions are welcome, and they are greatly appreciated! Every little bit
|
6
|
+
helps, and credit will always be given.
|
7
|
+
|
8
|
+
You can contribute in many ways:
|
9
|
+
|
10
|
+
Types of Contributions
|
11
|
+
----------------------
|
12
|
+
|
13
|
+
Report Bugs
|
14
|
+
~~~~~~~~~~~
|
15
|
+
|
16
|
+
Report bugs at https://github.com/apiology/checkoff/issues
|
17
|
+
|
18
|
+
If you are reporting a bug, please include:
|
19
|
+
|
20
|
+
* Your operating system name and version.
|
21
|
+
* Any details about your local setup that might be helpful in troubleshooting.
|
22
|
+
* Detailed steps to reproduce the bug.
|
23
|
+
|
24
|
+
Fix Bugs
|
25
|
+
~~~~~~~~
|
26
|
+
|
27
|
+
Look through the GitHub issues for bugs. Anything tagged with "bug"
|
28
|
+
and "help wanted" is open to whoever wants to implement a fix for it.
|
29
|
+
|
30
|
+
Implement Features
|
31
|
+
~~~~~~~~~~~~~~~~~~
|
32
|
+
|
33
|
+
Look through the GitHub issues for features. Anything tagged with "enhancement"
|
34
|
+
and "help wanted" is open to whoever wants to implement it.
|
35
|
+
|
36
|
+
If you have a new feature in mind, please start it by filing an issue
|
37
|
+
so we can discuss the need and approach before you invest time into
|
38
|
+
coding it.
|
39
|
+
|
40
|
+
Write Documentation
|
41
|
+
~~~~~~~~~~~~~~~~~~~
|
42
|
+
|
43
|
+
Checkoff could always use more documentation, whether as part of
|
44
|
+
the official Checkoff docs, in docstrings, or even on the web in blog posts, articles,
|
45
|
+
and such.
|
46
|
+
|
47
|
+
Submit Feedback
|
48
|
+
~~~~~~~~~~~~~~~
|
49
|
+
|
50
|
+
The best way to send feedback is to file an issue at
|
51
|
+
https://github.com/apiology/checkoff/issues.
|
52
|
+
|
53
|
+
If you are proposing a new feature:
|
54
|
+
|
55
|
+
* Explain in detail how it would work.
|
56
|
+
* Keep the scope as narrow as possible, to make it easier to implement.
|
57
|
+
* Remember that this is a volunteer-driven project, and that contributions
|
58
|
+
are welcome :)
|
59
|
+
|
60
|
+
Get Started!
|
61
|
+
------------
|
62
|
+
|
63
|
+
Ready to contribute? See DEVELOPMENT.md in this directory for details
|
64
|
+
on how to set yourself up for local development.
|
65
|
+
|
66
|
+
Pull Request Guidelines
|
67
|
+
-----------------------
|
68
|
+
|
69
|
+
Before you submit a pull request, check that it meets these guidelines:
|
70
|
+
|
71
|
+
1. The pull request should include tests.
|
72
|
+
|
73
|
+
2. If the pull request adds functionality, the docs should be updated. Put your
|
74
|
+
new functionality into a function with a docstring, and add the feature to
|
75
|
+
the list in README.md.
|
data/DEVELOPMENT.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -12,7 +12,7 @@ GIT
|
|
12
12
|
PATH
|
13
13
|
remote: .
|
14
14
|
specs:
|
15
|
-
checkoff (0.
|
15
|
+
checkoff (0.18.0)
|
16
16
|
activesupport
|
17
17
|
asana (> 0.10.0)
|
18
18
|
cache_method
|
@@ -22,7 +22,7 @@ PATH
|
|
22
22
|
GEM
|
23
23
|
remote: https://rubygems.org/
|
24
24
|
specs:
|
25
|
-
activesupport (6.1.
|
25
|
+
activesupport (6.1.6.1)
|
26
26
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
27
27
|
i18n (>= 1.6, < 2)
|
28
28
|
minitest (>= 5.1)
|
@@ -33,10 +33,12 @@ GEM
|
|
33
33
|
cache (0.4.1)
|
34
34
|
cache_method (0.2.7)
|
35
35
|
cache (>= 0.2.1)
|
36
|
+
chef-utils (17.10.0)
|
37
|
+
concurrent-ruby
|
36
38
|
childprocess (4.0.0)
|
37
39
|
coderay (1.1.3)
|
38
40
|
concurrent-ruby (1.1.10)
|
39
|
-
dalli (3.2.
|
41
|
+
dalli (3.2.2)
|
40
42
|
docile (1.4.0)
|
41
43
|
faraday (1.5.1)
|
42
44
|
faraday-em_http (~> 1.0)
|
@@ -61,15 +63,30 @@ GEM
|
|
61
63
|
faraday_middleware
|
62
64
|
multi_json
|
63
65
|
gli (2.21.0)
|
64
|
-
i18n (1.
|
66
|
+
i18n (1.11.0)
|
65
67
|
concurrent-ruby (~> 1.0)
|
66
68
|
imagen (0.1.8)
|
67
69
|
parser (>= 2.5, != 2.5.1.1)
|
68
70
|
iniparse (1.5.0)
|
69
71
|
jwt (2.2.3)
|
72
|
+
kramdown (2.4.0)
|
73
|
+
rexml
|
74
|
+
kramdown-parser-gfm (1.1.0)
|
75
|
+
kramdown (~> 2.0)
|
76
|
+
mdl (0.11.0)
|
77
|
+
kramdown (~> 2.3)
|
78
|
+
kramdown-parser-gfm (~> 1.1)
|
79
|
+
mixlib-cli (~> 2.1, >= 2.1.1)
|
80
|
+
mixlib-config (>= 2.2.1, < 4)
|
81
|
+
mixlib-shellout
|
70
82
|
method_source (1.0.0)
|
71
|
-
minitest (5.
|
83
|
+
minitest (5.16.2)
|
72
84
|
minitest-profile (0.0.2)
|
85
|
+
mixlib-cli (2.1.8)
|
86
|
+
mixlib-config (3.0.27)
|
87
|
+
tomlrb
|
88
|
+
mixlib-shellout (3.2.7)
|
89
|
+
chef-utils
|
73
90
|
mocha (1.12.0)
|
74
91
|
multi_json (1.15.0)
|
75
92
|
multi_xml (0.6.0)
|
@@ -90,7 +107,7 @@ GEM
|
|
90
107
|
pry (0.14.1)
|
91
108
|
coderay (~> 1.1)
|
92
109
|
method_source (~> 1.0)
|
93
|
-
rack (2.2.
|
110
|
+
rack (2.2.4)
|
94
111
|
rainbow (3.0.0)
|
95
112
|
rake (13.0.3)
|
96
113
|
regexp_parser (2.1.1)
|
@@ -120,6 +137,7 @@ GEM
|
|
120
137
|
simplecov-html (0.12.3)
|
121
138
|
simplecov-lcov (0.8.0)
|
122
139
|
simplecov_json_formatter (0.1.3)
|
140
|
+
tomlrb (2.0.3)
|
123
141
|
tzinfo (2.0.4)
|
124
142
|
concurrent-ruby (~> 1.0)
|
125
143
|
undercover (0.4.3)
|
@@ -127,7 +145,7 @@ GEM
|
|
127
145
|
rainbow (>= 2.1, < 4.0)
|
128
146
|
rugged (>= 0.27, < 1.2)
|
129
147
|
unicode-display_width (2.0.0)
|
130
|
-
zeitwerk (2.
|
148
|
+
zeitwerk (2.6.0)
|
131
149
|
|
132
150
|
PLATFORMS
|
133
151
|
ruby
|
@@ -140,6 +158,7 @@ DEPENDENCIES
|
|
140
158
|
bump
|
141
159
|
bundler
|
142
160
|
checkoff!
|
161
|
+
mdl
|
143
162
|
minitest-profile
|
144
163
|
mocha
|
145
164
|
overcommit (>= 0.58.0)
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2016-2022, Vince Broz
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
SOFTWARE.
|
22
|
-
|
data/Makefile
CHANGED
@@ -39,6 +39,9 @@ clear_metrics: ## remove or reset result artifacts created by tests and quality
|
|
39
39
|
|
40
40
|
clean: clear_metrics ## remove all built artifacts
|
41
41
|
|
42
|
+
|
43
|
+
typecheck: ## validate types in code and configuration
|
44
|
+
|
42
45
|
overcommit: ## run precommit quality checks
|
43
46
|
bundle exec overcommit --run
|
44
47
|
|
data/README.md
CHANGED
@@ -149,18 +149,14 @@ personal_access_token: 'some_big_long_string_from_asana.com_here'
|
|
149
149
|
|
150
150
|
Alternately you can set environment variables to match - e.g., `ASANA__PERSONAL_ACCESS_TOKEN`
|
151
151
|
|
152
|
-
##
|
152
|
+
## Contributions
|
153
153
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
```
|
154
|
+
This project, as with all others, rests on the shoulders of a broad
|
155
|
+
ecosystem supported by many volunteers doing thankless work, along
|
156
|
+
with specific contributors.
|
158
157
|
|
159
|
-
|
158
|
+
In particular I'd like to call out:
|
160
159
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
bump --tag --tag-prefix=v ${type_of_bump:?}
|
165
|
-
rake release
|
166
|
-
```
|
160
|
+
* [Audrey Roy Greenfeld](https://github.com/audreyfeldroy) for the
|
161
|
+
cookiecutter tool and associated examples, which keep my many
|
162
|
+
projects building with shared boilerplate with a minimum of fuss.
|
data/checkoff.gemspec
CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
|
33
33
|
spec.add_development_dependency 'bump'
|
34
34
|
spec.add_development_dependency 'bundler'
|
35
|
+
spec.add_development_dependency 'mdl'
|
35
36
|
spec.add_development_dependency 'minitest-profile'
|
36
37
|
spec.add_development_dependency 'mocha'
|
37
38
|
# 0.58.0 and 0.57.0 don't seem super compatible with signatures, and
|
data/coverage/.last_run.json
CHANGED
data/fix.sh
CHANGED
@@ -284,12 +284,7 @@ ensure_python_versions() {
|
|
284
284
|
}
|
285
285
|
|
286
286
|
major_minor="$(cut -d. -f1-2 <<<"${ver}")"
|
287
|
-
|
288
|
-
then
|
289
|
-
pyenv_install --patch "${ver}" < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index=1)
|
290
|
-
else
|
291
|
-
pyenv_install "${ver}"
|
292
|
-
fi
|
287
|
+
pyenv_install "${ver}"
|
293
288
|
else
|
294
289
|
pyenv install -s "${ver}"
|
295
290
|
fi
|
@@ -307,12 +302,12 @@ ensure_pyenv_virtualenvs() {
|
|
307
302
|
}
|
308
303
|
|
309
304
|
ensure_pip_and_wheel() {
|
310
|
-
#
|
311
|
-
#
|
305
|
+
# pip 22 seems to be better at finding pandas pre-compiled wheels
|
306
|
+
# for macOS, so let's make sure we're using at least that version
|
312
307
|
major_pip_version=$(pip --version | cut -d' ' -f2 | cut -d '.' -f 1)
|
313
308
|
if [[ major_pip_version -lt 21 ]]
|
314
309
|
then
|
315
|
-
pip install 'pip>=
|
310
|
+
pip install 'pip>=22'
|
316
311
|
fi
|
317
312
|
# wheel is helpful for being able to cache long package builds
|
318
313
|
pip show wheel >/dev/null 2>&1 || pip install wheel
|
data/lib/checkoff/cli.rb
CHANGED
@@ -61,7 +61,7 @@ module Checkoff
|
|
61
61
|
to_workspace_arg:,
|
62
62
|
to_project_arg:,
|
63
63
|
to_section_arg:,
|
64
|
-
config: Checkoff::ConfigLoader.load(:asana),
|
64
|
+
config: Checkoff::Internal::ConfigLoader.load(:asana),
|
65
65
|
projects: Checkoff::Projects.new(config: config),
|
66
66
|
sections: Checkoff::Sections.new(config: config),
|
67
67
|
logger: $stderr)
|
@@ -122,7 +122,7 @@ module Checkoff
|
|
122
122
|
class ViewSubcommand
|
123
123
|
def initialize(workspace_name, project_name, section_name,
|
124
124
|
task_name,
|
125
|
-
config: Checkoff::ConfigLoader.load(:asana),
|
125
|
+
config: Checkoff::Internal::ConfigLoader.load(:asana),
|
126
126
|
projects: Checkoff::Projects.new(config: config),
|
127
127
|
sections: Checkoff::Sections.new(config: config,
|
128
128
|
projects: projects),
|
@@ -201,7 +201,7 @@ module Checkoff
|
|
201
201
|
# CLI subcommand that creates a task
|
202
202
|
class QuickaddSubcommand
|
203
203
|
def initialize(workspace_name, task_name,
|
204
|
-
config: Checkoff::ConfigLoader.load(:asana),
|
204
|
+
config: Checkoff::Internal::ConfigLoader.load(:asana),
|
205
205
|
workspaces: Checkoff::Workspaces.new(config: config),
|
206
206
|
tasks: Checkoff::Tasks.new(config: config))
|
207
207
|
@workspace_name = workspace_name
|
data/lib/checkoff/clients.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
require 'forwardable'
|
6
|
-
require_relative 'config_loader'
|
6
|
+
require_relative 'internal/config_loader'
|
7
7
|
require 'asana'
|
8
8
|
|
9
9
|
# https://developers.asana.com/docs/clients
|
@@ -18,7 +18,7 @@ module Checkoff
|
|
18
18
|
LONG_CACHE_TIME = MINUTE * 15
|
19
19
|
SHORT_CACHE_TIME = MINUTE
|
20
20
|
|
21
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
21
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
22
22
|
asana_client_class: Asana::Client)
|
23
23
|
@config = config
|
24
24
|
@asana_client_class = asana_client_class
|
@@ -16,7 +16,7 @@ cat > "${underscored_plural_name}.rb" << EOF
|
|
16
16
|
|
17
17
|
require 'forwardable'
|
18
18
|
require 'cache_method'
|
19
|
-
require_relative 'config_loader'
|
19
|
+
require_relative 'internal/config_loader'
|
20
20
|
require_relative 'workspaces'
|
21
21
|
require_relative 'clients'
|
22
22
|
|
@@ -31,7 +31,7 @@ module Checkoff
|
|
31
31
|
LONG_CACHE_TIME = MINUTE * 15
|
32
32
|
SHORT_CACHE_TIME = MINUTE
|
33
33
|
|
34
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
34
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
35
35
|
workspaces: Checkoff::Workspaces.new(config: config),
|
36
36
|
clients: Checkoff::Clients.new(config: config),
|
37
37
|
client: clients.client)
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
require 'forwardable'
|
6
6
|
require 'cache_method'
|
7
|
-
require_relative 'config_loader'
|
7
|
+
require_relative 'internal/config_loader'
|
8
8
|
require_relative 'workspaces'
|
9
9
|
require_relative 'clients'
|
10
10
|
|
@@ -20,7 +20,7 @@ module Checkoff
|
|
20
20
|
LONG_CACHE_TIME = MINUTE * 15
|
21
21
|
SHORT_CACHE_TIME = MINUTE
|
22
22
|
|
23
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
23
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
24
24
|
workspaces: Checkoff::Workspaces.new(config: config),
|
25
25
|
clients: Checkoff::Clients.new(config: config),
|
26
26
|
client: clients.client)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'active_support/core_ext/hash'
|
5
|
+
|
6
|
+
module Checkoff
|
7
|
+
module Internal
|
8
|
+
# Use the provided config from a YAML file, and fall back to env
|
9
|
+
# variable if it's not populated for a key'
|
10
|
+
class EnvFallbackConfigLoader
|
11
|
+
def initialize(config, sym, yaml_filename)
|
12
|
+
@config = config
|
13
|
+
@envvar_prefix = sym.upcase
|
14
|
+
@yaml_filename = yaml_filename
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
config_value = @config[key]
|
19
|
+
return config_value unless config_value.nil?
|
20
|
+
|
21
|
+
ENV[envvar_name(key)]
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch(key)
|
25
|
+
out = self[key]
|
26
|
+
return out unless out.nil?
|
27
|
+
|
28
|
+
raise KeyError,
|
29
|
+
"Please configure either the #{key} key in #{@yaml_filename} or set #{envvar_name(key)}"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def envvar_name(key)
|
35
|
+
"#{@envvar_prefix}__#{key.upcase}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Load configuration file
|
40
|
+
class ConfigLoader
|
41
|
+
class << self
|
42
|
+
def load(sym)
|
43
|
+
yaml_result = load_yaml_file(sym)
|
44
|
+
EnvFallbackConfigLoader.new(yaml_result, sym, yaml_filename(sym))
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def load_yaml_file(sym)
|
50
|
+
filename = yaml_filename(sym)
|
51
|
+
return {} unless File.exist?(filename)
|
52
|
+
|
53
|
+
YAML.load_file(filename).with_indifferent_access
|
54
|
+
end
|
55
|
+
|
56
|
+
def yaml_filename(sym)
|
57
|
+
file = "#{sym}.yml"
|
58
|
+
File.expand_path("~/.#{file}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/bash -eu
|
2
|
+
|
3
|
+
set -o pipefail
|
4
|
+
|
5
|
+
underscored_plural_name="${1:?underscored plural name of entities minus .rb}"
|
6
|
+
class_name="${2:?class name without Checkoff:: prefix}"
|
7
|
+
|
8
|
+
cat > "${underscored_plural_name}.rb" << EOF
|
9
|
+
#!/usr/bin/env ruby
|
10
|
+
|
11
|
+
# frozen_string_literal: true
|
12
|
+
|
13
|
+
module Checkoff
|
14
|
+
module Internal
|
15
|
+
class ${class_name}
|
16
|
+
def initialize(_deps = {}); end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
EOF
|
21
|
+
|
22
|
+
git add "${underscored_plural_name}.rb"
|
data/lib/checkoff/my_tasks.rb
CHANGED
@@ -14,7 +14,7 @@ module Checkoff
|
|
14
14
|
|
15
15
|
attr_reader :projects
|
16
16
|
|
17
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
17
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
18
18
|
projects: Checkoff::Projects.new(config: config))
|
19
19
|
@config = config
|
20
20
|
@projects = projects
|
data/lib/checkoff/projects.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'config_loader'
|
3
|
+
require_relative 'internal/config_loader'
|
4
4
|
require_relative 'workspaces'
|
5
5
|
require_relative 'clients'
|
6
6
|
require 'cache_method'
|
@@ -23,7 +23,7 @@ module Checkoff
|
|
23
23
|
LONG_CACHE_TIME = MINUTE * 15
|
24
24
|
SHORT_CACHE_TIME = MINUTE * 5
|
25
25
|
|
26
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
26
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
27
27
|
workspaces: Checkoff::Workspaces.new(config: config),
|
28
28
|
clients: Checkoff::Clients.new(config: config),
|
29
29
|
client: clients.client)
|
data/lib/checkoff/sections.rb
CHANGED
@@ -17,7 +17,7 @@ module Checkoff
|
|
17
17
|
|
18
18
|
attr_reader :projects, :workspaces, :time, :my_tasks
|
19
19
|
|
20
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
20
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
21
21
|
projects: Checkoff::Projects.new(config: config),
|
22
22
|
workspaces: Checkoff::Workspaces.new(config: config),
|
23
23
|
clients: Checkoff::Clients.new(config: config),
|
data/lib/checkoff/subtasks.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
|
-
require_relative 'config_loader'
|
4
|
+
require_relative 'internal/config_loader'
|
5
5
|
require_relative 'projects'
|
6
6
|
|
7
7
|
module Checkoff
|
@@ -13,7 +13,7 @@ module Checkoff
|
|
13
13
|
|
14
14
|
extend Forwardable
|
15
15
|
|
16
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
16
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
17
17
|
projects: Checkoff::Projects.new(config: config))
|
18
18
|
@projects = projects
|
19
19
|
end
|
data/lib/checkoff/tags.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
require 'forwardable'
|
6
6
|
require 'cache_method'
|
7
|
-
require_relative 'config_loader'
|
7
|
+
require_relative 'internal/config_loader'
|
8
8
|
require_relative 'workspaces'
|
9
9
|
require_relative 'clients'
|
10
10
|
|
@@ -20,7 +20,7 @@ module Checkoff
|
|
20
20
|
LONG_CACHE_TIME = MINUTE * 15
|
21
21
|
SHORT_CACHE_TIME = MINUTE
|
22
22
|
|
23
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
23
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
24
24
|
workspaces: Checkoff::Workspaces.new(config: config),
|
25
25
|
clients: Checkoff::Clients.new(config: config),
|
26
26
|
client: clients.client)
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require 'forwardable'
|
6
|
+
require 'cache_method'
|
7
|
+
require 'json'
|
8
|
+
require_relative 'internal/config_loader'
|
9
|
+
require_relative 'workspaces'
|
10
|
+
require_relative 'clients'
|
11
|
+
|
12
|
+
# https://developers.asana.com/docs/task-selectors
|
13
|
+
|
14
|
+
module Checkoff
|
15
|
+
# Filter lists of tasks using declarative selectors.
|
16
|
+
class TaskSelectors
|
17
|
+
MINUTE = 60
|
18
|
+
HOUR = MINUTE * 60
|
19
|
+
DAY = 24 * HOUR
|
20
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
21
|
+
LONG_CACHE_TIME = MINUTE * 15
|
22
|
+
SHORT_CACHE_TIME = MINUTE
|
23
|
+
|
24
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
25
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
26
|
+
clients: Checkoff::Clients.new(config: config),
|
27
|
+
client: clients.client)
|
28
|
+
@workspaces = workspaces
|
29
|
+
@client = client
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param [Hash<Symbol, Object>] task_selector Filter based on
|
33
|
+
# description. Examples: {tag: 'foo'} {:not {tag: 'foo'} (:tag 'foo')
|
34
|
+
def filter_via_task_selector(task, task_selector)
|
35
|
+
return true if task_selector == []
|
36
|
+
|
37
|
+
return !filter_via_task_selector(task, task_selector.fetch(1)) if fn?(task_selector, :not)
|
38
|
+
|
39
|
+
return filter_via_task_selector(task, task_selector.fetch(1)).nil? if fn?(task_selector, :nil?)
|
40
|
+
|
41
|
+
return contains_tag?(task, task_selector.fetch(1)) if fn?(task_selector, :tag)
|
42
|
+
|
43
|
+
return custom_field_value(task, task_selector.fetch(1)) if fn?(task_selector, :custom_field_value)
|
44
|
+
|
45
|
+
raise "Syntax issue trying to handle #{task_selector}"
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def contains_tag?(task, tag_name)
|
51
|
+
task.tags.map(&:name).include? tag_name
|
52
|
+
end
|
53
|
+
|
54
|
+
def custom_field_value(task, custom_field_name)
|
55
|
+
custom_field = task.custom_fields.find { |field| field.fetch('name') == custom_field_name }
|
56
|
+
return nil if custom_field.nil?
|
57
|
+
|
58
|
+
custom_field['display_value']
|
59
|
+
end
|
60
|
+
|
61
|
+
def fn?(object, fn_name)
|
62
|
+
object.is_a?(Array) && !object.empty? && [fn_name, fn_name.to_s].include?(object[0])
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_reader :workspaces, :client
|
66
|
+
|
67
|
+
# bundle exec ./task_selectors.rb
|
68
|
+
# :nocov:
|
69
|
+
class << self
|
70
|
+
def project_name
|
71
|
+
ARGV[1] || raise('Please pass project name to pull tasks from as first argument')
|
72
|
+
end
|
73
|
+
|
74
|
+
def workspace_name
|
75
|
+
ARGV[0] || raise('Please pass workspace name as first argument')
|
76
|
+
end
|
77
|
+
|
78
|
+
def task_selector
|
79
|
+
task_selector_json = ARGV[2] || raise('Please pass task_selector in JSON form as third argument')
|
80
|
+
JSON.parse(task_selector_json)
|
81
|
+
end
|
82
|
+
|
83
|
+
def run
|
84
|
+
require 'checkoff/projects'
|
85
|
+
|
86
|
+
task_selectors = Checkoff::TaskSelectors.new
|
87
|
+
extra_fields = []
|
88
|
+
projects = Checkoff::Projects.new
|
89
|
+
project = projects.project(workspace_name, project_name)
|
90
|
+
raw_tasks = projects.tasks_from_project(project, extra_fields: extra_fields)
|
91
|
+
tasks = raw_tasks.filter { |task| task_selectors.filter_via_task_selector(task, task_selector) }
|
92
|
+
puts "Results: #{tasks}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
# :nocov:
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# :nocov:
|
100
|
+
abs_program_name = File.expand_path($PROGRAM_NAME)
|
101
|
+
Checkoff::TaskSelectors.run if abs_program_name == __FILE__
|
102
|
+
# :nocov:
|
data/lib/checkoff/tasks.rb
CHANGED
@@ -14,7 +14,7 @@ module Checkoff
|
|
14
14
|
LONG_CACHE_TIME = MINUTE * 15
|
15
15
|
SHORT_CACHE_TIME = MINUTE * 5
|
16
16
|
|
17
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
17
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
18
18
|
sections: Checkoff::Sections.new(config: config),
|
19
19
|
clients: Checkoff::Clients.new(config: config),
|
20
20
|
client: clients.client,
|
data/lib/checkoff/version.rb
CHANGED
data/lib/checkoff/workspaces.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'cache_method'
|
5
|
-
require_relative 'config_loader'
|
5
|
+
require_relative 'internal/config_loader'
|
6
6
|
require_relative 'clients'
|
7
7
|
|
8
8
|
# https://developers.asana.com/docs/workspaces
|
@@ -17,7 +17,7 @@ module Checkoff
|
|
17
17
|
LONG_CACHE_TIME = MINUTE * 15
|
18
18
|
SHORT_CACHE_TIME = MINUTE
|
19
19
|
|
20
|
-
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
20
|
+
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
21
21
|
clients: Checkoff::Clients.new(config: config),
|
22
22
|
client: clients.client)
|
23
23
|
@config = config
|
data/lib/checkoff.rb
CHANGED
data/rakelib/console.rake
CHANGED
@@ -2,5 +2,14 @@
|
|
2
2
|
|
3
3
|
desc 'Load up checkoff in pry'
|
4
4
|
task :console do |_t|
|
5
|
+
puts 'Example:'
|
6
|
+
puts
|
7
|
+
puts '# https://www.rubydoc.info/github/Asana/ruby-asana/master'
|
8
|
+
puts '> client = Checkoff::Clients.new.client'
|
9
|
+
puts '# https://developers.asana.com/docs/input-output-options'
|
10
|
+
puts '> workspace_gid = ENV.fetch("ASANA__DEFAULT_WORKSPACE_GID")'
|
11
|
+
puts "> task = client.tasks.find_by_id('1199961990964812', options: { fields: ['dependencies'] })"
|
12
|
+
puts '# Asana.md#ruby-asana / API shows how to manually call endpoints with a client'
|
13
|
+
puts
|
5
14
|
exec 'pry -I lib -r checkoff'
|
6
15
|
end
|
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.18.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: 2022-
|
11
|
+
date: 2022-07-12 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: mdl
|
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: minitest-profile
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -275,10 +289,13 @@ files:
|
|
275
289
|
- ".git-hooks/pre_commit/circle_ci.rb"
|
276
290
|
- ".gitattributes"
|
277
291
|
- ".gitignore"
|
292
|
+
- ".markdownlint_style.rb"
|
293
|
+
- ".mdlrc"
|
278
294
|
- ".overcommit.yml"
|
279
295
|
- ".rubocop.yml"
|
280
296
|
- ".yamllint.yml"
|
281
297
|
- CODE_OF_CONDUCT.md
|
298
|
+
- CONTRIBUTING.rst
|
282
299
|
- DEVELOPMENT.md
|
283
300
|
- Gemfile
|
284
301
|
- Gemfile.lock
|
@@ -301,14 +318,16 @@ files:
|
|
301
318
|
- lib/checkoff.rb
|
302
319
|
- lib/checkoff/cli.rb
|
303
320
|
- lib/checkoff/clients.rb
|
304
|
-
- lib/checkoff/config_loader.rb
|
305
321
|
- lib/checkoff/create-entity.sh
|
306
322
|
- lib/checkoff/custom_fields.rb
|
323
|
+
- lib/checkoff/internal/config_loader.rb
|
324
|
+
- lib/checkoff/internal/create-class.sh
|
307
325
|
- lib/checkoff/my_tasks.rb
|
308
326
|
- lib/checkoff/projects.rb
|
309
327
|
- lib/checkoff/sections.rb
|
310
328
|
- lib/checkoff/subtasks.rb
|
311
329
|
- lib/checkoff/tags.rb
|
330
|
+
- lib/checkoff/task_selectors.rb
|
312
331
|
- lib/checkoff/tasks.rb
|
313
332
|
- lib/checkoff/version.rb
|
314
333
|
- lib/checkoff/workspaces.rb
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'yaml'
|
4
|
-
require 'active_support/core_ext/hash'
|
5
|
-
|
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 [](key)
|
17
|
-
config_value = @config[key]
|
18
|
-
return config_value unless config_value.nil?
|
19
|
-
|
20
|
-
ENV[envvar_name(key)]
|
21
|
-
end
|
22
|
-
|
23
|
-
def fetch(key)
|
24
|
-
out = self[key]
|
25
|
-
return out unless out.nil?
|
26
|
-
|
27
|
-
raise KeyError,
|
28
|
-
"Please configure either the #{key} key in #{@yaml_filename} or set #{envvar_name(key)}"
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def envvar_name(key)
|
34
|
-
"#{@envvar_prefix}__#{key.upcase}"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Load configuration file
|
39
|
-
class ConfigLoader
|
40
|
-
class << self
|
41
|
-
def load(sym)
|
42
|
-
yaml_result = load_yaml_file(sym)
|
43
|
-
EnvFallbackConfigLoader.new(yaml_result, sym, yaml_filename(sym))
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def load_yaml_file(sym)
|
49
|
-
filename = yaml_filename(sym)
|
50
|
-
return {} unless File.exist?(filename)
|
51
|
-
|
52
|
-
YAML.load_file(filename).with_indifferent_access
|
53
|
-
end
|
54
|
-
|
55
|
-
def yaml_filename(sym)
|
56
|
-
file = "#{sym}.yml"
|
57
|
-
File.expand_path("~/.#{file}")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|