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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +14 -0
  3. data/Rakefile +11 -0
  4. data/bin/toolshed.rb +95 -16
  5. data/lib/toolshed/base.rb +7 -0
  6. data/lib/toolshed/cli.rb +13 -6
  7. data/lib/toolshed/client.rb +105 -83
  8. data/lib/toolshed/commands/checkout_branch.rb +26 -0
  9. data/lib/toolshed/commands/create_branch.rb +60 -0
  10. data/lib/toolshed/commands/create_pivotal_tracker_note.rb +9 -4
  11. data/lib/toolshed/commands/create_pull_request.rb +137 -0
  12. data/lib/toolshed/commands/delete_branch.rb +27 -0
  13. data/lib/toolshed/commands/get_daily_time_update.rb +21 -0
  14. data/lib/toolshed/commands/get_pivotal_tracker_story_information.rb +6 -3
  15. data/lib/toolshed/commands/list_branches.rb +13 -0
  16. data/lib/toolshed/commands/push_branch.rb +11 -0
  17. data/lib/toolshed/commands/update_pivotal_tracker_story_status.rb +8 -5
  18. data/lib/toolshed/git/git.rb +134 -0
  19. data/lib/toolshed/git/github.rb +88 -0
  20. data/lib/toolshed/ticket_tracking/pivotal_tracker.rb +111 -0
  21. data/lib/toolshed/ticket_tracking/ticket_tracking.rb +6 -0
  22. data/lib/toolshed/time_tracking/harvest.rb +68 -0
  23. data/lib/toolshed/time_tracking/time_tracking.rb +6 -0
  24. data/lib/toolshed/version.rb +1 -1
  25. data/lib/toolshed.rb +8 -2
  26. data/test/commands/checkout_branch_test.rb +28 -0
  27. data/test/commands/commands_helper.rb +2 -0
  28. data/test/commands/create_branch_test.rb +44 -0
  29. data/test/commands/create_pull_request_test.rb +125 -0
  30. data/test/commands/delete_branch_test.rb +75 -0
  31. data/test/commands/push_branch_test.rb +49 -0
  32. data/test/config.rb +1 -0
  33. data/test/git/git_helper.rb +31 -0
  34. data/test/git/git_test.rb +115 -0
  35. data/test/git/github_test.rb +91 -0
  36. data/test/helper.rb +98 -0
  37. data/toolshed.gemspec +8 -0
  38. metadata +151 -9
  39. data/lib/toolshed/commands/checkout_git_branch.rb +0 -23
  40. data/lib/toolshed/commands/create_git_branch.rb +0 -28
  41. data/lib/toolshed/commands/create_github_pull_request.rb +0 -77
  42. data/lib/toolshed/commands/push_git_branch.rb +0 -10
  43. data/lib/toolshed/github.rb +0 -89
  44. 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({ project_id: project_id, username: Toolshed::PivotalTracker.username, password: Toolshed::PivotalTracker.password })
13
- github = Toolshed::Github.new
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(github.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 == '')
@@ -0,0 +1,13 @@
1
+ module Toolshed
2
+ module Commands
3
+ class ListBranches
4
+ def execute(args, options = {})
5
+ git = Toolshed::Git::Github.new
6
+ branches = git.list_branches
7
+ branches.each do |branch|
8
+ puts branch['name']
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Toolshed
2
+ module Commands
3
+ class PushBranch
4
+ def execute(args, options = {})
5
+ branch_name = Toolshed::Git::Base.push(options)
6
+ puts "#{branch_name} has been pushed"
7
+ return
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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({ project_id: project_id, username: Toolshed::PivotalTracker.username, password: Toolshed::PivotalTracker.password })
14
- github = Toolshed::Github.new
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(github.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,6 @@
1
+ module Toolshed
2
+ module TicketTracking
3
+ def initialize(options={})
4
+ end
5
+ end
6
+ 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
@@ -0,0 +1,6 @@
1
+ module Toolshed
2
+ module TimeTracking
3
+ def initialize(options={})
4
+ end
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Toolshed
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end