idealian-git-pivotal 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG +14 -0
- data/LICENSE +21 -0
- data/Rakefile +35 -0
- data/VERSION +1 -0
- data/bin/git-bug +8 -0
- data/bin/git-chore +8 -0
- data/bin/git-feature +8 -0
- data/bin/git-finish +8 -0
- data/bin/git-pick +9 -0
- data/git-pivotal.gemspec +111 -0
- data/lib/commands/base.rb +63 -0
- data/lib/commands/bug.rb +19 -0
- data/lib/commands/chore.rb +19 -0
- data/lib/commands/feature.rb +19 -0
- data/lib/commands/finish.rb +41 -0
- data/lib/commands/pick.rb +61 -0
- data/lib/pivotal.rb +8 -0
- data/lib/pivotal/api.rb +17 -0
- data/lib/pivotal/associations.rb +17 -0
- data/lib/pivotal/attributes.rb +25 -0
- data/lib/pivotal/base.rb +72 -0
- data/lib/pivotal/collection.rb +63 -0
- data/lib/pivotal/project.rb +14 -0
- data/lib/pivotal/story.rb +35 -0
- data/readme.markdown +55 -0
- data/spec/commands/base_spec.rb +83 -0
- data/spec/commands/bug_spec.rb +25 -0
- data/spec/commands/chore_spec.rb +25 -0
- data/spec/commands/feature_spec.rb +25 -0
- data/spec/factories.rb +13 -0
- data/spec/factory.rb +26 -0
- data/spec/pivotal/api_spec.rb +18 -0
- data/spec/pivotal/associations_spec.rb +13 -0
- data/spec/pivotal/attributes_spec.rb +31 -0
- data/spec/pivotal/base_spec.rb +77 -0
- data/spec/pivotal/collection_spec.rb +25 -0
- data/spec/pivotal/project_spec.rb +34 -0
- data/spec/pivotal/story_spec.rb +100 -0
- data/spec/spec_helper.rb +18 -0
- metadata +191 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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
|
data/bin/git-bug
ADDED
data/bin/git-chore
ADDED
data/bin/git-feature
ADDED
data/bin/git-finish
ADDED
data/bin/git-pick
ADDED
@@ -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!
|
data/git-pivotal.gemspec
ADDED
@@ -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
|
data/lib/commands/bug.rb
ADDED
@@ -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
|