git-commit-story 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rvmrc +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/README.md +5 -0
- data/bin/git-commit-story +32 -0
- data/bin/git-cs +32 -0
- data/git-commit-story.gemspec +16 -0
- data/lib/git-commit-story.rb +73 -0
- data/spec/lib/git-commit-story_spec.rb +130 -0
- data/spec_watchr.rb +2 -0
- metadata +89 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rvmrc
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
git-commit-story (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.2.4)
|
10
|
+
rspec (2.13.0)
|
11
|
+
rspec-core (~> 2.13.0)
|
12
|
+
rspec-expectations (~> 2.13.0)
|
13
|
+
rspec-mocks (~> 2.13.0)
|
14
|
+
rspec-core (2.13.1)
|
15
|
+
rspec-expectations (2.13.0)
|
16
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
17
|
+
rspec-mocks (2.13.1)
|
18
|
+
watchr (0.7)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
git-commit-story!
|
25
|
+
rspec
|
26
|
+
watchr
|
data/README.md
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
This is a thin wrapper around git-commit that adds a story id to commit messages.
|
2
|
+
|
3
|
+
Usage: git commit-story --message 'message' --story 'story'
|
4
|
+
-m, --message MESSAGE The commit message
|
5
|
+
-s, --story STORY The story ID (This can be the Pivotal id, AgileZen id, or any label)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "git-commit-story"
|
5
|
+
|
6
|
+
class GitCommitStoryRunner
|
7
|
+
def initialize(args)
|
8
|
+
parse_args(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_args(args)
|
12
|
+
parser = OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: git commit-story --message 'message' --story 'story'"
|
14
|
+
opts.on("-m", "--message MESSAGE", "The commit message") do |message|
|
15
|
+
puts "message: #{message}"
|
16
|
+
@message = message
|
17
|
+
end
|
18
|
+
opts.on("-s", "--story STORY", "The story ID (This can be the Pivotal id, AgileZen id, or any label)") do |story_id|
|
19
|
+
@story = story_id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
parser.parse!
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
gcs = GitCommitStory.new(:commit_message => @message, :story_id => @story)
|
28
|
+
gcs.commit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
GitCommitStoryRunner.new(ARGV).run
|
data/bin/git-cs
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "git-commit-story"
|
5
|
+
|
6
|
+
class GitCommitStoryRunner
|
7
|
+
def initialize(args)
|
8
|
+
parse_args(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_args(args)
|
12
|
+
parser = OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: git commit-story --message 'message' --story 'story'"
|
14
|
+
opts.on("-m", "--message MESSAGE", "The commit message") do |message|
|
15
|
+
puts "message: #{message}"
|
16
|
+
@message = message
|
17
|
+
end
|
18
|
+
opts.on("-s", "--story STORY", "The story ID (This can be the Pivotal id, AgileZen id, or any label)") do |story_id|
|
19
|
+
@story = story_id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
parser.parse!
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
gcs = GitCommitStory.new(:commit_message => @message, :story_id => @story)
|
28
|
+
gcs.commit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
GitCommitStoryRunner.new(ARGV).run
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "git-commit-story"
|
3
|
+
s.executables << "git-commit-story"
|
4
|
+
s.version = "0.1.0"
|
5
|
+
s.date = "2013-04-30"
|
6
|
+
s.summary = "StreamSend git commit wrapper"
|
7
|
+
s.description = "Thin wrapper around git commit that adds a story id to commit messages"
|
8
|
+
s.authors = ["Jeff Roush"]
|
9
|
+
s.email = "jroush@ezpublishing.com"
|
10
|
+
s.files = ["lib/git-commit-story.rb"]
|
11
|
+
s.homepage = "https://github.com/Jeff-R/git-commit-story"
|
12
|
+
s.files = `git ls-files`.split($/)
|
13
|
+
|
14
|
+
s.add_development_dependency "rspec"
|
15
|
+
s.add_development_dependency "watchr"
|
16
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
class GitCommitStory
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@config_file_name = ".git-commit-story.yml"
|
9
|
+
config_file_options = options_from_config_file
|
10
|
+
config_file_options.merge!(options)
|
11
|
+
@options = config_file_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def options_from_config_file
|
15
|
+
if File.exist?(@config_file_name)
|
16
|
+
config_file_options = YAML.load_file(@config_file_name)
|
17
|
+
else
|
18
|
+
{}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def save_config_file
|
23
|
+
File.open(@config_file_name, "w") { |f| f.puts @options.to_yaml }
|
24
|
+
end
|
25
|
+
|
26
|
+
def story_id
|
27
|
+
if @options[:story_id]
|
28
|
+
@options[:story_id]
|
29
|
+
else
|
30
|
+
prompt = "Enter a story"
|
31
|
+
prompt += " [#{@options[:previous_story_id]}]" if @options[:previous_story_id]
|
32
|
+
puts prompt
|
33
|
+
response = $stdin.gets.strip
|
34
|
+
if response == ""
|
35
|
+
if @options[:previous_story_id]
|
36
|
+
@options[:story_id] = @options[:previous_story_id]
|
37
|
+
else
|
38
|
+
puts "No story id was supplied"
|
39
|
+
abort
|
40
|
+
end
|
41
|
+
else
|
42
|
+
@options[:story_id] = response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def final_commit_message
|
48
|
+
message = ""
|
49
|
+
if options[:commit_message]
|
50
|
+
message = options[:commit_message]
|
51
|
+
else
|
52
|
+
message = get_message_from_prompt
|
53
|
+
end
|
54
|
+
"#{message}\n\nstory: #{story_id}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_message_from_prompt
|
58
|
+
puts "Enter a commit message"
|
59
|
+
message = $stdin.gets
|
60
|
+
if message.length == 0
|
61
|
+
puts "No message supplied"
|
62
|
+
abort
|
63
|
+
end
|
64
|
+
message.strip
|
65
|
+
end
|
66
|
+
|
67
|
+
def commit
|
68
|
+
message = "git commit -m '#{final_commit_message}'"
|
69
|
+
result = system(message)
|
70
|
+
options[:previous_story_id] = story_id
|
71
|
+
save_config_file
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require "git-commit-story"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
describe GitCommitStory do
|
5
|
+
let(:config_file_name) { ".git-commit-story.yml" }
|
6
|
+
|
7
|
+
before do
|
8
|
+
YAML.stub(:load_file).with(config_file_name).and_return({})
|
9
|
+
File.stub(:open).with(anything, "w")
|
10
|
+
File.stub(:exist?).and_return(true)
|
11
|
+
$stdin.stub(:gets)
|
12
|
+
$stdout.stub(:puts)
|
13
|
+
$stderr.stub(:puts)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with a story id" do
|
17
|
+
it "doesn't prompt for a story" do
|
18
|
+
$stdout.should_not_receive(:puts)
|
19
|
+
$stdin.should_not_receive(:gets)
|
20
|
+
GitCommitStory.new(story_id: "anything").story_id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "without a story id" do
|
25
|
+
it "prompts for a story" do
|
26
|
+
$stdout.should_receive(:puts).with("Enter a story")
|
27
|
+
$stdin.should_receive(:gets).and_return("story")
|
28
|
+
gcs = GitCommitStory.new({})
|
29
|
+
gcs.story_id
|
30
|
+
end
|
31
|
+
|
32
|
+
it "saves the new story id to options" do
|
33
|
+
new_story_id = "my new story"
|
34
|
+
$stdin.stub(:gets).and_return("#{new_story_id}\n")
|
35
|
+
gcs = GitCommitStory.new({})
|
36
|
+
gcs.story_id
|
37
|
+
gcs.options[:story_id].should == new_story_id
|
38
|
+
end
|
39
|
+
|
40
|
+
it "includes a saved story id in the prompt" do
|
41
|
+
gcs = GitCommitStory.new({message: "new message"})
|
42
|
+
gcs.options[:previous_story_id] = "previous story"
|
43
|
+
$stdout.should_receive(:puts).with("Enter a story [previous story]")
|
44
|
+
$stdin.should_receive(:gets).and_return("")
|
45
|
+
gcs.story_id
|
46
|
+
end
|
47
|
+
|
48
|
+
it "uses the previous story id if the user presses enter" do
|
49
|
+
gcs = GitCommitStory.new({message: "new message"})
|
50
|
+
new_story_id = "previous story"
|
51
|
+
gcs.options[:previous_story_id] = new_story_id
|
52
|
+
$stdin.stub(:gets).and_return("")
|
53
|
+
gcs.story_id
|
54
|
+
gcs.options[:story_id].should == new_story_id
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "reads .git-commit-story.yml if one exists" do
|
59
|
+
YAML.should_receive(:load_file).with(config_file_name).and_return({foo: "bar"})
|
60
|
+
gcs = GitCommitStory.new({})
|
61
|
+
gcs.options[:foo].should == "bar"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "overrides config file options with passed options" do
|
65
|
+
YAML.should_receive(:load_file).with(config_file_name).and_return({foo: "bar", what: "ever"})
|
66
|
+
gcs = GitCommitStory.new({foo: "baz"})
|
67
|
+
gcs.options[:foo].should == "baz"
|
68
|
+
gcs.options[:what].should == "ever"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "saves its configuration to a .git-commit-story.yml" do
|
72
|
+
mock_file = mock("file")
|
73
|
+
options = { foo: "bar" }
|
74
|
+
mock_file.should_receive(:puts).with(options.to_yaml.to_s)
|
75
|
+
File.should_receive(:open).with(config_file_name, "w").and_yield(mock_file)
|
76
|
+
GitCommitStory.new(options).save_config_file
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "with a commit message" do
|
80
|
+
it "adds the story id to the commit message" do
|
81
|
+
commit_message = "the commit message"
|
82
|
+
gcs = GitCommitStory.new(commit_message: commit_message, story_id: "whatever")
|
83
|
+
message = "#{commit_message}\n\nstory: whatever"
|
84
|
+
gcs.final_commit_message.should == message
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "without a commit message" do
|
89
|
+
it "prompts for a commit message" do
|
90
|
+
$stdout.should_receive(:puts).with("Enter a commit message")
|
91
|
+
$stdin.should_receive(:gets).and_return("new commit message\n")
|
92
|
+
gcs = GitCommitStory.new(story_id: "whatever")
|
93
|
+
gcs.final_commit_message.should == "new commit message\n\nstory: whatever"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "saves a commit" do
|
98
|
+
gcs = GitCommitStory.new(:commit_message => "commit message", story_id: "whatever")
|
99
|
+
shell_command_string = "git commit -m '#{gcs.final_commit_message}'"
|
100
|
+
gcs.should_receive(:system).with(shell_command_string)
|
101
|
+
gcs.commit
|
102
|
+
end
|
103
|
+
|
104
|
+
it "saves the previous story_id after a commit" do
|
105
|
+
gcs = GitCommitStory.new(:commit_message => "commit message", story_id: "whatever")
|
106
|
+
gcs.stub(:system)
|
107
|
+
gcs.should_receive(:save_config_file)
|
108
|
+
gcs.commit
|
109
|
+
gcs.options[:previous_story_id].should == "whatever"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "aborts a commit if the user enters an empty message" do
|
113
|
+
gcs = GitCommitStory.new(story_id: "whatever")
|
114
|
+
$stdin.stub(:gets).and_return("")
|
115
|
+
$stdout.should_receive(:puts).with("No message supplied")
|
116
|
+
expect {
|
117
|
+
gcs.get_message_from_prompt
|
118
|
+
}.to raise_error SystemExit
|
119
|
+
end
|
120
|
+
|
121
|
+
it "aborts a commit if the user enters an empty story id" do
|
122
|
+
gcs = GitCommitStory.new(message: "whatever")
|
123
|
+
$stdin.stub(:gets).and_return("")
|
124
|
+
$stdout.should_receive(:puts).with("No story id was supplied")
|
125
|
+
expect {
|
126
|
+
gcs.story_id
|
127
|
+
}.to raise_error SystemExit
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
data/spec_watchr.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: git-commit-story
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeff Roush
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: watchr
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Thin wrapper around git commit that adds a story id to commit messages
|
47
|
+
email: jroush@ezpublishing.com
|
48
|
+
executables:
|
49
|
+
- git-commit-story
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- .rspec
|
55
|
+
- .rvmrc
|
56
|
+
- Gemfile
|
57
|
+
- Gemfile.lock
|
58
|
+
- README.md
|
59
|
+
- bin/git-commit-story
|
60
|
+
- bin/git-cs
|
61
|
+
- git-commit-story.gemspec
|
62
|
+
- lib/git-commit-story.rb
|
63
|
+
- spec/lib/git-commit-story_spec.rb
|
64
|
+
- spec_watchr.rb
|
65
|
+
homepage: https://github.com/Jeff-R/git-commit-story
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.25
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: StreamSend git commit wrapper
|
89
|
+
test_files: []
|