abt-cli 0.0.24 → 0.0.29
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 +1 -0
- data/lib/abt/cli.rb +32 -9
- data/lib/abt/cli/prompt.rb +12 -9
- data/lib/abt/directory_config.rb +43 -0
- data/lib/abt/docs.rb +10 -6
- data/lib/abt/providers/asana.rb +1 -0
- data/lib/abt/providers/asana/base_command.rb +33 -3
- data/lib/abt/providers/asana/commands/add.rb +0 -4
- data/lib/abt/providers/asana/commands/branch_name.rb +0 -13
- data/lib/abt/providers/asana/commands/current.rb +0 -18
- data/lib/abt/providers/asana/commands/finalize.rb +2 -4
- data/lib/abt/providers/asana/commands/pick.rb +11 -41
- data/lib/abt/providers/asana/commands/tasks.rb +2 -7
- data/lib/abt/providers/asana/commands/write_config.rb +73 -0
- data/lib/abt/providers/asana/configuration.rb +11 -3
- data/lib/abt/providers/asana/path.rb +2 -2
- data/lib/abt/providers/asana/services/project_picker.rb +54 -0
- data/lib/abt/providers/asana/services/task_picker.rb +83 -0
- data/lib/abt/providers/devops.rb +1 -0
- data/lib/abt/providers/devops/api.rb +10 -0
- data/lib/abt/providers/devops/base_command.rb +34 -14
- data/lib/abt/providers/devops/commands/boards.rb +1 -2
- data/lib/abt/providers/devops/commands/branch_name.rb +10 -16
- data/lib/abt/providers/devops/commands/current.rb +0 -19
- data/lib/abt/providers/devops/commands/harvest_time_entry_data.rb +10 -16
- data/lib/abt/providers/devops/commands/pick.rb +11 -47
- data/lib/abt/providers/devops/commands/work_items.rb +3 -6
- data/lib/abt/providers/devops/commands/write_config.rb +47 -0
- data/lib/abt/providers/devops/configuration.rb +1 -1
- data/lib/abt/providers/devops/path.rb +3 -3
- data/lib/abt/providers/devops/services/board_picker.rb +58 -0
- data/lib/abt/providers/devops/services/project_picker.rb +73 -0
- data/lib/abt/providers/devops/services/work_item_picker.rb +98 -0
- data/lib/abt/providers/git/commands/branch.rb +1 -1
- data/lib/abt/providers/harvest.rb +1 -0
- data/lib/abt/providers/harvest/base_command.rb +45 -3
- data/lib/abt/providers/harvest/commands/current.rb +0 -28
- data/lib/abt/providers/harvest/commands/pick.rb +12 -27
- data/lib/abt/providers/harvest/commands/projects.rb +2 -9
- data/lib/abt/providers/harvest/commands/tasks.rb +2 -19
- data/lib/abt/providers/harvest/commands/write_config.rb +41 -0
- data/lib/abt/providers/harvest/configuration.rb +1 -1
- data/lib/abt/providers/harvest/path.rb +1 -1
- data/lib/abt/providers/harvest/services/project_picker.rb +53 -0
- data/lib/abt/providers/harvest/services/task_picker.rb +50 -0
- data/lib/abt/version.rb +1 -1
- metadata +13 -5
- data/lib/abt/providers/asana/commands/init.rb +0 -42
- data/lib/abt/providers/devops/commands/init.rb +0 -79
- data/lib/abt/providers/harvest/commands/init.rb +0 -53
@@ -15,46 +15,31 @@ module Abt
|
|
15
15
|
|
16
16
|
def self.flags
|
17
17
|
[
|
18
|
-
["-d", "--dry-run", "Keep existing configuration"]
|
18
|
+
["-d", "--dry-run", "Keep existing configuration"],
|
19
|
+
["-c", "--clean", "Don't reuse project configuration"]
|
19
20
|
]
|
20
21
|
end
|
21
22
|
|
22
23
|
def perform
|
23
|
-
|
24
|
-
require_project!
|
25
|
-
|
26
|
-
warn(project["name"])
|
27
|
-
task = pick_task
|
24
|
+
pick!
|
28
25
|
|
29
26
|
print_task(project, task)
|
30
27
|
|
31
28
|
return if flags[:"dry-run"]
|
32
29
|
|
33
|
-
config.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def project
|
39
|
-
project_assignment["project"]
|
40
|
-
end
|
41
|
-
|
42
|
-
def pick_task
|
43
|
-
cli.prompt.choice("Select a task", tasks)
|
44
|
-
end
|
30
|
+
unless config.local_available?
|
31
|
+
warn("No local configuration to update - will function as dry run")
|
32
|
+
return
|
33
|
+
end
|
45
34
|
|
46
|
-
|
47
|
-
@tasks ||= project_assignment["task_assignments"].map { |ta| ta["task"] }
|
35
|
+
config.path = path
|
48
36
|
end
|
49
37
|
|
50
|
-
|
51
|
-
@project_assignment ||= begin
|
52
|
-
project_assignments.find { |pa| pa["project"]["id"].to_s == project_id }
|
53
|
-
end
|
54
|
-
end
|
38
|
+
private
|
55
39
|
|
56
|
-
def
|
57
|
-
|
40
|
+
def pick!
|
41
|
+
prompt_project! if project_id.nil? || flags[:clean]
|
42
|
+
prompt_task!
|
58
43
|
end
|
59
44
|
end
|
60
45
|
end
|
@@ -22,17 +22,10 @@ module Abt
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def projects
|
25
|
-
@projects ||=
|
26
|
-
|
27
|
-
project_assignments.map do |project_assignment|
|
28
|
-
project_assignment["project"].merge("client" => project_assignment["client"])
|
29
|
-
end
|
25
|
+
@projects ||= project_assignments.map do |project_assignment|
|
26
|
+
project_assignment["project"].merge("client" => project_assignment["client"])
|
30
27
|
end
|
31
28
|
end
|
32
|
-
|
33
|
-
def project_assignments
|
34
|
-
@project_assignments ||= api.get_paged("users/me/project_assignments")
|
35
|
-
end
|
36
29
|
end
|
37
30
|
end
|
38
31
|
end
|
@@ -14,7 +14,7 @@ module Abt
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def perform
|
17
|
-
|
17
|
+
prompt_project! unless project_id
|
18
18
|
|
19
19
|
tasks.each do |task|
|
20
20
|
print_task(project, task)
|
@@ -23,25 +23,8 @@ module Abt
|
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
-
def project
|
27
|
-
project_assignment["project"]
|
28
|
-
end
|
29
|
-
|
30
26
|
def tasks
|
31
|
-
@tasks ||=
|
32
|
-
warn("Fetching tasks...")
|
33
|
-
project_assignment["task_assignments"].map { |ta| ta["task"] }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def project_assignment
|
38
|
-
@project_assignment ||= begin
|
39
|
-
project_assignments.find { |pa| pa["project"]["id"].to_s == project_id }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def project_assignments
|
44
|
-
@project_assignments ||= api.get_paged("users/me/project_assignments")
|
27
|
+
@tasks ||= project_assignment["task_assignments"].map { |ta| ta["task"] }
|
45
28
|
end
|
46
29
|
end
|
47
30
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Commands
|
7
|
+
class WriteConfig < BaseCommand
|
8
|
+
def self.usage
|
9
|
+
"abt write-config harvest[:<project-id>[/<task-id>]]"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
"Write Harvest settings to .abt.yml"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.flags
|
17
|
+
[
|
18
|
+
["-c", "--clean", "Don't reuse configuration"]
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def perform
|
23
|
+
prompt_project! if project_id.nil? || flags[:clean]
|
24
|
+
prompt_task! if task_id.nil? || flags[:clean]
|
25
|
+
|
26
|
+
update_directory_config!
|
27
|
+
|
28
|
+
warn("Harvest configuration written to #{Abt::DirectoryConfig::FILE_NAME}")
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def update_directory_config!
|
34
|
+
cli.directory_config["harvest"] = { "path" => path.to_s }
|
35
|
+
cli.directory_config.save!
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Services
|
7
|
+
class ProjectPicker
|
8
|
+
class Result
|
9
|
+
attr_reader :project, :path
|
10
|
+
|
11
|
+
def initialize(project:, path:)
|
12
|
+
@project = project
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.call(**args)
|
18
|
+
new(**args).call
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :cli, :project_assignments
|
22
|
+
|
23
|
+
def initialize(cli:, project_assignments:)
|
24
|
+
@cli = cli
|
25
|
+
@project_assignments = project_assignments
|
26
|
+
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
project = cli.prompt.search("Select a project", searchable_projects)["project"]
|
30
|
+
|
31
|
+
path = Path.from_ids(project_id: project["id"])
|
32
|
+
|
33
|
+
Result.new(project: project, path: path)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def searchable_projects
|
39
|
+
@searchable_projects ||= project_assignments.map do |project_assignment|
|
40
|
+
client = project_assignment["client"]
|
41
|
+
project = project_assignment["project"]
|
42
|
+
|
43
|
+
project_assignment.merge(
|
44
|
+
"name" => "#{client['name']} > #{project['name']}",
|
45
|
+
"project" => project
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Abt
|
4
|
+
module Providers
|
5
|
+
module Harvest
|
6
|
+
module Services
|
7
|
+
class TaskPicker
|
8
|
+
class Result
|
9
|
+
attr_reader :task, :path
|
10
|
+
|
11
|
+
def initialize(task:, path:)
|
12
|
+
@task = task
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.call(**args)
|
18
|
+
new(**args).call
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :cli, :path, :project_assignment
|
22
|
+
|
23
|
+
def initialize(cli:, path:, project_assignment:)
|
24
|
+
@cli = cli
|
25
|
+
@path = path
|
26
|
+
@project_assignment = project_assignment
|
27
|
+
end
|
28
|
+
|
29
|
+
def call
|
30
|
+
task = cli.prompt.choice("Select a task from #{project['name']}", tasks)
|
31
|
+
|
32
|
+
path_with_task = Path.from_ids(project_id: path.project_id, task_id: task["id"])
|
33
|
+
|
34
|
+
Result.new(task: task, path: path_with_task)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def project
|
40
|
+
project_assignment["project"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def tasks
|
44
|
+
@tasks ||= project_assignment["task_assignments"].map { |ta| ta["task"] }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
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.29
|
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-03-
|
11
|
+
date: 2021-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-inflector
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- "./lib/abt/cli/global_commands/share.rb"
|
89
89
|
- "./lib/abt/cli/global_commands/version.rb"
|
90
90
|
- "./lib/abt/cli/prompt.rb"
|
91
|
+
- "./lib/abt/directory_config.rb"
|
91
92
|
- "./lib/abt/docs.rb"
|
92
93
|
- "./lib/abt/docs/cli.rb"
|
93
94
|
- "./lib/abt/docs/markdown.rb"
|
@@ -104,14 +105,16 @@ files:
|
|
104
105
|
- "./lib/abt/providers/asana/commands/current.rb"
|
105
106
|
- "./lib/abt/providers/asana/commands/finalize.rb"
|
106
107
|
- "./lib/abt/providers/asana/commands/harvest_time_entry_data.rb"
|
107
|
-
- "./lib/abt/providers/asana/commands/init.rb"
|
108
108
|
- "./lib/abt/providers/asana/commands/pick.rb"
|
109
109
|
- "./lib/abt/providers/asana/commands/projects.rb"
|
110
110
|
- "./lib/abt/providers/asana/commands/share.rb"
|
111
111
|
- "./lib/abt/providers/asana/commands/start.rb"
|
112
112
|
- "./lib/abt/providers/asana/commands/tasks.rb"
|
113
|
+
- "./lib/abt/providers/asana/commands/write_config.rb"
|
113
114
|
- "./lib/abt/providers/asana/configuration.rb"
|
114
115
|
- "./lib/abt/providers/asana/path.rb"
|
116
|
+
- "./lib/abt/providers/asana/services/project_picker.rb"
|
117
|
+
- "./lib/abt/providers/asana/services/task_picker.rb"
|
115
118
|
- "./lib/abt/providers/devops.rb"
|
116
119
|
- "./lib/abt/providers/devops/api.rb"
|
117
120
|
- "./lib/abt/providers/devops/base_command.rb"
|
@@ -120,12 +123,15 @@ files:
|
|
120
123
|
- "./lib/abt/providers/devops/commands/clear.rb"
|
121
124
|
- "./lib/abt/providers/devops/commands/current.rb"
|
122
125
|
- "./lib/abt/providers/devops/commands/harvest_time_entry_data.rb"
|
123
|
-
- "./lib/abt/providers/devops/commands/init.rb"
|
124
126
|
- "./lib/abt/providers/devops/commands/pick.rb"
|
125
127
|
- "./lib/abt/providers/devops/commands/share.rb"
|
126
128
|
- "./lib/abt/providers/devops/commands/work_items.rb"
|
129
|
+
- "./lib/abt/providers/devops/commands/write_config.rb"
|
127
130
|
- "./lib/abt/providers/devops/configuration.rb"
|
128
131
|
- "./lib/abt/providers/devops/path.rb"
|
132
|
+
- "./lib/abt/providers/devops/services/board_picker.rb"
|
133
|
+
- "./lib/abt/providers/devops/services/project_picker.rb"
|
134
|
+
- "./lib/abt/providers/devops/services/work_item_picker.rb"
|
129
135
|
- "./lib/abt/providers/git.rb"
|
130
136
|
- "./lib/abt/providers/git/commands/branch.rb"
|
131
137
|
- "./lib/abt/providers/harvest.rb"
|
@@ -133,7 +139,6 @@ files:
|
|
133
139
|
- "./lib/abt/providers/harvest/base_command.rb"
|
134
140
|
- "./lib/abt/providers/harvest/commands/clear.rb"
|
135
141
|
- "./lib/abt/providers/harvest/commands/current.rb"
|
136
|
-
- "./lib/abt/providers/harvest/commands/init.rb"
|
137
142
|
- "./lib/abt/providers/harvest/commands/pick.rb"
|
138
143
|
- "./lib/abt/providers/harvest/commands/projects.rb"
|
139
144
|
- "./lib/abt/providers/harvest/commands/share.rb"
|
@@ -141,8 +146,11 @@ files:
|
|
141
146
|
- "./lib/abt/providers/harvest/commands/stop.rb"
|
142
147
|
- "./lib/abt/providers/harvest/commands/tasks.rb"
|
143
148
|
- "./lib/abt/providers/harvest/commands/track.rb"
|
149
|
+
- "./lib/abt/providers/harvest/commands/write_config.rb"
|
144
150
|
- "./lib/abt/providers/harvest/configuration.rb"
|
145
151
|
- "./lib/abt/providers/harvest/path.rb"
|
152
|
+
- "./lib/abt/providers/harvest/services/project_picker.rb"
|
153
|
+
- "./lib/abt/providers/harvest/services/task_picker.rb"
|
146
154
|
- "./lib/abt/version.rb"
|
147
155
|
- bin/abt
|
148
156
|
homepage: https://github.com/abtion/abt
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Abt
|
4
|
-
module Providers
|
5
|
-
module Asana
|
6
|
-
module Commands
|
7
|
-
class Init < BaseCommand
|
8
|
-
def self.usage
|
9
|
-
"abt init asana"
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.description
|
13
|
-
"Pick Asana project for current git repository"
|
14
|
-
end
|
15
|
-
|
16
|
-
def perform
|
17
|
-
require_local_config!
|
18
|
-
|
19
|
-
projects # Load projects up front to make it obvious that searches are instant
|
20
|
-
project = cli.prompt.search("Select a project", projects)
|
21
|
-
|
22
|
-
config.path = Path.from_ids(project_gid: project["gid"])
|
23
|
-
|
24
|
-
print_project(project)
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def projects
|
30
|
-
@projects ||= begin
|
31
|
-
warn("Fetching projects...")
|
32
|
-
api.get_paged("projects",
|
33
|
-
workspace: config.workspace_gid,
|
34
|
-
archived: false,
|
35
|
-
opt_fields: "name,permalink_url")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Abt
|
4
|
-
module Providers
|
5
|
-
module Devops
|
6
|
-
module Commands
|
7
|
-
class Init < BaseCommand
|
8
|
-
AZURE_DEV_URL_REGEX = %r{^https://dev\.azure\.com/(?<organization>[^/]+)/(?<project>[^/]+)}.freeze
|
9
|
-
VS_URL_REGEX = %r{^https://(?<organization>[^.]+)\.visualstudio\.com/(?<project>[^/]+)}.freeze
|
10
|
-
|
11
|
-
def self.usage
|
12
|
-
"abt init devops"
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.description
|
16
|
-
"Pick DevOps board for current git repository"
|
17
|
-
end
|
18
|
-
|
19
|
-
def perform
|
20
|
-
require_local_config!
|
21
|
-
board = cli.prompt.choice("Select a project work board", boards)
|
22
|
-
|
23
|
-
config.path = Path.from_ids(
|
24
|
-
organization_name: organization_name,
|
25
|
-
project_name: project_name,
|
26
|
-
board_id: board["id"]
|
27
|
-
)
|
28
|
-
print_board(organization_name, project_name, board)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def boards
|
34
|
-
@boards ||= api.get_paged("work/boards")
|
35
|
-
end
|
36
|
-
|
37
|
-
def project_name
|
38
|
-
@project_name ||= begin
|
39
|
-
if (match = AZURE_DEV_URL_REGEX.match(project_url)) ||
|
40
|
-
(match = VS_URL_REGEX.match(project_url))
|
41
|
-
match[:project]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def organization_name
|
47
|
-
@organization_name ||= begin
|
48
|
-
if (match = AZURE_DEV_URL_REGEX.match(project_url)) ||
|
49
|
-
(match = VS_URL_REGEX.match(project_url))
|
50
|
-
match[:organization]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def project_url
|
56
|
-
@project_url ||= begin
|
57
|
-
loop do
|
58
|
-
url = cli.prompt.text(project_url_prompt_text)
|
59
|
-
|
60
|
-
break url if AZURE_DEV_URL_REGEX =~ url || VS_URL_REGEX =~ url
|
61
|
-
|
62
|
-
warn("Invalid URL")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def project_url_prompt_text
|
68
|
-
<<~TXT
|
69
|
-
Please provide the URL for the devops project
|
70
|
-
For instance https://{organization}.visualstudio.com/{project} or https://dev.azure.com/{organization}/{project}
|
71
|
-
|
72
|
-
Enter URL
|
73
|
-
TXT
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|