idealian-git-pivotal 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg
2
+ coverage
3
+ *.gem
@@ -0,0 +1,14 @@
1
+ v 0.1.3
2
+ - Fixed bug preventing command line args from being properly interpretted
3
+
4
+ v 0.1.2
5
+ - Fixed bug introduced in v 0.1.1 which prevented git pick from completing
6
+
7
+ v 0.1.1
8
+ - Updated git pick to tell Pivotal who owns the picked feature
9
+ - Improved Pivotal Tracker framework write ability
10
+
11
+ v 0.1.0
12
+ - Initial release
13
+ - Basic framework for reading from Pivotal Tracker
14
+ - git pick utility
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Jeff Tucker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'spec/rake/spectask'
4
+
5
+ $LOAD_PATH.unshift('lib')
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gemspec|
10
+ gemspec.name = "git-pivotal"
11
+ gemspec.summary = "A collection of git utilities to ease integration with Pivotal Tracker"
12
+ gemspec.description = "A collection of git utilities to ease integration with Pivotal Tracker"
13
+ gemspec.email = "jeff@trydionel.com"
14
+ gemspec.homepage = "http://github.com/trydionel/git-pivotal"
15
+ gemspec.authors = ["Jeff Tucker", "Sam Stokes"]
16
+
17
+ gemspec.add_dependency "nokogiri"
18
+ gemspec.add_dependency "rest-client"
19
+ gemspec.add_dependency "builder"
20
+
21
+ gemspec.add_development_dependency "rspec"
22
+ gemspec.add_development_dependency "rcov"
23
+ gemspec.add_development_dependency "mocha"
24
+ end
25
+
26
+ Jeweler::GemcutterTasks.new
27
+ rescue
28
+ puts "Jeweler not available. Install it with: gem install jeweler"
29
+ end
30
+
31
+ Spec::Rake::SpecTask.new do |t|
32
+ t.spec_opts = ['--color']
33
+ t.rcov = true
34
+ t.rcov_opts = ['--exclude', 'gems']
35
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.2
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'pivotal'
6
+ require 'commands/bug'
7
+
8
+ exit Commands::Bug.new(STDIN, STDOUT, *ARGV).run!
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'pivotal'
6
+ require 'commands/chore'
7
+
8
+ exit Commands::Chore.new(STDIN, STDOUT, *ARGV).run!
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'pivotal'
6
+ require 'commands/feature'
7
+
8
+ exit Commands::Feature.new(STDIN, STDOUT, *ARGV).run!
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'pivotal'
6
+ require 'commands/finish'
7
+
8
+ exit Commands::Finish.new(STDIN, STDOUT, *ARGV).run!
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'pivotal'
6
+ require 'commands/feature'
7
+
8
+ STDOUT.puts "DEPRECATION WARNING: git pick has been deprecated. Please use git feature instead."
9
+ exit Commands::Feature.new(STDIN, STDOUT, *ARGV).run!
@@ -0,0 +1,111 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{git-pivotal}
8
+ s.version = "0.2.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jeff Tucker", "Sam Stokes"]
12
+ s.date = %q{2010-03-11}
13
+ s.description = %q{A collection of git utilities to ease integration with Pivotal Tracker}
14
+ s.email = %q{jeff@trydionel.com}
15
+ s.executables = ["git-bug", "git-chore", "git-feature", "git-finish", "git-pick"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "CHANGELOG",
22
+ "LICENSE",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "bin/git-bug",
26
+ "bin/git-chore",
27
+ "bin/git-feature",
28
+ "bin/git-finish",
29
+ "bin/git-pick",
30
+ "git-pivotal.gemspec",
31
+ "lib/commands/base.rb",
32
+ "lib/commands/bug.rb",
33
+ "lib/commands/chore.rb",
34
+ "lib/commands/feature.rb",
35
+ "lib/commands/finish.rb",
36
+ "lib/commands/pick.rb",
37
+ "lib/pivotal.rb",
38
+ "lib/pivotal/api.rb",
39
+ "lib/pivotal/associations.rb",
40
+ "lib/pivotal/attributes.rb",
41
+ "lib/pivotal/base.rb",
42
+ "lib/pivotal/collection.rb",
43
+ "lib/pivotal/project.rb",
44
+ "lib/pivotal/story.rb",
45
+ "readme.markdown",
46
+ "spec/commands/base_spec.rb",
47
+ "spec/commands/bug_spec.rb",
48
+ "spec/commands/chore_spec.rb",
49
+ "spec/commands/feature_spec.rb",
50
+ "spec/factories.rb",
51
+ "spec/factory.rb",
52
+ "spec/pivotal/api_spec.rb",
53
+ "spec/pivotal/associations_spec.rb",
54
+ "spec/pivotal/attributes_spec.rb",
55
+ "spec/pivotal/base_spec.rb",
56
+ "spec/pivotal/collection_spec.rb",
57
+ "spec/pivotal/project_spec.rb",
58
+ "spec/pivotal/story_spec.rb",
59
+ "spec/spec_helper.rb"
60
+ ]
61
+ s.homepage = %q{http://github.com/trydionel/git-pivotal}
62
+ s.rdoc_options = ["--charset=UTF-8"]
63
+ s.require_paths = ["lib"]
64
+ s.rubygems_version = %q{1.3.6}
65
+ s.summary = %q{A collection of git utilities to ease integration with Pivotal Tracker}
66
+ s.test_files = [
67
+ "spec/commands/base_spec.rb",
68
+ "spec/commands/bug_spec.rb",
69
+ "spec/commands/chore_spec.rb",
70
+ "spec/commands/feature_spec.rb",
71
+ "spec/factories.rb",
72
+ "spec/factory.rb",
73
+ "spec/pivotal/api_spec.rb",
74
+ "spec/pivotal/associations_spec.rb",
75
+ "spec/pivotal/attributes_spec.rb",
76
+ "spec/pivotal/base_spec.rb",
77
+ "spec/pivotal/collection_spec.rb",
78
+ "spec/pivotal/project_spec.rb",
79
+ "spec/pivotal/story_spec.rb",
80
+ "spec/spec_helper.rb"
81
+ ]
82
+
83
+ if s.respond_to? :specification_version then
84
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
85
+ s.specification_version = 3
86
+
87
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
88
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
89
+ s.add_runtime_dependency(%q<rest-client>, [">= 0"])
90
+ s.add_runtime_dependency(%q<builder>, [">= 0"])
91
+ s.add_development_dependency(%q<rspec>, [">= 0"])
92
+ s.add_development_dependency(%q<rcov>, [">= 0"])
93
+ s.add_development_dependency(%q<mocha>, [">= 0"])
94
+ else
95
+ s.add_dependency(%q<nokogiri>, [">= 0"])
96
+ s.add_dependency(%q<rest-client>, [">= 0"])
97
+ s.add_dependency(%q<builder>, [">= 0"])
98
+ s.add_dependency(%q<rspec>, [">= 0"])
99
+ s.add_dependency(%q<rcov>, [">= 0"])
100
+ s.add_dependency(%q<mocha>, [">= 0"])
101
+ end
102
+ else
103
+ s.add_dependency(%q<nokogiri>, [">= 0"])
104
+ s.add_dependency(%q<rest-client>, [">= 0"])
105
+ s.add_dependency(%q<builder>, [">= 0"])
106
+ s.add_dependency(%q<rspec>, [">= 0"])
107
+ s.add_dependency(%q<rcov>, [">= 0"])
108
+ s.add_dependency(%q<mocha>, [">= 0"])
109
+ end
110
+ end
111
+
@@ -0,0 +1,63 @@
1
+ require 'optparse'
2
+
3
+ module Commands
4
+ class Base
5
+
6
+ attr_accessor :input, :output, :options
7
+
8
+ def initialize(input=STDIN, output=STDOUT, *args)
9
+ @input = input
10
+ @output = output
11
+ @options = {}
12
+
13
+ parse_gitconfig
14
+ parse_argv(*args)
15
+ end
16
+
17
+ def put(string, newline=true)
18
+ @output.print(newline ? string + "\n" : string) unless options[:quiet]
19
+ end
20
+
21
+ def sys(cmd)
22
+ put cmd if options[:verbose]
23
+ system cmd
24
+ end
25
+
26
+ def get(cmd)
27
+ put cmd if options[:verbose]
28
+ `#{cmd}`
29
+ end
30
+
31
+ def run!
32
+ unless options[:api_token] && options[:project_id]
33
+ put "Pivotal Tracker API Token and Project ID are required"
34
+ return 1
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def parse_gitconfig
41
+ token = get("git config --get pivotal.api-token").strip
42
+ id = get("git config --get pivotal.project-id").strip
43
+ name = get("git config --get pivotal.full-name").strip
44
+
45
+ options[:api_token] = token unless token == ""
46
+ options[:project_id] = id unless id == ""
47
+ options[:full_name] = name unless name == ""
48
+ end
49
+
50
+ def parse_argv(*args)
51
+ OptionParser.new do |opts|
52
+ opts.banner = "Usage: git pick [options]"
53
+ opts.on("-k", "--api-key=", "Pivotal Tracker API key") { |k| options[:api_token] = k }
54
+ opts.on("-p", "--project-id=", "Pivotal Trakcer project id") { |p| options[:project_id] = p }
55
+ opts.on("-n", "--full-name=", "Pivotal Trakcer full name") { |n| options[:full_name] = n }
56
+ opts.on("-q", "--quiet", "Quiet, no-interaction mode") { |q| options[:quiet] = q }
57
+ opts.on("-v", "--[no-]verbose", "Run verbosely") { |v| options[:verbose] = v }
58
+ opts.on_tail("-h", "--help", "This usage guide") { put opts; exit 0 }
59
+ end.parse!(args)
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,19 @@
1
+ require 'commands/pick'
2
+
3
+ module Commands
4
+ class Bug < Pick
5
+
6
+ def type
7
+ "bug"
8
+ end
9
+
10
+ def plural_type
11
+ "bugs"
12
+ end
13
+
14
+ def branch_suffix
15
+ "bugfix"
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'commands/pick'
2
+
3
+ module Commands
4
+ class Chore < Pick
5
+
6
+ def type
7
+ "chore"
8
+ end
9
+
10
+ def plural_type
11
+ "chores"
12
+ end
13
+
14
+ def branch_suffix
15
+ "chore"
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'commands/pick'
2
+
3
+ module Commands
4
+ class Feature < Pick
5
+
6
+ def type
7
+ "feature"
8
+ end
9
+
10
+ def plural_type
11
+ "features"
12
+ end
13
+
14
+ def branch_suffix
15
+ "feature"
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ require 'commands/base'
2
+
3
+ module Commands
4
+ class Finish < Base
5
+
6
+ def run!
7
+ super
8
+
9
+ # clunky way to get branch name... need better method
10
+ current_branch = get('git status | head -1').gsub(/^.+On branch /, '').chomp
11
+ story_id = current_branch[/\d+/]
12
+ unless story_id
13
+ put "Branch name must contain a Pivotal Tracker story id"
14
+ return 1
15
+ end
16
+
17
+ api = Pivotal::Api.new(:api_token => options[:api_token])
18
+ project = api.projects.find(:id => options[:project_id])
19
+ story = project.stories.find(:id => story_id)
20
+
21
+ put "Marking Story #{story_id} as finished..."
22
+ if story.update_attributes(:current_state => :finished)
23
+
24
+ target_branch = "develop"
25
+ put "Merging #{current_branch} into #{target_branch}"
26
+ sys "git checkout #{target_branch}"
27
+ sys "git merge --no-ff #{current_branch}"
28
+
29
+ put "Removing #{current_branch} branch"
30
+ sys "git branch -d #{current_branch}"
31
+
32
+ return 0
33
+ else
34
+ put "Unable to mark Story #{story_id} as finished"
35
+
36
+ return 1
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,61 @@
1
+ require 'commands/base'
2
+
3
+ module Commands
4
+ class Pick < Base
5
+
6
+ def type
7
+ raise Error "must define in subclass"
8
+ end
9
+
10
+ def plural_type
11
+ raise Error "must define in subclass"
12
+ end
13
+
14
+ def branch_suffix
15
+ raise Error "must define in subclass"
16
+ end
17
+
18
+ def run!
19
+ super
20
+
21
+ put "Retrieving latest #{plural_type} from Pivotal Tracker..."
22
+ api = Pivotal::Api.new(:api_token => options[:api_token])
23
+
24
+ project = api.projects.find(:id => options[:project_id])
25
+ story = project.stories.find(:conditions => { :story_type => type, :current_state => :unstarted }, :limit => 1).first
26
+
27
+ unless story
28
+ put "No #{plural_type} available!"
29
+ return 0
30
+ end
31
+
32
+ put "Story: #{story.name}"
33
+ put "URL: #{story.url}"
34
+
35
+ put "Updating #{type} status in Pivotal Tracker..."
36
+ if story.start!(:owned_by => options[:full_name])
37
+
38
+ suffix = branch_suffix
39
+ unless options[:quiet]
40
+ put "Enter branch name (will be prepended by #{story.id}) [#{suffix}]: ", false
41
+ suffix = input.gets.chomp
42
+
43
+ suffix = "feature" if suffix == ""
44
+ end
45
+
46
+ branch = "#{story.id}-#{suffix}"
47
+ if get("git branch").match(branch).nil?
48
+ put "Creating #{branch} branch..."
49
+ sys "git checkout -b #{branch}"
50
+ end
51
+
52
+ return 0
53
+ else
54
+ put "Unable to mark #{type} as started"
55
+
56
+ return 1
57
+ end
58
+ end
59
+
60
+ end
61
+ end