dude-cli 2.0.4 → 2.1.0.alpha2

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/.github/workflows/verify.yml +32 -0
  3. data/.rspec +0 -1
  4. data/.rubocop.yml +13 -0
  5. data/CHANGELOG.md +7 -3
  6. data/Gemfile +3 -1
  7. data/Gemfile.lock +48 -9
  8. data/LICENCE +20 -0
  9. data/README.md +32 -6
  10. data/Rakefile +5 -3
  11. data/bin/console +4 -3
  12. data/bin/dude +2 -2
  13. data/dude.gemspec +25 -18
  14. data/lib/dude.rb +9 -9
  15. data/lib/dude/code_management.rb +10 -0
  16. data/lib/dude/code_management/github/client.rb +23 -0
  17. data/lib/dude/code_management/github/create_pull_request.rb +53 -0
  18. data/lib/dude/commands.rb +24 -17
  19. data/lib/dude/commands/checkout.rb +4 -2
  20. data/lib/dude/commands/install.rb +32 -18
  21. data/lib/dude/commands/move.rb +5 -3
  22. data/lib/dude/commands/pr.rb +11 -0
  23. data/lib/dude/commands/pr/create.rb +49 -0
  24. data/lib/dude/commands/pr/remove.rb +15 -0
  25. data/lib/dude/commands/start.rb +9 -3
  26. data/lib/dude/commands/stop.rb +4 -2
  27. data/lib/dude/commands/tasks.rb +6 -3
  28. data/lib/dude/commands/track.rb +5 -3
  29. data/lib/dude/commands/version.rb +3 -1
  30. data/lib/dude/git.rb +3 -0
  31. data/lib/dude/git/checkout.rb +20 -1
  32. data/lib/dude/git/current_branch_name.rb +3 -1
  33. data/lib/dude/git/remote_name.rb +21 -0
  34. data/lib/dude/project_management/client.rb +14 -6
  35. data/lib/dude/project_management/entities/issue.rb +10 -7
  36. data/lib/dude/project_management/jira.rb +2 -1
  37. data/lib/dude/project_management/jira/client.rb +14 -7
  38. data/lib/dude/project_management/jira/fetch_current_task.rb +37 -0
  39. data/lib/dude/project_management/jira/fetch_current_tasks.rb +48 -0
  40. data/lib/dude/project_management/jira/get_task_name_by_id.rb +1 -1
  41. data/lib/dude/project_management/jira/move_task_to_list.rb +15 -13
  42. data/lib/dude/project_management/trello.rb +5 -3
  43. data/lib/dude/project_management/trello/client.rb +40 -21
  44. data/lib/dude/project_management/trello/fetch_current_task.rb +43 -0
  45. data/lib/dude/project_management/trello/fetch_current_tasks.rb +53 -0
  46. data/lib/dude/project_management/trello/fetch_lists.rb +24 -0
  47. data/lib/dude/project_management/trello/get_task_name_by_id.rb +25 -0
  48. data/lib/dude/project_management/trello/move_task_to_list.rb +55 -0
  49. data/lib/dude/settings.rb +3 -0
  50. data/lib/dude/templates/pull_request_template +7 -0
  51. data/lib/dude/time_trackers/toggl.rb +2 -0
  52. data/lib/dude/time_trackers/toggl/base.rb +4 -0
  53. data/lib/dude/time_trackers/toggl/start_time_entry.rb +3 -2
  54. data/lib/dude/time_trackers/toggl/stop_time_entry.rb +3 -1
  55. data/lib/dude/version.rb +3 -1
  56. metadata +77 -21
  57. data/lib/dude/project_management/entities/board.rb +0 -9
  58. data/lib/dude/project_management/jira/get_current_tasks.rb +0 -40
  59. data/lib/dude/project_management/trello/checkout.rb +0 -4
  60. data/lib/dude/project_management/trello/get_current_tasks.rb +0 -24
  61. data/lib/dude/project_management/trello/get_lists.rb +0 -15
  62. data/lib/dude/project_management/trello/move_tasks_to_list.rb +0 -14
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dude
2
4
  module Git
3
5
  class CurrentBranchName
4
6
  def call
5
- %x(git rev-parse --abbrev-ref HEAD).chomp
7
+ `git rev-parse --abbrev-ref HEAD`.chomp
6
8
  end
7
9
  end
8
10
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dude
4
+ module Git
5
+ class RemoteName
6
+ def call
7
+ extract_name push_url
8
+ end
9
+
10
+ private
11
+
12
+ def push_url
13
+ `git remote show origin`.split("\n")[1]
14
+ end
15
+
16
+ def extract_name(url)
17
+ url.scan(%r{(?<=github\.com[/:])(.*)(?=\.git)})[0][0]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,7 @@
1
- # require 'forwardable'
2
- require 'dude/project_management/jira/client'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './jira/client'
4
+ require_relative './trello/client'
3
5
 
4
6
  module Dude
5
7
  module ProjectManagement
@@ -9,16 +11,22 @@ module Dude
9
11
  attr_reader :client
10
12
 
11
13
  def initialize
12
- return unless LIST_OF_AVAILABLE_PROJECT_MANAGEMENT_TOOLS.include? settings['PROJECT_MANAGEMENT_TOOL']
13
- @client = Dude::ProjectManagement::Jira::Client.new
14
+ tool = settings['PROJECT_MANAGEMENT_TOOL']
15
+ return unless LIST_OF_AVAILABLE_PROJECT_MANAGEMENT_TOOLS.include? tool
16
+
17
+ @client = setup_client(tool)
14
18
  end
15
19
 
16
20
  def respond_to_missing?(method_name, include_private = false)
17
21
  client.respond_to_missing?(method_name, include_private)
18
22
  end
19
23
 
20
- def method_missing(m, *args, &block)
21
- client.send(m, *args, &block)
24
+ def method_missing(method, *args, &block)
25
+ client.send(method, *args, &block)
26
+ end
27
+
28
+ def setup_client(tool)
29
+ Object.const_get("Dude::ProjectManagement::#{tool.capitalize}::Client").new
22
30
  end
23
31
  end
24
32
  end
@@ -1,15 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dude
2
4
  module ProjectManagement
3
5
  module Entities
4
6
  class Issue
5
- attr_accessor :id, :title, :description, :status, :assignee
7
+ attr_accessor :id, :title, :description, :status, :assignee, :url
6
8
 
7
- def initialize(id: , title:, description:, status:, assignee: nil)
8
- @id = id
9
- @title = title
10
- @description = description
11
- @status = status
12
- @assignee = assignee
9
+ def initialize(params)
10
+ @id = params[:id]
11
+ @title = params[:title]
12
+ @description = params[:description]
13
+ @status = params[:status]
14
+ @assignee = params[:assignee]
15
+ @url = params[:url]
13
16
  end
14
17
 
15
18
  def todo?
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dude/project_management/jira/client'
2
4
 
3
5
  module Dude
4
6
  module ProjectManagement
5
7
  module Jira
6
-
7
8
  end
8
9
  end
9
10
  end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'jira-ruby'
2
- require 'dude/project_management/jira/get_current_tasks'
3
- require 'dude/project_management/jira/move_task_to_list'
4
- require 'dude/project_management/jira/get_task_name_by_id'
4
+ require_relative './fetch_current_tasks'
5
+ require_relative './fetch_current_task'
6
+ require_relative './move_task_to_list'
7
+ require_relative './get_task_name_by_id'
5
8
 
6
9
  module Dude
7
10
  module ProjectManagement
@@ -28,12 +31,16 @@ module Dude
28
31
  client.respond_to_missing?(method_name, include_private)
29
32
  end
30
33
 
31
- def method_missing(m, *args, &block)
32
- client.send(m, *args, &block)
34
+ def method_missing(method, *args, &block)
35
+ client.send(method, *args, &block)
36
+ end
37
+
38
+ def fetch_current_tasks
39
+ FetchCurrentTasks.new(client).call
33
40
  end
34
41
 
35
- def get_current_tasks
36
- GetCurrentTasks.new(client).call
42
+ def fetch_current_task(id)
43
+ FetchCurrentTask.new(client, id: id).call
37
44
  end
38
45
 
39
46
  def move_task_to_list(id, list)
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../entities/issue'
4
+
5
+ module Dude
6
+ module ProjectManagement
7
+ module Jira
8
+ class FetchCurrentTask
9
+ include Settings
10
+
11
+ def initialize(client, id:)
12
+ @client = client
13
+ @id = id
14
+ end
15
+
16
+ def call
17
+ create_issue(client.Issue.find(id))
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :client, :id
23
+
24
+ def create_issue(issue)
25
+ Entities::Issue.new(
26
+ id: issue.key,
27
+ title: issue.summary,
28
+ description: issue.description,
29
+ status: issue.status.name,
30
+ assignee: issue&.assignee&.displayName,
31
+ url: "#{settings['ATLASSIAN_URL']}/browse/#{issue.key}"
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../entities/issue'
4
+
5
+ module Dude
6
+ module ProjectManagement
7
+ module Jira
8
+ class FetchCurrentTasks
9
+ include Settings
10
+
11
+ def initialize(client)
12
+ @client = client
13
+ end
14
+
15
+ def call
16
+ board = client.Board.find(settings['ATLASSIAN_BOARD_ID'])
17
+
18
+ all_issues = board_type(board)
19
+
20
+ all_issues.map { |issue| create_issue(issue) }
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :client
26
+
27
+ def board_type(board)
28
+ case board.type
29
+ when 'kanban' then board.issues
30
+ when 'simple', 'scrum' then board.sprints(state: 'active').flat_map(&:issues)
31
+ else raise Dude::ToBeImplementedError
32
+ end
33
+ end
34
+
35
+ def create_issue(issue)
36
+ Entities::Issue.new(
37
+ id: issue.key,
38
+ title: issue.summary,
39
+ description: issue.description,
40
+ status: issue.status.name,
41
+ assignee: issue&.assignee&.displayName,
42
+ url: "#{settings['ATLASSIAN_URL']}/browse/#{issue.key}"
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,4 +1,4 @@
1
- require 'dude/project_management/jira/client'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Dude
4
4
  module ProjectManagement
@@ -1,4 +1,4 @@
1
- require 'dude/project_management/jira/client'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Dude
4
4
  module ProjectManagement
@@ -14,33 +14,35 @@ module Dude
14
14
 
15
15
  def call
16
16
  issue = client.Issue.find(id)
17
- available_transitions = client.Transition.all(:issue => issue)
17
+ available_transitions = client.Transition.all(issue: issue)
18
+ transition_id = generate_transition_id(issue, available_transitions)
19
+ transition = issue.transitions.build
20
+ transition.save!(transition: { id: transition_id })
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :client, :id, :list_name
18
26
 
19
- transition_id = if list_name
27
+ def generate_transition_id(issue, available_transitions)
28
+ if list_name
20
29
  available_transitions.find { |transition| transition.name == list_name }.id
21
30
  else
22
31
  select_list_for_moving(issue, available_transitions).id
23
32
  end
24
-
25
- transition = issue.transitions.build
26
- transition.save!(transition: { id: transition_id })
27
33
  end
28
34
 
29
- private
30
-
31
- def select_list_for_moving(issuem, available_transitions)
32
- puts "Please, select list for moving:".green.bold
35
+ def select_list_for_moving(_issue, available_transitions)
36
+ puts 'Please, select list for moving:'.green.bold
33
37
 
34
38
  available_transitions.each_with_index do |ea, index|
35
39
  puts "#{index + 1}: #{ea.name.bold}"
36
40
  end
37
41
 
38
42
  print "\nList index: ".bold
39
- list_index = STDIN.gets.chomp
43
+ list_index = $stdin.gets.chomp
40
44
  available_transitions[list_index.to_i - 1]
41
45
  end
42
-
43
- attr_reader :client, :id, :list_name
44
46
  end
45
47
  end
46
48
  end
@@ -1,6 +1,8 @@
1
- require_relative './trello/client'
1
+ # frozen_string_literal: true
2
2
 
3
- module ProjectsManagement
4
- module Trello
3
+ module Dude
4
+ module ProjectManagement
5
+ module Trello
6
+ end
5
7
  end
6
8
  end
@@ -1,32 +1,51 @@
1
- # TODO
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './fetch_current_tasks'
4
+ require_relative './fetch_current_task'
5
+ require_relative './move_task_to_list'
6
+ require_relative './get_task_name_by_id'
2
7
 
3
8
  require 'faraday'
4
9
  require 'json'
5
10
 
6
11
  module Dude
7
- module Trello
8
- class Client
9
- private
10
-
11
- def faraday_client
12
- @faraday_client ||= Faraday.new('https://api.trello.com/', {
13
- params: {
14
- key: "62b20e9eeab2d6e06145c69178521225",
15
- token: "6285fc2d2ff6100a5c341838d0e4acfed3601ae503beb973ddccf1cfab088537"
16
- }
17
- })
18
- end
12
+ module ProjectManagement
13
+ module Trello
14
+ class Client
15
+ include Settings
19
16
 
20
- def method_missing(method, *args, &block)
21
- faraday_client.send(method, *args, &block)
22
- end
17
+ def client
18
+ @client ||= Faraday.new('https://api.trello.com/', {
19
+ params: {
20
+ key: settings['TRELLO_KEY'],
21
+ token: settings['TRELLO_TOKEN']
22
+ }
23
+ })
24
+ end
23
25
 
24
- def get_current_tasks
25
- GetCurrentTasks.new(client).call
26
- end
26
+ def method_missing(method, *args, &block)
27
+ faraday_client.send(method, *args, &block)
28
+ end
29
+
30
+ def respond_to_missing?(method_name, include_private = false)
31
+ client.respond_to_missing?(method_name, include_private)
32
+ end
33
+
34
+ def fetch_current_tasks
35
+ FetchCurrentTasks.new(client).call
36
+ end
37
+
38
+ def fetch_current_task(id)
39
+ FetchCurrentTask.new(client, id: id).call
40
+ end
41
+
42
+ def move_task_to_list(id, list)
43
+ MoveTaskToList.new(client, id: id, list_name: list).call
44
+ end
27
45
 
28
- def move_task_to_list(id, list)
29
- MoveTasksToList.new(client, id: id, list_name: list).call
46
+ def get_task_name_by_id(id)
47
+ GetTaskNameById.new(client, id: id).call
48
+ end
30
49
  end
31
50
  end
32
51
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dude
4
+ module ProjectManagement
5
+ module Trello
6
+ class FetchCurrentTask
7
+ include Settings
8
+
9
+ def initialize(client, id:)
10
+ @client = client
11
+ @id = id
12
+ end
13
+
14
+ def call
15
+ response = client.get("/1/boards/#{settings['ATLASSIAN_BOARD_ID']}/cards/#{id}")
16
+ create_issue JSON.parse(response.body)
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :client, :id
22
+
23
+ def create_issue(issue)
24
+ Entities::Issue.new(
25
+ id: issue['idShort'],
26
+ title: issue['name'],
27
+ description: issue['desc'],
28
+ status: settings['IN_PROGRESS_LIST_NAME'], # OMG, let's fix this later
29
+ assignee: members(issue),
30
+ url: issue['shortUrl']
31
+ )
32
+ end
33
+
34
+ def members(issue)
35
+ people = issue['idMembers'].map do |person|
36
+ JSON.parse(client.get("/1/members/#{person}", fields: 'fullName').body)['fullName']
37
+ end
38
+ people.empty? ? nil : people.join(', ')
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './fetch_lists'
4
+
5
+ module Dude
6
+ module ProjectManagement
7
+ module Trello
8
+ class FetchCurrentTasks
9
+ include Settings
10
+
11
+ attr_reader :fetch_lists
12
+
13
+ def initialize(client, fetch_lists: nil)
14
+ @client = client
15
+
16
+ @fetch_lists = fetch_lists || FetchLists.new(client)
17
+ end
18
+
19
+ def call
20
+ lists = fetch_lists.call
21
+ lists.map { |list| retrieve_list_issues(list) }.flatten
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :client
27
+
28
+ def retrieve_list_issues(list)
29
+ response = client.get("/1/lists/#{list['id']}/cards")
30
+ body = JSON.parse(response.body)
31
+ body.map { |issue| create_issue(issue, list) }
32
+ end
33
+
34
+ def create_issue(issue, current_list)
35
+ Entities::Issue.new(
36
+ id: issue['idShort'],
37
+ title: issue['name'],
38
+ description: issue['desc'],
39
+ status: current_list['name'],
40
+ assignee: members(issue)
41
+ )
42
+ end
43
+
44
+ def members(issue)
45
+ people = issue['idMembers'].map do |person|
46
+ JSON.parse(client.get("/1/members/#{person}", fields: 'fullName').body)['fullName']
47
+ end
48
+ people.empty? ? nil : people.join(', ')
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end