toolshed 0.0.5 → 0.0.6
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/.travis.yml +14 -0
- data/Rakefile +11 -0
- data/bin/toolshed.rb +95 -16
- data/lib/toolshed/base.rb +7 -0
- data/lib/toolshed/cli.rb +13 -6
- data/lib/toolshed/client.rb +105 -83
- data/lib/toolshed/commands/checkout_branch.rb +26 -0
- data/lib/toolshed/commands/create_branch.rb +60 -0
- data/lib/toolshed/commands/create_pivotal_tracker_note.rb +9 -4
- data/lib/toolshed/commands/create_pull_request.rb +137 -0
- data/lib/toolshed/commands/delete_branch.rb +27 -0
- data/lib/toolshed/commands/get_daily_time_update.rb +21 -0
- data/lib/toolshed/commands/get_pivotal_tracker_story_information.rb +6 -3
- data/lib/toolshed/commands/list_branches.rb +13 -0
- data/lib/toolshed/commands/push_branch.rb +11 -0
- data/lib/toolshed/commands/update_pivotal_tracker_story_status.rb +8 -5
- data/lib/toolshed/git/git.rb +134 -0
- data/lib/toolshed/git/github.rb +88 -0
- data/lib/toolshed/ticket_tracking/pivotal_tracker.rb +111 -0
- data/lib/toolshed/ticket_tracking/ticket_tracking.rb +6 -0
- data/lib/toolshed/time_tracking/harvest.rb +68 -0
- data/lib/toolshed/time_tracking/time_tracking.rb +6 -0
- data/lib/toolshed/version.rb +1 -1
- data/lib/toolshed.rb +8 -2
- data/test/commands/checkout_branch_test.rb +28 -0
- data/test/commands/commands_helper.rb +2 -0
- data/test/commands/create_branch_test.rb +44 -0
- data/test/commands/create_pull_request_test.rb +125 -0
- data/test/commands/delete_branch_test.rb +75 -0
- data/test/commands/push_branch_test.rb +49 -0
- data/test/config.rb +1 -0
- data/test/git/git_helper.rb +31 -0
- data/test/git/git_test.rb +115 -0
- data/test/git/github_test.rb +91 -0
- data/test/helper.rb +98 -0
- data/toolshed.gemspec +8 -0
- metadata +151 -9
- data/lib/toolshed/commands/checkout_git_branch.rb +0 -23
- data/lib/toolshed/commands/create_git_branch.rb +0 -28
- data/lib/toolshed/commands/create_github_pull_request.rb +0 -77
- data/lib/toolshed/commands/push_git_branch.rb +0 -10
- data/lib/toolshed/github.rb +0 -89
- data/lib/toolshed/pivotal_tracker.rb +0 -87
@@ -0,0 +1,137 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module Commands
|
3
|
+
class CreatePullRequest
|
4
|
+
def execute(args, options = {})
|
5
|
+
# see what branch is checked out and where we are branched from
|
6
|
+
puts "Current Branch: #{Toolshed::Git::Base.branch_name}"
|
7
|
+
puts "Branched From: #{Toolshed::Git::Base.branched_from}"
|
8
|
+
puts "Using Defaults: #{(Toolshed::Client.use_defaults.nil?) ? 'No' : 'Yes'}"
|
9
|
+
|
10
|
+
unless (Toolshed::Client.ticket_tracking_tool.empty?)
|
11
|
+
ticket_tracking_url = ''
|
12
|
+
ticket_tracking_title = ''
|
13
|
+
ticket_id = ''
|
14
|
+
|
15
|
+
begin
|
16
|
+
ticket_tracker_class = Object.const_get("Toolshed::TicketTracking::#{Toolshed::Client.ticket_tracking_tool.camel_case}")
|
17
|
+
|
18
|
+
if Object.const_get("#{ticket_tracker_class}::USE_PROJECT_ID")
|
19
|
+
ticket_tracker_project_id = read_user_input_ticket_tracker_project_id("Project ID (Default: #{Toolshed::Client.default_pivotal_tracker_project_id}):", { default: Toolshed::Client.default_pivotal_tracker_project_id })
|
20
|
+
options.merge!({ project_id: ticket_tracker_project_id })
|
21
|
+
end
|
22
|
+
|
23
|
+
ticket_tracker = ticket_tracker_class.create_instance(options)
|
24
|
+
|
25
|
+
# @TODO - refactor this code into the git module seems more appropriate since it's performing git functions
|
26
|
+
ticket_id = read_user_input_ticket_tracker_ticket_id("Ticket ID (Default: #{Toolshed::TicketTracking::PivotalTracker::story_id_from_branch_name(Toolshed::Git::Base.branch_name)}):", { default: Toolshed::TicketTracking::PivotalTracker::story_id_from_branch_name(Toolshed::Git::Base.branch_name) })
|
27
|
+
ticket_information = ticket_tracker.story_information(ticket_id)
|
28
|
+
|
29
|
+
ticket_tracking_url = ticket_information.url
|
30
|
+
ticket_tracking_title = ticket_tracker_class.clean(ticket_information.name)
|
31
|
+
ticket_id = ticket_information.id
|
32
|
+
|
33
|
+
puts "Ticket Tracking URL: #{ticket_tracking_url}"
|
34
|
+
puts "Ticket Tracking title: #{ticket_tracking_title}"
|
35
|
+
puts "Ticket ID: #{ticket_id}"
|
36
|
+
rescue
|
37
|
+
puts "Ticket tracking tool is not supported at this time"
|
38
|
+
return
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
pull_request_url = ''
|
43
|
+
begin
|
44
|
+
git_tool_class = Object.const_get("Toolshed::Git::#{Toolshed::Client.git_tool.camel_case}")
|
45
|
+
git_tool = git_tool_class.create_instance
|
46
|
+
|
47
|
+
# create the pull request prompt when needed
|
48
|
+
title = read_user_input_pull_request_title("Pull request title (Default: #{ticket_tracking_title}):", options.merge!({ :default => ticket_tracking_title }))
|
49
|
+
body = read_user_input_pull_request_body("Pull request body (Default: #{ticket_tracking_url}):", options.merge!({ :default => ticket_tracking_url }))
|
50
|
+
|
51
|
+
puts "Pull request being created"
|
52
|
+
git_pull_request_result = git_tool.create_pull_request(title, body)
|
53
|
+
pull_request_url = git_pull_request_result["html_url"]
|
54
|
+
|
55
|
+
add_note_to_ticket = read_user_input_add_note_to_ticket("Would you like to add a note with the pull request url?")
|
56
|
+
if (add_note_to_ticket)
|
57
|
+
result = ticket_tracker.add_note(ticket_id, pull_request_url)
|
58
|
+
result = ticket_tracker.update_ticket_status(ticket_id, Object.const_get("#{ticket_tracker_class}::DEFAULT_COMPLETED_STATUS"))
|
59
|
+
end
|
60
|
+
|
61
|
+
puts "Created Pull Request: #{pull_request_url}"
|
62
|
+
rescue => e
|
63
|
+
puts e.message
|
64
|
+
exit
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def read_user_input_add_note_to_ticket(message)
|
69
|
+
return true if (Toolshed::Client.use_defaults)
|
70
|
+
|
71
|
+
puts message
|
72
|
+
value = $stdin.gets.chomp
|
73
|
+
|
74
|
+
until (%w(y n).include?(value.downcase))
|
75
|
+
puts "Value must be Y or N"
|
76
|
+
puts message
|
77
|
+
value = $stdin.gets.chomp
|
78
|
+
end
|
79
|
+
|
80
|
+
(value == 'y') ? true : false
|
81
|
+
end
|
82
|
+
|
83
|
+
def read_user_input_pull_request_title(message, options)
|
84
|
+
return options[:title] if (options.has_key?(:title))
|
85
|
+
return options[:default] if (Toolshed::Client.use_defaults)
|
86
|
+
|
87
|
+
puts message
|
88
|
+
value = $stdin.gets.chomp
|
89
|
+
if (value.empty?)
|
90
|
+
value = default
|
91
|
+
end
|
92
|
+
|
93
|
+
value
|
94
|
+
end
|
95
|
+
|
96
|
+
def read_user_input_pull_request_body(message, options)
|
97
|
+
return options[:body] if (options.has_key?(:body))
|
98
|
+
return options[:default] if (Toolshed::Client.use_defaults)
|
99
|
+
|
100
|
+
puts message
|
101
|
+
value = $stdin.gets.chomp
|
102
|
+
|
103
|
+
if (value.empty?)
|
104
|
+
value = default
|
105
|
+
end
|
106
|
+
|
107
|
+
value
|
108
|
+
end
|
109
|
+
|
110
|
+
def read_user_input_ticket_tracker_project_id(message, options)
|
111
|
+
return options[:default] if (Toolshed::Client.use_defaults)
|
112
|
+
|
113
|
+
puts message
|
114
|
+
value = $stdin.gets.chomp
|
115
|
+
|
116
|
+
if (value.empty?)
|
117
|
+
value = default
|
118
|
+
end
|
119
|
+
|
120
|
+
value
|
121
|
+
end
|
122
|
+
|
123
|
+
def read_user_input_ticket_tracker_ticket_id(message, options)
|
124
|
+
return options[:default] if (Toolshed::Client.use_defaults)
|
125
|
+
|
126
|
+
puts message
|
127
|
+
value = $stdin.gets.chomp
|
128
|
+
|
129
|
+
if (value.empty?)
|
130
|
+
value = default
|
131
|
+
end
|
132
|
+
|
133
|
+
value
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module Commands
|
3
|
+
class DeleteBranch
|
4
|
+
def execute(args, options = {})
|
5
|
+
branch_name = read_user_input("Ticket ID or branch name:", options)
|
6
|
+
branch_name = Toolshed::Git::Base.delete(branch_name)
|
7
|
+
puts "#{branch_name} has been deleted"
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
def read_user_input(message, options)
|
12
|
+
return options[:branch_name] if (options.has_key?(:branch_name))
|
13
|
+
|
14
|
+
puts message
|
15
|
+
value = $stdin.gets.chomp
|
16
|
+
|
17
|
+
until (!value.empty?)
|
18
|
+
puts "Branch name cannot be empty"
|
19
|
+
puts message
|
20
|
+
value = $stdin.gets.chomp
|
21
|
+
end
|
22
|
+
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module Commands
|
3
|
+
class GetDailyTimeUpdate
|
4
|
+
def execute(args, options = {})
|
5
|
+
if (Toolshed::Client.time_tracking_tool == 'harvest')
|
6
|
+
harvest = Toolshed::TimeTracking::Harvest.new
|
7
|
+
|
8
|
+
puts "Getting time entries:"
|
9
|
+
|
10
|
+
notes = harvest.previous
|
11
|
+
notes = "#{notes}\n\n#{harvest.today}"
|
12
|
+
|
13
|
+
puts notes
|
14
|
+
else
|
15
|
+
puts "Time tracking tool is undefined implementation needed"
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -9,10 +9,13 @@ module Toolshed
|
|
9
9
|
project_id = Toolshed::Client.default_pivotal_tracker_project_id
|
10
10
|
end
|
11
11
|
|
12
|
-
pivotal_tracker = Toolshed::PivotalTracker.new({
|
13
|
-
|
12
|
+
pivotal_tracker = Toolshed::TicketTracking::PivotalTracker.new({
|
13
|
+
project_id: project_id,
|
14
|
+
username: Toolshed::TicketTracking::PivotalTracker.username,
|
15
|
+
password: Toolshed::TicketTracking::PivotalTracker.password,
|
16
|
+
})
|
14
17
|
|
15
|
-
default_story_id = Toolshed::PivotalTracker::story_id_from_branch_name(
|
18
|
+
default_story_id = Toolshed::TicketTracking::PivotalTracker::story_id_from_branch_name(Toolshed::Git::Base.branch_name)
|
16
19
|
print "Story ID (Default: #{default_story_id})? "
|
17
20
|
story_id = $stdin.gets.chomp.strip
|
18
21
|
if (story_id == '')
|
@@ -10,20 +10,23 @@ module Toolshed
|
|
10
10
|
project_id = Toolshed::Client.default_pivotal_tracker_project_id
|
11
11
|
end
|
12
12
|
|
13
|
-
pivotal_tracker = Toolshed::PivotalTracker.new({
|
14
|
-
|
13
|
+
pivotal_tracker = Toolshed::TicketTracking::PivotalTracker.new({
|
14
|
+
project_id: project_id,
|
15
|
+
username: Toolshed::TicketTracking::PivotalTracker.username,
|
16
|
+
password: Toolshed::TicketTracking::PivotalTracker.password,
|
17
|
+
})
|
15
18
|
|
16
|
-
default_story_id = Toolshed::PivotalTracker::story_id_from_branch_name(
|
19
|
+
default_story_id = Toolshed::TicketTracking::PivotalTracker::story_id_from_branch_name(Toolshed::Git::Base.branch_name)
|
17
20
|
print "Story ID (Default: #{default_story_id})? "
|
18
21
|
story_id = $stdin.gets.chomp.strip
|
19
22
|
if (story_id == '')
|
20
23
|
story_id = default_story_id
|
21
24
|
end
|
22
25
|
|
23
|
-
print "Status (Default: #{Toolshed::PivotalTracker::STORY_STATUS_DEFAULT})? "
|
26
|
+
print "Status (Default: #{Toolshed::TicketTracking::PivotalTracker::STORY_STATUS_DEFAULT})? "
|
24
27
|
story_status = $stdin.gets.chomp.strip
|
25
28
|
if (story_status == '')
|
26
|
-
story_status = Toolshed::PivotalTracker::STORY_STATUS_DEFAULT
|
29
|
+
story_status = Toolshed::TicketTracking::PivotalTracker::STORY_STATUS_DEFAULT
|
27
30
|
end
|
28
31
|
|
29
32
|
begin
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module Git
|
3
|
+
DEFAULT_GIT_TOOL = 'github'
|
4
|
+
|
5
|
+
def branch_name
|
6
|
+
# branch information
|
7
|
+
branch_name = `git rev-parse --abbrev-ref HEAD`.strip
|
8
|
+
end
|
9
|
+
|
10
|
+
def branched_from
|
11
|
+
branched_from = `git rev-parse --abbrev-ref --symbolic-full-name @{u}`.split('/')[-1].strip
|
12
|
+
end
|
13
|
+
|
14
|
+
def branch_name_from_id(id)
|
15
|
+
branch_name = `git branch | grep \"#{id}\"`.gsub("*", "").strip
|
16
|
+
end
|
17
|
+
|
18
|
+
def checkout(branch_name)
|
19
|
+
branch_name = Toolshed::Git::Base.branch_name_from_id(branch_name)
|
20
|
+
until system("git checkout #{branch_name} #{Toolshed::Client.git_quiet}")
|
21
|
+
sleep 1
|
22
|
+
end
|
23
|
+
|
24
|
+
unless (Toolshed::Git::Base.git_submodule_command.empty?)
|
25
|
+
until system(Toolshed::Git::Base.git_submodule_command)
|
26
|
+
sleep 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
branch_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(branch_name)
|
34
|
+
branch_name = Toolshed::Git::Base.branch_name_from_id(branch_name)
|
35
|
+
|
36
|
+
# if delete your current branch checkout master so it can be deleted
|
37
|
+
if (branch_name == Toolshed::Git::Base.branch_name)
|
38
|
+
Toolshed::Git::Base.checkout('master')
|
39
|
+
end
|
40
|
+
|
41
|
+
until system("git push #{Toolshed::Client.push_to_remote_name} :#{branch_name}; git branch -D #{branch_name}")
|
42
|
+
sleep 1
|
43
|
+
end
|
44
|
+
|
45
|
+
branch_name
|
46
|
+
end
|
47
|
+
|
48
|
+
def git_submodule_command
|
49
|
+
git_submodule_command = ''
|
50
|
+
if (Toolshed::Client.use_git_submodules)
|
51
|
+
git_submodule_command = "git submodule update #{Toolshed::Client.git_quiet}"
|
52
|
+
end
|
53
|
+
|
54
|
+
git_submodule_command
|
55
|
+
end
|
56
|
+
|
57
|
+
def clean_branch_name(branch_name)
|
58
|
+
branch_name.strip.downcase.tr(" ", "_").gsub("-", "").gsub("&", "").gsub("/", "_").gsub(".", "_").gsub("'", "").gsub("__", "_").gsub(":", "")
|
59
|
+
end
|
60
|
+
|
61
|
+
def push(options = {})
|
62
|
+
branch_name = (options.has_key?(:branch_name)) ? Toolshed::Git::Base.branch_name_from_id(options[:branch_name]) : Toolshed::Git::Base.branch_name
|
63
|
+
force_command = (options.has_key?(:force_command)) ? '--force' : ''
|
64
|
+
|
65
|
+
until system("git push #{Toolshed::Client.push_to_remote_name} #{branch_name} #{force_command}")
|
66
|
+
sleep 1
|
67
|
+
end
|
68
|
+
|
69
|
+
branch_name
|
70
|
+
end
|
71
|
+
|
72
|
+
class GitValidator
|
73
|
+
include Veto.validator
|
74
|
+
|
75
|
+
validates :from_remote_name, :presence => true
|
76
|
+
validates :from_remote_branch_name, :presence => true
|
77
|
+
validates :to_remote_name, :presence => true
|
78
|
+
validates :to_remote_branch_name, :presence => true
|
79
|
+
end
|
80
|
+
|
81
|
+
class Base
|
82
|
+
extend Toolshed::Git
|
83
|
+
|
84
|
+
attr_accessor :from_remote_name, :from_remote_branch_name, :to_remote_name, :to_remote_branch_name, :validator
|
85
|
+
|
86
|
+
def initialize(options={})
|
87
|
+
# options with defaults
|
88
|
+
self.from_remote_name = Toolshed::Client.pull_from_remote_name
|
89
|
+
unless (options[:from_remote_name].nil?)
|
90
|
+
self.from_remote_name = options[:from_remote_name]
|
91
|
+
end
|
92
|
+
|
93
|
+
self.to_remote_name = Toolshed::Client.push_to_remote_name
|
94
|
+
unless (options[:to_remote_name].nil?)
|
95
|
+
self.to_remote_name = options[:to_remote_name]
|
96
|
+
end
|
97
|
+
|
98
|
+
# options that do not have a default
|
99
|
+
unless (options[:from_remote_branch_name].nil?)
|
100
|
+
self.from_remote_branch_name = options[:from_remote_branch_name]
|
101
|
+
end
|
102
|
+
|
103
|
+
unless (options[:to_remote_branch_name].nil?)
|
104
|
+
self.to_remote_branch_name = options[:to_remote_branch_name]
|
105
|
+
end
|
106
|
+
|
107
|
+
self.validator = ::Toolshed::Git::GitValidator.new
|
108
|
+
end
|
109
|
+
|
110
|
+
def create_branch
|
111
|
+
self.validator.validate!(self)
|
112
|
+
|
113
|
+
new_branch_name = Toolshed::Git::Base.clean_branch_name(self.to_remote_branch_name)
|
114
|
+
until system("git remote update #{Toolshed::Client.git_quiet}")
|
115
|
+
sleep 1
|
116
|
+
end
|
117
|
+
|
118
|
+
until system("git checkout -b #{new_branch_name} #{self.from_remote_name}/#{self.from_remote_branch_name} #{Toolshed::Client.git_quiet}")
|
119
|
+
sleep 1
|
120
|
+
end
|
121
|
+
|
122
|
+
unless (Toolshed::Git::Base.git_submodule_command.empty?)
|
123
|
+
until system(Toolshed::Git::Base.git_submodule_command)
|
124
|
+
sleep 1
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
until system("git push #{self.to_remote_name} #{new_branch_name} #{Toolshed::Client.git_quiet}")
|
129
|
+
sleep 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module Git
|
3
|
+
class Github < Base
|
4
|
+
extend Toolshed::Git
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
attr_accessor :default_options
|
8
|
+
|
9
|
+
def initialize(options={})
|
10
|
+
super(options)
|
11
|
+
|
12
|
+
username = Toolshed::Client::github_username
|
13
|
+
password = Toolshed::Client::github_password
|
14
|
+
|
15
|
+
unless (options[:username].nil?)
|
16
|
+
username = options[:username]
|
17
|
+
end
|
18
|
+
|
19
|
+
unless (options[:password].nil?)
|
20
|
+
password = options[:password]
|
21
|
+
end
|
22
|
+
|
23
|
+
@auth = { username: username, password: password }
|
24
|
+
self.default_options = {
|
25
|
+
:headers => {
|
26
|
+
"User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1309.0 Safari/537.17"
|
27
|
+
},
|
28
|
+
basic_auth: @auth,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_pull_request(title, body, options={})
|
33
|
+
options.merge!(self.default_options)
|
34
|
+
options.merge!({
|
35
|
+
body: {
|
36
|
+
title: title,
|
37
|
+
body: body,
|
38
|
+
head: "#{Toolshed::Client.github_username}:#{Toolshed::Git::Base.branch_name}",
|
39
|
+
base: Toolshed::Git::Base.branched_from
|
40
|
+
}.to_json
|
41
|
+
})
|
42
|
+
|
43
|
+
response = HTTParty.post("#{Toolshed::Client::GITHUB_BASE_API_URL}repos/#{Toolshed::Client.pull_from_repository_user}/#{Toolshed::Client.pull_from_repository_name}/pulls", options).response
|
44
|
+
response = JSON.parse(response.body)
|
45
|
+
if (response["errors"].nil?)
|
46
|
+
response
|
47
|
+
else
|
48
|
+
raise "validation errors #{response.inspect}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def list_branches(options={})
|
53
|
+
options.merge!(self.default_options)
|
54
|
+
|
55
|
+
response = HTTParty.get("#{Toolshed::Client::GITHUB_BASE_API_URL}repos/#{Toolshed::Client.github_username}/#{Toolshed::Client.pull_from_repository_name}/branches", options).response
|
56
|
+
response = JSON.parse(response.body)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.username
|
60
|
+
username = Toolshed::Client::github_username
|
61
|
+
if (username.nil?)
|
62
|
+
# prompt to ask for username
|
63
|
+
puts "Github username? "
|
64
|
+
username = $stdin.gets.chomp.strip
|
65
|
+
end
|
66
|
+
|
67
|
+
return username
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.password
|
71
|
+
password = Toolshed::Client::github_password
|
72
|
+
if (password.nil?)
|
73
|
+
# prompt to ask for password
|
74
|
+
system "stty -echo"
|
75
|
+
puts "Github password? "
|
76
|
+
password = $stdin.gets.chomp.strip
|
77
|
+
system "stty echo"
|
78
|
+
end
|
79
|
+
|
80
|
+
return password
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.create_instance
|
84
|
+
Toolshed::Git::Github.new({ username: Toolshed::Git::Github.username, password: Toolshed::Git::Github.password })
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module TicketTracking
|
3
|
+
class PivotalTracker
|
4
|
+
extend TicketTracking
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
DEFAULT_COMPLETED_STATUS = 'finished'
|
8
|
+
USE_PROJECT_ID = true
|
9
|
+
|
10
|
+
attr_accessor :project_id, :token
|
11
|
+
|
12
|
+
def initialize(options={})
|
13
|
+
username = Toolshed::Client::pivotal_tracker_username
|
14
|
+
password = Toolshed::Client::pivotal_tracker_password
|
15
|
+
|
16
|
+
unless (options[:username].nil?)
|
17
|
+
username = options[:username]
|
18
|
+
end
|
19
|
+
|
20
|
+
unless (options[:password].nil?)
|
21
|
+
password = options[:password]
|
22
|
+
end
|
23
|
+
|
24
|
+
self.token = ::PivotalTracker::Client.token(username, password)
|
25
|
+
|
26
|
+
self.project_id = (options[:project_id].nil?) ? Toolshed::Client.default_pivotal_tracker_project_id : options[:project_id]
|
27
|
+
@pt_project = ::PivotalTracker::Project.find(self.project_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Instance methods
|
32
|
+
#
|
33
|
+
def story_information(story_id)
|
34
|
+
return @pt_project.stories.find(story_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_note(story_id, note_text)
|
38
|
+
story = @pt_project.stories.find(story_id)
|
39
|
+
results = story.notes.create(text: note_text)
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_ticket_status(story_id, current_state, options={})
|
43
|
+
options.merge!({
|
44
|
+
:headers => {
|
45
|
+
"X-TrackerToken" => self.token,
|
46
|
+
"User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1309.0 Safari/537.17",
|
47
|
+
"Content-Type" => "application/json",
|
48
|
+
},
|
49
|
+
body: {
|
50
|
+
current_state: current_state
|
51
|
+
}.to_json
|
52
|
+
})
|
53
|
+
|
54
|
+
response = HTTParty.put("#{Toolshed::Client::PIVOTAL_TRACKER_BASE_API_URL}projects/#{self.project_id}/stories/#{story_id}", options).response
|
55
|
+
response = JSON.parse(response.body)
|
56
|
+
|
57
|
+
if (response["error"].nil?)
|
58
|
+
response
|
59
|
+
else
|
60
|
+
raise "validation errors #{response.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Class methods
|
66
|
+
#
|
67
|
+
def self.story_id_from_branch_name(branch_name)
|
68
|
+
story_id = branch_name.split("_")[0]
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.username
|
72
|
+
username = Toolshed::Client::pivotal_tracker_username
|
73
|
+
if (username.nil?)
|
74
|
+
# prompt to ask for username
|
75
|
+
puts "PivotalTracker username? "
|
76
|
+
username = $stdin.gets.chomp.strip
|
77
|
+
end
|
78
|
+
|
79
|
+
return username
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.password
|
83
|
+
password = Toolshed::Client::pivotal_tracker_password
|
84
|
+
if (password.nil?)
|
85
|
+
# prompt to ask for password
|
86
|
+
system "stty -echo"
|
87
|
+
puts "PivotalTracker password? "
|
88
|
+
password = $stdin.gets.chomp.strip
|
89
|
+
system "stty echo"
|
90
|
+
end
|
91
|
+
|
92
|
+
return password
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Get the pivotal tracker object based off of the project_id
|
97
|
+
#
|
98
|
+
def self.create_instance(options={})
|
99
|
+
unless (options.has_key?(:project_id))
|
100
|
+
raise 'Unable to use PivotalTracker as project id was not supplied'
|
101
|
+
end
|
102
|
+
|
103
|
+
pivotal_tracker = Toolshed::TicketTracking::PivotalTracker.new({ project_id: options[:project_id], username: Toolshed::TicketTracking::PivotalTracker.username, password: Toolshed::TicketTracking::PivotalTracker.password })
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.clean(title)
|
107
|
+
title.gsub("'", "").gsub("\"", "")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Toolshed
|
2
|
+
module TimeTracking
|
3
|
+
class Harvest
|
4
|
+
extend TimeTracking
|
5
|
+
|
6
|
+
MAX_ATTEMPTS = 10
|
7
|
+
|
8
|
+
attr_accessor :harvest_client, :project_id
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
username = Toolshed::Client::time_tracking_username
|
12
|
+
password = Toolshed::Client::time_tracking_password
|
13
|
+
owner = Toolshed::Client.time_tracking_owner
|
14
|
+
|
15
|
+
unless (options[:username].nil?)
|
16
|
+
username = options[:username]
|
17
|
+
end
|
18
|
+
|
19
|
+
unless (options[:password].nil?)
|
20
|
+
password = options[:password]
|
21
|
+
end
|
22
|
+
|
23
|
+
unless (options[:sub_domain].nil?)
|
24
|
+
owner = options[:sub_domain]
|
25
|
+
end
|
26
|
+
|
27
|
+
self.harvest_client = ::Harvest.client('ackmanndickenson', 'jwaller@ackmanndickenson.com', 'V0AU2gRMLhs1')
|
28
|
+
self.project_id = self.get_project_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def previous(days_ago=1)
|
32
|
+
notes = "Previous:\n\n"
|
33
|
+
|
34
|
+
time_entries = self.harvest_client.time.all((DateTime.now - days_ago), self.project_id)
|
35
|
+
if (time_entries.size > 0 || days_ago == Toolshed::TimeTracking::Harvest::MAX_ATTEMPTS)
|
36
|
+
time_entries.each do |time_entry|
|
37
|
+
notes = "#{notes}#{time_entry.notes}\n"
|
38
|
+
end
|
39
|
+
else
|
40
|
+
notes = self.previous(days_ago + 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
notes
|
44
|
+
end
|
45
|
+
|
46
|
+
def today
|
47
|
+
notes = "Today:\n\n"
|
48
|
+
|
49
|
+
time_entries = self.harvest_client.time.all(Time.now, self.project_id)
|
50
|
+
time_entries.each do |time_entry|
|
51
|
+
notes = "#{notes}#{time_entry.notes}\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
notes
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_project_id
|
58
|
+
print "Project ID (Default: #{Toolshed::Client.time_tracking_default_project_id})? "
|
59
|
+
project_id = $stdin.gets.chomp.strip
|
60
|
+
if (project_id == '')
|
61
|
+
project_id = Toolshed::Client.time_tracking_default_project_id
|
62
|
+
end
|
63
|
+
|
64
|
+
project_id
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/toolshed/version.rb
CHANGED