dude-cli 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/.travis.yml +4 -3
- data/CHANGELOG.md +25 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +55 -54
- data/README.md +41 -25
- data/bin/dude +3 -2
- data/dude.gemspec +16 -16
- data/lib/dude.rb +14 -0
- data/lib/dude/commands.rb +24 -0
- data/lib/dude/commands/checkout.rb +21 -0
- data/lib/dude/commands/install.rb +57 -0
- data/lib/dude/commands/move.rb +15 -0
- data/lib/dude/commands/start.rb +29 -0
- data/lib/dude/commands/stop.rb +15 -0
- data/lib/dude/commands/tasks.rb +31 -0
- data/lib/dude/commands/track.rb +28 -0
- data/lib/dude/commands/version.rb +11 -0
- data/lib/dude/git.rb +5 -0
- data/lib/dude/git/checkout.rb +2 -16
- data/lib/dude/git/current_branch_name.rb +1 -2
- data/lib/dude/project_management/client.rb +25 -0
- data/lib/dude/project_management/entities/board.rb +9 -0
- data/lib/dude/project_management/entities/issue.rb +37 -0
- data/lib/dude/project_management/jira.rb +9 -0
- data/lib/dude/project_management/jira/client.rb +49 -0
- data/lib/dude/project_management/jira/get_current_tasks.rb +40 -0
- data/lib/dude/project_management/jira/get_task_name_by_id.rb +24 -0
- data/lib/dude/project_management/jira/move_task_to_list.rb +47 -0
- data/lib/dude/project_management/trello.rb +6 -0
- data/lib/dude/project_management/trello/checkout.rb +4 -0
- data/lib/dude/project_management/trello/client.rb +33 -0
- data/lib/dude/project_management/trello/get_current_tasks.rb +24 -0
- data/lib/dude/project_management/trello/get_lists.rb +15 -0
- data/lib/dude/project_management/trello/move_tasks_to_list.rb +14 -0
- data/lib/dude/settings.rb +6 -2
- data/lib/dude/time_trackers/toggl.rb +5 -0
- data/lib/dude/time_trackers/toggl/base.rb +18 -0
- data/lib/dude/{toggl → time_trackers/toggl}/start_time_entry.rb +14 -8
- data/lib/dude/{toggl → time_trackers/toggl}/stop_time_entry.rb +4 -2
- data/lib/dude/version.rb +1 -1
- metadata +56 -103
- data/.ruby-version +0 -1
- data/LICENSE.txt +0 -21
- data/lib/dude/cli.rb +0 -156
- data/lib/dude/gitlab/add_spend_time.rb +0 -36
- data/lib/dude/gitlab/base.rb +0 -38
- data/lib/dude/gitlab/count_spend_time.rb +0 -13
- data/lib/dude/gitlab/estimate.rb +0 -20
- data/lib/dude/gitlab/get_issue_info.rb +0 -9
- data/lib/dude/gitlab/get_issue_time_spent.rb +0 -9
- data/lib/dude/gitlab/get_issue_title.rb +0 -14
- data/lib/dude/gitlab/get_my_issues.rb +0 -31
- data/lib/dude/gitlab/move_issue.rb +0 -37
- data/lib/dude/interface.rb +0 -98
- data/lib/dude/report.rb +0 -38
- data/lib/dude/service.rb +0 -18
- data/lib/dude/toggl.rb +0 -40
- data/lib/dude/toggl/base.rb +0 -36
- data/lib/dude/toggl/issue_spend_time.rb +0 -56
- data/lib/dude/toggl/report.rb +0 -25
@@ -0,0 +1,15 @@
|
|
1
|
+
module Dude
|
2
|
+
module Commands
|
3
|
+
class Move < Dry::CLI::Command
|
4
|
+
desc "Move task between board columns"
|
5
|
+
|
6
|
+
argument :id, required: true, desc: "The card short ID"
|
7
|
+
option :list, desc: "List name for moving card"
|
8
|
+
|
9
|
+
def call(id:, **options)
|
10
|
+
client = ProjectManagement::Client.new
|
11
|
+
client.move_task_to_list(id, options[:list])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dude
|
2
|
+
module Commands
|
3
|
+
class Start < Dry::CLI::Command
|
4
|
+
include Settings
|
5
|
+
|
6
|
+
desc "Start task (Do checkout, track and move actions)"
|
7
|
+
|
8
|
+
argument :id, required: true, desc: "The card short ID"
|
9
|
+
|
10
|
+
def call(id:)
|
11
|
+
Commands::Move.new.call(id: id, list: selected_list('in_progress'))
|
12
|
+
Commands::Checkout.new.call(id: id)
|
13
|
+
Commands::Track.new.call(id: id)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def selected_list(list)
|
19
|
+
case list
|
20
|
+
when 'todo' then settings['TODO_LIST_NAME']
|
21
|
+
when 'in_progress' then settings['IN_PROGRESS_LIST_NAME']
|
22
|
+
when 'code_review' then settings['CODE_REVIEW_LIST_NAME']
|
23
|
+
when 'testing' then settings['TESTING_LIST_NAME']
|
24
|
+
when 'done' then settings['DONE_LIST_NAME']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'dude/time_trackers/toggl/stop_time_entry'
|
2
|
+
|
3
|
+
module Dude
|
4
|
+
module Commands
|
5
|
+
class Stop < Dry::CLI::Command
|
6
|
+
include Settings
|
7
|
+
|
8
|
+
desc "Stop current time entry in Toggl"
|
9
|
+
|
10
|
+
def call
|
11
|
+
Dude::Toggl::StopTimeEntry.new.call
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'dude/project_management/client'
|
2
|
+
|
3
|
+
module Dude
|
4
|
+
module Commands
|
5
|
+
class Tasks < Dry::CLI::Command
|
6
|
+
include Settings
|
7
|
+
|
8
|
+
desc "Print tasks as list with ID's and assignees"
|
9
|
+
|
10
|
+
def call
|
11
|
+
tasks = Dude::ProjectManagement::Client.new.get_current_tasks
|
12
|
+
lists = tasks.map {|issue| issue.status}.uniq
|
13
|
+
|
14
|
+
lists.each do |list|
|
15
|
+
puts "#{list}:".green.bold
|
16
|
+
tasks.map do |issue|
|
17
|
+
puts printable_issue_template(issue) if issue.status == list
|
18
|
+
end
|
19
|
+
puts "\n"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def printable_issue_template(issue)
|
26
|
+
return "#{issue.id.to_s.bold}: #{issue.title}" + " (#{issue.assignee})".blue if issue.assignee
|
27
|
+
"#{issue.id.to_s.bold}: #{issue.title}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'dude/time_trackers/toggl/start_time_entry'
|
2
|
+
|
3
|
+
module Dude
|
4
|
+
module Commands
|
5
|
+
class Track < Dry::CLI::Command
|
6
|
+
include Settings
|
7
|
+
|
8
|
+
desc "Start time entry in Toggl with issue title and id"
|
9
|
+
|
10
|
+
argument :id, required: true, desc: "The card short ID"
|
11
|
+
|
12
|
+
def call(id:)
|
13
|
+
@id = id
|
14
|
+
Dude::Toggl::StartTimeEntry.new.call(task_title: task_title, project: settings['TOGGL_PROJECT_NAME'])
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :id
|
20
|
+
|
21
|
+
def task_title
|
22
|
+
client = ProjectManagement::Client.new
|
23
|
+
issue_title = client.get_task_name_by_id(id)
|
24
|
+
settings['TOGGL_TASK_FORMAT'].sub(/id/, id).sub(/title/, issue_title)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/dude/git.rb
ADDED
data/lib/dude/git/checkout.rb
CHANGED
@@ -1,22 +1,8 @@
|
|
1
1
|
module Dude
|
2
2
|
module Git
|
3
3
|
class Checkout
|
4
|
-
|
5
|
-
|
6
|
-
checkout if options[:branch_name]
|
7
|
-
print_message
|
8
|
-
end
|
9
|
-
|
10
|
-
def checkout
|
11
|
-
git.branch(options[:branch_name]).checkout
|
12
|
-
end
|
13
|
-
|
14
|
-
def print_message
|
15
|
-
puts "Branch changed to '#{options[:branch_name]}'".colorize(:green)
|
16
|
-
end
|
17
|
-
|
18
|
-
def git
|
19
|
-
@git ||= ::Git.init
|
4
|
+
def call(branch_name)
|
5
|
+
%x(git checkout -b #{branch_name})
|
20
6
|
end
|
21
7
|
end
|
22
8
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# require 'forwardable'
|
2
|
+
require 'dude/project_management/jira/client'
|
3
|
+
|
4
|
+
module Dude
|
5
|
+
module ProjectManagement
|
6
|
+
class Client
|
7
|
+
include Settings
|
8
|
+
|
9
|
+
attr_reader :client
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
return unless LIST_OF_AVAILABLE_PROJECT_MANAGEMENT_TOOLS.include? settings['PROJECT_MANAGEMENT_TOOL']
|
13
|
+
@client = Dude::ProjectManagement::Jira::Client.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def respond_to_missing?(method_name, include_private = false)
|
17
|
+
client.respond_to_missing?(method_name, include_private)
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(m, *args, &block)
|
21
|
+
client.send(m, *args, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Dude
|
2
|
+
module ProjectManagement
|
3
|
+
module Entities
|
4
|
+
class Issue
|
5
|
+
attr_accessor :id, :title, :description, :status, :assignee
|
6
|
+
|
7
|
+
def initialize(id: , title:, description:, status:, assignee: nil)
|
8
|
+
@id = id
|
9
|
+
@title = title
|
10
|
+
@description = description
|
11
|
+
@status = status
|
12
|
+
@assignee = assignee
|
13
|
+
end
|
14
|
+
|
15
|
+
def todo?
|
16
|
+
[TODO_LIST_NAME, 'Unclear'].include? status
|
17
|
+
end
|
18
|
+
|
19
|
+
def in_progress?
|
20
|
+
status == IN_PROGRESS_LIST_NAME
|
21
|
+
end
|
22
|
+
|
23
|
+
def ready_for_review?
|
24
|
+
status == CODE_REVIEW_LIST_NAME
|
25
|
+
end
|
26
|
+
|
27
|
+
def testable?
|
28
|
+
status == TESTING_LIST_NAME
|
29
|
+
end
|
30
|
+
|
31
|
+
def done?
|
32
|
+
status == DONE_LIST_NAME
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
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'
|
5
|
+
|
6
|
+
module Dude
|
7
|
+
module ProjectManagement
|
8
|
+
module Jira
|
9
|
+
class Client
|
10
|
+
include Settings
|
11
|
+
|
12
|
+
attr_reader :client, :project
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
options = {
|
16
|
+
username: settings['ATLASSIAN_EMAIL'],
|
17
|
+
password: settings['ATLASSIAN_TOKEN'],
|
18
|
+
site: settings['ATLASSIAN_URL'],
|
19
|
+
context_path: '',
|
20
|
+
auth_type: :basic
|
21
|
+
}
|
22
|
+
|
23
|
+
@client = JIRA::Client.new(options)
|
24
|
+
@project = client.Project.find(settings['ATLASSIAN_PROJECT_KEY'])
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to_missing?(method_name, include_private = false)
|
28
|
+
client.respond_to_missing?(method_name, include_private)
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(m, *args, &block)
|
32
|
+
client.send(m, *args, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_current_tasks
|
36
|
+
GetCurrentTasks.new(client).call
|
37
|
+
end
|
38
|
+
|
39
|
+
def move_task_to_list(id, list)
|
40
|
+
MoveTaskToList.new(client, id: id, list_name: list).call
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_task_name_by_id(id)
|
44
|
+
GetTaskNameById.new(client, id: id).call
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'dude/project_management/entities/issue'
|
2
|
+
require 'dude/project_management/jira/client'
|
3
|
+
|
4
|
+
module Dude
|
5
|
+
module ProjectManagement
|
6
|
+
module Jira
|
7
|
+
class GetCurrentTasks
|
8
|
+
include Settings
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
board = client.Board.find(settings['ATLASSIAN_BOARD_ID'])
|
16
|
+
|
17
|
+
all_issues = case board.type
|
18
|
+
when 'kanban' then board.issues
|
19
|
+
when 'simple', 'scrum' then board.sprints(state: 'active').flat_map { |sprint| sprint.issues }
|
20
|
+
else raise Dude::ToBeImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
all_issues.map do |issue|
|
24
|
+
Entities::Issue.new({
|
25
|
+
id: issue.key,
|
26
|
+
title: issue.summary,
|
27
|
+
description: issue.description,
|
28
|
+
status: issue.status.name,
|
29
|
+
assignee: issue&.assignee&.displayName
|
30
|
+
})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :client
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'dude/project_management/jira/client'
|
2
|
+
|
3
|
+
module Dude
|
4
|
+
module ProjectManagement
|
5
|
+
module Jira
|
6
|
+
class GetTaskNameById
|
7
|
+
include Settings
|
8
|
+
|
9
|
+
def initialize(client, id:)
|
10
|
+
@client = client
|
11
|
+
@id = id
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
client.Issue.find(id).summary
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :client, :id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'dude/project_management/jira/client'
|
2
|
+
|
3
|
+
module Dude
|
4
|
+
module ProjectManagement
|
5
|
+
module Jira
|
6
|
+
class MoveTaskToList
|
7
|
+
include Settings
|
8
|
+
|
9
|
+
def initialize(client, id:, list_name:)
|
10
|
+
@client = client
|
11
|
+
@id = id
|
12
|
+
@list_name = list_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
issue = client.Issue.find(id)
|
17
|
+
available_transitions = client.Transition.all(:issue => issue)
|
18
|
+
|
19
|
+
transition_id = if list_name
|
20
|
+
available_transitions.find { |transition| transition.name == list_name }.id
|
21
|
+
else
|
22
|
+
select_list_for_moving(issue, available_transitions).id
|
23
|
+
end
|
24
|
+
|
25
|
+
transition = issue.transitions.build
|
26
|
+
transition.save!(transition: { id: transition_id })
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def select_list_for_moving(issuem, available_transitions)
|
32
|
+
puts "Please, select list for moving:".green.bold
|
33
|
+
|
34
|
+
available_transitions.each_with_index do |ea, index|
|
35
|
+
puts "#{index + 1}: #{ea.name.bold}"
|
36
|
+
end
|
37
|
+
|
38
|
+
print "\nList index: ".bold
|
39
|
+
list_index = STDIN.gets.chomp
|
40
|
+
available_transitions[list_index.to_i - 1]
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :client, :id, :list_name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|