spire-git-pivotal-tracker 1.0.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 (30) hide show
  1. data/LICENSE +202 -0
  2. data/NOTICE +2 -0
  3. data/README.md +176 -0
  4. data/bin/git-finish +19 -0
  5. data/bin/git-release +19 -0
  6. data/bin/git-start +19 -0
  7. data/lib/git-pivotal-tracker-integration/command/base.rb +47 -0
  8. data/lib/git-pivotal-tracker-integration/command/command.rb +20 -0
  9. data/lib/git-pivotal-tracker-integration/command/configuration.rb +109 -0
  10. data/lib/git-pivotal-tracker-integration/command/finish.rb +57 -0
  11. data/lib/git-pivotal-tracker-integration/command/prepare-commit-msg.sh +26 -0
  12. data/lib/git-pivotal-tracker-integration/command/release.rb +56 -0
  13. data/lib/git-pivotal-tracker-integration/command/start.rb +67 -0
  14. data/lib/git-pivotal-tracker-integration/util/git.rb +263 -0
  15. data/lib/git-pivotal-tracker-integration/util/shell.rb +36 -0
  16. data/lib/git-pivotal-tracker-integration/util/story.rb +124 -0
  17. data/lib/git-pivotal-tracker-integration/util/util.rb +20 -0
  18. data/lib/git-pivotal-tracker-integration/version-update/gradle.rb +64 -0
  19. data/lib/git-pivotal-tracker-integration/version-update/version_update.rb +20 -0
  20. data/lib/git_pivotal_tracker_integration.rb +18 -0
  21. data/spec/git-pivotal-tracker-integration/command/base_spec.rb +38 -0
  22. data/spec/git-pivotal-tracker-integration/command/configuration_spec.rb +91 -0
  23. data/spec/git-pivotal-tracker-integration/command/finish_spec.rb +45 -0
  24. data/spec/git-pivotal-tracker-integration/command/release_spec.rb +57 -0
  25. data/spec/git-pivotal-tracker-integration/command/start_spec.rb +54 -0
  26. data/spec/git-pivotal-tracker-integration/util/git_spec.rb +235 -0
  27. data/spec/git-pivotal-tracker-integration/util/shell_spec.rb +52 -0
  28. data/spec/git-pivotal-tracker-integration/util/story_spec.rb +137 -0
  29. data/spec/git-pivotal-tracker-integration/version-update/gradle_spec.rb +74 -0
  30. metadata +215 -0
@@ -0,0 +1,36 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'git-pivotal-tracker-integration/util/util'
17
+
18
+ # Utilities for dealing with the shell
19
+ class GitPivotalTrackerIntegration::Util::Shell
20
+
21
+ # Executes a command
22
+ #
23
+ # @param [String] command the command to execute
24
+ # @param [Boolean] abort_on_failure whether to +Kernel#abort+ with +FAIL+ as
25
+ # the message when the command's +Status#existstatus+ is not +0+
26
+ # @return [String] the result of the command
27
+ def self.exec(command, abort_on_failure = true)
28
+ result = `#{command}`
29
+ if $?.exitstatus != 0 && abort_on_failure
30
+ abort 'FAIL'
31
+ end
32
+
33
+ result
34
+ end
35
+
36
+ end
@@ -0,0 +1,124 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'git-pivotal-tracker-integration/util/util'
17
+ require 'highline/import'
18
+ require 'pivotal-tracker'
19
+
20
+ # Utilities for dealing with +PivotalTracker::Story+s
21
+ class GitPivotalTrackerIntegration::Util::Story
22
+
23
+ # Print a human readable version of a story. This pretty prints the title,
24
+ # description, and notes for the story.
25
+ #
26
+ # @param [PivotalTracker::Story] story the story to pretty print
27
+ # @return [void]
28
+ def self.pretty_print(story)
29
+ print_label LABEL_TITLE
30
+ print_value story.name
31
+
32
+ description = story.description
33
+ if !description.nil? && !description.empty?
34
+ print_label 'Description'
35
+ print_value description
36
+ end
37
+
38
+ PivotalTracker::Note.all(story).sort_by { |note| note.noted_at }.each_with_index do |note, index|
39
+ print_label "Note #{index + 1}"
40
+ print_value note.text
41
+ end
42
+
43
+ puts
44
+ end
45
+
46
+ # Selects a Pivotal Tracker story by doing the following steps:
47
+ #
48
+ # @param [PivotalTracker::Project] project the project to select stories from
49
+ # @param [String, nil] filter a filter for selecting the story to start. This
50
+ # filter can be either:
51
+ # * a story id: selects the story represented by the id
52
+ # * a story type (feature, bug, chore): offers the user a selection of stories of the given type
53
+ # * +nil+: offers the user a selection of stories of all types
54
+ # @param [Fixnum] limit The number maximum number of stories the user can choose from
55
+ # @return [PivotalTracker::Story] The Pivotal Tracker story selected by the user
56
+ def self.select_story(project, filter = nil, limit = 5)
57
+ if filter =~ /[[:digit:]]/
58
+ story = project.stories.find filter.to_i
59
+ else
60
+ story = find_story project, filter, limit
61
+ end
62
+
63
+ story
64
+ end
65
+
66
+ private
67
+
68
+ CANDIDATE_STATES = %w(rejected unstarted unscheduled).freeze
69
+
70
+ LABEL_DESCRIPTION = 'Description'.freeze
71
+
72
+ LABEL_TITLE = 'Title'.freeze
73
+
74
+ LABEL_WIDTH = (LABEL_DESCRIPTION.length + 2).freeze
75
+
76
+ CONTENT_WIDTH = (HighLine.new.output_cols - LABEL_WIDTH).freeze
77
+
78
+ def self.print_label(label)
79
+ print "%#{LABEL_WIDTH}s" % ["#{label}: "]
80
+ end
81
+
82
+ def self.print_value(value)
83
+ if value.nil? || value.empty?
84
+ puts ''
85
+ else
86
+ value.scan(/\S.{0,#{CONTENT_WIDTH - 2}}\S(?=\s|$)|\S+/).each_with_index do |line, index|
87
+ if index == 0
88
+ puts line
89
+ else
90
+ puts "%#{LABEL_WIDTH}s%s" % ['', line]
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ def self.find_story(project, type, limit)
97
+ criteria = {
98
+ :current_state => CANDIDATE_STATES,
99
+ :limit => limit
100
+ }
101
+ if type
102
+ criteria[:story_type] = type
103
+ end
104
+
105
+ candidates = project.stories.all criteria
106
+ if candidates.length == 1
107
+ story = candidates[0]
108
+ else
109
+ story = choose do |menu|
110
+ menu.prompt = 'Choose story to start: '
111
+
112
+ candidates.each do |story|
113
+ name = type ? story.name : '%-7s %s' % [story.story_type.upcase, story.name]
114
+ menu.choice(name) { story }
115
+ end
116
+ end
117
+
118
+ puts
119
+ end
120
+
121
+ story
122
+ end
123
+
124
+ end
@@ -0,0 +1,20 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'git_pivotal_tracker_integration'
17
+
18
+ # A module encapsulating utilities for the project
19
+ module GitPivotalTrackerIntegration::Util
20
+ end
@@ -0,0 +1,64 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'git-pivotal-tracker-integration/version-update/version_update'
17
+
18
+ # A version updater for dealing with _typical_ Gradle projects. This updater
19
+ # assumes that the version of the current project is stored within a
20
+ # +gradle.properties+ file in the root of the repository. This properties
21
+ # file should have an entry with a key of +version+ and version number as the key.
22
+ class GitPivotalTrackerIntegration::VersionUpdate::Gradle
23
+
24
+ # Creates an instance of this updater
25
+ #
26
+ # @param [String] root The root of the repository
27
+ def initialize(root)
28
+ @gradle_properties = File.expand_path 'gradle.properties', root
29
+
30
+ if File.exist? @gradle_properties
31
+ groups = nil
32
+ File.open(@gradle_properties, 'r') do |file|
33
+ groups = file.read().scan(/version[=:](.*)/)
34
+ end
35
+ @version = groups[0] ? groups[0][0]: nil
36
+ end
37
+ end
38
+
39
+ # Whether this updater supports updating this project
40
+ #
41
+ # @return [Boolean] +true+ if a valid version number was found on
42
+ # initialization, +false+ otherwise
43
+ def supports?
44
+ !@version.nil?
45
+ end
46
+
47
+ # The current version of the project
48
+ #
49
+ # @return [String] the current version of the project
50
+ def current_version
51
+ @version
52
+ end
53
+
54
+ # Update the version of the project
55
+ #
56
+ # @param [String] new_version the version to update the project to
57
+ # @return [void]
58
+ def update_version(new_version)
59
+ contents = File.read(@gradle_properties)
60
+ contents = contents.gsub(/(version[=:])#{@version}/, "\\1#{new_version}")
61
+ File.open(@gradle_properties, 'w') { |file| file.write(contents) }
62
+ end
63
+
64
+ end
@@ -0,0 +1,20 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'git_pivotal_tracker_integration'
17
+
18
+ # A module encapsulating version update implementations
19
+ module GitPivotalTrackerIntegration::VersionUpdate
20
+ end
@@ -0,0 +1,18 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # The root module for the project
17
+ module GitPivotalTrackerIntegration
18
+ end
@@ -0,0 +1,38 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'spec_helper'
17
+ require 'git-pivotal-tracker-integration/command/base'
18
+ require 'git-pivotal-tracker-integration/command/configuration'
19
+ require 'git-pivotal-tracker-integration/util/git'
20
+
21
+ describe GitPivotalTrackerIntegration::Command::Base do
22
+
23
+ before do
24
+ $stdout = StringIO.new
25
+ $stderr = StringIO.new
26
+
27
+ @project = double('project')
28
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:repository_root)
29
+ GitPivotalTrackerIntegration::Command::Configuration.any_instance.should_receive(:api_token)
30
+ GitPivotalTrackerIntegration::Command::Configuration.any_instance.should_receive(:project_id)
31
+ PivotalTracker::Project.should_receive(:find).and_return(@project)
32
+ @base = GitPivotalTrackerIntegration::Command::Base.new
33
+ end
34
+
35
+ it 'should not run' do
36
+ lambda { @base.run }.should raise_error
37
+ end
38
+ end
@@ -0,0 +1,91 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'spec_helper'
17
+ require 'git-pivotal-tracker-integration/command/configuration'
18
+ require 'git-pivotal-tracker-integration/util/git'
19
+ require 'pivotal-tracker'
20
+
21
+ describe GitPivotalTrackerIntegration::Command::Configuration do
22
+
23
+ before do
24
+ $stdout = StringIO.new
25
+ $stderr = StringIO.new
26
+ @configuration = GitPivotalTrackerIntegration::Command::Configuration.new
27
+ end
28
+
29
+ it 'should not prompt the user for the API token if it is already configured' do
30
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:get_config).with('pivotal.api-token', :inherited).and_return('test_api_token')
31
+
32
+ api_token = @configuration.api_token
33
+
34
+ expect(api_token).to eq('test_api_token')
35
+ end
36
+
37
+ it 'should prompt the user for the API token if it is not configured' do
38
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:get_config).with('pivotal.api-token', :inherited).and_return('')
39
+ @configuration.should_receive(:ask).and_return('test_api_token')
40
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:set_config).with('pivotal.api-token', 'test_api_token', :global)
41
+
42
+ api_token = @configuration.api_token
43
+
44
+ expect(api_token).to eq('test_api_token')
45
+ end
46
+
47
+ it 'should not prompt the user for the project id if it is already configured' do
48
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:get_config).with('pivotal.project-id', :inherited).and_return('test_project_id')
49
+
50
+ project_id = @configuration.project_id
51
+
52
+ expect(project_id).to eq('test_project_id')
53
+ end
54
+
55
+ it 'should prompt the user for the API token if it is not configured' do
56
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:get_config).with('pivotal.project-id', :inherited).and_return('')
57
+ menu = double('menu')
58
+ menu.should_receive(:prompt=)
59
+ PivotalTracker::Project.should_receive(:all).and_return([
60
+ PivotalTracker::Project.new(:id => 'id-2', :name => 'name-2'),
61
+ PivotalTracker::Project.new(:id => 'id-1', :name => 'name-1')])
62
+ menu.should_receive(:choice).with('name-1')
63
+ menu.should_receive(:choice).with('name-2')
64
+ @configuration.should_receive(:choose) { |&arg| arg.call menu }.and_return('test_project_id')
65
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:set_config).with('pivotal.project-id', 'test_project_id', :local)
66
+
67
+ project_id = @configuration.project_id
68
+
69
+ expect(project_id).to eq('test_project_id')
70
+ end
71
+
72
+ it 'should persist the story when requested' do
73
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:set_config).with('pivotal-story-id', 12345678, :branch)
74
+
75
+ @configuration.story = PivotalTracker::Story.new(:id => 12345678)
76
+ end
77
+
78
+ it 'should return a story when requested' do
79
+ project = double('project')
80
+ stories = double('stories')
81
+ story = double('story')
82
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:get_config).with('pivotal-story-id', :branch).and_return('12345678')
83
+ project.should_receive(:stories).and_return(stories)
84
+ stories.should_receive(:find).with(12345678).and_return(story)
85
+
86
+ result = @configuration.story project
87
+
88
+ expect(result).to be(story)
89
+ end
90
+
91
+ end
@@ -0,0 +1,45 @@
1
+ # Git Pivotal Tracker Integration
2
+ # Copyright (c) 2013 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'spec_helper'
17
+ require 'git-pivotal-tracker-integration/command/configuration'
18
+ require 'git-pivotal-tracker-integration/command/finish'
19
+ require 'git-pivotal-tracker-integration/util/git'
20
+ require 'pivotal-tracker'
21
+
22
+ describe GitPivotalTrackerIntegration::Command::Finish do
23
+
24
+ before do
25
+ $stdout = StringIO.new
26
+ $stderr = StringIO.new
27
+
28
+ @project = double('project')
29
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:repository_root)
30
+ GitPivotalTrackerIntegration::Command::Configuration.any_instance.should_receive(:api_token)
31
+ GitPivotalTrackerIntegration::Command::Configuration.any_instance.should_receive(:project_id)
32
+ PivotalTracker::Project.should_receive(:find).and_return(@project)
33
+ @finish = GitPivotalTrackerIntegration::Command::Finish.new
34
+ end
35
+
36
+ it 'should run' do
37
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:trivial_merge?)
38
+ GitPivotalTrackerIntegration::Command::Configuration.any_instance.should_receive(:story)
39
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:merge)
40
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:branch_name).and_return('master')
41
+ GitPivotalTrackerIntegration::Util::Git.should_receive(:push).with('master')
42
+
43
+ @finish.run nil
44
+ end
45
+ end