checkoff 0.14.1 → 0.15.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/Gemfile.lock +3 -3
- data/Makefile +7 -3
- data/README.md +36 -10
- data/coverage/.last_run.json +2 -2
- data/fix.sh +31 -2
- data/lib/checkoff.rb +2 -0
- data/lib/checkoff/clients.rb +55 -0
- data/lib/checkoff/create-entity.sh +85 -0
- data/lib/checkoff/custom_fields.rb +68 -0
- data/lib/checkoff/projects.rb +8 -9
- data/lib/checkoff/sections.rb +8 -2
- data/lib/checkoff/subtasks.rb +2 -0
- data/lib/checkoff/tags.rb +68 -0
- data/lib/checkoff/version.rb +1 -1
- data/lib/checkoff/workspaces.rb +28 -13
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73dc8e8ee25d08cf3457dac6284c7a7ab5476db7d3e1fadbe66d75a1f0546297
|
4
|
+
data.tar.gz: 623ea9cd3331007bb831d72d14e063d9f92751eda5b1819270e69edb4ff7ca2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd1155bea5724f05e4b1b6f12c172358ccb49d000bf1c22e77663df3b1239d442730c5879d116b4cca411a3a57f4acbf09fee5fa8b9b33c0537179e31601a8b3
|
7
|
+
data.tar.gz: d5e1f8a9aadaffbaf9cd18d8ba976d368b1eec6edd1e829bfa5b42780ee34cddbf661207c3554a9665eec07bce553db9b7a2c19e1e899f7e34df82efd9d7a64d
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/apiology/ruby-asana
|
3
|
-
revision:
|
3
|
+
revision: ab9393136d9ca59b75e42a661fdddc1c65c8f7c3
|
4
4
|
branch: checkoff_fixes
|
5
5
|
specs:
|
6
|
-
asana (0.10.
|
6
|
+
asana (0.10.6)
|
7
7
|
faraday (~> 1.0)
|
8
8
|
faraday_middleware (~> 1.0)
|
9
9
|
faraday_middleware-multi_json (~> 0.0)
|
@@ -12,7 +12,7 @@ GIT
|
|
12
12
|
PATH
|
13
13
|
remote: .
|
14
14
|
specs:
|
15
|
-
checkoff (0.
|
15
|
+
checkoff (0.15.0)
|
16
16
|
activesupport
|
17
17
|
asana (> 0.10.0)
|
18
18
|
cache_method
|
data/Makefile
CHANGED
@@ -23,9 +23,11 @@ requirements_dev.txt.installed: requirements_dev.txt
|
|
23
23
|
|
24
24
|
pip_install: requirements_dev.txt.installed ## Install Python dependencies
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
# bundle install doesn't get run here so that we can catch it below in
|
27
|
+
# fresh-checkout and fresh-rbenv cases
|
28
|
+
Gemfile.lock: Gemfile
|
28
29
|
|
30
|
+
# Ensure any Gemfile.lock changes ensure a bundle is installed.
|
29
31
|
Gemfile.lock.installed: Gemfile.lock
|
30
32
|
bundle install
|
31
33
|
touch Gemfile.lock.installed
|
@@ -37,9 +39,11 @@ clear_metrics: ## remove or reset result artifacts created by tests and quality
|
|
37
39
|
|
38
40
|
clean: clear_metrics ## remove all built artifacts
|
39
41
|
|
40
|
-
|
42
|
+
overcommit: ## run precommit quality checks
|
41
43
|
bundle exec overcommit --run
|
42
44
|
|
45
|
+
quality: overcommit ## run precommit quality checks
|
46
|
+
|
43
47
|
test: ## Run lower-level tests
|
44
48
|
@bundle exec rake test
|
45
49
|
|
data/README.md
CHANGED
@@ -4,12 +4,28 @@ Command-line and gem client for Asana (unofficial)
|
|
4
4
|
|
5
5
|
## Using
|
6
6
|
|
7
|
-
```
|
7
|
+
```sh
|
8
8
|
$ checkoff --help
|
9
|
-
|
10
|
-
|
9
|
+
NAME
|
10
|
+
checkoff - Command-line client for Asana (unofficial)
|
11
|
+
|
12
|
+
|
13
|
+
SYNOPSIS
|
14
|
+
checkoff [global options] command [command options] [arguments...]
|
15
|
+
|
11
16
|
|
12
|
-
|
17
|
+
|
18
|
+
GLOBAL OPTIONS
|
19
|
+
--help - Show this message
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
COMMANDS
|
24
|
+
help - Shows a list of commands or help for one command
|
25
|
+
mv - Move tasks from one section to another within a project
|
26
|
+
quickadd - Add a short task to Asana
|
27
|
+
view - Output representation of Asana tasks
|
28
|
+
$
|
13
29
|
```
|
14
30
|
|
15
31
|
Let's say we have a project like this:
|
@@ -18,7 +34,7 @@ Let's say we have a project like this:
|
|
18
34
|
|
19
35
|
Checkoff outputs things in JSON. 'jq' is a great tool to use in combination:
|
20
36
|
|
21
|
-
```
|
37
|
+
```sh
|
22
38
|
$ checkoff view 'Personal Projects' 'Create demo'
|
23
39
|
{"":[{"name":"This is a task that doesn't belong to any sections."}],"Write it:":[{"name":"Write something"}],"Publish to github:":[{"name":"git push!"}],"Make sure it looks OK!:":[{"name":"Looks it up in your browser..."}]}
|
24
40
|
$
|
@@ -52,7 +68,7 @@ $ checkoff view 'Personal Projects' 'Create demo' | jq
|
|
52
68
|
|
53
69
|
You can drill down into a section on the command line:
|
54
70
|
|
55
|
-
```
|
71
|
+
```sh
|
56
72
|
$ checkoff view 'Personal Projects' 'Create demo' 'Publish to github:'
|
57
73
|
[{"name":"git push!"}]
|
58
74
|
```
|
@@ -71,12 +87,21 @@ $ checkoff view 'Personal Projects' 'Create demo' | jq 'to_entries | map(.value)
|
|
71
87
|
|
72
88
|
And even gather counts for project metrics:
|
73
89
|
|
74
|
-
```
|
90
|
+
```sh
|
75
91
|
$ checkoff view 'Personal Projects' 'Create demo' | jq 'to_entries | map(.value) | flatten | map(.name) | length'
|
76
92
|
4
|
77
93
|
$
|
78
94
|
```
|
79
95
|
|
96
|
+
## Naming things
|
97
|
+
|
98
|
+
Since checkoff looks up things by their name, if you have two things
|
99
|
+
with the same name, you're probably going to have a bad time.
|
100
|
+
|
101
|
+
If you need to talk about the section of a project which contains
|
102
|
+
tasks that don't have a section, use `Untitled section` as the name.
|
103
|
+
This is a quirk of the Asana API which seemed as good as any other idea.
|
104
|
+
|
80
105
|
## Caching
|
81
106
|
|
82
107
|
Note that I don't know of a way through the Asana API to target
|
@@ -94,7 +119,7 @@ clear the cache.
|
|
94
119
|
|
95
120
|
This will work under OS X:
|
96
121
|
|
97
|
-
```
|
122
|
+
```sh
|
98
123
|
brew install memcached
|
99
124
|
ln -sfv /usr/local/opt/memcached/*.plist ~/Library/LaunchAgents
|
100
125
|
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.memcached.plist
|
@@ -103,7 +128,8 @@ gem install checkoff
|
|
103
128
|
|
104
129
|
## Configuring
|
105
130
|
|
106
|
-
You'll need to create a file called `.asana.yml` in your home
|
131
|
+
You'll need to create a file called `.asana.yml` in your home
|
132
|
+
directory, that looks like this:
|
107
133
|
|
108
134
|
```yaml
|
109
135
|
---
|
@@ -129,7 +155,7 @@ Alternately you can set environment variables to match - e.g., `ASANA__PERSONAL_
|
|
129
155
|
|
130
156
|
## Developing
|
131
157
|
|
132
|
-
```
|
158
|
+
```sh
|
133
159
|
bundle install
|
134
160
|
bundle exec exe/checkoff --help
|
135
161
|
```
|
data/coverage/.last_run.json
CHANGED
data/fix.sh
CHANGED
@@ -127,10 +127,33 @@ ensure_bundle() {
|
|
127
127
|
bundler_version=$(bundle --version | cut -d ' ' -f3)
|
128
128
|
bundler_version_major=$(cut -d. -f1 <<< "${bundler_version}")
|
129
129
|
bundler_version_minor=$(cut -d. -f2 <<< "${bundler_version}")
|
130
|
+
bundler_version_patch=$(cut -d. -f3 <<< "${bundler_version}")
|
130
131
|
# Version 2.1 of bundler seems to have some issues with nokogiri:
|
131
132
|
#
|
132
133
|
# https://app.asana.com/0/1107901397356088/1199504270687298
|
133
|
-
|
134
|
+
|
135
|
+
# Version 2.2.22 of bundler comes with a fix to ensure the 'bundle
|
136
|
+
# update --conservative' flag works as expected - important when
|
137
|
+
# doing a 'bundle update' on a about-to-be-published gem after
|
138
|
+
# bumping a gem version.
|
139
|
+
need_better_bundler=false
|
140
|
+
if [ "${bundler_version_major}" -lt 2 ]
|
141
|
+
then
|
142
|
+
need_better_bundler=true
|
143
|
+
elif [ "${bundler_version_major}" -eq 2 ]
|
144
|
+
then
|
145
|
+
if [ "${bundler_version_minor}" -lt 2 ]
|
146
|
+
then
|
147
|
+
need_better_bundler=true
|
148
|
+
elif [ "${bundler_version_minor}" -eq 2 ]
|
149
|
+
then
|
150
|
+
if [ "${bundler_version_patch}" -lt 22 ]
|
151
|
+
then
|
152
|
+
need_better_bundler=true
|
153
|
+
fi
|
154
|
+
fi
|
155
|
+
fi
|
156
|
+
if [ "${need_better_bundler}" = true ]
|
134
157
|
then
|
135
158
|
gem install --no-document bundler
|
136
159
|
fi
|
@@ -143,7 +166,13 @@ ensure_bundle() {
|
|
143
166
|
# re-resolve and consider the new platform when picking gems, all
|
144
167
|
# without needing to have a machine that matches PLATFORM handy to
|
145
168
|
# install those platform-specific gems on.'
|
146
|
-
|
169
|
+
#
|
170
|
+
# This affects nokogiri, which will try to reinstall itself in
|
171
|
+
# Docker builds where it's already installed if this is not run.
|
172
|
+
for platform in x86_64-darwin-20 x86_64-linux
|
173
|
+
do
|
174
|
+
grep "${platform:?}" Gemfile.lock >/dev/null 2>&1 || bundle lock --add-platform "${platform:?}"
|
175
|
+
done
|
147
176
|
}
|
148
177
|
|
149
178
|
set_ruby_local_version() {
|
data/lib/checkoff.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require 'forwardable'
|
6
|
+
require_relative 'config_loader'
|
7
|
+
require 'asana'
|
8
|
+
|
9
|
+
# https://developers.asana.com/docs/clients
|
10
|
+
|
11
|
+
module Checkoff
|
12
|
+
# Pulls a configured Asana client object which can be used to access the API
|
13
|
+
class Clients
|
14
|
+
MINUTE = 60
|
15
|
+
HOUR = MINUTE * 60
|
16
|
+
DAY = 24 * HOUR
|
17
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
18
|
+
LONG_CACHE_TIME = MINUTE * 15
|
19
|
+
SHORT_CACHE_TIME = MINUTE
|
20
|
+
|
21
|
+
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
22
|
+
asana_client_class: Asana::Client)
|
23
|
+
@config = config
|
24
|
+
@asana_client_class = asana_client_class
|
25
|
+
end
|
26
|
+
|
27
|
+
def client
|
28
|
+
@client ||= @asana_client_class.new do |c|
|
29
|
+
c.authentication :access_token, @config.fetch(:personal_access_token)
|
30
|
+
c.default_headers 'asana-enable' => 'string_ids,new_sections'
|
31
|
+
c.default_headers 'asana-disable' => 'new_user_task_lists'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :workspaces
|
38
|
+
|
39
|
+
# bundle exec ./clients.rb
|
40
|
+
# :nocov:
|
41
|
+
class << self
|
42
|
+
def run
|
43
|
+
clients = Checkoff::Clients.new
|
44
|
+
client = clients.client
|
45
|
+
puts "Results: #{client}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# :nocov:
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# :nocov:
|
53
|
+
abs_program_name = File.expand_path($PROGRAM_NAME)
|
54
|
+
Checkoff::Clients.run if abs_program_name == __FILE__
|
55
|
+
# :nocov:
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/bin/bash -eu
|
2
|
+
|
3
|
+
set -o pipefail
|
4
|
+
|
5
|
+
underscored_plural_name="${1:?underscored plural name of entities minus .rb}"
|
6
|
+
# Sorry, shellcheck, I can't express 'end of line' in a simple variable search and replace
|
7
|
+
# shellcheck disable=SC2001
|
8
|
+
underscored_singular_name=$(sed -e 's/s$//g' <<< "${underscored_plural_name}")
|
9
|
+
kabob_case_plural_name=${underscored_plural_name/_/-}
|
10
|
+
class_name="${2:?class name without Checkoff:: prefix}"
|
11
|
+
|
12
|
+
cat > "${underscored_plural_name}.rb" << EOF
|
13
|
+
#!/usr/bin/env ruby
|
14
|
+
|
15
|
+
# frozen_string_literal: true
|
16
|
+
|
17
|
+
require 'forwardable'
|
18
|
+
require 'cache_method'
|
19
|
+
require_relative 'config_loader'
|
20
|
+
require_relative 'workspaces'
|
21
|
+
require_relative 'clients'
|
22
|
+
|
23
|
+
# https://developers.asana.com/docs/${kabob_case_plural_name}
|
24
|
+
|
25
|
+
module Checkoff
|
26
|
+
class ${class_name}
|
27
|
+
MINUTE = 60
|
28
|
+
HOUR = MINUTE * 60
|
29
|
+
DAY = 24 * HOUR
|
30
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
31
|
+
LONG_CACHE_TIME = MINUTE * 15
|
32
|
+
SHORT_CACHE_TIME = MINUTE
|
33
|
+
|
34
|
+
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
35
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
36
|
+
clients: Checkoff::Clients.new(config: config),
|
37
|
+
client: clients.client)
|
38
|
+
@workspaces = workspaces
|
39
|
+
@client = client
|
40
|
+
end
|
41
|
+
|
42
|
+
def ${underscored_singular_name}_or_raise(workspace_name, ${underscored_singular_name}_name)
|
43
|
+
${underscored_singular_name} = ${underscored_singular_name}(workspace_name, ${underscored_singular_name}_name)
|
44
|
+
raise "Could not find ${underscored_singular_name} #{${underscored_singular_name}_name} under workspace #{workspace_name}." if ${underscored_singular_name}.nil?
|
45
|
+
|
46
|
+
${underscored_singular_name}
|
47
|
+
end
|
48
|
+
cache_method :${underscored_singular_name}_or_raise, LONG_CACHE_TIME
|
49
|
+
|
50
|
+
def ${underscored_singular_name}(workspace_name, ${underscored_singular_name}_name)
|
51
|
+
workspace = workspaces.workspace_by_name(workspace_name)
|
52
|
+
${underscored_plural_name} = client.${underscored_plural_name}.get_${underscored_plural_name}_for_workspace(workspace_gid: workspace.gid)
|
53
|
+
${underscored_plural_name}.find { |${underscored_singular_name}| ${underscored_singular_name}.name == ${underscored_singular_name}_name }
|
54
|
+
end
|
55
|
+
cache_method :${underscored_singular_name}, LONG_CACHE_TIME
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :workspaces, :client
|
60
|
+
|
61
|
+
# bundle exec ./${underscored_plural_name}.rb
|
62
|
+
# :nocov:
|
63
|
+
class << self
|
64
|
+
def run
|
65
|
+
workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
|
66
|
+
${underscored_singular_name}_name = ARGV[1] || raise('Please pass ${underscored_singular_name} name as second argument')
|
67
|
+
${underscored_plural_name} = Checkoff::${class_name}.new
|
68
|
+
${underscored_singular_name} = ${underscored_plural_name}.${underscored_singular_name}_or_raise(workspace_name, ${underscored_singular_name}_name)
|
69
|
+
puts "Results: #{${underscored_singular_name}}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
# :nocov:
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# :nocov:
|
77
|
+
abs_program_name = File.expand_path(\$PROGRAM_NAME)
|
78
|
+
Checkoff::${class_name}.run if abs_program_name == __FILE__
|
79
|
+
# :nocov:
|
80
|
+
EOF
|
81
|
+
|
82
|
+
chmod +x "${underscored_plural_name}.rb"
|
83
|
+
git add "${underscored_plural_name}.rb"
|
84
|
+
|
85
|
+
echo "You can start by running 'bundle exec ./${underscored_plural_name}.rb' and tweaking from there"
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require 'forwardable'
|
6
|
+
require 'cache_method'
|
7
|
+
require_relative 'config_loader'
|
8
|
+
require_relative 'workspaces'
|
9
|
+
require_relative 'clients'
|
10
|
+
|
11
|
+
# https://developers.asana.com/docs/custom-fields
|
12
|
+
|
13
|
+
module Checkoff
|
14
|
+
# Work with custom fields in Asana
|
15
|
+
class CustomFields
|
16
|
+
MINUTE = 60
|
17
|
+
HOUR = MINUTE * 60
|
18
|
+
DAY = 24 * HOUR
|
19
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
20
|
+
LONG_CACHE_TIME = MINUTE * 15
|
21
|
+
SHORT_CACHE_TIME = MINUTE
|
22
|
+
|
23
|
+
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
24
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
25
|
+
clients: Checkoff::Clients.new(config: config),
|
26
|
+
client: clients.client)
|
27
|
+
@workspaces = workspaces
|
28
|
+
@client = client
|
29
|
+
end
|
30
|
+
|
31
|
+
def custom_field_or_raise(workspace_name, custom_field_name)
|
32
|
+
custom_field = custom_field(workspace_name, custom_field_name)
|
33
|
+
raise "Could not find custom_field #{custom_field_name} under workspace #{workspace_name}." if custom_field.nil?
|
34
|
+
|
35
|
+
custom_field
|
36
|
+
end
|
37
|
+
cache_method :custom_field_or_raise, LONG_CACHE_TIME
|
38
|
+
|
39
|
+
def custom_field(workspace_name, custom_field_name)
|
40
|
+
workspace = workspaces.workspace_by_name(workspace_name)
|
41
|
+
custom_fields = client.custom_fields.get_custom_fields_for_workspace(workspace_gid: workspace.gid)
|
42
|
+
custom_fields.find { |custom_field| custom_field.name == custom_field_name }
|
43
|
+
end
|
44
|
+
cache_method :custom_field, LONG_CACHE_TIME
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :workspaces, :client
|
49
|
+
|
50
|
+
# bundle exec ./custom_fields.rb
|
51
|
+
# :nocov:
|
52
|
+
class << self
|
53
|
+
def run
|
54
|
+
workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
|
55
|
+
custom_field_name = ARGV[1] || raise('Please pass custom_field name as second argument')
|
56
|
+
custom_fields = Checkoff::CustomFields.new
|
57
|
+
custom_field = custom_fields.custom_field_or_raise(workspace_name, custom_field_name)
|
58
|
+
puts "Results: #{custom_field}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# :nocov:
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# :nocov:
|
66
|
+
abs_program_name = File.expand_path($PROGRAM_NAME)
|
67
|
+
Checkoff::CustomFields.run if abs_program_name == __FILE__
|
68
|
+
# :nocov:
|
data/lib/checkoff/projects.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'config_loader'
|
4
|
-
|
4
|
+
require_relative 'workspaces'
|
5
|
+
require_relative 'clients'
|
5
6
|
require 'cache_method'
|
6
7
|
require 'asana'
|
7
8
|
|
@@ -23,16 +24,12 @@ module Checkoff
|
|
23
24
|
SHORT_CACHE_TIME = MINUTE * 5
|
24
25
|
|
25
26
|
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
26
|
-
|
27
|
-
|
27
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
28
|
+
clients: Checkoff::Clients.new(config: config),
|
29
|
+
client: clients.client)
|
28
30
|
@config = config
|
29
|
-
@asana_client = asana_client
|
30
31
|
@workspaces = workspaces
|
31
|
-
|
32
|
-
|
33
|
-
# Returns Asana Ruby API Client object
|
34
|
-
def client
|
35
|
-
@workspaces.client
|
32
|
+
@client = client
|
36
33
|
end
|
37
34
|
|
38
35
|
# Default options used in Asana API to pull taskso
|
@@ -84,6 +81,8 @@ module Checkoff
|
|
84
81
|
|
85
82
|
private
|
86
83
|
|
84
|
+
attr_reader :client
|
85
|
+
|
87
86
|
def projects
|
88
87
|
client.projects
|
89
88
|
end
|
data/lib/checkoff/sections.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
|
+
require_relative 'projects'
|
5
|
+
require_relative 'workspaces'
|
6
|
+
require_relative 'clients'
|
4
7
|
|
5
8
|
module Checkoff
|
6
9
|
# Query different sections of Asana projects
|
@@ -16,10 +19,13 @@ module Checkoff
|
|
16
19
|
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
17
20
|
projects: Checkoff::Projects.new(config: config),
|
18
21
|
workspaces: Checkoff::Workspaces.new(config: config),
|
22
|
+
clients: Checkoff::Clients.new(config: config),
|
23
|
+
client: clients.client,
|
19
24
|
time: Time)
|
20
25
|
@projects = projects
|
21
26
|
@workspaces = workspaces
|
22
27
|
@time = time
|
28
|
+
@client = client
|
23
29
|
end
|
24
30
|
|
25
31
|
# Returns a list of Asana API section objects for a given project
|
@@ -72,6 +78,8 @@ module Checkoff
|
|
72
78
|
|
73
79
|
private
|
74
80
|
|
81
|
+
attr_reader :client
|
82
|
+
|
75
83
|
# Given a project object, pull all tasks, then provide a Hash of
|
76
84
|
# tasks with section name -> task list of the uncompleted tasks
|
77
85
|
def tasks_by_section_for_project(project)
|
@@ -80,8 +88,6 @@ module Checkoff
|
|
80
88
|
by_section(active_tasks, project.gid)
|
81
89
|
end
|
82
90
|
|
83
|
-
def_delegators :@projects, :client
|
84
|
-
|
85
91
|
# Given a list of tasks, pull a Hash of tasks with section name -> task list
|
86
92
|
def by_section(tasks, project_gid)
|
87
93
|
by_section = {}
|
data/lib/checkoff/subtasks.rb
CHANGED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require 'forwardable'
|
6
|
+
require 'cache_method'
|
7
|
+
require_relative 'config_loader'
|
8
|
+
require_relative 'workspaces'
|
9
|
+
require_relative 'clients'
|
10
|
+
|
11
|
+
# https://developers.asana.com/docs/tags
|
12
|
+
|
13
|
+
module Checkoff
|
14
|
+
# Work with tags in Asana
|
15
|
+
class Tags
|
16
|
+
MINUTE = 60
|
17
|
+
HOUR = MINUTE * 60
|
18
|
+
DAY = 24 * HOUR
|
19
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
20
|
+
LONG_CACHE_TIME = MINUTE * 15
|
21
|
+
SHORT_CACHE_TIME = MINUTE
|
22
|
+
|
23
|
+
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
24
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
25
|
+
clients: Checkoff::Clients.new(config: config),
|
26
|
+
client: clients.client)
|
27
|
+
@workspaces = workspaces
|
28
|
+
@client = client
|
29
|
+
end
|
30
|
+
|
31
|
+
def tag_or_raise(workspace_name, tag_name)
|
32
|
+
tag = tag(workspace_name, tag_name)
|
33
|
+
raise "Could not find tag #{tag_name} under workspace #{workspace_name}." if tag.nil?
|
34
|
+
|
35
|
+
tag
|
36
|
+
end
|
37
|
+
cache_method :tag_or_raise, LONG_CACHE_TIME
|
38
|
+
|
39
|
+
def tag(workspace_name, tag_name)
|
40
|
+
workspace = workspaces.workspace_by_name(workspace_name)
|
41
|
+
tags = client.tags.get_tags_for_workspace(workspace_gid: workspace.gid)
|
42
|
+
tags.find { |tag| tag.name == tag_name }
|
43
|
+
end
|
44
|
+
cache_method :tag, LONG_CACHE_TIME
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :workspaces, :client
|
49
|
+
|
50
|
+
# bundle exec ./tags.rb
|
51
|
+
# :nocov:
|
52
|
+
class << self
|
53
|
+
def run
|
54
|
+
workspace_name = ARGV[0] || raise('Please pass workspace name as first argument')
|
55
|
+
tag_name = ARGV[1] || raise('Please pass tag name as second argument')
|
56
|
+
tags = Checkoff::Tags.new
|
57
|
+
tag = tags.tag_or_raise(workspace_name, tag_name)
|
58
|
+
puts "Results: #{tag}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# :nocov:
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# :nocov:
|
66
|
+
abs_program_name = File.expand_path($PROGRAM_NAME)
|
67
|
+
Checkoff::Tags.run if abs_program_name == __FILE__
|
68
|
+
# :nocov:
|
data/lib/checkoff/version.rb
CHANGED
data/lib/checkoff/workspaces.rb
CHANGED
@@ -1,32 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'forwardable'
|
4
|
+
require 'cache_method'
|
5
|
+
require_relative 'config_loader'
|
6
|
+
require_relative 'clients'
|
7
|
+
|
8
|
+
# https://developers.asana.com/docs/workspaces
|
9
|
+
|
3
10
|
module Checkoff
|
4
11
|
# Query different workspaces of Asana projects
|
5
12
|
class Workspaces
|
13
|
+
MINUTE = 60
|
14
|
+
HOUR = MINUTE * 60
|
15
|
+
DAY = 24 * HOUR
|
16
|
+
REALLY_LONG_CACHE_TIME = HOUR * 1
|
17
|
+
LONG_CACHE_TIME = MINUTE * 15
|
18
|
+
SHORT_CACHE_TIME = MINUTE
|
19
|
+
|
6
20
|
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
7
|
-
|
21
|
+
clients: Checkoff::Clients.new(config: config),
|
22
|
+
client: clients.client)
|
8
23
|
@config = config
|
9
|
-
@
|
10
|
-
end
|
11
|
-
|
12
|
-
# Returns Asana Ruby API Client object
|
13
|
-
def client
|
14
|
-
@client ||= @asana_client.new do |c|
|
15
|
-
c.authentication :access_token, @config.fetch(:personal_access_token)
|
16
|
-
c.default_headers 'asana-enable' => 'string_ids,new_sections'
|
17
|
-
c.default_headers 'asana-disable' => 'new_user_task_lists'
|
18
|
-
end
|
24
|
+
@client = client
|
19
25
|
end
|
20
26
|
|
21
27
|
# Pulls an Asana workspace object
|
22
|
-
def
|
28
|
+
def workspace(workspace_name)
|
23
29
|
client.workspaces.find_all.find do |workspace|
|
24
30
|
workspace.name == workspace_name
|
25
|
-
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def workspace_or_raise(workspace_name)
|
35
|
+
workspace = workspace(workspace_name)
|
36
|
+
raise "Could not find workspace #{workspace_name}" if workspace.nil?
|
37
|
+
|
38
|
+
workspace
|
26
39
|
end
|
27
40
|
|
28
41
|
private
|
29
42
|
|
43
|
+
attr_reader :client
|
44
|
+
|
30
45
|
def default_workspace_gid
|
31
46
|
@config.fetch(:default_workspace_gid)
|
32
47
|
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.15.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: 2021-08-
|
11
|
+
date: 2021-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -299,10 +299,14 @@ files:
|
|
299
299
|
- fix.sh
|
300
300
|
- lib/checkoff.rb
|
301
301
|
- lib/checkoff/cli.rb
|
302
|
+
- lib/checkoff/clients.rb
|
302
303
|
- lib/checkoff/config_loader.rb
|
304
|
+
- lib/checkoff/create-entity.sh
|
305
|
+
- lib/checkoff/custom_fields.rb
|
303
306
|
- lib/checkoff/projects.rb
|
304
307
|
- lib/checkoff/sections.rb
|
305
308
|
- lib/checkoff/subtasks.rb
|
309
|
+
- lib/checkoff/tags.rb
|
306
310
|
- lib/checkoff/tasks.rb
|
307
311
|
- lib/checkoff/version.rb
|
308
312
|
- lib/checkoff/workspaces.rb
|