abt-cli 0.0.15 → 0.0.20

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/bin/abt +1 -1
  3. data/lib/abt.rb +4 -3
  4. data/lib/abt/ari.rb +20 -0
  5. data/lib/abt/ari_list.rb +13 -0
  6. data/lib/abt/base_command.rb +63 -0
  7. data/lib/abt/cli.rb +68 -49
  8. data/lib/abt/cli/arguments_parser.rb +48 -0
  9. data/lib/abt/cli/prompt.rb +7 -6
  10. data/lib/abt/docs.rb +35 -28
  11. data/lib/abt/docs/cli.rb +42 -11
  12. data/lib/abt/docs/markdown.rb +38 -11
  13. data/lib/abt/git_config.rb +26 -31
  14. data/lib/abt/providers/asana/base_command.rb +17 -37
  15. data/lib/abt/providers/asana/commands/add.rb +12 -10
  16. data/lib/abt/providers/asana/commands/{branch-name.rb → branch_name.rb} +12 -7
  17. data/lib/abt/providers/asana/commands/clear.rb +19 -6
  18. data/lib/abt/providers/asana/commands/current.rb +22 -37
  19. data/lib/abt/providers/asana/commands/finalize.rb +8 -12
  20. data/lib/abt/providers/asana/commands/harvest_time_entry_data.rb +12 -7
  21. data/lib/abt/providers/asana/commands/init.rb +9 -9
  22. data/lib/abt/providers/asana/commands/pick.rb +28 -15
  23. data/lib/abt/providers/asana/commands/projects.rb +4 -4
  24. data/lib/abt/providers/asana/commands/share.rb +5 -9
  25. data/lib/abt/providers/asana/commands/start.rb +26 -18
  26. data/lib/abt/providers/asana/commands/tasks.rb +7 -6
  27. data/lib/abt/providers/asana/configuration.rb +23 -37
  28. data/lib/abt/providers/asana/path.rb +36 -0
  29. data/lib/abt/providers/devops/api.rb +12 -0
  30. data/lib/abt/providers/devops/base_command.rb +18 -44
  31. data/lib/abt/providers/devops/commands/boards.rb +7 -5
  32. data/lib/abt/providers/devops/commands/{branch-name.rb → branch_name.rb} +10 -6
  33. data/lib/abt/providers/devops/commands/clear.rb +19 -6
  34. data/lib/abt/providers/devops/commands/current.rb +17 -41
  35. data/lib/abt/providers/devops/commands/harvest_time_entry_data.rb +12 -4
  36. data/lib/abt/providers/devops/commands/init.rb +18 -18
  37. data/lib/abt/providers/devops/commands/pick.rb +16 -16
  38. data/lib/abt/providers/devops/commands/share.rb +6 -7
  39. data/lib/abt/providers/devops/commands/work-items.rb +4 -4
  40. data/lib/abt/providers/devops/configuration.rb +20 -57
  41. data/lib/abt/providers/devops/path.rb +50 -0
  42. data/lib/abt/providers/git/commands/branch.rb +28 -28
  43. data/lib/abt/providers/harvest/base_command.rb +18 -36
  44. data/lib/abt/providers/harvest/commands/clear.rb +19 -6
  45. data/lib/abt/providers/harvest/commands/current.rb +27 -34
  46. data/lib/abt/providers/harvest/commands/init.rb +8 -9
  47. data/lib/abt/providers/harvest/commands/pick.rb +15 -8
  48. data/lib/abt/providers/harvest/commands/projects.rb +4 -4
  49. data/lib/abt/providers/harvest/commands/share.rb +7 -11
  50. data/lib/abt/providers/harvest/commands/start.rb +6 -42
  51. data/lib/abt/providers/harvest/commands/stop.rb +10 -10
  52. data/lib/abt/providers/harvest/commands/tasks.rb +7 -4
  53. data/lib/abt/providers/harvest/commands/track.rb +66 -21
  54. data/lib/abt/providers/harvest/configuration.rb +23 -38
  55. data/lib/abt/providers/harvest/path.rb +36 -0
  56. data/lib/abt/version.rb +1 -1
  57. metadata +11 -7
  58. data/lib/abt/providers/asana/commands/clear_global.rb +0 -24
  59. data/lib/abt/providers/devops/commands/clear_global.rb +0 -24
  60. data/lib/abt/providers/harvest/commands/clear_global.rb +0 -24
@@ -5,15 +5,15 @@ module Abt
5
5
  module Harvest
6
6
  module Commands
7
7
  class Tasks < BaseCommand
8
- def self.command
9
- 'tasks harvest'
8
+ def self.usage
9
+ 'abt tasks harvest'
10
10
  end
11
11
 
12
12
  def self.description
13
13
  'List available tasks on project - useful for piping into grep etc.'
14
14
  end
15
15
 
16
- def call
16
+ def perform
17
17
  require_project!
18
18
 
19
19
  tasks.each do |task|
@@ -28,7 +28,10 @@ module Abt
28
28
  end
29
29
 
30
30
  def tasks
31
- @tasks ||= project_assignment['task_assignments'].map { |ta| ta['task'] }
31
+ @tasks ||= begin
32
+ warn 'Fetching tasks...'
33
+ project_assignment['task_assignments'].map { |ta| ta['task'] }
34
+ end
32
35
  end
33
36
 
34
37
  def project_assignment
@@ -5,22 +5,31 @@ module Abt
5
5
  module Harvest
6
6
  module Commands
7
7
  class Track < BaseCommand
8
- def self.command
9
- 'track harvest[:<project-id>/<task-id>]'
8
+ def self.usage
9
+ 'abt track harvest[:<project-id>/<task-id>] [options]'
10
10
  end
11
11
 
12
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
13
+ 'Start tracker for current or specified task. Add a relevant ARI to link the time entry, e.g. `abt track harvest asana`'
14
14
  end
15
15
 
16
- def call
16
+ def self.flags
17
+ [
18
+ ['-s', '--set', 'Set specified task as current'],
19
+ ['-c', '--comment COMMENT', 'Override comment'],
20
+ ['-t', '--time HOURS', 'Set hours. Creates a stopped entry unless used with --running'],
21
+ ['-r', '--running', 'Used with --time, starts the created time entry']
22
+ ]
23
+ end
24
+
25
+ def perform
17
26
  require_task!
18
27
 
19
28
  print_task(created_time_entry['project'], created_time_entry['task'])
20
29
 
21
- cli.warn 'Tracker successfully started'
22
- rescue Abt::HttpError::HttpError => e
23
- cli.abort 'Invalid task'
30
+ maybe_override_current_task
31
+ rescue Abt::HttpError::HttpError => _e
32
+ abort 'Invalid task'
24
33
  end
25
34
 
26
35
  private
@@ -30,6 +39,19 @@ module Abt
30
39
  end
31
40
 
32
41
  def create_time_entry
42
+ body = time_entry_base_data
43
+ body.merge!(hours: flags[:time]) if flags.key? :time
44
+
45
+ result = api.post('time_entries', Oj.dump(body, mode: :json))
46
+
47
+ if flags.key?(:time) && flags[:running]
48
+ api.patch("time_entries/#{result['id']}/restart")
49
+ end
50
+
51
+ result
52
+ end
53
+
54
+ def time_entry_base_data
33
55
  body = {
34
56
  project_id: project_id,
35
57
  task_id: task_id,
@@ -38,33 +60,56 @@ module Abt
38
60
  }
39
61
 
40
62
  if external_link_data
63
+ warn <<~TXT
64
+ Linking to:
65
+ #{external_link_data[:notes]}
66
+ #{external_link_data[:external_reference][:permalink]}
67
+ TXT
41
68
  body.merge! external_link_data
42
69
  else
43
- cli.warn 'No external link provided'
44
- body[:notes] ||= cli.prompt.text('Fill in comment (optional)')
70
+ warn 'No external link provided'
45
71
  end
46
72
 
47
- api.post('time_entries', Oj.dump(body, mode: :json))
73
+ body[:notes] = flags[:comment] if flags.key?(:comment)
74
+ body[:notes] ||= cli.prompt.text('Fill in comment (optional)')
75
+ body
48
76
  end
49
77
 
50
78
  def external_link_data
51
79
  @external_link_data ||= begin
52
- input = StringIO.new(cli.args.join(' '))
53
- output = StringIO.new
54
- Abt::Cli.new(argv: ['harvest-time-entry-data'], output: output, input: input).perform
55
-
56
- lines = output.string.strip.lines
80
+ lines = call_harvest_time_entry_data_for_other_aris
57
81
 
58
- return if lines.empty?
82
+ if lines.empty?
83
+ nil
84
+ else
85
+ if lines.length > 1
86
+ abort('Got reference data from multiple scheme providers, only one is supported at a time')
87
+ end
59
88
 
60
- # TODO: Make user choose which reference to use by printing the urls
61
- if lines.length > 1
62
- cli.abort('Multiple providers had harvest reference data, only one is supported at a time') # rubocop:disable Layout/LineLength
89
+ Oj.load(lines.first, symbol_keys: true)
63
90
  end
64
-
65
- Oj.load(lines.first)
66
91
  end
67
92
  end
93
+
94
+ def call_harvest_time_entry_data_for_other_aris
95
+ other_aris = cli.aris - [ari]
96
+ return [] if other_aris.empty?
97
+
98
+ input = StringIO.new(other_aris.to_s)
99
+ output = StringIO.new
100
+ Abt::Cli.new(argv: ['harvest-time-entry-data'], output: output, input: input).perform
101
+
102
+ output.string.strip.lines
103
+ end
104
+
105
+ def maybe_override_current_task
106
+ return unless flags[:set]
107
+ return if path == config.path
108
+ return unless config.local_available?
109
+
110
+ config.path = path
111
+ warn 'Current task updated'
112
+ end
68
113
  end
69
114
  end
70
115
  end
@@ -8,52 +8,32 @@ module Abt
8
8
 
9
9
  def initialize(cli:)
10
10
  @cli = cli
11
- @git = GitConfig.new(namespace: 'abt.harvest')
12
11
  end
13
12
 
14
13
  def local_available?
15
- GitConfig.local_available?
14
+ git.available?
16
15
  end
17
16
 
18
- def project_id
19
- local_available? ? git['projectId'] : nil
17
+ def path
18
+ Path.new(local_available? && git['path'] || '')
20
19
  end
21
20
 
22
- def task_id
23
- local_available? ? git['taskId'] : nil
21
+ def path=(new_path)
22
+ git['path'] = new_path
24
23
  end
25
24
 
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
25
+ def clear_local(verbose: true)
26
+ git.clear(output: verbose ? cli.err_output : nil)
32
27
  end
33
28
 
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.keys.each do |key|
48
- cli.puts 'Deleting configuration: ' + key
49
- git.global[key] = nil
50
- end
29
+ def clear_global(verbose: true)
30
+ git_global.clear(output: verbose ? cli.err_output : nil)
51
31
  end
52
32
 
53
33
  def access_token
54
- return git.global['accessToken'] unless git.global['accessToken'].nil?
34
+ return git_global['accessToken'] unless git_global['accessToken'].nil?
55
35
 
56
- git.global['accessToken'] = cli.prompt.text([
36
+ git_global['accessToken'] = cli.prompt.text([
57
37
  'Please provide your personal access token for Harvest.',
58
38
  'If you don\'t have one, create one here: https://id.getharvest.com/developers',
59
39
  '',
@@ -62,9 +42,9 @@ module Abt
62
42
  end
63
43
 
64
44
  def account_id
65
- return git.global['accountId'] unless git.global['accountId'].nil?
45
+ return git_global['accountId'] unless git_global['accountId'].nil?
66
46
 
67
- git.global['accountId'] = cli.prompt.text([
47
+ git_global['accountId'] = cli.prompt.text([
68
48
  'Please provide harvest account id.',
69
49
  'This information is shown next to your generated access token',
70
50
  '',
@@ -73,18 +53,23 @@ module Abt
73
53
  end
74
54
 
75
55
  def user_id
76
- return git.global['userId'] unless git.global['userId'].nil?
56
+ return git_global['userId'] unless git_global['userId'].nil?
77
57
 
78
- git.global['userId'] = api.get('users/me')['id'].to_s
58
+ git_global['userId'] = api.get('users/me')['id'].to_s
79
59
  end
80
60
 
81
61
  private
82
62
 
83
- attr_reader :git
63
+ def git
64
+ @git ||= GitConfig.new('local', 'abt.harvest')
65
+ end
66
+
67
+ def git_global
68
+ @git_global ||= GitConfig.new('global', 'abt.harvest')
69
+ end
84
70
 
85
71
  def api
86
- @api ||=
87
- Abt::Providers::Harvest::Api.new(access_token: access_token, account_id: account_id)
72
+ @api ||= Api.new(access_token: access_token, account_id: account_id)
88
73
  end
89
74
  end
90
75
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Abt
4
+ module Providers
5
+ module Harvest
6
+ class Path < String
7
+ PATH_REGEX = %r{^(?<project_id>\d+)?(/(?<task_id>\d+))?$}.freeze
8
+
9
+ def self.from_ids(project_id = nil, task_id = nil)
10
+ path = project_id ? [project_id, *task_id].join('/') : ''
11
+ new path
12
+ end
13
+
14
+ def initialize(path = '')
15
+ raise Abt::Cli::Abort, "Invalid path: #{path}" unless path =~ PATH_REGEX
16
+
17
+ super
18
+ end
19
+
20
+ def project_id
21
+ match[:project_id]
22
+ end
23
+
24
+ def task_id
25
+ match[:task_id]
26
+ end
27
+
28
+ private
29
+
30
+ def match
31
+ @match ||= PATH_REGEX.match(self)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/abt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Abt
4
- VERSION = '0.0.15'
4
+ VERSION = '0.0.20'
5
5
  end
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.15
4
+ version: 0.0.20
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-02-08 00:00:00.000000000 Z
11
+ date: 2021-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-inflector
@@ -75,7 +75,11 @@ extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
77
  - "./lib/abt.rb"
78
+ - "./lib/abt/ari.rb"
79
+ - "./lib/abt/ari_list.rb"
80
+ - "./lib/abt/base_command.rb"
78
81
  - "./lib/abt/cli.rb"
82
+ - "./lib/abt/cli/arguments_parser.rb"
79
83
  - "./lib/abt/cli/prompt.rb"
80
84
  - "./lib/abt/docs.rb"
81
85
  - "./lib/abt/docs/cli.rb"
@@ -88,9 +92,8 @@ files:
88
92
  - "./lib/abt/providers/asana/api.rb"
89
93
  - "./lib/abt/providers/asana/base_command.rb"
90
94
  - "./lib/abt/providers/asana/commands/add.rb"
91
- - "./lib/abt/providers/asana/commands/branch-name.rb"
95
+ - "./lib/abt/providers/asana/commands/branch_name.rb"
92
96
  - "./lib/abt/providers/asana/commands/clear.rb"
93
- - "./lib/abt/providers/asana/commands/clear_global.rb"
94
97
  - "./lib/abt/providers/asana/commands/current.rb"
95
98
  - "./lib/abt/providers/asana/commands/finalize.rb"
96
99
  - "./lib/abt/providers/asana/commands/harvest_time_entry_data.rb"
@@ -101,13 +104,13 @@ files:
101
104
  - "./lib/abt/providers/asana/commands/start.rb"
102
105
  - "./lib/abt/providers/asana/commands/tasks.rb"
103
106
  - "./lib/abt/providers/asana/configuration.rb"
107
+ - "./lib/abt/providers/asana/path.rb"
104
108
  - "./lib/abt/providers/devops.rb"
105
109
  - "./lib/abt/providers/devops/api.rb"
106
110
  - "./lib/abt/providers/devops/base_command.rb"
107
111
  - "./lib/abt/providers/devops/commands/boards.rb"
108
- - "./lib/abt/providers/devops/commands/branch-name.rb"
112
+ - "./lib/abt/providers/devops/commands/branch_name.rb"
109
113
  - "./lib/abt/providers/devops/commands/clear.rb"
110
- - "./lib/abt/providers/devops/commands/clear_global.rb"
111
114
  - "./lib/abt/providers/devops/commands/current.rb"
112
115
  - "./lib/abt/providers/devops/commands/harvest_time_entry_data.rb"
113
116
  - "./lib/abt/providers/devops/commands/init.rb"
@@ -115,13 +118,13 @@ files:
115
118
  - "./lib/abt/providers/devops/commands/share.rb"
116
119
  - "./lib/abt/providers/devops/commands/work-items.rb"
117
120
  - "./lib/abt/providers/devops/configuration.rb"
121
+ - "./lib/abt/providers/devops/path.rb"
118
122
  - "./lib/abt/providers/git.rb"
119
123
  - "./lib/abt/providers/git/commands/branch.rb"
120
124
  - "./lib/abt/providers/harvest.rb"
121
125
  - "./lib/abt/providers/harvest/api.rb"
122
126
  - "./lib/abt/providers/harvest/base_command.rb"
123
127
  - "./lib/abt/providers/harvest/commands/clear.rb"
124
- - "./lib/abt/providers/harvest/commands/clear_global.rb"
125
128
  - "./lib/abt/providers/harvest/commands/current.rb"
126
129
  - "./lib/abt/providers/harvest/commands/init.rb"
127
130
  - "./lib/abt/providers/harvest/commands/pick.rb"
@@ -132,6 +135,7 @@ files:
132
135
  - "./lib/abt/providers/harvest/commands/tasks.rb"
133
136
  - "./lib/abt/providers/harvest/commands/track.rb"
134
137
  - "./lib/abt/providers/harvest/configuration.rb"
138
+ - "./lib/abt/providers/harvest/path.rb"
135
139
  - "./lib/abt/version.rb"
136
140
  - bin/abt
137
141
  homepage: https://github.com/abtion/abt
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Abt
4
- module Providers
5
- module Asana
6
- module Commands
7
- class ClearGlobal < BaseCommand
8
- def self.command
9
- 'clear-global asana'
10
- end
11
-
12
- def self.description
13
- 'Clear all global configuration'
14
- end
15
-
16
- def call
17
- cli.warn 'Clearing Asana project configuration'
18
- config.clear_global
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Abt
4
- module Providers
5
- module Devops
6
- module Commands
7
- class ClearGlobal < BaseCommand
8
- def self.command
9
- 'clear-global devops'
10
- end
11
-
12
- def self.description
13
- 'Clear all global configuration'
14
- end
15
-
16
- def call
17
- cli.warn 'Clearing global DevOps configuration'
18
- config.clear_global
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Abt
4
- module Providers
5
- module Harvest
6
- module Commands
7
- class ClearGlobal < BaseCommand
8
- def self.command
9
- 'clear-global harvest'
10
- end
11
-
12
- def self.description
13
- 'Clear all global configuration'
14
- end
15
-
16
- def call
17
- cli.warn 'Clearing Harvest project configuration'
18
- config.clear_global
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end