abt-cli 0.0.2 → 0.0.7
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/bin/abt +4 -1
- data/lib/abt.rb +11 -0
- data/lib/abt/cli.rb +37 -32
- data/lib/abt/cli/dialogs.rb +18 -2
- data/lib/abt/cli/io.rb +23 -0
- data/lib/abt/docs.rb +57 -0
- data/lib/abt/{help → docs}/cli.rb +4 -4
- data/lib/abt/{help → docs}/markdown.rb +4 -4
- data/lib/abt/git_config.rb +55 -49
- data/lib/abt/helpers.rb +16 -0
- data/lib/abt/providers/asana.rb +9 -50
- data/lib/abt/providers/asana/api.rb +57 -0
- data/lib/abt/providers/asana/base_command.rb +14 -16
- data/lib/abt/providers/asana/commands/clear.rb +24 -0
- data/lib/abt/providers/asana/commands/clear_global.rb +24 -0
- data/lib/abt/providers/asana/commands/current.rb +77 -0
- data/lib/abt/providers/asana/commands/finalize.rb +71 -0
- data/lib/abt/providers/asana/commands/harvest_time_entry_data.rb +50 -0
- data/lib/abt/providers/asana/commands/init.rb +70 -0
- data/lib/abt/providers/asana/commands/pick.rb +55 -0
- data/lib/abt/providers/asana/commands/projects.rb +39 -0
- data/lib/abt/providers/asana/commands/share.rb +29 -0
- data/lib/abt/providers/asana/commands/start.rb +105 -0
- data/lib/abt/providers/asana/commands/tasks.rb +40 -0
- data/lib/abt/providers/asana/configuration.rb +125 -0
- data/lib/abt/providers/harvest.rb +9 -42
- data/lib/abt/providers/harvest/api.rb +62 -0
- data/lib/abt/providers/harvest/base_command.rb +12 -16
- data/lib/abt/providers/harvest/commands/clear.rb +24 -0
- data/lib/abt/providers/harvest/commands/clear_global.rb +24 -0
- data/lib/abt/providers/harvest/commands/current.rb +83 -0
- data/lib/abt/providers/harvest/commands/init.rb +83 -0
- data/lib/abt/providers/harvest/commands/pick.rb +51 -0
- data/lib/abt/providers/harvest/commands/projects.rb +40 -0
- data/lib/abt/providers/harvest/commands/share.rb +29 -0
- data/lib/abt/providers/harvest/commands/start.rb +101 -0
- data/lib/abt/providers/harvest/commands/stop.rb +58 -0
- data/lib/abt/providers/harvest/commands/tasks.rb +45 -0
- data/lib/abt/providers/harvest/configuration.rb +91 -0
- data/lib/abt/version.rb +1 -1
- metadata +32 -26
- data/lib/abt/asana_client.rb +0 -53
- data/lib/abt/harvest_client.rb +0 -58
- data/lib/abt/help.rb +0 -56
- data/lib/abt/providers/asana/clear.rb +0 -24
- data/lib/abt/providers/asana/clear_global.rb +0 -24
- data/lib/abt/providers/asana/current.rb +0 -69
- data/lib/abt/providers/asana/harvest_link_entry_data.rb +0 -48
- data/lib/abt/providers/asana/init.rb +0 -62
- data/lib/abt/providers/asana/move.rb +0 -54
- data/lib/abt/providers/asana/pick_task.rb +0 -46
- data/lib/abt/providers/asana/projects.rb +0 -30
- data/lib/abt/providers/asana/start.rb +0 -22
- data/lib/abt/providers/asana/tasks.rb +0 -35
- data/lib/abt/providers/harvest/clear.rb +0 -24
- data/lib/abt/providers/harvest/clear_global.rb +0 -24
- data/lib/abt/providers/harvest/current.rb +0 -79
- data/lib/abt/providers/harvest/init.rb +0 -61
- data/lib/abt/providers/harvest/pick_task.rb +0 -45
- data/lib/abt/providers/harvest/projects.rb +0 -29
- data/lib/abt/providers/harvest/start.rb +0 -58
- data/lib/abt/providers/harvest/stop.rb +0 -51
- data/lib/abt/providers/harvest/tasks.rb +0 -36
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Commands
|
7
|
+
class Projects < BaseCommand
|
8
|
+
def self.command
|
9
|
+
'projects harvest'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'List all available projects - useful for piping into grep etc.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
projects.map do |project|
|
18
|
+
print_project(project)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def projects
|
25
|
+
@projects ||= begin
|
26
|
+
cli.warn 'Fetching projects...'
|
27
|
+
project_assignments.map do |project_assignment|
|
28
|
+
project_assignment['project'].merge('client' => project_assignment['client'])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def project_assignments
|
34
|
+
@project_assignments ||= api.get_paged('users/me/project_assignments')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Commands
|
7
|
+
class Share < BaseCommand
|
8
|
+
def self.command
|
9
|
+
'share harvest[:<project-id>[/<task-id>]]'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'Print project/task config string'
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
if project_id.nil?
|
18
|
+
cli.warn 'No project selected'
|
19
|
+
elsif task_id.nil?
|
20
|
+
cli.print_provider_command('harvest', project_id)
|
21
|
+
else
|
22
|
+
cli.print_provider_command('harvest', "#{project_id}/#{task_id}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Commands
|
7
|
+
class Start < BaseCommand
|
8
|
+
def self.command
|
9
|
+
'start harvest[:<project-id>/<task-id>]'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'Start tracker for current or specified task. Add a relevant provider to link the time entry: E.g. `abt start harvest asana`' # rubocop:disable Layout/LineLength
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
abort 'No current/provided task' if task_id.nil?
|
18
|
+
|
19
|
+
maybe_override_current_task
|
20
|
+
|
21
|
+
print_task(project, task)
|
22
|
+
|
23
|
+
cli.abort('No task selected') if task_id.nil?
|
24
|
+
|
25
|
+
create_time_entry
|
26
|
+
|
27
|
+
cli.warn 'Tracker successfully started'
|
28
|
+
rescue Abt::HttpError::HttpError => e
|
29
|
+
cli.warn e
|
30
|
+
cli.abort 'Unable to start tracker'
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def maybe_override_current_task
|
36
|
+
return if arg_str.nil?
|
37
|
+
return if same_args_as_config?
|
38
|
+
return unless config.local_available?
|
39
|
+
|
40
|
+
should_override = cli.prompt_boolean 'Set selected task as current?'
|
41
|
+
Current.new(arg_str: arg_str, cli: cli).call if should_override
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_time_entry
|
45
|
+
body = {
|
46
|
+
project_id: project_id,
|
47
|
+
task_id: task_id,
|
48
|
+
user_id: config.user_id,
|
49
|
+
spent_date: Date.today.iso8601
|
50
|
+
}
|
51
|
+
|
52
|
+
if external_link_data
|
53
|
+
body.merge! external_link_data
|
54
|
+
else
|
55
|
+
cli.warn 'No external link provided'
|
56
|
+
body[:notes] ||= cli.prompt('Fill in comment (optional)')
|
57
|
+
end
|
58
|
+
|
59
|
+
api.post('time_entries', Oj.dump(body, mode: :json))
|
60
|
+
end
|
61
|
+
|
62
|
+
def project
|
63
|
+
project_assignment['project']
|
64
|
+
end
|
65
|
+
|
66
|
+
def task
|
67
|
+
@task ||= project_assignment['task_assignments'].map { |ta| ta['task'] }.find do |task|
|
68
|
+
task['id'].to_s == task_id
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def project_assignment
|
73
|
+
@project_assignment ||= begin
|
74
|
+
project_assignments.find { |pa| pa['project']['id'].to_s == project_id }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def project_assignments
|
79
|
+
@project_assignments ||= api.get_paged('users/me/project_assignments')
|
80
|
+
end
|
81
|
+
|
82
|
+
def external_link_data
|
83
|
+
@external_link_data ||= begin
|
84
|
+
arg_strs = cli.args.join(' ')
|
85
|
+
lines = `#{$PROGRAM_NAME} harvest-time-entry-data #{arg_strs}`.split("\n")
|
86
|
+
|
87
|
+
return if lines.empty?
|
88
|
+
|
89
|
+
# TODO: Make user choose which reference to use by printing the urls
|
90
|
+
if lines.length > 1
|
91
|
+
cli.abort('Multiple providers had harvest reference data, only one is supported at a time') # rubocop:disable Layout/LineLength
|
92
|
+
end
|
93
|
+
|
94
|
+
Oj.load(lines.first)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Commands
|
7
|
+
class Stop < BaseCommand
|
8
|
+
def self.command
|
9
|
+
'stop harvest'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'Stop running harvest tracker'
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
cli.abort 'No running time entry' if time_entry.nil?
|
18
|
+
|
19
|
+
stop_time_entry
|
20
|
+
|
21
|
+
cli.warn 'Harvest time entry stopped'
|
22
|
+
print_task(project, task)
|
23
|
+
rescue Abt::HttpError::HttpError => e
|
24
|
+
cli.warn e
|
25
|
+
cli.abort 'Unable to stop time entry'
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def stop_time_entry
|
31
|
+
api.patch("time_entries/#{time_entry['id']}/stop")
|
32
|
+
end
|
33
|
+
|
34
|
+
def project
|
35
|
+
time_entry['project']
|
36
|
+
end
|
37
|
+
|
38
|
+
def task
|
39
|
+
time_entry['task']
|
40
|
+
end
|
41
|
+
|
42
|
+
def time_entry
|
43
|
+
@time_entry ||= begin
|
44
|
+
api.get_paged(
|
45
|
+
'time_entries',
|
46
|
+
is_running: true,
|
47
|
+
user_id: config.user_id
|
48
|
+
).first
|
49
|
+
rescue Abt::HttpError::HttpError => e # rubocop:disable Layout/RescueEnsureAlignment
|
50
|
+
cli.warn e
|
51
|
+
cli.abort 'Unable to fetch running time entry'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Commands
|
7
|
+
class Tasks < BaseCommand
|
8
|
+
def self.command
|
9
|
+
'tasks harvest'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'List available tasks on project - useful for piping into grep etc.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
tasks.each do |task|
|
18
|
+
print_task(project, task)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def project
|
25
|
+
project_assignment['project']
|
26
|
+
end
|
27
|
+
|
28
|
+
def tasks
|
29
|
+
@tasks ||= project_assignment['task_assignments'].map { |ta| ta['task'] }
|
30
|
+
end
|
31
|
+
|
32
|
+
def project_assignment
|
33
|
+
@project_assignment ||= begin
|
34
|
+
project_assignments.find { |pa| pa['project']['id'].to_s == project_id }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def project_assignments
|
39
|
+
@project_assignments ||= api.get_paged('users/me/project_assignments')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
class Configuration
|
7
|
+
attr_accessor :cli
|
8
|
+
|
9
|
+
def initialize(cli:)
|
10
|
+
@cli = cli
|
11
|
+
@git = GitConfig.new(namespace: 'abt.harvest')
|
12
|
+
end
|
13
|
+
|
14
|
+
def local_available?
|
15
|
+
GitConfig.local_available?
|
16
|
+
end
|
17
|
+
|
18
|
+
def project_id
|
19
|
+
local_available? ? git['projectId'] : nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def task_id
|
23
|
+
local_available? ? git['taskId'] : nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def project_id=(value)
|
27
|
+
value = value.to_s unless value.nil?
|
28
|
+
return if project_id == value
|
29
|
+
|
30
|
+
clear_local
|
31
|
+
git['projectId'] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def task_id=(value)
|
35
|
+
value = value.to_s unless value.nil?
|
36
|
+
git['taskId'] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear_local
|
40
|
+
cli.abort 'No local configuration was found' unless local_available?
|
41
|
+
|
42
|
+
git['projectId'] = nil
|
43
|
+
git['taskId'] = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def clear_global
|
47
|
+
git.global['userId'] = nil
|
48
|
+
git.global['accountId'] = nil
|
49
|
+
git.global['accessToken'] = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def access_token
|
53
|
+
return git.global['accessToken'] unless git.global['accessToken'].nil?
|
54
|
+
|
55
|
+
git.global['accessToken'] = cli.prompt([
|
56
|
+
'Please provide your personal access token for Harvest.',
|
57
|
+
'If you don\'t have one, create one here: https://id.getharvest.com/developers',
|
58
|
+
'',
|
59
|
+
'Enter access token'
|
60
|
+
].join("\n"))
|
61
|
+
end
|
62
|
+
|
63
|
+
def account_id
|
64
|
+
return git.global['accountId'] unless git.global['accountId'].nil?
|
65
|
+
|
66
|
+
git.global['accountId'] = cli.prompt([
|
67
|
+
'Please provide harvest account id.',
|
68
|
+
'This information is shown next to your generated access token',
|
69
|
+
'',
|
70
|
+
'Enter account id'
|
71
|
+
].join("\n"))
|
72
|
+
end
|
73
|
+
|
74
|
+
def user_id
|
75
|
+
return git.global['userId'] unless git.global['userId'].nil?
|
76
|
+
|
77
|
+
git.global['userId'] = api.get('users/me')['id'].to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
attr_reader :git
|
83
|
+
|
84
|
+
def api
|
85
|
+
@api ||=
|
86
|
+
Abt::Providers::Harvest::Api.new(access_token: access_token, account_id: account_id)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/abt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abt-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesper Sørensen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-inflector
|
@@ -75,39 +75,45 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- "./lib/abt.rb"
|
78
|
-
- "./lib/abt/asana_client.rb"
|
79
78
|
- "./lib/abt/cli.rb"
|
80
79
|
- "./lib/abt/cli/dialogs.rb"
|
80
|
+
- "./lib/abt/cli/io.rb"
|
81
|
+
- "./lib/abt/docs.rb"
|
82
|
+
- "./lib/abt/docs/cli.rb"
|
83
|
+
- "./lib/abt/docs/markdown.rb"
|
81
84
|
- "./lib/abt/git_config.rb"
|
82
|
-
- "./lib/abt/
|
83
|
-
- "./lib/abt/help.rb"
|
84
|
-
- "./lib/abt/help/cli.rb"
|
85
|
-
- "./lib/abt/help/markdown.rb"
|
85
|
+
- "./lib/abt/helpers.rb"
|
86
86
|
- "./lib/abt/http_error.rb"
|
87
87
|
- "./lib/abt/providers.rb"
|
88
88
|
- "./lib/abt/providers/asana.rb"
|
89
|
+
- "./lib/abt/providers/asana/api.rb"
|
89
90
|
- "./lib/abt/providers/asana/base_command.rb"
|
90
|
-
- "./lib/abt/providers/asana/clear.rb"
|
91
|
-
- "./lib/abt/providers/asana/clear_global.rb"
|
92
|
-
- "./lib/abt/providers/asana/current.rb"
|
93
|
-
- "./lib/abt/providers/asana/
|
94
|
-
- "./lib/abt/providers/asana/
|
95
|
-
- "./lib/abt/providers/asana/
|
96
|
-
- "./lib/abt/providers/asana/
|
97
|
-
- "./lib/abt/providers/asana/projects.rb"
|
98
|
-
- "./lib/abt/providers/asana/
|
99
|
-
- "./lib/abt/providers/asana/
|
91
|
+
- "./lib/abt/providers/asana/commands/clear.rb"
|
92
|
+
- "./lib/abt/providers/asana/commands/clear_global.rb"
|
93
|
+
- "./lib/abt/providers/asana/commands/current.rb"
|
94
|
+
- "./lib/abt/providers/asana/commands/finalize.rb"
|
95
|
+
- "./lib/abt/providers/asana/commands/harvest_time_entry_data.rb"
|
96
|
+
- "./lib/abt/providers/asana/commands/init.rb"
|
97
|
+
- "./lib/abt/providers/asana/commands/pick.rb"
|
98
|
+
- "./lib/abt/providers/asana/commands/projects.rb"
|
99
|
+
- "./lib/abt/providers/asana/commands/share.rb"
|
100
|
+
- "./lib/abt/providers/asana/commands/start.rb"
|
101
|
+
- "./lib/abt/providers/asana/commands/tasks.rb"
|
102
|
+
- "./lib/abt/providers/asana/configuration.rb"
|
100
103
|
- "./lib/abt/providers/harvest.rb"
|
104
|
+
- "./lib/abt/providers/harvest/api.rb"
|
101
105
|
- "./lib/abt/providers/harvest/base_command.rb"
|
102
|
-
- "./lib/abt/providers/harvest/clear.rb"
|
103
|
-
- "./lib/abt/providers/harvest/clear_global.rb"
|
104
|
-
- "./lib/abt/providers/harvest/current.rb"
|
105
|
-
- "./lib/abt/providers/harvest/init.rb"
|
106
|
-
- "./lib/abt/providers/harvest/
|
107
|
-
- "./lib/abt/providers/harvest/projects.rb"
|
108
|
-
- "./lib/abt/providers/harvest/
|
109
|
-
- "./lib/abt/providers/harvest/
|
110
|
-
- "./lib/abt/providers/harvest/
|
106
|
+
- "./lib/abt/providers/harvest/commands/clear.rb"
|
107
|
+
- "./lib/abt/providers/harvest/commands/clear_global.rb"
|
108
|
+
- "./lib/abt/providers/harvest/commands/current.rb"
|
109
|
+
- "./lib/abt/providers/harvest/commands/init.rb"
|
110
|
+
- "./lib/abt/providers/harvest/commands/pick.rb"
|
111
|
+
- "./lib/abt/providers/harvest/commands/projects.rb"
|
112
|
+
- "./lib/abt/providers/harvest/commands/share.rb"
|
113
|
+
- "./lib/abt/providers/harvest/commands/start.rb"
|
114
|
+
- "./lib/abt/providers/harvest/commands/stop.rb"
|
115
|
+
- "./lib/abt/providers/harvest/commands/tasks.rb"
|
116
|
+
- "./lib/abt/providers/harvest/configuration.rb"
|
111
117
|
- "./lib/abt/version.rb"
|
112
118
|
- bin/abt
|
113
119
|
homepage: https://github.com/abtion/abt
|