abt-cli 0.0.30 → 0.0.31
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/lib/abt/providers/asana/commands/clear.rb +1 -1
- data/lib/abt/providers/devops/commands/clear.rb +1 -1
- data/lib/abt/providers/harvest/commands/clear.rb +1 -1
- data/lib/abt/providers/harvest/commands/track.rb +72 -39
- data/lib/abt/providers/harvest/harvest_helpers.rb +25 -0
- data/lib/abt/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b0f6705f90f844f11a301d2aee417ded8524de882bba8cd114d62ceee77ee92
|
4
|
+
data.tar.gz: d51120f9529853801fefd8b557102e1cac058685da5208f5a42577726e3c871d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2e08dd8e61a8d0271661af7e653b4da5d26f5ba0790cf657e2ec0c8524d784af707e1cd9bb2914192ba6943ae1d39f845aedd80c3dbffc2f529a46b9a0dba5d
|
7
|
+
data.tar.gz: 728e3b2cfbe503ab9188b789510c112e3f2c569e32a3a541f1f30e454bfdd80381f0a35185fc0b10ad9ff9751141dc168bdb84422b09657b46621f04df982df1
|
@@ -22,7 +22,7 @@ module Abt
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def perform
|
25
|
-
abort("Flags --global and --all cannot be used
|
25
|
+
abort("Flags --global and --all cannot be used together") if flags[:global] && flags[:all]
|
26
26
|
|
27
27
|
config.clear_local unless flags[:global]
|
28
28
|
config.clear_global if flags[:global] || flags[:all]
|
@@ -22,7 +22,7 @@ module Abt
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def perform
|
25
|
-
abort("Flags --global and --all cannot be used
|
25
|
+
abort("Flags --global and --all cannot be used together") if flags[:global] && flags[:all]
|
26
26
|
|
27
27
|
config.clear_local unless flags[:global]
|
28
28
|
config.clear_global if flags[:global] || flags[:all]
|
@@ -22,7 +22,7 @@ module Abt
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def perform
|
25
|
-
abort("Flags --global and --all cannot be used
|
25
|
+
abort("Flags --global and --all cannot be used together") if flags[:global] && flags[:all]
|
26
26
|
|
27
27
|
config.clear_local unless flags[:global]
|
28
28
|
config.clear_global if flags[:global] || flags[:all]
|
@@ -4,7 +4,7 @@ module Abt
|
|
4
4
|
module Providers
|
5
5
|
module Harvest
|
6
6
|
module Commands
|
7
|
-
class Track < BaseCommand
|
7
|
+
class Track < BaseCommand # rubocop:disable Metrics/ClassLength
|
8
8
|
def self.usage
|
9
9
|
"abt track harvest[:<project-id>/<task-id>] [options]"
|
10
10
|
end
|
@@ -20,15 +20,21 @@ module Abt
|
|
20
20
|
["-s", "--set", "Set specified task as current"],
|
21
21
|
["-c", "--comment COMMENT", "Override comment"],
|
22
22
|
["-t", "--time HOURS",
|
23
|
-
"
|
24
|
-
["-
|
23
|
+
"Track amount of hours, this will create a stopped entry."],
|
24
|
+
["-i", "--since HH:MM",
|
25
|
+
"Start entry today at specified time. The computed duration will be deducted from the running entry if one exists."] # rubocop:disable Layout/LineLength
|
25
26
|
]
|
26
27
|
end
|
27
28
|
|
28
29
|
def perform
|
30
|
+
abort("Flags --time and --since cannot be used together") if flags[:time] && flags[:since]
|
31
|
+
|
29
32
|
require_task!
|
30
33
|
|
31
|
-
|
34
|
+
maybe_adjust_previous_entry
|
35
|
+
entry = create_entry!
|
36
|
+
|
37
|
+
print_task(entry["project"], entry["task"])
|
32
38
|
|
33
39
|
maybe_override_current_task
|
34
40
|
rescue Abt::HttpError::HttpError => _e
|
@@ -37,31 +43,41 @@ module Abt
|
|
37
43
|
|
38
44
|
private
|
39
45
|
|
40
|
-
def
|
41
|
-
|
46
|
+
def create_entry!
|
47
|
+
result = api.post("time_entries", Oj.dump(entry_data, mode: :json))
|
48
|
+
api.patch("time_entries/#{result['id']}/restart") if flags.key?(:since)
|
49
|
+
result
|
42
50
|
end
|
43
51
|
|
44
|
-
def
|
45
|
-
|
52
|
+
def maybe_adjust_previous_entry
|
53
|
+
return unless flags.key?(:since)
|
54
|
+
return unless since_flag_duration # Ensure --since flag is valid before fetching data
|
55
|
+
return unless previous_entry
|
56
|
+
|
57
|
+
adjust_previous_entry
|
58
|
+
end
|
46
59
|
|
47
|
-
|
60
|
+
def adjust_previous_entry
|
61
|
+
updated_hours = previous_entry["hours"] - since_flag_duration
|
62
|
+
abort("Cannot adjust previous entry to a negative duration") if updated_hours <= 0
|
48
63
|
|
49
|
-
api.patch("time_entries/#{
|
64
|
+
api.patch("time_entries/#{previous_entry['id']}", Oj.dump({ hours: updated_hours }, mode: :json))
|
50
65
|
|
51
|
-
|
66
|
+
subtracted_minutes = (since_flag_duration * 60).round
|
67
|
+
warn("~#{subtracted_minutes} minute(s) subtracted from previous entry")
|
52
68
|
end
|
53
69
|
|
54
|
-
def
|
55
|
-
body =
|
70
|
+
def entry_data
|
71
|
+
body = entry_base_data
|
56
72
|
|
57
73
|
maybe_add_external_link(body)
|
58
74
|
maybe_add_comment(body)
|
59
|
-
|
75
|
+
maybe_add_hours(body)
|
60
76
|
|
61
77
|
body
|
62
78
|
end
|
63
79
|
|
64
|
-
def
|
80
|
+
def entry_base_data
|
65
81
|
{
|
66
82
|
project_id: project_id,
|
67
83
|
task_id: task_id,
|
@@ -74,8 +90,8 @@ module Abt
|
|
74
90
|
if external_link_data
|
75
91
|
warn(<<~TXT)
|
76
92
|
Linking to:
|
77
|
-
|
78
|
-
|
93
|
+
#{external_link_data[:notes]}
|
94
|
+
#{external_link_data[:external_reference][:permalink]}
|
79
95
|
TXT
|
80
96
|
body.merge!(external_link_data)
|
81
97
|
else
|
@@ -83,38 +99,40 @@ module Abt
|
|
83
99
|
end
|
84
100
|
end
|
85
101
|
|
86
|
-
def maybe_add_comment(body)
|
87
|
-
body[:notes] = flags[:comment] if flags.key?(:comment)
|
88
|
-
body[:notes] ||= cli.prompt.text("Fill in comment (optional)")
|
89
|
-
end
|
90
|
-
|
91
|
-
def maybe_add_time(body)
|
92
|
-
body[:hours] = flags[:time] if flags.key?(:time)
|
93
|
-
end
|
94
|
-
|
95
102
|
def external_link_data
|
96
103
|
return @external_link_data if instance_variable_defined?(:@external_link_data)
|
104
|
+
return @external_link_data = nil if link_data_lines.empty?
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
return @external_link_data = nil if lines.empty?
|
101
|
-
|
102
|
-
if lines.length > 1
|
106
|
+
if link_data_lines.length > 1
|
103
107
|
abort("Got reference data from multiple scheme providers, only one is supported at a time")
|
104
108
|
end
|
105
109
|
|
106
|
-
@external_link_data = Oj.load(
|
110
|
+
@external_link_data = Oj.load(link_data_lines.first, symbol_keys: true)
|
107
111
|
end
|
108
112
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
113
|
+
def link_data_lines
|
114
|
+
@link_data_lines ||= begin
|
115
|
+
other_aris = cli.aris - [ari]
|
116
|
+
other_aris.map do |other_ari|
|
117
|
+
input = StringIO.new(other_ari.to_s)
|
118
|
+
output = StringIO.new
|
119
|
+
Abt::Cli.new(argv: ["harvest-time-entry-data"], output: output, input: input).perform
|
120
|
+
output.string.chomp
|
121
|
+
end.reject(&:empty?)
|
122
|
+
end
|
123
|
+
end
|
112
124
|
|
113
|
-
|
114
|
-
|
115
|
-
|
125
|
+
def maybe_add_comment(body)
|
126
|
+
body[:notes] = flags[:comment] if flags.key?(:comment)
|
127
|
+
body[:notes] ||= cli.prompt.text("Fill in comment (optional)")
|
128
|
+
end
|
116
129
|
|
117
|
-
|
130
|
+
def maybe_add_hours(body)
|
131
|
+
if flags[:time]
|
132
|
+
body[:hours] = flags[:time]
|
133
|
+
elsif flags[:since]
|
134
|
+
body[:hours] = since_flag_duration
|
135
|
+
end
|
118
136
|
end
|
119
137
|
|
120
138
|
def maybe_override_current_task
|
@@ -125,6 +143,21 @@ module Abt
|
|
125
143
|
config.path = path
|
126
144
|
warn("Current task updated")
|
127
145
|
end
|
146
|
+
|
147
|
+
def since_flag_duration
|
148
|
+
@since_flag_duration ||= begin
|
149
|
+
since_hours = HarvestHelpers.decimal_hours_from_string(flags[:since])
|
150
|
+
now_hours = HarvestHelpers.decimal_hours_from_string(Time.now.strftime("%T"))
|
151
|
+
|
152
|
+
abort("Specified \"since\" time (#{flags[:since]}) is in the future") if now_hours <= since_hours
|
153
|
+
|
154
|
+
now_hours - since_hours
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def previous_entry
|
159
|
+
@previous_entry ||= api.get_paged("time_entries", is_running: true, user_id: config.user_id).first
|
160
|
+
end
|
128
161
|
end
|
129
162
|
end
|
130
163
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
class HarvestHelpers
|
7
|
+
class << self
|
8
|
+
HOURS_REGEX = /(?<hours>\d+)/.freeze
|
9
|
+
MINUTES_REGEX = /(?<minutes>[0-5][0-9])/.freeze
|
10
|
+
SECONDS_REGEX = /(?<seconds>[0-5][0-9])/.freeze
|
11
|
+
TIME_REGEX = /^#{HOURS_REGEX}:#{MINUTES_REGEX}(?::#{SECONDS_REGEX})?$/.freeze
|
12
|
+
|
13
|
+
def decimal_hours_from_string(hh_mm_ss)
|
14
|
+
match = TIME_REGEX.match(hh_mm_ss)
|
15
|
+
raise Abt::Cli::Abort, "Invalid time: #{hh_mm_ss}, supported formats are: HH:MM, HH:MM:SS" if match.nil?
|
16
|
+
|
17
|
+
match[:hours].to_i +
|
18
|
+
match[:minutes].to_i / 60.0 +
|
19
|
+
match[:seconds].to_i / 60.0 / 60.0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
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.31
|
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-
|
11
|
+
date: 2021-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-inflector
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- "./lib/abt/providers/harvest/commands/track.rb"
|
148
148
|
- "./lib/abt/providers/harvest/commands/write_config.rb"
|
149
149
|
- "./lib/abt/providers/harvest/configuration.rb"
|
150
|
+
- "./lib/abt/providers/harvest/harvest_helpers.rb"
|
150
151
|
- "./lib/abt/providers/harvest/path.rb"
|
151
152
|
- "./lib/abt/providers/harvest/services/project_picker.rb"
|
152
153
|
- "./lib/abt/providers/harvest/services/task_picker.rb"
|