abt-cli 0.0.22 → 0.0.27

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/bin/abt +2 -2
  3. data/lib/abt.rb +5 -0
  4. data/lib/abt/cli.rb +28 -9
  5. data/lib/abt/cli/prompt.rb +37 -53
  6. data/lib/abt/directory_config.rb +25 -0
  7. data/lib/abt/docs.rb +10 -6
  8. data/lib/abt/docs/markdown.rb +5 -2
  9. data/lib/abt/helpers.rb +26 -8
  10. data/lib/abt/providers/asana.rb +1 -0
  11. data/lib/abt/providers/asana/base_command.rb +37 -3
  12. data/lib/abt/providers/asana/commands/add.rb +0 -4
  13. data/lib/abt/providers/asana/commands/branch_name.rb +0 -13
  14. data/lib/abt/providers/asana/commands/current.rb +1 -20
  15. data/lib/abt/providers/asana/commands/finalize.rb +6 -2
  16. data/lib/abt/providers/asana/commands/harvest_time_entry_data.rb +7 -5
  17. data/lib/abt/providers/asana/commands/pick.rb +12 -46
  18. data/lib/abt/providers/asana/commands/start.rb +9 -3
  19. data/lib/abt/providers/asana/commands/tasks.rb +2 -7
  20. data/lib/abt/providers/asana/configuration.rb +28 -12
  21. data/lib/abt/providers/asana/path.rb +1 -1
  22. data/lib/abt/providers/asana/services/project_picker.rb +54 -0
  23. data/lib/abt/providers/asana/services/task_picker.rb +83 -0
  24. data/lib/abt/providers/devops.rb +1 -0
  25. data/lib/abt/providers/devops/api.rb +10 -0
  26. data/lib/abt/providers/devops/base_command.rb +38 -14
  27. data/lib/abt/providers/devops/commands/boards.rb +1 -2
  28. data/lib/abt/providers/devops/commands/branch_name.rb +10 -16
  29. data/lib/abt/providers/devops/commands/current.rb +1 -21
  30. data/lib/abt/providers/devops/commands/harvest_time_entry_data.rb +16 -20
  31. data/lib/abt/providers/devops/commands/pick.rb +18 -39
  32. data/lib/abt/providers/devops/commands/work_items.rb +3 -6
  33. data/lib/abt/providers/devops/configuration.rb +10 -14
  34. data/lib/abt/providers/devops/path.rb +4 -4
  35. data/lib/abt/providers/devops/services/board_picker.rb +54 -0
  36. data/lib/abt/providers/devops/services/project_picker.rb +79 -0
  37. data/lib/abt/providers/devops/services/work_item_picker.rb +93 -0
  38. data/lib/abt/providers/git/commands/branch.rb +7 -3
  39. data/lib/abt/providers/harvest.rb +1 -0
  40. data/lib/abt/providers/harvest/base_command.rb +49 -3
  41. data/lib/abt/providers/harvest/commands/current.rb +1 -30
  42. data/lib/abt/providers/harvest/commands/pick.rb +12 -23
  43. data/lib/abt/providers/harvest/commands/projects.rb +0 -5
  44. data/lib/abt/providers/harvest/commands/tasks.rb +1 -16
  45. data/lib/abt/providers/harvest/commands/track.rb +33 -19
  46. data/lib/abt/providers/harvest/configuration.rb +1 -1
  47. data/lib/abt/providers/harvest/path.rb +1 -1
  48. data/lib/abt/providers/harvest/services/project_picker.rb +53 -0
  49. data/lib/abt/providers/harvest/services/task_picker.rb +50 -0
  50. data/lib/abt/version.rb +1 -1
  51. metadata +10 -5
  52. data/lib/abt/providers/asana/commands/init.rb +0 -42
  53. data/lib/abt/providers/devops/commands/init.rb +0 -76
  54. data/lib/abt/providers/harvest/commands/init.rb +0 -54
@@ -15,7 +15,7 @@ module Abt
15
15
  end
16
16
 
17
17
  def path
18
- Path.new(local_available? && git["path"] || "")
18
+ Path.new(local_available? && git["path"] || Abt.directory_config.dig("harvest", "path") || "")
19
19
  end
20
20
 
21
21
  def path=(new_path)
@@ -6,7 +6,7 @@ module Abt
6
6
  class Path < String
7
7
  PATH_REGEX = %r{^(?<project_id>\d+)?/?(?<task_id>\d+)?$}.freeze
8
8
 
9
- def self.from_ids(project_id = nil, task_id = nil)
9
+ def self.from_ids(project_id: nil, task_id: nil)
10
10
  path = project_id ? [project_id, *task_id].join("/") : ""
11
11
  new(path)
12
12
  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.new([path, task["id"]].join("/"))
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Abt
4
- VERSION = "0.0.22"
4
+ VERSION = "0.0.27"
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.22
4
+ version: 0.0.27
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 00:00:00.000000000 Z
11
+ date: 2021-03-26 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,7 +105,6 @@ 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"
@@ -112,6 +112,8 @@ files:
112
112
  - "./lib/abt/providers/asana/commands/tasks.rb"
113
113
  - "./lib/abt/providers/asana/configuration.rb"
114
114
  - "./lib/abt/providers/asana/path.rb"
115
+ - "./lib/abt/providers/asana/services/project_picker.rb"
116
+ - "./lib/abt/providers/asana/services/task_picker.rb"
115
117
  - "./lib/abt/providers/devops.rb"
116
118
  - "./lib/abt/providers/devops/api.rb"
117
119
  - "./lib/abt/providers/devops/base_command.rb"
@@ -120,12 +122,14 @@ files:
120
122
  - "./lib/abt/providers/devops/commands/clear.rb"
121
123
  - "./lib/abt/providers/devops/commands/current.rb"
122
124
  - "./lib/abt/providers/devops/commands/harvest_time_entry_data.rb"
123
- - "./lib/abt/providers/devops/commands/init.rb"
124
125
  - "./lib/abt/providers/devops/commands/pick.rb"
125
126
  - "./lib/abt/providers/devops/commands/share.rb"
126
127
  - "./lib/abt/providers/devops/commands/work_items.rb"
127
128
  - "./lib/abt/providers/devops/configuration.rb"
128
129
  - "./lib/abt/providers/devops/path.rb"
130
+ - "./lib/abt/providers/devops/services/board_picker.rb"
131
+ - "./lib/abt/providers/devops/services/project_picker.rb"
132
+ - "./lib/abt/providers/devops/services/work_item_picker.rb"
129
133
  - "./lib/abt/providers/git.rb"
130
134
  - "./lib/abt/providers/git/commands/branch.rb"
131
135
  - "./lib/abt/providers/harvest.rb"
@@ -133,7 +137,6 @@ files:
133
137
  - "./lib/abt/providers/harvest/base_command.rb"
134
138
  - "./lib/abt/providers/harvest/commands/clear.rb"
135
139
  - "./lib/abt/providers/harvest/commands/current.rb"
136
- - "./lib/abt/providers/harvest/commands/init.rb"
137
140
  - "./lib/abt/providers/harvest/commands/pick.rb"
138
141
  - "./lib/abt/providers/harvest/commands/projects.rb"
139
142
  - "./lib/abt/providers/harvest/commands/share.rb"
@@ -143,6 +146,8 @@ files:
143
146
  - "./lib/abt/providers/harvest/commands/track.rb"
144
147
  - "./lib/abt/providers/harvest/configuration.rb"
145
148
  - "./lib/abt/providers/harvest/path.rb"
149
+ - "./lib/abt/providers/harvest/services/project_picker.rb"
150
+ - "./lib/abt/providers/harvest/services/task_picker.rb"
146
151
  - "./lib/abt/version.rb"
147
152
  - bin/abt
148
153
  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
- abort("Must be run inside a git repository") unless config.local_available?
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"])
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,76 +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
- abort("Must be run inside a git repository") unless config.local_available?
21
-
22
- board = cli.prompt.choice("Select a project work board", boards)
23
-
24
- config.path = Path.from_ids(organization_name, project_name, board["id"])
25
- print_board(organization_name, project_name, board)
26
- end
27
-
28
- private
29
-
30
- def boards
31
- @boards ||= api.get_paged("work/boards")
32
- end
33
-
34
- def project_name
35
- @project_name ||= begin
36
- if (match = AZURE_DEV_URL_REGEX.match(project_url)) ||
37
- (match = VS_URL_REGEX.match(project_url))
38
- match[:project]
39
- end
40
- end
41
- end
42
-
43
- def organization_name
44
- @organization_name ||= begin
45
- if (match = AZURE_DEV_URL_REGEX.match(project_url)) ||
46
- (match = VS_URL_REGEX.match(project_url))
47
- match[:organization]
48
- end
49
- end
50
- end
51
-
52
- def project_url
53
- @project_url ||= begin
54
- loop do
55
- url = cli.prompt.text(project_url_prompt_text)
56
-
57
- break url if AZURE_DEV_URL_REGEX =~ url || VS_URL_REGEX =~ url
58
-
59
- warn("Invalid URL")
60
- end
61
- end
62
- end
63
-
64
- def project_url_prompt_text
65
- <<~TXT
66
- Please provide the URL for the devops project
67
- For instance https://{organization}.visualstudio.com/{project} or https://dev.azure.com/{organization}/{project}
68
-
69
- Enter URL
70
- TXT
71
- end
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Abt
4
- module Providers
5
- module Harvest
6
- module Commands
7
- class Init < BaseCommand
8
- def self.usage
9
- "abt init harvest"
10
- end
11
-
12
- def self.description
13
- "Pick Harvest project for current git repository"
14
- end
15
-
16
- def perform
17
- abort("Must be run inside a git repository") unless config.local_available?
18
-
19
- projects # Load projects up front to make it obvious that searches are instant
20
- project = cli.prompt.search("Select a project", searchable_projects)["project"]
21
-
22
- config.path = Path.from_ids(project["id"])
23
-
24
- print_project(project)
25
- end
26
-
27
- private
28
-
29
- def searchable_projects
30
- @searchable_projects ||= projects.map do |project|
31
- {
32
- "name" => "#{project['client']['name']} > #{project['name']}",
33
- "project" => project
34
- }
35
- end
36
- end
37
-
38
- def projects
39
- @projects ||= begin
40
- warn("Fetching projects...")
41
- project_assignments.map do |project_assignment|
42
- project_assignment["project"].merge("client" => project_assignment["client"])
43
- end
44
- end
45
- end
46
-
47
- def project_assignments
48
- @project_assignments ||= api.get_paged("users/me/project_assignments")
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end