dude-cli 2.1.0.alpha2 → 2.1.0

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/verify.yml +2 -2
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +7 -0
  6. data/Gemfile.lock +29 -9
  7. data/README.md +44 -44
  8. data/dude.gemspec +3 -2
  9. data/lib/dude.rb +11 -1
  10. data/lib/dude/code_management/github/client.rb +7 -3
  11. data/lib/dude/code_management/github/create_pull_request.rb +16 -8
  12. data/lib/dude/commands.rb +4 -0
  13. data/lib/dude/commands/commit.rb +23 -0
  14. data/lib/dude/commands/health_check.rb +15 -0
  15. data/lib/dude/commands/install.rb +63 -53
  16. data/lib/dude/commands/pr/remove.rb +1 -1
  17. data/lib/dude/commands/start.rb +6 -8
  18. data/lib/dude/commands/stop.rb +0 -2
  19. data/lib/dude/commands/tasks.rb +0 -2
  20. data/lib/dude/commands/track.rb +2 -4
  21. data/lib/dude/config.rb +18 -0
  22. data/lib/dude/git.rb +1 -0
  23. data/lib/dude/git/commit.rb +20 -0
  24. data/lib/dude/health_check.rb +39 -0
  25. data/lib/dude/project_management/client.rb +1 -3
  26. data/lib/dude/project_management/jira/client.rb +16 -8
  27. data/lib/dude/project_management/jira/fetch_current_task.rb +3 -3
  28. data/lib/dude/project_management/jira/fetch_current_tasks.rb +2 -4
  29. data/lib/dude/project_management/jira/get_task_name_by_id.rb +0 -2
  30. data/lib/dude/project_management/jira/move_task_to_list.rb +0 -2
  31. data/lib/dude/project_management/trello/client.rb +9 -5
  32. data/lib/dude/project_management/trello/fetch_current_task.rb +2 -4
  33. data/lib/dude/project_management/trello/fetch_current_tasks.rb +0 -2
  34. data/lib/dude/project_management/trello/fetch_lists.rb +1 -3
  35. data/lib/dude/project_management/trello/get_task_name_by_id.rb +1 -3
  36. data/lib/dude/project_management/trello/move_task_to_list.rb +1 -3
  37. data/lib/dude/setup/github.rb +35 -0
  38. data/lib/dude/setup/jira.rb +64 -0
  39. data/lib/dude/setup/toggl.rb +47 -0
  40. data/lib/dude/setup/trello.rb +58 -0
  41. data/lib/dude/templates/duderc_template +32 -0
  42. data/lib/dude/time_trackers/toggl/base.rb +2 -4
  43. data/lib/dude/version.rb +1 -1
  44. metadata +29 -6
  45. data/lib/dude/templates/pull_request_template +0 -7
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dude
4
+ module Commands
5
+ class Commit < Dry::CLI::Command
6
+ desc 'Create a commit with id and title of current story'
7
+
8
+ argument :id, required: true, desc: 'The card short ID'
9
+
10
+ def call(id:)
11
+ Dude::Git::Commit.new.call(commit_name(id))
12
+ end
13
+
14
+ private
15
+
16
+ def commit_name(id)
17
+ client = ProjectManagement::Client.new
18
+ issue_title = client.get_task_name_by_id(id)
19
+ "[#{id}] #{issue_title}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../health_check'
4
+
5
+ module Dude
6
+ module Commands
7
+ class HealthCheck < Dry::CLI::Command
8
+ desc 'Run healthcheck for enabled integrations'
9
+
10
+ def call
11
+ Dude::HealthCheck.new.call
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,6 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'tty-prompt'
4
+ require 'fileutils'
5
+
3
6
  require_relative '../settings'
7
+ require_relative '../setup/jira'
8
+ require_relative '../setup/trello'
9
+ require_relative '../setup/toggl'
10
+ require_relative '../setup/github'
4
11
 
5
12
  module Dude
6
13
  module Commands
@@ -8,63 +15,66 @@ module Dude
8
15
  desc 'Creates .duderc for future configuration'
9
16
 
10
17
  def call
11
- path = File.join(Dir.home, Settings::CONFIG_FILE)
12
- if File.exist?(path)
13
- puts 'Config file already exists'
14
- else
15
- File.open(path, 'w') { |f| f.write(duderc_file_content) }
16
- puts '.duderc created in your HOME directory'
17
- end
18
+ @prompt = TTY::Prompt.new
19
+
20
+ create_file_if_not_exists
21
+
22
+ @current_settings = Dude::Config.configure_with('.duderc.yml')
23
+ @current_settings[:project_management_tool] = setup_project_management_tool # jira, trello
24
+ @current_settings = send("setup_#{current_settings[:project_management_tool]}")
25
+ setup_features.each { send("setup_#{_1}") } # toggl, github
26
+
27
+ save
18
28
  end
19
29
 
20
30
  private
21
31
 
22
- def duderc_file_content
23
- <<~HEREDOC
24
- # Please, don't use quotes and spaces.
25
- # Write all variables using following format: NAME=VALUE
26
-
27
- # Replace it with your project list names. Skip for empty lists
28
- TODO_LIST_NAME=To Do
29
- IN_PROGRESS_LIST_NAME=In Progress
30
- CODE_REVIEW_LIST_NAME=Code Review
31
- TESTING_LIST_NAME=TESTABLE
32
- DONE_LIST_NAME=Done
33
-
34
- # Your Toggl project name
35
- TOGGL_PROJECT_NAME=
36
- # Your Toggl API token can be found at the bottom of the page: https://track.toggl.com/profile
37
- TOGGL_TOKEN=
38
- # Can be copied from url here: https://toggl.com/app/projects/. Example: 123456
39
- TOGGL_WORKSPACE_ID=
40
- # Use the *id* and *title* and specify format for the task titles in Trello or keep it as it is
41
- TOGGL_TASK_FORMAT=[id] title
42
-
43
- # Now jira/trello only (Github, Gitlab)
44
- # Choose one and uncomment section for Jira or Trello
45
-
46
- # [TRELLO setup start]
47
- # # https://trello.com/app-key
48
- # PROJECT_MANAGEMENT_TOOL=trello
49
- # TRELLO_KEY=
50
- # TRELLO_TOKEN=
51
- # [TRELLO setup end]
52
-
53
- # [JIRA setup start]
54
- PROJECT_MANAGEMENT_TOOL=jira
55
- ATLASSIAN_EMAIL=
56
- # How to create Atlassian token: https://support.siteimprove.com/hc/en-gb/articles/360004317332-How-to-create-an-API-token-from-your-Atlassian-account
57
- ATLASSIAN_TOKEN=
58
- # URL of your project. Example: https://example.atlassian.net
59
- ATLASSIAN_URL=
60
- # KEY of your project. If your issues have id BT-123 - BT is the key
61
- ATLASSIAN_PROJECT_KEY=
62
- # Just open your atlassian main board and copy id from the url after rapidView=*ID* part.
63
- # Example: https://dealmakerns.atlassian.net/secure/RapidBoard.jspa?rapidView=23&projectKey=DT - 23 is the id
64
- ATLASSIAN_BOARD_ID=
65
- # [JIRA setup end]
66
-
67
- HEREDOC
32
+ attr_reader :prompt, :current_settings
33
+
34
+ def setup_project_management_tool
35
+ prompt.select(Dude::Config.style_prompt("Select project management tool you're going to use:")) do |menu|
36
+ menu.choice name: 'Jira', value: 'jira'
37
+ menu.choice name: 'Trello', value: 'trello'
38
+ menu.choice name: 'Pivotal Tracker', value: 'pivotal', disabled: '(coming in future)'
39
+ menu.choice name: 'Github', value: 'github', disabled: '(coming in future)'
40
+ end
41
+ end
42
+
43
+ def method_missing(method, *args, &block)
44
+ return super unless method.start_with?('setup_')
45
+
46
+ const_name = method.to_s.split('setup_').last
47
+ Object.const_get("Dude::Setup::#{const_name.capitalize}").new(prompt).call(settings: current_settings)
48
+ end
49
+
50
+ def respond_to_missing?(method_name, include_private = false)
51
+ client.respond_to_missing?(method_name, include_private)
52
+ end
53
+
54
+ def setup_features
55
+ prompt.multi_select(Dude::Config.style_prompt('Select features you want to use:')) do |menu|
56
+ menu.choice 'Toggl time tracking features (Create/stop time entries)', :toggl
57
+ menu.choice 'Github PR creation', :github
58
+ end
59
+ end
60
+
61
+ def save
62
+ File.open('.duderc.yml', 'w') { |file| file.write(current_settings.to_yaml) }
63
+ puts 'Configuration file has been sucessfully updated'.green.bold
64
+ puts 'Your settings are in the .duderc.yml file'.yellow
65
+ puts 'You could change it manually for editing Toggl task format and Github PR template'.yellow
66
+ rescue StandardError => e
67
+ puts "Something went wrong: #{e}"
68
+ end
69
+
70
+ def create_file_if_not_exists
71
+ path = File.join(Dir.pwd, Config::FILE_NAME)
72
+ if File.exist?(path)
73
+ puts 'Config file already exists. All settings will be rewrited'
74
+ else
75
+ FileUtils.cp(File.join(File.dirname(__FILE__), '../templates/duderc_template'), path)
76
+ puts '.duderc created in your HOME directory'
77
+ end
68
78
  end
69
79
  end
70
80
  end
@@ -7,7 +7,7 @@ module Dude
7
7
  desc 'Remove'
8
8
 
9
9
  def call(*)
10
- puts '123'
10
+ puts 'To be created later'
11
11
  end
12
12
  end
13
13
  end
@@ -3,8 +3,6 @@
3
3
  module Dude
4
4
  module Commands
5
5
  class Start < Dry::CLI::Command
6
- include Settings
7
-
8
6
  desc 'Start task (Do checkout, track and move actions)'
9
7
 
10
8
  argument :id, required: true, desc: 'The card short ID'
@@ -19,16 +17,16 @@ module Dude
19
17
 
20
18
  def selected_list(list)
21
19
  case list
22
- when 'todo' then settings['TODO_LIST_NAME']
23
- when 'in_progress' then settings['IN_PROGRESS_LIST_NAME']
24
- when 'code_review' then settings['CODE_REVIEW_LIST_NAME']
25
- when 'testing' then settings['TESTING_LIST_NAME']
26
- when 'done' then settings['DONE_LIST_NAME']
20
+ when 'todo' then Dude::SETTINGS[:todo_list_name]
21
+ when 'in_progress' then Dude::SETTINGS[:in_progress_list_name]
22
+ when 'code_review' then Dude::SETTINGS[:code_review_list_name]
23
+ when 'testing' then Dude::SETTINGS[:testing_list_name]
24
+ when 'done' then Dude::SETTINGS[:done_list_name]
27
25
  end
28
26
  end
29
27
 
30
28
  def time_tracking_enabled?
31
- !settings['TOGGL_TOKEN'].nil?
29
+ !Dude::SETTINGS.dig(:toggl, :token).nil?
32
30
  end
33
31
  end
34
32
  end
@@ -5,8 +5,6 @@ require_relative '../time_trackers/toggl/stop_time_entry'
5
5
  module Dude
6
6
  module Commands
7
7
  class Stop < Dry::CLI::Command
8
- include Settings
9
-
10
8
  desc 'Stop current time entry in Toggl'
11
9
 
12
10
  def call
@@ -5,8 +5,6 @@ require_relative '../project_management/client'
5
5
  module Dude
6
6
  module Commands
7
7
  class Tasks < Dry::CLI::Command
8
- include Settings
9
-
10
8
  desc "Print tasks as list with ID's and assignees"
11
9
 
12
10
  def call
@@ -5,15 +5,13 @@ require_relative '../time_trackers/toggl/start_time_entry'
5
5
  module Dude
6
6
  module Commands
7
7
  class Track < Dry::CLI::Command
8
- include Settings
9
-
10
8
  desc 'Start time entry in Toggl with issue title and id'
11
9
 
12
10
  argument :id, required: true, desc: 'The card short ID'
13
11
 
14
12
  def call(id:)
15
13
  @id = id
16
- Dude::Toggl::StartTimeEntry.new.call(task_title: task_title, project: settings['TOGGL_PROJECT_NAME'])
14
+ Dude::Toggl::StartTimeEntry.new.call(task_title: task_title, project: Dude::SETTINGS.dig(:toggl, :project_name))
17
15
  end
18
16
 
19
17
  private
@@ -23,7 +21,7 @@ module Dude
23
21
  def task_title
24
22
  client = ProjectManagement::Client.new
25
23
  issue_title = client.get_task_name_by_id(id)
26
- settings['TOGGL_TASK_FORMAT'].sub(/id/, id).sub(/title/, issue_title)
24
+ Dude::SETTINGS.dig(:toggl, :task_format).sub(/{issue_id}/, id).sub(/{issue_title}/, issue_title)
27
25
  end
28
26
  end
29
27
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dude
4
+ class Config
5
+ FILE_NAME = '.duderc.yml'
6
+
7
+ # Configure through yaml file
8
+ def self.configure_with(path_to_yaml_file)
9
+ YAML.safe_load(IO.read(path_to_yaml_file), [Symbol])
10
+ rescue StandardError
11
+ {}
12
+ end
13
+
14
+ def self.style_prompt(text)
15
+ "#{'=>'.green.bold} #{text}"
16
+ end
17
+ end
18
+ end
data/lib/dude/git.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative './git/checkout'
4
4
  require_relative './git/current_branch_name'
5
+ require_relative './git/commit'
5
6
  require_relative './git/remote_name'
6
7
 
7
8
  module Git
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dude
4
+ module Git
5
+ class Commit
6
+ def call(commit_name)
7
+ @commit_name = commit_name
8
+ create_commit
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :commit_name
14
+
15
+ def create_commit
16
+ `git commit -m "#{commit_name}"`
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './project_management/jira/client'
4
+ require_relative './project_management/trello/client'
5
+
6
+ module Dude
7
+ class HealthCheck
8
+ def call
9
+ validate(:jira, enabled: Dude::SETTINGS.dig(:jira, :token)) do
10
+ Dude::ProjectManagement::Jira::Client.new.health_check
11
+ end
12
+
13
+ validate(:trello, enabled: Dude::SETTINGS.dig(:trello, :token)) do
14
+ Dude::ProjectManagement::Trello::Client.new.health_check
15
+ end
16
+
17
+ validate(:github, enabled: Dude::SETTINGS.dig(:github, :token)) do
18
+ Dude::CodeManagement::Github::Client.new.health_check
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def validate(check, enabled:)
25
+ prepare_validation(check)
26
+ end_validation(check, enabled ? yield : nil, enabled: enabled)
27
+ end
28
+
29
+ def prepare_validation(check)
30
+ print "#{check.capitalize} status: [#{'WAIT'.yellow}]\r"
31
+ end
32
+
33
+ def end_validation(check, status, enabled: false)
34
+ return puts "#{check.capitalize} status: [#{'DISABLED'.blue}] " unless enabled
35
+
36
+ puts "#{check.capitalize} status: [#{status ? 'OK'.green : 'FAILURE'.red}] "
37
+ end
38
+ end
39
+ end
@@ -6,12 +6,10 @@ require_relative './trello/client'
6
6
  module Dude
7
7
  module ProjectManagement
8
8
  class Client
9
- include Settings
10
-
11
9
  attr_reader :client
12
10
 
13
11
  def initialize
14
- tool = settings['PROJECT_MANAGEMENT_TOOL']
12
+ tool = Dude::SETTINGS[:project_management_tool]
15
13
  return unless LIST_OF_AVAILABLE_PROJECT_MANAGEMENT_TOOLS.include? tool
16
14
 
17
15
  @client = setup_client(tool)
@@ -10,21 +10,23 @@ module Dude
10
10
  module ProjectManagement
11
11
  module Jira
12
12
  class Client
13
- include Settings
14
-
15
13
  attr_reader :client, :project
16
14
 
17
- def initialize
18
- options = {
19
- username: settings['ATLASSIAN_EMAIL'],
20
- password: settings['ATLASSIAN_TOKEN'],
21
- site: settings['ATLASSIAN_URL'],
15
+ def options
16
+ {
17
+ username: Dude::SETTINGS.dig(:jira, :email),
18
+ password: Dude::SETTINGS.dig(:jira, :token),
19
+ site: Dude::SETTINGS.dig(:jira, :project, :url),
22
20
  context_path: '',
23
21
  auth_type: :basic
24
22
  }
23
+ end
25
24
 
25
+ def initialize
26
26
  @client = JIRA::Client.new(options)
27
- @project = client.Project.find(settings['ATLASSIAN_PROJECT_KEY'])
27
+ @project = client.Project.find(Dude::SETTINGS.dig(:jira, :project, :key))
28
+ rescue StandardError
29
+ nil
28
30
  end
29
31
 
30
32
  def respond_to_missing?(method_name, include_private = false)
@@ -50,6 +52,12 @@ module Dude
50
52
  def get_task_name_by_id(id)
51
53
  GetTaskNameById.new(client, id: id).call
52
54
  end
55
+
56
+ def health_check
57
+ @project && true
58
+ rescue StandardError
59
+ false
60
+ end
53
61
  end
54
62
  end
55
63
  end
@@ -6,8 +6,6 @@ module Dude
6
6
  module ProjectManagement
7
7
  module Jira
8
8
  class FetchCurrentTask
9
- include Settings
10
-
11
9
  def initialize(client, id:)
12
10
  @client = client
13
11
  @id = id
@@ -15,6 +13,8 @@ module Dude
15
13
 
16
14
  def call
17
15
  create_issue(client.Issue.find(id))
16
+ rescue JIRA::HTTPError
17
+ puts "#{'Error:'.red.bold} Task #{id.bold} not found. Try again with correct task ID"
18
18
  end
19
19
 
20
20
  private
@@ -28,7 +28,7 @@ module Dude
28
28
  description: issue.description,
29
29
  status: issue.status.name,
30
30
  assignee: issue&.assignee&.displayName,
31
- url: "#{settings['ATLASSIAN_URL']}/browse/#{issue.key}"
31
+ url: "#{Dude::SETTINGS.dig(:jira, :project, :url)}/browse/#{issue.key}"
32
32
  )
33
33
  end
34
34
  end
@@ -6,14 +6,12 @@ module Dude
6
6
  module ProjectManagement
7
7
  module Jira
8
8
  class FetchCurrentTasks
9
- include Settings
10
-
11
9
  def initialize(client)
12
10
  @client = client
13
11
  end
14
12
 
15
13
  def call
16
- board = client.Board.find(settings['ATLASSIAN_BOARD_ID'])
14
+ board = client.Board.find(Dude::SETTINGS.dig(:jira, :board_id))
17
15
 
18
16
  all_issues = board_type(board)
19
17
 
@@ -39,7 +37,7 @@ module Dude
39
37
  description: issue.description,
40
38
  status: issue.status.name,
41
39
  assignee: issue&.assignee&.displayName,
42
- url: "#{settings['ATLASSIAN_URL']}/browse/#{issue.key}"
40
+ url: "#{Dude::SETTINGS.dig(:jira, :project, :url)}/browse/#{issue.key}"
43
41
  )
44
42
  end
45
43
  end