abt-cli 0.0.16 → 0.0.21

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/abt/ari.rb +20 -0
  3. data/lib/abt/ari_list.rb +13 -0
  4. data/lib/abt/base_command.rb +63 -0
  5. data/lib/abt/cli.rb +59 -47
  6. data/lib/abt/cli/arguments_parser.rb +9 -24
  7. data/lib/abt/cli/global_commands/commands.rb +23 -0
  8. data/lib/abt/cli/global_commands/examples.rb +23 -0
  9. data/lib/abt/cli/global_commands/help.rb +23 -0
  10. data/lib/abt/cli/global_commands/readme.rb +23 -0
  11. data/lib/abt/cli/global_commands/share.rb +36 -0
  12. data/lib/abt/cli/global_commands/version.rb +23 -0
  13. data/lib/abt/cli/prompt.rb +5 -4
  14. data/lib/abt/docs.rb +32 -15
  15. data/lib/abt/docs/cli.rb +5 -5
  16. data/lib/abt/docs/markdown.rb +8 -7
  17. data/lib/abt/git_config.rb +20 -36
  18. data/lib/abt/providers/asana/base_command.rb +15 -35
  19. data/lib/abt/providers/asana/commands/add.rb +9 -7
  20. data/lib/abt/providers/asana/commands/branch_name.rb +9 -4
  21. data/lib/abt/providers/asana/commands/clear.rb +2 -0
  22. data/lib/abt/providers/asana/commands/current.rb +19 -34
  23. data/lib/abt/providers/asana/commands/finalize.rb +5 -9
  24. data/lib/abt/providers/asana/commands/harvest_time_entry_data.rb +9 -4
  25. data/lib/abt/providers/asana/commands/init.rb +6 -6
  26. data/lib/abt/providers/asana/commands/pick.rb +16 -11
  27. data/lib/abt/providers/asana/commands/projects.rb +1 -1
  28. data/lib/abt/providers/asana/commands/share.rb +5 -7
  29. data/lib/abt/providers/asana/commands/start.rb +14 -12
  30. data/lib/abt/providers/asana/commands/tasks.rb +4 -3
  31. data/lib/abt/providers/asana/configuration.rb +20 -26
  32. data/lib/abt/providers/asana/path.rb +36 -0
  33. data/lib/abt/providers/devops/api.rb +12 -0
  34. data/lib/abt/providers/devops/base_command.rb +15 -40
  35. data/lib/abt/providers/devops/commands/boards.rb +2 -2
  36. data/lib/abt/providers/devops/commands/branch_name.rb +7 -3
  37. data/lib/abt/providers/devops/commands/clear.rb +2 -0
  38. data/lib/abt/providers/devops/commands/current.rb +14 -38
  39. data/lib/abt/providers/devops/commands/harvest_time_entry_data.rb +9 -1
  40. data/lib/abt/providers/devops/commands/init.rb +15 -15
  41. data/lib/abt/providers/devops/commands/pick.rb +5 -12
  42. data/lib/abt/providers/devops/commands/share.rb +6 -5
  43. data/lib/abt/providers/devops/commands/work-items.rb +1 -1
  44. data/lib/abt/providers/devops/configuration.rb +17 -46
  45. data/lib/abt/providers/devops/path.rb +50 -0
  46. data/lib/abt/providers/git/commands/branch.rb +22 -16
  47. data/lib/abt/providers/harvest/base_command.rb +16 -34
  48. data/lib/abt/providers/harvest/commands/clear.rb +2 -0
  49. data/lib/abt/providers/harvest/commands/current.rb +24 -31
  50. data/lib/abt/providers/harvest/commands/init.rb +5 -6
  51. data/lib/abt/providers/harvest/commands/pick.rb +3 -4
  52. data/lib/abt/providers/harvest/commands/projects.rb +1 -1
  53. data/lib/abt/providers/harvest/commands/share.rb +5 -7
  54. data/lib/abt/providers/harvest/commands/start.rb +1 -1
  55. data/lib/abt/providers/harvest/commands/stop.rb +7 -7
  56. data/lib/abt/providers/harvest/commands/tasks.rb +4 -1
  57. data/lib/abt/providers/harvest/commands/track.rb +26 -19
  58. data/lib/abt/providers/harvest/configuration.rb +20 -29
  59. data/lib/abt/providers/harvest/path.rb +36 -0
  60. data/lib/abt/version.rb +1 -1
  61. metadata +14 -3
  62. data/lib/abt/cli/base_command.rb +0 -61
@@ -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
@@ -10,7 +10,7 @@ module Abt
10
10
  end
11
11
 
12
12
  def self.description
13
- 'Start tracker for current or specified task. Add a relevant scheme argument to link the time entry, e.g. `abt track harvest asana`'
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
16
  def self.flags
@@ -29,7 +29,7 @@ module Abt
29
29
 
30
30
  maybe_override_current_task
31
31
  rescue Abt::HttpError::HttpError => _e
32
- cli.abort 'Invalid task'
32
+ abort 'Invalid task'
33
33
  end
34
34
 
35
35
  private
@@ -60,14 +60,14 @@ module Abt
60
60
  }
61
61
 
62
62
  if external_link_data
63
- cli.warn <<~TXT
63
+ warn <<~TXT
64
64
  Linking to:
65
65
  #{external_link_data[:notes]}
66
66
  #{external_link_data[:external_reference][:permalink]}
67
67
  TXT
68
68
  body.merge! external_link_data
69
69
  else
70
- cli.warn 'No external link provided'
70
+ warn 'No external link provided'
71
71
  end
72
72
 
73
73
  body[:notes] = flags[:comment] if flags.key?(:comment)
@@ -77,31 +77,38 @@ module Abt
77
77
 
78
78
  def external_link_data
79
79
  @external_link_data ||= begin
80
- input = StringIO.new(cli.scheme_arguments.to_s)
81
- output = StringIO.new
82
- Abt::Cli.new(argv: ['harvest-time-entry-data'], output: output, input: input).perform
80
+ lines = call_harvest_time_entry_data_for_other_aris
83
81
 
84
- lines = output.string.strip.lines
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
85
88
 
86
- return if lines.empty?
87
-
88
- # TODO: Make user choose which reference to use by printing the urls
89
- if lines.length > 1
90
- cli.abort('Got reference data from multiple scheme providers, only one is supported at a time')
89
+ Oj.load(lines.first, symbol_keys: true)
91
90
  end
92
-
93
- Oj.load(lines.first, symbol_keys: true)
94
91
  end
95
92
  end
96
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
+
97
105
  def maybe_override_current_task
98
106
  return unless flags[:set]
99
- return if same_args_as_config?
107
+ return if path == config.path
100
108
  return unless config.local_available?
101
109
 
102
- input = StringIO.new("harvest:#{project_id}/#{task_id}")
103
- output = StringIO.new
104
- Abt::Cli.new(argv: ['current'], output: output, input: input).perform
110
+ config.path = path
111
+ warn 'Current task updated'
105
112
  end
106
113
  end
107
114
  end
@@ -8,32 +8,18 @@ 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
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(verbose: false)
31
- git['projectId'] = value
32
- end
33
-
34
- def task_id=(value)
35
- value = value.to_s unless value.nil?
36
- git['taskId'] = value
21
+ def path=(new_path)
22
+ git['path'] = new_path
37
23
  end
38
24
 
39
25
  def clear_local(verbose: true)
@@ -41,13 +27,13 @@ module Abt
41
27
  end
42
28
 
43
29
  def clear_global(verbose: true)
44
- git.global.clear(output: verbose ? cli.err_output : nil)
30
+ git_global.clear(output: verbose ? cli.err_output : nil)
45
31
  end
46
32
 
47
33
  def access_token
48
- return git.global['accessToken'] unless git.global['accessToken'].nil?
34
+ return git_global['accessToken'] unless git_global['accessToken'].nil?
49
35
 
50
- git.global['accessToken'] = cli.prompt.text([
36
+ git_global['accessToken'] = cli.prompt.text([
51
37
  'Please provide your personal access token for Harvest.',
52
38
  'If you don\'t have one, create one here: https://id.getharvest.com/developers',
53
39
  '',
@@ -56,9 +42,9 @@ module Abt
56
42
  end
57
43
 
58
44
  def account_id
59
- return git.global['accountId'] unless git.global['accountId'].nil?
45
+ return git_global['accountId'] unless git_global['accountId'].nil?
60
46
 
61
- git.global['accountId'] = cli.prompt.text([
47
+ git_global['accountId'] = cli.prompt.text([
62
48
  'Please provide harvest account id.',
63
49
  'This information is shown next to your generated access token',
64
50
  '',
@@ -67,18 +53,23 @@ module Abt
67
53
  end
68
54
 
69
55
  def user_id
70
- return git.global['userId'] unless git.global['userId'].nil?
56
+ return git_global['userId'] unless git_global['userId'].nil?
71
57
 
72
- git.global['userId'] = api.get('users/me')['id'].to_s
58
+ git_global['userId'] = api.get('users/me')['id'].to_s
73
59
  end
74
60
 
75
61
  private
76
62
 
77
- 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
78
70
 
79
71
  def api
80
- @api ||=
81
- 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)
82
73
  end
83
74
  end
84
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.16'
4
+ VERSION = '0.0.21'
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.16
4
+ version: 0.0.21
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-11 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-inflector
@@ -75,9 +75,17 @@ 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"
79
82
  - "./lib/abt/cli/arguments_parser.rb"
80
- - "./lib/abt/cli/base_command.rb"
83
+ - "./lib/abt/cli/global_commands/commands.rb"
84
+ - "./lib/abt/cli/global_commands/examples.rb"
85
+ - "./lib/abt/cli/global_commands/help.rb"
86
+ - "./lib/abt/cli/global_commands/readme.rb"
87
+ - "./lib/abt/cli/global_commands/share.rb"
88
+ - "./lib/abt/cli/global_commands/version.rb"
81
89
  - "./lib/abt/cli/prompt.rb"
82
90
  - "./lib/abt/docs.rb"
83
91
  - "./lib/abt/docs/cli.rb"
@@ -102,6 +110,7 @@ files:
102
110
  - "./lib/abt/providers/asana/commands/start.rb"
103
111
  - "./lib/abt/providers/asana/commands/tasks.rb"
104
112
  - "./lib/abt/providers/asana/configuration.rb"
113
+ - "./lib/abt/providers/asana/path.rb"
105
114
  - "./lib/abt/providers/devops.rb"
106
115
  - "./lib/abt/providers/devops/api.rb"
107
116
  - "./lib/abt/providers/devops/base_command.rb"
@@ -115,6 +124,7 @@ files:
115
124
  - "./lib/abt/providers/devops/commands/share.rb"
116
125
  - "./lib/abt/providers/devops/commands/work-items.rb"
117
126
  - "./lib/abt/providers/devops/configuration.rb"
127
+ - "./lib/abt/providers/devops/path.rb"
118
128
  - "./lib/abt/providers/git.rb"
119
129
  - "./lib/abt/providers/git/commands/branch.rb"
120
130
  - "./lib/abt/providers/harvest.rb"
@@ -131,6 +141,7 @@ files:
131
141
  - "./lib/abt/providers/harvest/commands/tasks.rb"
132
142
  - "./lib/abt/providers/harvest/commands/track.rb"
133
143
  - "./lib/abt/providers/harvest/configuration.rb"
144
+ - "./lib/abt/providers/harvest/path.rb"
134
145
  - "./lib/abt/version.rb"
135
146
  - bin/abt
136
147
  homepage: https://github.com/abtion/abt
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Abt
4
- class Cli
5
- class BaseCommand
6
- def self.usage
7
- raise NotImplementedError, 'Command classes must implement .command'
8
- end
9
-
10
- def self.description
11
- raise NotImplementedError, 'Command classes must implement .description'
12
- end
13
-
14
- def self.flags
15
- []
16
- end
17
-
18
- attr_reader :path, :flags, :cli
19
-
20
- def initialize(path:, flags:, cli:)
21
- @cli = cli
22
- @path = path
23
- @flags = parse_flags(flags)
24
- end
25
-
26
- def perform
27
- raise NotImplementedError, 'Command classes must implement #perform'
28
- end
29
-
30
- private
31
-
32
- def parse_flags(flags)
33
- result = {}
34
-
35
- flag_parser.parse!(flags.dup, into: result)
36
-
37
- cli.exit_with_message(flag_parser.help) if result[:help]
38
-
39
- result
40
- rescue OptionParser::InvalidOption => e
41
- cli.abort e.message
42
- end
43
-
44
- def flag_parser
45
- @flag_parser ||= OptionParser.new do |opts|
46
- opts.banner = <<~TXT
47
- #{self.class.description}
48
-
49
- Usage: #{self.class.usage}
50
- TXT
51
-
52
- opts.on('-h', '--help')
53
-
54
- self.class.flags.each do |(*flag)|
55
- opts.on(*flag)
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end