abt-cli 0.0.22 → 0.0.27

Sign up to get free protection for your applications and to get access to all the features.
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