v2gpti 1.1.9 → 1.2.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/bin/git-deliver +1 -1
  3. data/bin/git-finish +1 -1
  4. data/bin/git-newbug +1 -1
  5. data/bin/git-newfeature +1 -1
  6. data/bin/git-qa +1 -1
  7. data/bin/git-release +1 -1
  8. data/bin/git-report +1 -1
  9. data/bin/git-start +1 -1
  10. data/bin/git-uat +1 -1
  11. data/config_template +16 -0
  12. data/lib/git-pivotal-tracker-integration/command/base.rb +235 -322
  13. data/lib/git-pivotal-tracker-integration/command/configuration.rb +183 -109
  14. data/lib/git-pivotal-tracker-integration/command/deliver.rb +145 -200
  15. data/lib/git-pivotal-tracker-integration/command/finish.rb +70 -63
  16. data/lib/git-pivotal-tracker-integration/command/newbug.rb +36 -39
  17. data/lib/git-pivotal-tracker-integration/command/newfeature.rb +43 -42
  18. data/lib/git-pivotal-tracker-integration/command/release.rb +171 -203
  19. data/lib/git-pivotal-tracker-integration/command/report.rb +33 -36
  20. data/lib/git-pivotal-tracker-integration/command/start.rb +74 -78
  21. data/lib/git-pivotal-tracker-integration/util/git.rb +202 -204
  22. data/lib/git-pivotal-tracker-integration/util/shell.rb +19 -16
  23. data/lib/git-pivotal-tracker-integration/util/story.rb +155 -177
  24. data/lib/git-pivotal-tracker-integration/version-update/gradle.rb +44 -40
  25. data/lib/git-pivotal-tracker-integration.rb +44 -0
  26. data/spec/git-pivotal-tracker-integration/command/configuration_spec.rb +1 -2
  27. data/spec/git-pivotal-tracker-integration/command/finish_spec.rb +1 -1
  28. data/spec/git-pivotal-tracker-integration/command/release_spec.rb +1 -1
  29. data/spec/git-pivotal-tracker-integration/command/start_spec.rb +1 -1
  30. data/spec/git-pivotal-tracker-integration/util/story_spec.rb +21 -32
  31. data/tracker_api/lib/tracker_api/client.rb +241 -0
  32. data/tracker_api/lib/tracker_api/endpoints/activity.rb +38 -0
  33. data/tracker_api/lib/tracker_api/endpoints/comments.rb +27 -0
  34. data/tracker_api/lib/tracker_api/endpoints/epic.rb +17 -0
  35. data/tracker_api/lib/tracker_api/endpoints/epics.rb +20 -0
  36. data/tracker_api/lib/tracker_api/endpoints/file_attachment.rb +18 -0
  37. data/tracker_api/lib/tracker_api/endpoints/iterations.rb +20 -0
  38. data/tracker_api/lib/tracker_api/endpoints/me.rb +17 -0
  39. data/tracker_api/lib/tracker_api/endpoints/memberships.rb +20 -0
  40. data/tracker_api/lib/tracker_api/endpoints/notifications.rb +20 -0
  41. data/tracker_api/lib/tracker_api/endpoints/project.rb +17 -0
  42. data/tracker_api/lib/tracker_api/endpoints/projects.rb +18 -0
  43. data/tracker_api/lib/tracker_api/endpoints/stories.rb +20 -0
  44. data/tracker_api/lib/tracker_api/endpoints/story.rb +37 -0
  45. data/tracker_api/lib/tracker_api/endpoints/tasks.rb +20 -0
  46. data/tracker_api/lib/tracker_api/error.rb +18 -0
  47. data/tracker_api/lib/tracker_api/logger.rb +31 -0
  48. data/tracker_api/lib/tracker_api/resources/account.rb +18 -0
  49. data/tracker_api/lib/tracker_api/resources/activity.rb +24 -0
  50. data/tracker_api/lib/tracker_api/resources/base.rb +71 -0
  51. data/tracker_api/lib/tracker_api/resources/change.rb +15 -0
  52. data/tracker_api/lib/tracker_api/resources/comment.rb +20 -0
  53. data/tracker_api/lib/tracker_api/resources/epic.rb +17 -0
  54. data/tracker_api/lib/tracker_api/resources/file_attachment.rb +23 -0
  55. data/tracker_api/lib/tracker_api/resources/iteration.rb +24 -0
  56. data/tracker_api/lib/tracker_api/resources/label.rb +14 -0
  57. data/tracker_api/lib/tracker_api/resources/me.rb +21 -0
  58. data/tracker_api/lib/tracker_api/resources/membership_summary.rb +15 -0
  59. data/tracker_api/lib/tracker_api/resources/notification.rb +26 -0
  60. data/tracker_api/lib/tracker_api/resources/person.rb +14 -0
  61. data/tracker_api/lib/tracker_api/resources/primary_resource.rb +13 -0
  62. data/tracker_api/lib/tracker_api/resources/project.rb +131 -0
  63. data/tracker_api/lib/tracker_api/resources/project_membership.rb +16 -0
  64. data/tracker_api/lib/tracker_api/resources/story.rb +102 -0
  65. data/tracker_api/lib/tracker_api/resources/task.rb +16 -0
  66. data/tracker_api/lib/tracker_api/resources/time_zone.rb +13 -0
  67. data/tracker_api/lib/tracker_api/version.rb +3 -0
  68. data/tracker_api/lib/tracker_api.rb +60 -0
  69. metadata +202 -53
  70. data/lib/git-pivotal-tracker-integration/command/command.rb +0 -20
  71. data/lib/git-pivotal-tracker-integration/util/util.rb +0 -20
  72. data/lib/git-pivotal-tracker-integration/version-update/version_update.rb +0 -20
  73. data/lib/git_pivotal_tracker_integration.rb +0 -18
@@ -13,99 +13,95 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'git-pivotal-tracker-integration/command/base'
17
- require 'git-pivotal-tracker-integration/command/command'
18
- require 'git-pivotal-tracker-integration/util/git'
19
- require 'git-pivotal-tracker-integration/util/story'
20
- require 'pivotal-tracker'
21
-
22
- # The class that encapsulates starting a Pivotal Tracker Story
23
- class GitPivotalTrackerIntegration::Command::Start < GitPivotalTrackerIntegration::Command::Base
24
-
25
- # Starts a Pivotal Tracker story by doing the following steps:
26
- # * Create a branch
27
- # * Add default commit hook
28
- # * Start the story on Pivotal Tracker
29
- #
30
- # @param [String, nil] filter a filter for selecting the story to start. This
31
- # filter can be either:
32
- # * a story id
33
- # * a story type (feature, bug, chore)
34
- # * +nil+
35
- # @return [void]
36
- def run(args)
37
- my_projects = PivotalTracker::Project.all
38
- filter = args[0]
39
- $LOG.debug("#{self.class} in project:#{@project.name} pwd:#{pwd} branch:#{GitPivotalTrackerIntegration::Util::Git.branch_name} args:#{filter}")
40
- self.check_branch
41
- story = nil
42
- if (!args.nil? && args.any?{|arg| arg.include?("-n")})
43
- story = self.create_story(args)
44
- else
45
- story = GitPivotalTrackerIntegration::Util::Story.select_story @project, filter
46
- end
47
- if story.nil?
48
- abort "There are no available stories."
49
- end
50
- if story.story_type == "feature" && story.estimate < 0
51
- estimate_story(story)
52
- end
53
- $LOG.debug("story:#{story.name}")
54
- GitPivotalTrackerIntegration::Util::Story.pretty_print story
16
+ module GitPivotalTrackerIntegration
17
+ module Command
55
18
 
56
- development_branch_name = development_branch_name story
57
- GitPivotalTrackerIntegration::Util::Git.create_branch development_branch_name
58
- @configuration.story = story
59
- GitPivotalTrackerIntegration::Util::Git.add_hook 'prepare-commit-msg', File.join(File.dirname(__FILE__), !OS.windows? ? 'prepare-commit-msg.sh' : 'prepare-commit-msg-win.sh' )
19
+ # The class that encapsulates starting a Pivotal Tracker Story
20
+ class Start < Base
60
21
 
61
- start_on_tracker story
62
- end
22
+ # Starts a Pivotal Tracker story by doing the following steps:
23
+ # * Create a branch
24
+ # * Add default commit hook
25
+ # * Start the story on Pivotal Tracker
26
+ #
27
+ # @param [String, nil] filter a filter for selecting the story to start. This
28
+ # filter can be either:
29
+ # * a story id
30
+ # * a story type (feature, bug, chore)
31
+ # * +nil+
32
+ # @return [void]
33
+ def run(args)
34
+ filter = args[0]
35
+ $LOG.debug("#{self.class} in project:#{@project.name} pwd:#{pwd} branch:#{Util::Git.branch_name} args:#{filter}")
36
+ self.check_branch
37
+ story = nil
38
+ if (!args.nil? && args.any?{|arg| arg.include?("-n")})
39
+ story = self.create_story(args)
40
+ else
41
+ story = Util::Story.select_story @project, filter
42
+ end
63
43
 
64
- def check_branch
44
+ abort "There are no available stories." if story.nil?
65
45
 
66
- current_branch = GitPivotalTrackerIntegration::Util::Git.branch_name
67
- # suggested_branch = (GitPivotalTrackerIntegration::Util::Shell.exec "git config --get git-pivotal-tracker-integration.feature-root 2>/dev/null", false).chomp
68
- suggested_branch = "develop"
46
+ if story.story_type == "feature" && story.estimate.to_i <= 0
47
+ story.estimate = estimate_story
48
+ story.save
49
+ end
69
50
 
70
- if !suggested_branch.nil? && suggested_branch.length !=0 && current_branch != suggested_branch
71
- $LOG.warn("Currently checked out branch is '#{current_branch}'.")
72
- should_chage_branch = ask("Your currently checked out branch is '#{current_branch}'. Do you want to checkout '#{suggested_branch}' before starting?(Y/n)")
73
- if should_chage_branch != "n"
74
- $LOG.debug("Checking out branch '#{suggested_branch}'")
75
- print "Checking out branch '#{suggested_branch}'...\n\n"
76
- $LOG.debug(GitPivotalTrackerIntegration::Util::Shell.exec "git checkout --quiet #{suggested_branch}")
77
- end
51
+ $LOG.debug("story:#{story.name}")
52
+ Util::Story.pretty_print story
53
+
54
+ Util::Git.create_branch feature_branch(story)
55
+ @configuration.story = story
56
+ Util::Git.add_hook 'prepare-commit-msg', File.join(File.dirname(__FILE__), !OS.windows? ? 'prepare-commit-msg.sh' : 'prepare-commit-msg-win.sh' )
78
57
 
58
+ start_on_tracker story
79
59
  end
80
60
 
81
- end
61
+ def check_branch
62
+ current_branch = Util::Git.branch_name
63
+ # suggested_branch = (Util::Shell.exec "git config --get git-pivotal-tracker-integration.feature-root 2>/dev/null", false).chomp
64
+ suggested_branch = 'develop'
65
+
66
+ if !suggested_branch.nil? && suggested_branch.length !=0 && current_branch != suggested_branch
67
+ $LOG.warn("Currently checked out branch is '#{current_branch}'.")
68
+ should_change_branch = ask("Your currently checked out branch is '#{current_branch}'. Do you want to checkout '#{suggested_branch}' before starting?(Y/n)")
69
+ if should_change_branch != "n"
70
+ $LOG.debug("Checking out branch '#{suggested_branch}'")
71
+ print "Checking out branch '#{suggested_branch}'...\n\n"
72
+ $LOG.debug(Util::Shell.exec "git checkout --quiet #{suggested_branch}")
73
+ end
74
+ end
75
+ end
82
76
 
83
- private
77
+ private
84
78
 
85
- def development_branch_name(story)
86
- prefix = "#{story.id}-"
87
- story_name = "#{story.name.gsub(/[^0-9a-z\\s]/i, '_')}"
88
- if(story_name.length > 30)
79
+ def feature_branch(story)
80
+ prefix = "#{story.id}-"
81
+ story_name = "#{story.name.gsub(/[^0-9a-z\\s]/i, '_')}"
82
+ if(story_name.length > 30)
89
83
  suggested_suffix = story_name[0..27]
90
84
  suggested_suffix << "__"
91
- else
85
+ else
92
86
  suggested_suffix = story_name
87
+ end
88
+ branch_name = ask("Enter branch name (#{story.id}-<#{suggested_suffix}>): ")
89
+ branch_name = branch_name.empty? ? "#{prefix}#{suggested_suffix}" : "#{prefix}#{branch_name}"
90
+ branch_name.gsub(/[^0-9a-z\\s\-]/i, '_')
93
91
  end
94
- branch_name = "#{prefix}" + ask("Enter branch name (#{story.id}-<#{suggested_suffix}>): ")
95
- puts
96
- if branch_name == "#{prefix}"
97
- branch_name << suggested_suffix
92
+
93
+ def start_on_tracker(story)
94
+ print 'Starting story on Pivotal Tracker... '
95
+ story.attributes = {
96
+ :current_state => 'started',
97
+ :owned_by => Util::Git.get_config('user.name')
98
+ }
99
+ story.save
100
+ puts 'OK'
98
101
  end
99
- branch_name.gsub(/[^0-9a-z\\s\-]/i, '_')
100
- end
101
102
 
102
- def start_on_tracker(story)
103
- print 'Starting story on Pivotal Tracker... '
104
- story.update(
105
- :current_state => 'started',
106
- :owned_by => GitPivotalTrackerIntegration::Util::Git.get_config('user.name')
107
- )
108
- puts 'OK'
109
- end
103
+ end
110
104
 
105
+ end
111
106
  end
107
+
@@ -13,232 +13,230 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'git-pivotal-tracker-integration/util/shell'
17
- require 'git-pivotal-tracker-integration/util/util'
18
-
19
- # Utilities for dealing with Git
20
- class GitPivotalTrackerIntegration::Util::Git
21
-
22
- # Adds a Git hook to the current repository
23
- #
24
- # @param [String] name the name of the hook to add
25
- # @param [String] source the file to use as the source for the created hook
26
- # @param [Boolean] overwrite whether to overwrite the hook if it already exists
27
- # @return [void]
28
- def self.add_hook(name, source, overwrite = false)
29
- hooks_directory = File.join repository_root, '.git', 'hooks'
30
- hook = File.join hooks_directory, name
31
-
32
- if overwrite || !File.exist?(hook)
33
- print "Creating Git hook #{name}... "
34
-
35
- FileUtils.mkdir_p hooks_directory
36
- File.open(source, 'r') do |input|
37
- File.open(hook, 'w') do |output|
38
- output.write(input.read)
39
- output.chmod(0755)
16
+ module GitPivotalTrackerIntegration
17
+ module Util
18
+
19
+ # Utilities for dealing with Git
20
+ class Git
21
+
22
+ KEY_REMOTE = 'remote'.freeze
23
+ KEY_ROOT_BRANCH = 'root-branch'.freeze
24
+ KEY_ROOT_REMOTE = 'root-remote'.freeze
25
+ RELEASE_BRANCH_NAME = 'pivotal-tracker-release'.freeze
26
+
27
+ # Adds a Git hook to the current repository
28
+ #
29
+ # @param [String] name the name of the hook to add
30
+ # @param [String] source the file to use as the source for the created hook
31
+ # @param [Boolean] overwrite whether to overwrite the hook if it already exists
32
+ # @return [void]
33
+ def self.add_hook(name, source, overwrite = false)
34
+ hooks_directory = File.join repository_root, '.git', 'hooks'
35
+ hook = File.join hooks_directory, name
36
+
37
+ if overwrite || !File.exist?(hook)
38
+ print "Creating Git hook #{name}... "
39
+
40
+ FileUtils.mkdir_p hooks_directory
41
+ File.open(source, 'r') do |input|
42
+ File.open(hook, 'w') do |output|
43
+ output.write(input.read)
44
+ output.chmod(0755)
45
+ end
46
+ end
47
+
48
+ puts 'OK'
40
49
  end
41
50
  end
42
51
 
43
- puts 'OK'
44
- end
45
- end
52
+ # Returns the name of the currently checked out branch
53
+ #
54
+ # @return [String] the name of the currently checked out branch
55
+ def self.branch_name
56
+ Util::Shell.exec('git branch').scan(/\* (.*)/)[0][0]
57
+ end
46
58
 
47
- # Returns the name of the currently checked out branch
48
- #
49
- # @return [String] the name of the currently checked out branch
50
- def self.branch_name
51
- GitPivotalTrackerIntegration::Util::Shell.exec('git branch').scan(/\* (.*)/)[0][0]
52
- end
59
+ # Creates a branch with a given +name+. First pulls the current branch to
60
+ # ensure that it is up to date and then creates and checks out the new
61
+ # branch. If specified, sets branch-specific properties that are passed in.
62
+ #
63
+ # @param [String] name the name of the branch to create
64
+ # @param [Boolean] print_messages whether to print messages
65
+ # @return [void]
66
+ def self.create_branch(name, print_messages = true)
67
+ root_branch = branch_name
68
+ root_remote = get_config KEY_REMOTE, :branch
69
+
70
+ print "Pulling #{root_branch}... " if print_messages
71
+ Util::Shell.exec 'git pull --quiet --ff-only'
72
+ puts 'OK' if print_messages
73
+
74
+ print "Creating and checking out #{name}... " if print_messages
75
+
76
+ Util::Shell.exec "git checkout --quiet -b #{name}"
77
+ set_config KEY_ROOT_BRANCH, root_branch, :branch
78
+ set_config KEY_ROOT_REMOTE, root_remote, :branch
79
+ puts 'OK' if print_messages
80
+ end
53
81
 
54
- # Creates a branch with a given +name+. First pulls the current branch to
55
- # ensure that it is up to date and then creates and checks out the new
56
- # branch. If specified, sets branch-specific properties that are passed in.
57
- #
58
- # @param [String] name the name of the branch to create
59
- # @param [Boolean] print_messages whether to print messages
60
- # @return [void]
61
- def self.create_branch(name, print_messages = true)
62
- root_branch = branch_name
63
- root_remote = get_config KEY_REMOTE, :branch
64
-
65
- if print_messages; print "Pulling #{root_branch}... " end
66
- GitPivotalTrackerIntegration::Util::Shell.exec 'git pull --quiet --ff-only'
67
- if print_messages; puts 'OK'
68
- end
82
+ # Creates a commit with a given message. The commit includes all change
83
+ # files.
84
+ #
85
+ # @param [String] message The commit message, which will be appended with
86
+ # +[#<story-id]+
87
+ # @param [PivotalTracker::Story] story the story associated with the current
88
+ # commit
89
+ # @return [void]
90
+ def self.create_commit(message, story)
91
+ Util::Shell.exec "git commit --quiet --all --allow-empty --message \"#{message}\n\n[##{story.id}]\""
92
+ end
69
93
 
70
- if print_messages; print "Creating and checking out #{name}... " end
71
- GitPivotalTrackerIntegration::Util::Shell.exec "git checkout --quiet -b #{name}"
72
- set_config KEY_ROOT_BRANCH, root_branch, :branch
73
- set_config KEY_ROOT_REMOTE, root_remote, :branch
74
- if print_messages; puts 'OK'
75
- end
76
- end
94
+ # Creates a tag with the given name. Before creating the tag, commits all
95
+ # outstanding changes with a commit message that reflects that these changes
96
+ # are for a release.
97
+ #
98
+ # @param [String] name the name of the tag to create
99
+ # @param [PivotalTracker::Story] story the story associated with the current
100
+ # tag
101
+ # @return [void]
102
+ def self.create_release_tag(name, story)
103
+ root_branch = branch_name
104
+
105
+ print "Creating tag v#{name}... "
106
+
107
+ create_branch RELEASE_BRANCH_NAME, false
108
+ create_commit "#{name} Release", story
109
+ Util::Shell.exec "git tag v#{name}"
110
+ Util::Shell.exec "git checkout --quiet #{root_branch}"
111
+ Util::Shell.exec "git branch --quiet -D #{RELEASE_BRANCH_NAME}"
112
+
113
+ puts 'OK'
114
+ end
77
115
 
78
- # Creates a commit with a given message. The commit includes all change
79
- # files.
80
- #
81
- # @param [String] message The commit message, which will be appended with
82
- # +[#<story-id]+
83
- # @param [PivotalTracker::Story] story the story associated with the current
84
- # commit
85
- # @return [void]
86
- def self.create_commit(message, story)
87
- GitPivotalTrackerIntegration::Util::Shell.exec "git commit --quiet --all --allow-empty --message \"#{message}\n\n[##{story.id}]\""
88
- end
116
+ # Returns a Git configuration value. This value is read using the +git
117
+ # config+ command. The scope of the value to read can be controlled with the
118
+ # +scope+ parameter.
119
+ #
120
+ # @param [String] key the key of the configuration to retrieve
121
+ # @param [:branch, :inherited] scope the scope to read the configuration from
122
+ # * +:branch+: equivalent to calling +git config branch.branch-name.key+
123
+ # * +:inherited+: equivalent to calling +git config key+
124
+ # @return [String] the value of the configuration
125
+ # @raise if the specified scope is not +:branch+ or +:inherited+
126
+ def self.get_config(key, scope = :inherited)
127
+ if :branch == scope
128
+ Util::Shell.exec("git config branch.#{branch_name}.#{key}", false).strip
129
+ elsif :inherited == scope
130
+ Util::Shell.exec("git config #{key}", false).strip
131
+ else
132
+ raise "Unable to get Git configuration for scope '#{scope}'"
133
+ end
134
+ end
89
135
 
90
- # Creates a tag with the given name. Before creating the tag, commits all
91
- # outstanding changes with a commit message that reflects that these changes
92
- # are for a release.
93
- #
94
- # @param [String] name the name of the tag to create
95
- # @param [PivotalTracker::Story] story the story associated with the current
96
- # tag
97
- # @return [void]
98
- def self.create_release_tag(name, story)
99
- root_branch = branch_name
100
-
101
- print "Creating tag v#{name}... "
102
-
103
- create_branch RELEASE_BRANCH_NAME, false
104
- create_commit "#{name} Release", story
105
- GitPivotalTrackerIntegration::Util::Shell.exec "git tag v#{name}"
106
- GitPivotalTrackerIntegration::Util::Shell.exec "git checkout --quiet #{root_branch}"
107
- GitPivotalTrackerIntegration::Util::Shell.exec "git branch --quiet -D #{RELEASE_BRANCH_NAME}"
108
-
109
- puts 'OK'
110
- end
136
+ # Merges the current branch to its root branch and deletes the current branch
137
+ #
138
+ # @param [PivotalTracker::Story] story the story associated with the current branch
139
+ # @param [Boolean] no_complete whether to suppress the +Completes+ statement in the commit message
140
+ # @return [void]
141
+ def self.merge(story, no_complete)
142
+ development_branch = branch_name
143
+ root_branch = get_config KEY_ROOT_BRANCH, :branch
144
+
145
+ print "Merging #{development_branch} to #{root_branch}... "
146
+ Util::Shell.exec "git checkout --quiet #{root_branch}"
147
+ Util::Shell.exec 'git pull --quiet --ff-only'
148
+ Util::Shell.exec "git merge --quiet --no-ff -m \"Merge #{development_branch} to #{root_branch}\n\n[#{no_complete ? '' : 'Completes '}##{story.id}]\" #{development_branch}"
149
+ puts 'OK'
150
+
151
+ print "Deleting #{development_branch}... "
152
+ Util::Shell.exec "git branch --quiet -D #{development_branch}"
153
+ puts 'OK'
154
+ end
111
155
 
112
- # Returns a Git configuration value. This value is read using the +git
113
- # config+ command. The scope of the value to read can be controlled with the
114
- # +scope+ parameter.
115
- #
116
- # @param [String] key the key of the configuration to retrieve
117
- # @param [:branch, :inherited] scope the scope to read the configuration from
118
- # * +:branch+: equivalent to calling +git config branch.branch-name.key+
119
- # * +:inherited+: equivalent to calling +git config key+
120
- # @return [String] the value of the configuration
121
- # @raise if the specified scope is not +:branch+ or +:inherited+
122
- def self.get_config(key, scope = :inherited)
123
- if :branch == scope
124
- GitPivotalTrackerIntegration::Util::Shell.exec("git config branch.#{branch_name}.#{key}", false).strip
125
- elsif :inherited == scope
126
- GitPivotalTrackerIntegration::Util::Shell.exec("git config #{key}", false).strip
127
- else
128
- raise "Unable to get Git configuration for scope '#{scope}'"
129
- end
130
- end
156
+ # Push changes to the remote of the current branch
157
+ #
158
+ # @param [String] refs the explicit references to push
159
+ # @return [void]
160
+ def self.push(*refs)
161
+ remote = get_config KEY_REMOTE, :branch
131
162
 
132
- # Merges the current branch to its root branch and deletes the current branch
133
- #
134
- # @param [PivotalTracker::Story] story the story associated with the current branch
135
- # @param [Boolean] no_complete whether to suppress the +Completes+ statement in the commit message
136
- # @return [void]
137
- def self.merge(story, no_complete)
138
- development_branch = branch_name
139
- root_branch = get_config KEY_ROOT_BRANCH, :branch
140
-
141
- print "Merging #{development_branch} to #{root_branch}... "
142
- GitPivotalTrackerIntegration::Util::Shell.exec "git checkout --quiet #{root_branch}"
143
- GitPivotalTrackerIntegration::Util::Shell.exec "git merge --quiet --no-ff -m \"Merge #{development_branch} to #{root_branch}\n\n[#{no_complete ? '' : 'Completes '}##{story.id}]\" #{development_branch}"
144
- puts 'OK'
145
-
146
- print "Deleting #{development_branch}... "
147
- GitPivotalTrackerIntegration::Util::Shell.exec "git branch --quiet -D #{development_branch}"
148
- puts 'OK'
149
- end
163
+ print "Pushing to #{remote}... "
164
+ Util::Shell.exec "git push --quiet #{remote} " + refs.join(' ')
165
+ puts 'OK'
166
+ end
150
167
 
151
- # Push changes to the remote of the current branch
152
- #
153
- # @param [String] refs the explicit references to push
154
- # @return [void]
155
- def self.push(*refs)
156
- remote = get_config KEY_REMOTE, :branch
168
+ # Returns the root path of the current Git repository. The root is
169
+ # determined by ascending the path hierarchy, starting with the current
170
+ # working directory (+Dir#pwd+), until a directory is found that contains a
171
+ # +.git/+ sub directory.
172
+ #
173
+ # @return [String] the root path of the Git repository
174
+ # @raise if the current working directory is not in a Git repository
175
+ def self.repository_root
176
+ repository_root = Dir.pwd
177
+
178
+ until Dir.entries(repository_root).any? { |child| File.directory?(child) && (child =~ /^.git$/) }
179
+ next_repository_root = File.expand_path('..', repository_root)
180
+ abort('Current working directory is not in a Git repository') unless repository_root != next_repository_root
181
+ repository_root = next_repository_root
182
+ end
157
183
 
158
- print "Pushing to #{remote}... "
159
- GitPivotalTrackerIntegration::Util::Shell.exec "git push --quiet #{remote} " + refs.join(' ')
160
- puts 'OK'
161
- end
184
+ repository_root
185
+ end
162
186
 
163
- # Returns the root path of the current Git repository. The root is
164
- # determined by ascending the path hierarchy, starting with the current
165
- # working directory (+Dir#pwd+), until a directory is found that contains a
166
- # +.git/+ sub directory.
167
- #
168
- # @return [String] the root path of the Git repository
169
- # @raise if the current working directory is not in a Git repository
170
- def self.repository_root
171
- repository_root = Dir.pwd
172
-
173
- until Dir.entries(repository_root).any? { |child| File.directory?(child) && (child =~ /^.git$/) }
174
- next_repository_root = File.expand_path('..', repository_root)
175
- abort('Current working directory is not in a Git repository') unless repository_root != next_repository_root
176
- repository_root = next_repository_root
177
- end
187
+ # Sets a Git configuration value. This value is set using the +git config+
188
+ # command. The scope of the set value can be controlled with the +scope+
189
+ # parameter.
190
+ #
191
+ # @param [String] key the key of configuration to store
192
+ # @param [String] value the value of the configuration to store
193
+ # @param [:branch, :global, :local] scope the scope to store the configuration value in.
194
+ # * +:branch+: equivalent to calling +git config --local branch.branch-name.key value+
195
+ # * +:global+: equivalent to calling +git config --global key value+
196
+ # * +:local+: equivalent to calling +git config --local key value+
197
+ # @return [void]
198
+ # @raise if the specified scope is not +:branch+, +:global+, or +:local+
199
+ def self.set_config(key, value, scope = :local)
200
+ if :branch == scope
201
+ Util::Shell.exec "git config --local branch.#{branch_name}.#{key} #{value}"
202
+ elsif :global == scope
203
+ Util::Shell.exec "git config --global #{key} #{value}"
204
+ elsif :local == scope
205
+ Util::Shell.exec "git config --local #{key} #{value}"
206
+ else
207
+ raise "Unable to set Git configuration for scope '#{scope}'"
208
+ end
209
+ end
178
210
 
179
- repository_root
180
- end
211
+ # Checks whether merging the current branch back to its root branch would be
212
+ # a trivial merge. A trivial merge is defined as one where the net change
213
+ # of the merge would be the same as the net change of the branch being
214
+ # merged. The easiest way to ensure that a merge is trivial is to rebase a
215
+ # development branch onto the tip of its root branch.
216
+ #
217
+ # @return [void]
218
+ def self.trivial_merge?
219
+ development_branch = branch_name
220
+ root_branch = get_config KEY_ROOT_BRANCH, :branch
181
221
 
182
- # Sets a Git configuration value. This value is set using the +git config+
183
- # command. The scope of the set value can be controlled with the +scope+
184
- # parameter.
185
- #
186
- # @param [String] key the key of configuration to store
187
- # @param [String] value the value of the configuration to store
188
- # @param [:branch, :global, :local] scope the scope to store the configuration value in.
189
- # * +:branch+: equivalent to calling +git config --local branch.branch-name.key value+
190
- # * +:global+: equivalent to calling +git config --global key value+
191
- # * +:local+: equivalent to calling +git config --local key value+
192
- # @return [void]
193
- # @raise if the specified scope is not +:branch+, +:global+, or +:local+
194
- def self.set_config(key, value, scope = :local)
195
- if :branch == scope
196
- GitPivotalTrackerIntegration::Util::Shell.exec "git config --local branch.#{branch_name}.#{key} #{value}"
197
- elsif :global == scope
198
- GitPivotalTrackerIntegration::Util::Shell.exec "git config --global #{key} #{value}"
199
- elsif :local == scope
200
- GitPivotalTrackerIntegration::Util::Shell.exec "git config --local #{key} #{value}"
201
- else
202
- raise "Unable to set Git configuration for scope '#{scope}'"
203
- end
204
- end
222
+ print "Checking for trivial merge from #{development_branch} to #{root_branch}... "
205
223
 
206
- # Checks whether merging the current branch back to its root branch would be
207
- # a trivial merge. A trivial merge is defined as one where the net change
208
- # of the merge would be the same as the net change of the branch being
209
- # merged. The easiest way to ensure that a merge is trivial is to rebase a
210
- # development branch onto the tip of its root branch.
211
- #
212
- # @return [void]
213
- def self.trivial_merge?
214
- development_branch = branch_name
215
- root_branch = get_config KEY_ROOT_BRANCH, :branch
224
+ Util::Shell.exec "git checkout --quiet #{root_branch}"
225
+ Util::Shell.exec 'git pull --quiet --ff-only'
226
+ Util::Shell.exec "git checkout --quiet #{development_branch}"
216
227
 
217
- print "Checking for trivial merge from #{development_branch} to #{root_branch}... "
228
+ root_tip = Util::Shell.exec "git rev-parse #{root_branch}"
229
+ common_ancestor = Util::Shell.exec "git merge-base #{root_branch} #{development_branch}"
218
230
 
219
- GitPivotalTrackerIntegration::Util::Shell.exec "git checkout --quiet #{root_branch}"
220
- GitPivotalTrackerIntegration::Util::Shell.exec 'git pull --quiet --ff-only'
221
- GitPivotalTrackerIntegration::Util::Shell.exec "git checkout --quiet #{development_branch}"
231
+ if root_tip != common_ancestor
232
+ abort "\n#{root_branch} branch is ahead of your #{development_branch} branch. \nSo please merge #{root_branch} to #{development_branch} and resolve any conflicts if any. Run 'git merge #{root_branch}' and try git finish again."
233
+ end
222
234
 
223
- root_tip = GitPivotalTrackerIntegration::Util::Shell.exec "git rev-parse #{root_branch}"
224
- common_ancestor = GitPivotalTrackerIntegration::Util::Shell.exec "git merge-base #{root_branch} #{development_branch}"
235
+ puts 'OK'
236
+ end
225
237
 
226
- if root_tip != common_ancestor
227
- abort "\n#{root_branch} branch is ahead of your #{development_branch} branch. \nSo please merge #{root_branch} to #{development_branch} and resolve any conflicts if any. Run 'git merge #{root_branch}' and try git finish again."
228
238
  end
229
239
 
230
- puts 'OK'
231
240
  end
232
-
233
- private
234
-
235
- KEY_REMOTE = 'remote'.freeze
236
-
237
- KEY_ROOT_BRANCH = 'root-branch'.freeze
238
-
239
- KEY_ROOT_REMOTE = 'root-remote'.freeze
240
-
241
- RELEASE_BRANCH_NAME = 'pivotal-tracker-release'.freeze
242
-
243
241
  end
244
242