abt-cli 0.0.15 → 0.0.16
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 +1 -1
- data/lib/abt.rb +4 -3
- data/lib/abt/cli.rb +70 -48
- data/lib/abt/cli/arguments_parser.rb +70 -0
- data/lib/abt/cli/base_command.rb +61 -0
- data/lib/abt/cli/prompt.rb +2 -2
- data/lib/abt/docs.rb +24 -18
- data/lib/abt/docs/cli.rb +42 -11
- data/lib/abt/docs/markdown.rb +36 -10
- data/lib/abt/git_config.rb +11 -0
- data/lib/abt/providers/asana/base_command.rb +13 -13
- data/lib/abt/providers/asana/commands/add.rb +3 -3
- data/lib/abt/providers/asana/commands/{branch-name.rb → branch_name.rb} +3 -3
- data/lib/abt/providers/asana/commands/clear.rb +17 -6
- data/lib/abt/providers/asana/commands/current.rb +3 -3
- data/lib/abt/providers/asana/commands/finalize.rb +3 -3
- data/lib/abt/providers/asana/commands/harvest_time_entry_data.rb +3 -3
- data/lib/abt/providers/asana/commands/init.rb +3 -3
- data/lib/abt/providers/asana/commands/pick.rb +13 -5
- data/lib/abt/providers/asana/commands/projects.rb +3 -3
- data/lib/abt/providers/asana/commands/share.rb +5 -5
- data/lib/abt/providers/asana/commands/start.rb +13 -7
- data/lib/abt/providers/asana/commands/tasks.rb +3 -3
- data/lib/abt/providers/asana/configuration.rb +5 -13
- data/lib/abt/providers/devops/base_command.rb +14 -15
- data/lib/abt/providers/devops/commands/boards.rb +6 -4
- data/lib/abt/providers/devops/commands/{branch-name.rb → branch_name.rb} +3 -3
- data/lib/abt/providers/devops/commands/clear.rb +17 -6
- data/lib/abt/providers/devops/commands/current.rb +3 -3
- data/lib/abt/providers/devops/commands/harvest_time_entry_data.rb +3 -3
- data/lib/abt/providers/devops/commands/init.rb +3 -3
- data/lib/abt/providers/devops/commands/pick.rb +12 -5
- data/lib/abt/providers/devops/commands/share.rb +4 -4
- data/lib/abt/providers/devops/commands/work-items.rb +3 -3
- data/lib/abt/providers/devops/configuration.rb +5 -13
- data/lib/abt/providers/git/commands/branch.rb +15 -21
- data/lib/abt/providers/harvest/base_command.rb +13 -13
- data/lib/abt/providers/harvest/commands/clear.rb +17 -6
- data/lib/abt/providers/harvest/commands/current.rb +3 -3
- data/lib/abt/providers/harvest/commands/init.rb +3 -3
- data/lib/abt/providers/harvest/commands/pick.rb +13 -5
- data/lib/abt/providers/harvest/commands/projects.rb +3 -3
- data/lib/abt/providers/harvest/commands/share.rb +5 -5
- data/lib/abt/providers/harvest/commands/start.rb +6 -42
- data/lib/abt/providers/harvest/commands/stop.rb +3 -3
- data/lib/abt/providers/harvest/commands/tasks.rb +3 -3
- data/lib/abt/providers/harvest/commands/track.rb +49 -11
- data/lib/abt/providers/harvest/configuration.rb +5 -11
- data/lib/abt/version.rb +1 -1
- metadata +6 -7
- data/lib/abt/providers/asana/commands/clear_global.rb +0 -24
- data/lib/abt/providers/devops/commands/clear_global.rb +0 -24
- data/lib/abt/providers/harvest/commands/clear_global.rb +0 -24
@@ -5,21 +5,21 @@ module Abt
|
|
5
5
|
module Asana
|
6
6
|
module Commands
|
7
7
|
class Share < BaseCommand
|
8
|
-
def self.
|
9
|
-
'share asana[:<project-gid>[/<task-gid>]]'
|
8
|
+
def self.usage
|
9
|
+
'abt share asana[:<project-gid>[/<task-gid>]]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'Print project/task config string'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def perform
|
17
17
|
require_project!
|
18
18
|
|
19
19
|
if task_gid.nil?
|
20
|
-
cli.
|
20
|
+
cli.print_scheme_argument('asana', project_gid)
|
21
21
|
else
|
22
|
-
cli.
|
22
|
+
cli.print_scheme_argument('asana', "#{project_gid}/#{task_gid}")
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -5,15 +5,21 @@ module Abt
|
|
5
5
|
module Asana
|
6
6
|
module Commands
|
7
7
|
class Start < BaseCommand
|
8
|
-
def self.
|
9
|
-
'start asana[:<project-gid>/<task-gid>]'
|
8
|
+
def self.usage
|
9
|
+
'abt start asana[:<project-gid>/<task-gid>]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
|
-
'
|
13
|
+
'Move current or specified task to WIP section (column) and assign it to you'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def self.flags
|
17
|
+
[
|
18
|
+
['-s', '--set', 'Set specified task as current']
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def perform
|
17
23
|
require_task!
|
18
24
|
|
19
25
|
maybe_override_current_task
|
@@ -25,12 +31,12 @@ module Abt
|
|
25
31
|
private
|
26
32
|
|
27
33
|
def maybe_override_current_task
|
28
|
-
return
|
34
|
+
return unless flags[:set]
|
35
|
+
return if path.nil?
|
29
36
|
return if same_args_as_config?
|
30
37
|
return unless config.local_available?
|
31
38
|
|
32
|
-
|
33
|
-
Current.new(arg_str: arg_str, cli: cli).call if should_override
|
39
|
+
Current.new(path: path, cli: cli).call
|
34
40
|
end
|
35
41
|
|
36
42
|
def update_assignee_if_needed
|
@@ -5,15 +5,15 @@ module Abt
|
|
5
5
|
module Asana
|
6
6
|
module Commands
|
7
7
|
class Tasks < BaseCommand
|
8
|
-
def self.
|
9
|
-
'tasks asana'
|
8
|
+
def self.usage
|
9
|
+
'abt tasks asana'
|
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
|
16
|
+
def perform
|
17
17
|
require_project!
|
18
18
|
|
19
19
|
tasks.each do |task|
|
@@ -49,7 +49,7 @@ module Abt
|
|
49
49
|
def project_gid=(value)
|
50
50
|
return if project_gid == value
|
51
51
|
|
52
|
-
clear_local
|
52
|
+
clear_local(verbose: false)
|
53
53
|
git['projectGid'] = value unless value.nil?
|
54
54
|
end
|
55
55
|
|
@@ -57,20 +57,12 @@ module Abt
|
|
57
57
|
git['taskGid'] = value
|
58
58
|
end
|
59
59
|
|
60
|
-
def clear_local
|
61
|
-
|
62
|
-
|
63
|
-
git['projectGid'] = nil
|
64
|
-
git['taskGid'] = nil
|
65
|
-
git['wipSectionGid'] = nil
|
66
|
-
git['finalizedSectionGid'] = nil
|
60
|
+
def clear_local(verbose: true)
|
61
|
+
git.clear(output: verbose ? cli.err_output : nil)
|
67
62
|
end
|
68
63
|
|
69
|
-
def clear_global
|
70
|
-
git.global.
|
71
|
-
cli.puts 'Deleting configuration: ' + key
|
72
|
-
git.global[key] = nil
|
73
|
-
end
|
64
|
+
def clear_global(verbose: true)
|
65
|
+
git.global.clear(output: verbose ? cli.err_output : nil)
|
74
66
|
end
|
75
67
|
|
76
68
|
def access_token
|
@@ -3,19 +3,18 @@
|
|
3
3
|
module Abt
|
4
4
|
module Providers
|
5
5
|
module Devops
|
6
|
-
class BaseCommand
|
7
|
-
attr_reader :
|
6
|
+
class BaseCommand < Abt::Cli::BaseCommand
|
7
|
+
attr_reader :organization_name, :project_name, :board_id, :work_item_id, :config
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
|
9
|
+
def initialize(path:, cli:, **)
|
10
|
+
super
|
11
11
|
|
12
12
|
@config = Configuration.new(cli: cli)
|
13
|
-
@cli = cli
|
14
13
|
|
15
|
-
if
|
16
|
-
|
14
|
+
if path.nil?
|
15
|
+
use_current_path
|
17
16
|
else
|
18
|
-
|
17
|
+
use_path(path)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
@@ -55,28 +54,28 @@ module Abt
|
|
55
54
|
end
|
56
55
|
|
57
56
|
def print_board(organization_name, project_name, board)
|
58
|
-
|
57
|
+
path = "#{organization_name}/#{project_name}/#{board['id']}"
|
59
58
|
|
60
|
-
cli.
|
59
|
+
cli.print_scheme_argument('devops', path, board['name'])
|
61
60
|
# cli.warn board['url'] if board.key?('url') && cli.output.isatty # TODO: Web URL
|
62
61
|
end
|
63
62
|
|
64
63
|
def print_work_item(organization, project, board, work_item)
|
65
|
-
|
64
|
+
path = "#{organization}/#{project}/#{board['id']}/#{work_item['id']}"
|
66
65
|
|
67
|
-
cli.
|
66
|
+
cli.print_scheme_argument('devops', path, work_item['name'])
|
68
67
|
cli.warn work_item['url'] if work_item.key?('url') && cli.output.isatty
|
69
68
|
end
|
70
69
|
|
71
|
-
def
|
70
|
+
def use_current_path
|
72
71
|
@organization_name = config.organization_name
|
73
72
|
@project_name = config.project_name
|
74
73
|
@board_id = config.board_id
|
75
74
|
@work_item_id = config.work_item_id
|
76
75
|
end
|
77
76
|
|
78
|
-
def
|
79
|
-
args =
|
77
|
+
def use_path(path)
|
78
|
+
args = path.to_s.split('/')
|
80
79
|
|
81
80
|
if args.length < 3
|
82
81
|
cli.abort 'Argument format is <organization>/<project>/<board-id>[/<work-item-id>]'
|
@@ -5,16 +5,18 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class Boards < BaseCommand
|
8
|
-
def self.
|
9
|
-
'boards devops'
|
8
|
+
def self.usage
|
9
|
+
'abt boards devops'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'List all boards - useful for piping into grep etc'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def perform
|
17
|
+
if organization_name.nil?
|
18
|
+
cli.abort 'No organization selected. Did you initialize DevOps?'
|
19
|
+
end
|
18
20
|
cli.abort 'No project selected. Did you initialize DevOps?' if project_name.nil?
|
19
21
|
|
20
22
|
boards.map do |board|
|
@@ -5,15 +5,15 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class BranchName < BaseCommand
|
8
|
-
def self.
|
9
|
-
'branch-name devops[:<organization-name>/<project-name>/<board-id>/<work-item-id>]'
|
8
|
+
def self.usage
|
9
|
+
'abt branch-name devops[:<organization-name>/<project-name>/<board-id>/<work-item-id>]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'Suggest a git branch name for the current/specified work-item.'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def perform
|
17
17
|
require_work_item!
|
18
18
|
|
19
19
|
cli.puts name
|
@@ -5,17 +5,28 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class Clear < BaseCommand
|
8
|
-
def self.
|
9
|
-
'clear devops'
|
8
|
+
def self.usage
|
9
|
+
'abt clear devops'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
|
-
'Clear DevOps
|
13
|
+
'Clear DevOps configuration'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
16
|
+
def self.flags
|
17
|
+
[
|
18
|
+
['-g', '--global', 'Clear global instead of local DevOp configuration (credentials etc.)'],
|
19
|
+
['-a', '--all', 'Clear all DevOp configuration']
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def perform
|
24
|
+
if flags[:global] && flags[:all]
|
25
|
+
abort('Flags --global and --all cannot be used at the same time')
|
26
|
+
end
|
27
|
+
|
28
|
+
config.clear_local unless flags[:global]
|
29
|
+
config.clear_global if flags[:global] || flags[:all]
|
19
30
|
end
|
20
31
|
end
|
21
32
|
end
|
@@ -5,15 +5,15 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class Current < BaseCommand
|
8
|
-
def self.
|
9
|
-
'current devops[:<organization-name>/<project-name>/<board-id>[/<work-item-id>]]'
|
8
|
+
def self.usage
|
9
|
+
'abt current devops[:<organization-name>/<project-name>/<board-id>[/<work-item-id>]]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'Get or set DevOps configuration for current git repository'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def perform
|
17
17
|
require_board!
|
18
18
|
|
19
19
|
if same_args_as_config? || !config.local_available?
|
@@ -5,15 +5,15 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class HarvestTimeEntryData < BaseCommand
|
8
|
-
def self.
|
9
|
-
'harvest-time-entry-data devops[:<organization-name>/<project-name>/<board-id>/<work-item-id>]'
|
8
|
+
def self.usage
|
9
|
+
'abt harvest-time-entry-data devops[:<organization-name>/<project-name>/<board-id>/<work-item-id>]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'Print Harvest time entry data for DevOps work item as json. Used by harvest start script.'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def perform
|
17
17
|
require_work_item!
|
18
18
|
|
19
19
|
body = {
|
@@ -8,15 +8,15 @@ module Abt
|
|
8
8
|
AZURE_DEV_URL_REGEX = %r{^https://dev\.azure\.com/(?<organization>[^/]+)/(?<project>[^/]+)}.freeze
|
9
9
|
VS_URL_REGEX = %r{^https://(?<organization>[^.]+)\.visualstudio\.com/(?<project>[^/]+)}.freeze
|
10
10
|
|
11
|
-
def self.
|
12
|
-
'init devops'
|
11
|
+
def self.usage
|
12
|
+
'abt init devops'
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.description
|
16
16
|
'Pick DevOps board for current git repository'
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def perform
|
20
20
|
cli.abort 'Must be run inside a git repository' unless config.local_available?
|
21
21
|
|
22
22
|
@organization_name = config.organization_name = organization_name_from_url
|
@@ -5,25 +5,32 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class Pick < BaseCommand
|
8
|
-
def self.
|
9
|
-
'pick devops[:<organization-name>/<project-name>/<board-id>]'
|
8
|
+
def self.usage
|
9
|
+
'abt pick devops[:<organization-name>/<project-name>/<board-id>]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'Pick work item for current git repository'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def self.flags
|
17
|
+
[
|
18
|
+
['-d', '--dry-run', 'Keep existing configuration']
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def perform
|
17
23
|
cli.abort 'Must be run inside a git repository' unless config.local_available?
|
18
24
|
require_board!
|
19
25
|
|
20
26
|
cli.warn "#{project_name} - #{board['name']}"
|
21
27
|
|
22
28
|
work_item = select_work_item
|
29
|
+
print_work_item(organization_name, project_name, board, work_item)
|
23
30
|
|
24
|
-
|
31
|
+
return if flags[:"dry-run"]
|
25
32
|
|
26
|
-
|
33
|
+
update_config!(work_item)
|
27
34
|
end
|
28
35
|
|
29
36
|
private
|
@@ -5,19 +5,19 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class Share < BaseCommand
|
8
|
-
def self.
|
9
|
-
'share devops[:<organization-name>/<project-name>/<board-id>[/<work-item-id>]]'
|
8
|
+
def self.usage
|
9
|
+
'abt share devops[:<organization-name>/<project-name>/<board-id>[/<work-item-id>]]'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'Print DevOps config string'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def perform
|
17
17
|
require_work_item!
|
18
18
|
|
19
19
|
args = [organization_name, project_name, board_id, work_item_id].compact
|
20
|
-
cli.
|
20
|
+
cli.print_scheme_argument('devops', args.join('/'))
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -5,15 +5,15 @@ module Abt
|
|
5
5
|
module Devops
|
6
6
|
module Commands
|
7
7
|
class WorkItems < BaseCommand
|
8
|
-
def self.
|
9
|
-
'work-items devops'
|
8
|
+
def self.usage
|
9
|
+
'abt work-items devops'
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.description
|
13
13
|
'List all work items on board - useful for piping into grep etc.'
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def perform
|
17
17
|
require_board!
|
18
18
|
|
19
19
|
work_items.each do |work_item|
|
@@ -34,7 +34,7 @@ module Abt
|
|
34
34
|
def organization_name=(value)
|
35
35
|
return if organization_name == value
|
36
36
|
|
37
|
-
clear_local
|
37
|
+
clear_local(verbose: false)
|
38
38
|
git['organizationName'] = value unless value.nil?
|
39
39
|
end
|
40
40
|
|
@@ -57,20 +57,12 @@ module Abt
|
|
57
57
|
git['workItemId'] = value
|
58
58
|
end
|
59
59
|
|
60
|
-
def clear_local
|
61
|
-
|
62
|
-
|
63
|
-
git['organizationName'] = nil
|
64
|
-
git['projectName'] = nil
|
65
|
-
git['boardId'] = nil
|
66
|
-
git['workItemId'] = nil
|
60
|
+
def clear_local(verbose: true)
|
61
|
+
git.clear(output: verbose ? cli.err_output : nil)
|
67
62
|
end
|
68
63
|
|
69
|
-
def clear_global
|
70
|
-
git.global.
|
71
|
-
cli.puts 'Deleting configuration: ' + key
|
72
|
-
git.global[key] = nil
|
73
|
-
end
|
64
|
+
def clear_global(verbose: true)
|
65
|
+
git.global.clear(output: verbose ? cli.err_output : nil)
|
74
66
|
end
|
75
67
|
|
76
68
|
def username_for_organization(organization_name)
|
@@ -4,22 +4,16 @@ module Abt
|
|
4
4
|
module Providers
|
5
5
|
module Git
|
6
6
|
module Commands
|
7
|
-
class Branch
|
8
|
-
|
9
|
-
|
10
|
-
def self.command
|
11
|
-
'branch git <provider>'
|
7
|
+
class Branch < Abt::Cli::BaseCommand
|
8
|
+
def self.usage
|
9
|
+
'abt branch git <scheme>[:<path>]'
|
12
10
|
end
|
13
11
|
|
14
12
|
def self.description
|
15
|
-
'Switch branch. Uses a compatible
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize(cli:, **)
|
19
|
-
@cli = cli
|
13
|
+
'Switch branch. Uses a compatible scheme to generate the branch-name: E.g. `abt branch git asana`'
|
20
14
|
end
|
21
15
|
|
22
|
-
def
|
16
|
+
def perform
|
23
17
|
create_and_switch unless switch
|
24
18
|
cli.warn "Switched to #{branch_name}"
|
25
19
|
end
|
@@ -45,29 +39,29 @@ module Abt
|
|
45
39
|
|
46
40
|
def branch_name # rubocop:disable Metrics/MethodLength
|
47
41
|
@branch_name ||= begin
|
48
|
-
if
|
42
|
+
if branch_names_from_scheme_arguments.empty?
|
49
43
|
cli.abort [
|
50
|
-
'None of the specified
|
51
|
-
'Did you add compatible
|
44
|
+
'None of the specified scheme arguments responded to `branch-name`.',
|
45
|
+
'Did you add compatible scheme? e.g.:',
|
52
46
|
' abt branch git asana',
|
53
47
|
' abt branch git devops'
|
54
48
|
].join("\n")
|
55
49
|
end
|
56
50
|
|
57
|
-
if
|
51
|
+
if branch_names_from_scheme_arguments.length > 1
|
58
52
|
cli.abort [
|
59
|
-
'Got branch names from multiple
|
60
|
-
'Branch names
|
61
|
-
*
|
53
|
+
'Got branch names from multiple scheme arguments, only one is supported',
|
54
|
+
'Branch names were:',
|
55
|
+
*branch_names_from_scheme_arguments.map { |name| " #{name}" }
|
62
56
|
].join("\n")
|
63
57
|
end
|
64
58
|
|
65
|
-
|
59
|
+
branch_names_from_scheme_arguments.first
|
66
60
|
end
|
67
61
|
end
|
68
62
|
|
69
|
-
def
|
70
|
-
input = StringIO.new(cli.
|
63
|
+
def branch_names_from_scheme_arguments
|
64
|
+
input = StringIO.new(cli.scheme_arguments.to_s)
|
71
65
|
output = StringIO.new
|
72
66
|
Abt::Cli.new(argv: ['branch-name'], output: output, input: input).perform
|
73
67
|
|