dude-cli 0.5.5 → 0.6.2.pre.rc1
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/lib/dude.rb +0 -4
- data/lib/dude/cli.rb +69 -27
- data/lib/dude/git/checkout.rb +23 -0
- data/lib/dude/git/current_branch_name.rb +10 -0
- data/lib/dude/gitlab/add_spend_time.rb +36 -0
- data/lib/dude/gitlab/base.rb +38 -0
- data/lib/dude/gitlab/count_spend_time.rb +13 -0
- data/lib/dude/gitlab/estimate.rb +20 -0
- data/lib/dude/gitlab/get_issue_info.rb +9 -0
- data/lib/dude/gitlab/get_issue_time_spent.rb +9 -0
- data/lib/dude/gitlab/get_issue_title.rb +14 -0
- data/lib/dude/gitlab/get_my_issues.rb +31 -0
- data/lib/dude/gitlab/move_issue.rb +37 -0
- data/lib/dude/interface.rb +1 -1
- data/lib/dude/report.rb +2 -2
- data/lib/dude/service.rb +18 -0
- data/lib/dude/toggl.rb +2 -43
- data/lib/dude/toggl/base.rb +28 -0
- data/lib/dude/toggl/issue_spend_time.rb +59 -0
- data/lib/dude/toggl/report.rb +25 -0
- data/lib/dude/toggl/start_time_entry.rb +47 -0
- data/lib/dude/toggl/stop_time_entry.rb +28 -0
- data/lib/dude/version.rb +1 -1
- metadata +21 -6
- data/lib/dude/git.rb +0 -20
- data/lib/dude/gitlab.rb +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 112ffe56830a86b563b232d649eb7a5de9d3a253d29a742406f8a16e7b047f03
|
4
|
+
data.tar.gz: 7c81844112d211cfcfda8437df65b882c57fa0e4606ed0527e9381a4a53d790a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a3e922f36813889f24938a62a803ed1cc8465a9a73bd9976676071216571cc99c6d99fadc6102b75b392386d69cb0baaa2297ee3ad03732b34644c21ed9f627
|
7
|
+
data.tar.gz: 79819eb036ce14b9d62e7de8a1c0341e9323f31382fb0e14ab6e6c671458c8fc4ce4e0234d78a8b827908f0ebed8920264428fe3d15abf5e75720fa53ac37923
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dude-cli (0.
|
4
|
+
dude-cli (0.6.1)
|
5
5
|
colorize (~> 0.8)
|
6
6
|
git (~> 1.3)
|
7
7
|
gitlab (~> 4.3)
|
@@ -22,7 +22,7 @@ GEM
|
|
22
22
|
terminal-table
|
23
23
|
http-cookie (1.0.3)
|
24
24
|
domain_name (~> 0.5)
|
25
|
-
httparty (0.16.
|
25
|
+
httparty (0.16.2)
|
26
26
|
multi_xml (>= 0.5.2)
|
27
27
|
mime-types (3.1)
|
28
28
|
mime-types-data (~> 3.2015)
|
data/lib/dude.rb
CHANGED
data/lib/dude/cli.rb
CHANGED
@@ -1,11 +1,32 @@
|
|
1
1
|
require 'thor'
|
2
|
-
require "dude/version"
|
3
2
|
require 'colorize'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
require 'gitlab'
|
4
|
+
require 'git'
|
5
|
+
require 'rest_client'
|
6
|
+
|
7
|
+
require 'dude/service'
|
8
|
+
require 'dude/settings'
|
9
|
+
require 'dude/interface'
|
10
|
+
require 'dude/report'
|
11
|
+
require 'dude/version'
|
12
|
+
|
13
|
+
require 'dude/git/checkout'
|
14
|
+
require 'dude/git/current_branch_name'
|
15
|
+
|
16
|
+
require 'dude/gitlab/base'
|
17
|
+
require 'dude/gitlab/estimate'
|
18
|
+
require 'dude/gitlab/add_spend_time'
|
19
|
+
require 'dude/gitlab/get_issue_title'
|
20
|
+
require 'dude/gitlab/get_issue_info'
|
21
|
+
require 'dude/gitlab/move_issue'
|
22
|
+
require 'dude/gitlab/get_my_issues'
|
23
|
+
require 'dude/gitlab/count_spend_time'
|
24
|
+
|
25
|
+
require 'dude/toggl/base'
|
26
|
+
require 'dude/toggl/report'
|
27
|
+
require 'dude/toggl/issue_spend_time'
|
28
|
+
require 'dude/toggl/start_time_entry'
|
29
|
+
require 'dude/toggl/stop_time_entry'
|
9
30
|
|
10
31
|
module Dude
|
11
32
|
class CLI < Thor
|
@@ -24,9 +45,8 @@ module Dude
|
|
24
45
|
desc 'checkout [ISSUE_ID]', 'checkout to branch with name "ID-issue-title"'
|
25
46
|
def checkout(issue_id, project_title = folder_name)
|
26
47
|
issue_title = get_issue_title(issue_id, project_title)
|
27
|
-
branch_name =
|
28
|
-
|
29
|
-
puts "Branch changed to '#{branch_name}'".colorize(:green)
|
48
|
+
branch_name = branch_name_for_issue(issue_title, issue_id)
|
49
|
+
Dude::Git::Checkout.call(branch_name: branch_name)
|
30
50
|
end
|
31
51
|
|
32
52
|
desc 'start [ISSUE_ID]', 'do checkout, track and move actions'
|
@@ -39,43 +59,65 @@ module Dude
|
|
39
59
|
desc 'track [ISSUE_ID]', 'start task in Toggl with issue title'
|
40
60
|
def track(issue_id, project_title = folder_name)
|
41
61
|
issue_title = get_issue_title(issue_id, project_title)
|
42
|
-
Toggl.
|
43
|
-
|
62
|
+
Dude::Toggl::StartTimeEntry.call(
|
63
|
+
title: "#{issue_title} (##{issue_id})", project_title: project_title
|
64
|
+
)
|
44
65
|
end
|
45
66
|
|
46
67
|
desc 'tasks', 'Show issues in current project assigned to you'
|
47
68
|
def tasks(project_title = folder_name)
|
48
|
-
issues = Gitlab.
|
69
|
+
issues = Dude::Gitlab::GetMyIssues.call(project_title: project_title)
|
49
70
|
Interface.new.issues_list(issues)
|
50
71
|
end
|
51
72
|
|
52
73
|
desc 'estimate [DURATION] [ISSUE_ID]', 'estimate time'
|
53
74
|
def estimate(duration, issue_id = current_issue_id, project_title = folder_name)
|
54
|
-
Gitlab.
|
55
|
-
|
75
|
+
Dude::Gitlab::Estimate.call(issue_id: issue_id, project_title: project_title, duration: duration)
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'spend [ISSUE_ID]', 'spend time'
|
79
|
+
def spend(issue_id = current_issue_id, project_title = folder_name)
|
80
|
+
old_data = Dude::Gitlab::CountSpendTime.call(issue_id: issue_id, project_title: project_title)
|
81
|
+
new_data = Dude::Toggl::IssueSpendTime.call(issue_id: issue_id, project_title: project_title)
|
82
|
+
diff = new_data - old_data
|
83
|
+
Dude::Gitlab::AddSpendTime.call(duration: diff, issue_id: issue_id, project_title: project_title)
|
56
84
|
end
|
57
85
|
|
58
86
|
desc 'stop', 'stop current time entry in Toggl, move issue to `To Do`'
|
59
|
-
def stop(project_title = folder_name)
|
60
|
-
Toggl.
|
61
|
-
move('To Do',
|
62
|
-
|
87
|
+
def stop(issue_id = current_issue_id, project_title = folder_name)
|
88
|
+
Dude::Toggl::StopTimeEntry.call
|
89
|
+
move('To Do', issue_id, project_title)
|
90
|
+
spend(issue_id, project_title)
|
91
|
+
puts 'Work suspended'.colorize(:yellow)
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'finish', 'stop current time entry in Toggl, move issue to `To Verify`'
|
95
|
+
def finish(issue_id = current_issue_id, project_title = folder_name)
|
96
|
+
Dude::Toggl::StopTimeEntry.call
|
97
|
+
move('To Verify', issue_id, project_title)
|
98
|
+
spend(current_issue_id, project_title)
|
99
|
+
puts "Issue ##{current_issue_id} finished".colorize(:green)
|
63
100
|
end
|
64
101
|
|
65
|
-
desc 'issue', 'Information about issue'
|
102
|
+
desc 'issue [ISSUE_ID]', 'Information about issue'
|
66
103
|
def issue(issue_id = current_issue_id, project_title = folder_name)
|
67
|
-
Gitlab.
|
104
|
+
issue_info = Dude::Gitlab::GetIssueInfo.call(
|
105
|
+
issue_id: issue_id, project_title: project_title
|
106
|
+
)
|
107
|
+
Interface.new.draw_issue_info(issue_info)
|
68
108
|
end
|
69
109
|
|
70
110
|
desc 'stats', 'display your stats from Toggl'
|
71
111
|
def stats
|
72
|
-
Toggl.
|
112
|
+
report = Dude::Toggl::Report.call
|
113
|
+
Interface.new.draw_report(report)
|
73
114
|
end
|
74
115
|
|
75
|
-
desc 'move', 'move issue to another column'
|
116
|
+
desc 'move [LABEL] [ISSUE_ID]', 'move issue to another column'
|
76
117
|
def move(label, issue_id = current_issue_id, project_title = folder_name)
|
77
|
-
Gitlab.
|
78
|
-
|
118
|
+
Dude::Gitlab::MoveIssue.call(
|
119
|
+
issue_id: issue_id, project_title: project_title, label: label
|
120
|
+
)
|
79
121
|
end
|
80
122
|
|
81
123
|
desc 'version', 'Show version'
|
@@ -90,11 +132,11 @@ module Dude
|
|
90
132
|
end
|
91
133
|
|
92
134
|
def current_issue_id
|
93
|
-
Git.
|
135
|
+
Dude::Git::CurrentBranchName.call.chomp.split('-').first
|
94
136
|
end
|
95
137
|
|
96
138
|
def get_issue_title(issue_id, project_title)
|
97
|
-
Gitlab.
|
139
|
+
Dude::Gitlab::GetIssueTitle.call(issue_id: issue_id, project_title: project_title)
|
98
140
|
end
|
99
141
|
|
100
142
|
def duderc_file_content
|
@@ -107,7 +149,7 @@ module Dude
|
|
107
149
|
@folder_name ||= File.basename(Dir.getwd)
|
108
150
|
end
|
109
151
|
|
110
|
-
def
|
152
|
+
def branch_name_for_issue(issue_title, issue_id)
|
111
153
|
issue_title.downcase.gsub(/[^a-z0-9\-_]+/, '-').prepend("#{issue_id}-")
|
112
154
|
end
|
113
155
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Dude
|
2
|
+
module Git
|
3
|
+
class Checkout
|
4
|
+
include Service
|
5
|
+
def call
|
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
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Dude
|
2
|
+
module Gitlab
|
3
|
+
class AddSpendTime < Dude::Gitlab::Base
|
4
|
+
def call
|
5
|
+
if duration_exists?
|
6
|
+
add_spend_time
|
7
|
+
print_success_message
|
8
|
+
else
|
9
|
+
print_error_message
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_spend_time
|
14
|
+
::Gitlab.add_time_spent_on_issue(
|
15
|
+
project_id, options[:issue_id], "#{options[:duration]}s"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def duration_exists?
|
20
|
+
options[:duration] > 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def print_success_message
|
24
|
+
puts "Added #{formatted_time} to spent time"
|
25
|
+
end
|
26
|
+
|
27
|
+
def print_error_message
|
28
|
+
puts "Nothing to add".colorize(:yellow)
|
29
|
+
end
|
30
|
+
|
31
|
+
def formatted_time
|
32
|
+
Time.at(options[:duration]).utc.strftime('%H:%M:%S').to_s.colorize(:green)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Dude
|
2
|
+
module Gitlab
|
3
|
+
class Base
|
4
|
+
include Service
|
5
|
+
include Settings
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
configure_gitlab
|
10
|
+
end
|
11
|
+
|
12
|
+
def check_input_data
|
13
|
+
throw_error if options[:issue_id].to_i.zero? || !issue_exists?
|
14
|
+
end
|
15
|
+
|
16
|
+
def throw_error
|
17
|
+
Interface.new.throw_error(options[:issue_id], options[:project_title])
|
18
|
+
end
|
19
|
+
|
20
|
+
def issue_exists?
|
21
|
+
!::Gitlab.issue(project_id, options[:issue_id]).nil?
|
22
|
+
rescue StandardError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def project_id
|
27
|
+
@project_id ||= ::Gitlab.project_search(options[:project_title])[0]&.id
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_gitlab
|
31
|
+
::Gitlab.configure do |config|
|
32
|
+
config.endpoint = settings['GITLAB_ENDPOINT']
|
33
|
+
config.private_token = settings['GITLAB_TOKEN']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Dude
|
2
|
+
module Gitlab
|
3
|
+
class Estimate < Dude::Gitlab::Base
|
4
|
+
def call
|
5
|
+
check_input_data
|
6
|
+
estimate_time
|
7
|
+
end
|
8
|
+
|
9
|
+
def estimate_time
|
10
|
+
::Gitlab.estimate_time_of_issue(project_id, options[:issue_id], options[:duration])
|
11
|
+
Interface.new.draw_time_estimate(options[:duration])
|
12
|
+
end
|
13
|
+
|
14
|
+
# def human_time_estimate
|
15
|
+
# ::Gitlab.issue(project_id, options[:issue_id]).
|
16
|
+
# to_h['time_stats']['human_time_estimate']
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dude
|
2
|
+
module Gitlab
|
3
|
+
class GetMyIssues < Dude::Gitlab::Base
|
4
|
+
MAX_ISSUES_PER_PAGE = 300
|
5
|
+
|
6
|
+
def call
|
7
|
+
my_issues
|
8
|
+
end
|
9
|
+
|
10
|
+
def my_issues
|
11
|
+
all_issues_on_project.select {|a| a.last.eql?(user.id) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def all_issues_on_project
|
15
|
+
::Gitlab.issues(project_id, per_page: MAX_ISSUES_PER_PAGE).map do |a|
|
16
|
+
[a.iid, a.title, a.labels, assignees_id(a)]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def user
|
21
|
+
@user ||= ::Gitlab.user
|
22
|
+
end
|
23
|
+
|
24
|
+
def assignees_id(issue)
|
25
|
+
issue&.assignees&.first['id']
|
26
|
+
rescue NoMethodError
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Dude
|
2
|
+
module Gitlab
|
3
|
+
class MoveIssue < Dude::Gitlab::Base
|
4
|
+
DEFAULT_LABELS = ['To Do', 'Doing', 'To Verify'].freeze
|
5
|
+
|
6
|
+
def call
|
7
|
+
check_input_data
|
8
|
+
move_issue
|
9
|
+
print_message
|
10
|
+
end
|
11
|
+
|
12
|
+
def move_issue
|
13
|
+
::Gitlab.edit_issue(project_id, options[:issue_id], labels_options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def labels_options
|
17
|
+
{ labels: new_issue_labels }
|
18
|
+
end
|
19
|
+
|
20
|
+
def all_issue_labels
|
21
|
+
::Gitlab.issue(project_id, options[:issue_id]).labels
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_issue_labels
|
25
|
+
all_issue_labels.reject {|e| DEFAULT_LABELS.include?(e)}
|
26
|
+
end
|
27
|
+
|
28
|
+
def new_issue_labels
|
29
|
+
default_issue_labels.push(options[:label]).join(',')
|
30
|
+
end
|
31
|
+
|
32
|
+
def print_message
|
33
|
+
puts "Issue ##{options[:issue_id]} moved to '#{options[:label]}'".colorize(:green)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/dude/interface.rb
CHANGED
data/lib/dude/report.rb
CHANGED
data/lib/dude/service.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Dude
|
2
|
+
module Service
|
3
|
+
attr_reader :options
|
4
|
+
def initialize(options = {})
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.included(klass)
|
9
|
+
klass.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def call(options = {})
|
14
|
+
new(options).call
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/dude/toggl.rb
CHANGED
@@ -12,27 +12,11 @@ module Dude
|
|
12
12
|
@options = options
|
13
13
|
end
|
14
14
|
|
15
|
-
def report
|
16
|
-
report = Report.new(toggl_report.get params: report_params)
|
17
|
-
Interface.new.draw_report(report)
|
18
|
-
end
|
19
|
-
|
20
|
-
def start_time_entry
|
21
|
-
toggl_api['time_entries/start'].post time_entry_params(options[:title]).to_json, content_type: :json
|
22
|
-
end
|
23
15
|
|
24
16
|
def stop_current_time_entry
|
25
17
|
toggl_api["time_entries/#{current_time_entry['id']}/stop"].put ''
|
26
|
-
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def report_params
|
31
|
-
{
|
32
|
-
workspace_id: settings['TOGGL_WORKSPACE_ID'],
|
33
|
-
user_agent: settings['TOGGL_EMAIL'],
|
34
|
-
since: Date.parse('monday').strftime('%Y-%m-%d')
|
35
|
-
}
|
18
|
+
rescue NoMethodError
|
19
|
+
puts 'No runned time entries in Toggl'.colorize(:yellow)
|
36
20
|
end
|
37
21
|
|
38
22
|
def time_entry_params(title)
|
@@ -45,23 +29,6 @@ module Dude
|
|
45
29
|
}
|
46
30
|
end
|
47
31
|
|
48
|
-
def project_id
|
49
|
-
projects_array.each do |arr|
|
50
|
-
return arr.last if arr.first.eql?(options[:project_title])
|
51
|
-
end
|
52
|
-
nil
|
53
|
-
end
|
54
|
-
|
55
|
-
def current_time_entry
|
56
|
-
JSON.parse(toggl_api['time_entries/current'].get)['data']
|
57
|
-
end
|
58
|
-
|
59
|
-
def projects_array
|
60
|
-
JSON.parse(
|
61
|
-
toggl_api["workspaces/#{settings['TOGGL_WORKSPACE_ID']}/projects"].get
|
62
|
-
).map { |a| [a['name'].downcase.gsub(/\s/, '-'), a['id']] }
|
63
|
-
end
|
64
|
-
|
65
32
|
def toggl_api
|
66
33
|
@toggl_api ||= RestClient::Resource.new(
|
67
34
|
'https://www.toggl.com/api/v8',
|
@@ -69,13 +36,5 @@ module Dude
|
|
69
36
|
'api_token'
|
70
37
|
)
|
71
38
|
end
|
72
|
-
|
73
|
-
def toggl_report
|
74
|
-
@toggl_report ||= RestClient::Resource.new(
|
75
|
-
'https://www.toggl.com/reports/api/v2/weekly',
|
76
|
-
settings['TOGGL_TOKEN'],
|
77
|
-
'api_token'
|
78
|
-
)
|
79
|
-
end
|
80
39
|
end
|
81
40
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dude
|
2
|
+
module Toggl
|
3
|
+
class Base
|
4
|
+
include Service
|
5
|
+
include Settings
|
6
|
+
|
7
|
+
def toggl_api
|
8
|
+
@toggl_api ||= RestClient::Resource.new(
|
9
|
+
'https://www.toggl.com/api/v8',
|
10
|
+
settings['TOGGL_TOKEN'],
|
11
|
+
'api_token'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def toggl_report
|
16
|
+
@toggl_report ||= RestClient::Resource.new(
|
17
|
+
'https://www.toggl.com/reports/api/v2/weekly',
|
18
|
+
settings['TOGGL_TOKEN'],
|
19
|
+
'api_token'
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def projects_response
|
24
|
+
toggl_api["workspaces/#{settings['TOGGL_WORKSPACE_ID']}/projects"].get
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Dude
|
2
|
+
module Toggl
|
3
|
+
class IssueSpendTime < Dude::Toggl::Base
|
4
|
+
def call
|
5
|
+
parse_time_entries_list
|
6
|
+
end
|
7
|
+
|
8
|
+
def params
|
9
|
+
{
|
10
|
+
workspace_id: settings['TOGGL_WORKSPACE_ID'],
|
11
|
+
user_agent: settings['TOGGL_EMAIL'],
|
12
|
+
start_date: '2013-03-10T15:42:46+02:00'
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
toggl_api['time_entries'].get params
|
18
|
+
end
|
19
|
+
|
20
|
+
def time_entries
|
21
|
+
JSON.parse(response.body)
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_issue_time_entries
|
25
|
+
time_entries.select { |entry| match_project_id?(entry) && match_issue_id?(entry) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def match_project_id?(time_entry)
|
29
|
+
time_entry['pid'].eql? project_id
|
30
|
+
end
|
31
|
+
|
32
|
+
def match_issue_id?(time_entry)
|
33
|
+
# TODO: Deprecated behaviour
|
34
|
+
time_entry['description'].match?(/\(##{options[:issue_id]}\)/) ||
|
35
|
+
time_entry['description'].match?(/##{options[:issue_id]}\s/)
|
36
|
+
end
|
37
|
+
|
38
|
+
def formatted_time_entries
|
39
|
+
current_issue_time_entries.map {|a| [a['description'], a['duration']]}
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_time_entries_list
|
43
|
+
current_issue_time_entries.map {|a| a['duration'] }.sum
|
44
|
+
end
|
45
|
+
|
46
|
+
def project_id
|
47
|
+
# TODO: Concretize project selection
|
48
|
+
@project_id ||= projects_array.find do |title, id|
|
49
|
+
title.eql?(options[:project_title])
|
50
|
+
end.last
|
51
|
+
end
|
52
|
+
|
53
|
+
def projects_array
|
54
|
+
JSON.parse(projects_response)
|
55
|
+
.map { |a| [a['name'].downcase.gsub(/\s/, '-'), a['id']] }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Dude
|
2
|
+
module Toggl
|
3
|
+
class Report < Dude::Toggl::Base
|
4
|
+
def call
|
5
|
+
Dude::Report.new(parsed_response)
|
6
|
+
end
|
7
|
+
|
8
|
+
def response
|
9
|
+
toggl_report.get params: params
|
10
|
+
end
|
11
|
+
|
12
|
+
def params
|
13
|
+
{
|
14
|
+
workspace_id: settings['TOGGL_WORKSPACE_ID'],
|
15
|
+
user_agent: settings['TOGGL_EMAIL'],
|
16
|
+
since: Date.parse('monday').strftime('%Y-%m-%d')
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def parsed_response
|
21
|
+
@parsed_response = JSON.parse(response.body)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Dude
|
2
|
+
module Toggl
|
3
|
+
class StartTimeEntry < Dude::Toggl::Base
|
4
|
+
|
5
|
+
def call
|
6
|
+
start_time_entry
|
7
|
+
print_message
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_time_entry
|
11
|
+
toggl_api['time_entries/start'].post(
|
12
|
+
time_entry_params(options[:title]),
|
13
|
+
content_type: :json
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def time_entry_params(title)
|
18
|
+
{
|
19
|
+
time_entry: {
|
20
|
+
description: title,
|
21
|
+
pid: project_id,
|
22
|
+
created_with: 'dude'
|
23
|
+
}
|
24
|
+
}.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
def project_id
|
28
|
+
projects_array.each do |arr|
|
29
|
+
return arr.last if arr.first.eql?(options[:project_title])
|
30
|
+
end
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def projects_array
|
35
|
+
parsed_response.map { |a| [a['name'].downcase.gsub(/\s/, '-'), a['id']] }
|
36
|
+
end
|
37
|
+
|
38
|
+
def parsed_response
|
39
|
+
JSON.parse(projects_response)
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_message
|
43
|
+
puts "Toggl task '#{options[:title]}' is started".colorize(:green)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dude
|
2
|
+
module Toggl
|
3
|
+
class StopTimeEntry < Dude::Toggl::Base
|
4
|
+
def call
|
5
|
+
stop_current_time_entry
|
6
|
+
print_success_message
|
7
|
+
rescue NoMethodError
|
8
|
+
print_error_message
|
9
|
+
end
|
10
|
+
|
11
|
+
def stop_current_time_entry
|
12
|
+
toggl_api["time_entries/#{current_time_entry['id']}/stop"].put ''
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_time_entry
|
16
|
+
JSON.parse(toggl_api['time_entries/current'].get)['data']
|
17
|
+
end
|
18
|
+
|
19
|
+
def print_success_message
|
20
|
+
puts 'Suspended current time entry in Toggl'.colorize(:green)
|
21
|
+
end
|
22
|
+
|
23
|
+
def print_error_message
|
24
|
+
puts 'No runned time entries in Toggl'.colorize(:yellow)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/dude/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dude-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.2.pre.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Pupko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -159,12 +159,27 @@ files:
|
|
159
159
|
- dude.gemspec
|
160
160
|
- lib/dude.rb
|
161
161
|
- lib/dude/cli.rb
|
162
|
-
- lib/dude/git.rb
|
163
|
-
- lib/dude/
|
162
|
+
- lib/dude/git/checkout.rb
|
163
|
+
- lib/dude/git/current_branch_name.rb
|
164
|
+
- lib/dude/gitlab/add_spend_time.rb
|
165
|
+
- lib/dude/gitlab/base.rb
|
166
|
+
- lib/dude/gitlab/count_spend_time.rb
|
167
|
+
- lib/dude/gitlab/estimate.rb
|
168
|
+
- lib/dude/gitlab/get_issue_info.rb
|
169
|
+
- lib/dude/gitlab/get_issue_time_spent.rb
|
170
|
+
- lib/dude/gitlab/get_issue_title.rb
|
171
|
+
- lib/dude/gitlab/get_my_issues.rb
|
172
|
+
- lib/dude/gitlab/move_issue.rb
|
164
173
|
- lib/dude/interface.rb
|
165
174
|
- lib/dude/report.rb
|
175
|
+
- lib/dude/service.rb
|
166
176
|
- lib/dude/settings.rb
|
167
177
|
- lib/dude/toggl.rb
|
178
|
+
- lib/dude/toggl/base.rb
|
179
|
+
- lib/dude/toggl/issue_spend_time.rb
|
180
|
+
- lib/dude/toggl/report.rb
|
181
|
+
- lib/dude/toggl/start_time_entry.rb
|
182
|
+
- lib/dude/toggl/stop_time_entry.rb
|
168
183
|
- lib/dude/version.rb
|
169
184
|
homepage: https://github.com/Random4405/dude
|
170
185
|
licenses:
|
@@ -181,9 +196,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
181
196
|
version: 2.2.0
|
182
197
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
198
|
requirements:
|
184
|
-
- - "
|
199
|
+
- - ">"
|
185
200
|
- !ruby/object:Gem::Version
|
186
|
-
version:
|
201
|
+
version: 1.3.1
|
187
202
|
requirements: []
|
188
203
|
rubyforge_project:
|
189
204
|
rubygems_version: 2.7.3
|
data/lib/dude/git.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'git'
|
2
|
-
|
3
|
-
module Dude
|
4
|
-
class Git
|
5
|
-
attr_accessor :options
|
6
|
-
|
7
|
-
def initialize(options = {})
|
8
|
-
@options = options
|
9
|
-
@git = ::Git.init
|
10
|
-
end
|
11
|
-
|
12
|
-
def call
|
13
|
-
@git.branch(options[:branch_name]).checkout if options[:branch_name]
|
14
|
-
end
|
15
|
-
|
16
|
-
def current_branch_name
|
17
|
-
%x(git rev-parse --abbrev-ref HEAD)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/dude/gitlab.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'gitlab'
|
2
|
-
require 'colorize'
|
3
|
-
require_relative 'settings'
|
4
|
-
require_relative 'interface'
|
5
|
-
|
6
|
-
module Dude
|
7
|
-
class Gitlab
|
8
|
-
include Dude::Settings
|
9
|
-
attr_accessor :options
|
10
|
-
|
11
|
-
def initialize(options = {})
|
12
|
-
@options = options
|
13
|
-
::Gitlab.configure do |config|
|
14
|
-
config.endpoint = settings['GITLAB_ENDPOINT']
|
15
|
-
config.private_token = settings['GITLAB_TOKEN']
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def issue_title
|
20
|
-
test_input_data
|
21
|
-
::Gitlab.issue(project_id, options[:issue_id]).title
|
22
|
-
end
|
23
|
-
|
24
|
-
def my_issues
|
25
|
-
all_issues_on_project.select {|a| a.last.eql?(user.id) }
|
26
|
-
end
|
27
|
-
|
28
|
-
def estimate_time(duration)
|
29
|
-
test_input_data
|
30
|
-
::Gitlab.estimate_time_of_issue(project_id, options[:issue_id], duration)
|
31
|
-
time = ::Gitlab.issue(project_id, options[:issue_id]).
|
32
|
-
to_h['time_stats']['human_time_estimate']
|
33
|
-
Interface.new.draw_time_estimate(time)
|
34
|
-
end
|
35
|
-
|
36
|
-
def issue_info
|
37
|
-
test_input_data
|
38
|
-
issue_info = ::Gitlab.issue(project_id, options[:issue_id]).to_h
|
39
|
-
Interface.new.draw_issue_info(issue_info)
|
40
|
-
end
|
41
|
-
|
42
|
-
def move_issue
|
43
|
-
test_input_data
|
44
|
-
labels = ::Gitlab.issue(project_id, options[:issue_id]).labels
|
45
|
-
labels = labels.reject {|e| ['To Do', 'Doing', 'To Verify'].include?(e)}.
|
46
|
-
push(options[:label]).join(',')
|
47
|
-
::Gitlab.edit_issue(project_id, options[:issue_id], { labels: labels })
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def test_input_data
|
53
|
-
if options[:issue_id].to_i.zero? || !issue_exists?
|
54
|
-
Interface.new.throw_error(options[:issue_id], options[:project_title])
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def issue_exists?
|
59
|
-
!::Gitlab.issue(project_id, options[:issue_id]).nil?
|
60
|
-
rescue
|
61
|
-
nil
|
62
|
-
end
|
63
|
-
|
64
|
-
def all_issues_on_project
|
65
|
-
::Gitlab.issues(project_id).map {|a| [a.iid, a.title, a.labels, assignees_id(a)]}
|
66
|
-
end
|
67
|
-
|
68
|
-
def assignees_id(issue)
|
69
|
-
issue&.assignees&.first['id']
|
70
|
-
rescue NoMethodError
|
71
|
-
nil
|
72
|
-
end
|
73
|
-
|
74
|
-
def user
|
75
|
-
@my_id ||= ::Gitlab.user
|
76
|
-
end
|
77
|
-
|
78
|
-
def project_id
|
79
|
-
@project_id ||= ::Gitlab.project_search(options[:project_title])[0]&.id
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|