pivotal-github 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rspec', '~> 2.12.0'
4
+ gem 'httparty', '~> 0.10.0'
5
+
6
+ # Specify your gem's dependencies in pivotal-github.gemspec
7
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Hartl
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # pivotal-github
2
+
3
+ **NOTE:** This gem is as-yet unreleased.
4
+
5
+ This gem facilitates a Pivotal Tracker–GitHub workflow inspired by [Logical Reality](http://lrdesign.com/).
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'pivotal-github'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install pivotal-github
20
+
21
+
22
+ ## Usage
23
+
24
+ The `pivotal-github` gem adds several additional Git commands to the local environment.
25
+
26
+ ### git story-commit
27
+
28
+ `git story-commit` makes a standard `git commit` with the story number added to the commit message. This automatically adds a link at Pivotal Tracker between the story and the diff at GitHub.
29
+
30
+ For example, when on a branch called `6283185-add-markdown-support`, the `git story-commit` command automatically adds `[#6283185]` to the commit message:
31
+
32
+ $ git story-commit -am "Add foo bars"
33
+ [6283185-add-markdown-support 6f56414] [#6283185] Add foo bars
34
+
35
+
36
+ Here's the full usage info:
37
+
38
+ $ git story-commit -h
39
+ Usage: git story-commit [options]
40
+ -m, --message MESSAGE add a commit message (including story #)
41
+ -f, --finish mark story as finished
42
+ -d, --deliver mark story as delivered
43
+ -a, --all commit all changed files
44
+ -h, --help this usage guide
45
+
46
+ Additionally, `git story-commit` accepts any options valid for `git commit`.
47
+
48
+ ### git story-push
49
+
50
+ `git story push` creates a remote branch at `origin` with the name of the current branch:
51
+
52
+ $ git story-push
53
+ * [new branch] 6283185-add-markdown-support -> 6283185-add-markdown-support
54
+
55
+ this usage guide
56
+
57
+ `git story-push` accepts any options valid for `git push`.
58
+
59
+ ### git story-pull
60
+
61
+ `git story-pull` syncs the local `master` with the remote `master`. On a branch called `6283185-add-markdown-support`, `git story-pull` is equivalent to the following:
62
+
63
+ $ git checkout master
64
+ $ git pull
65
+ $ git checkout 6283185-add-markdown-support
66
+
67
+ The purpose of `git story-pull` it to prepare the local story branch for rebasing against `master`:
68
+
69
+ $ git story-pull
70
+ $ git rebase master
71
+
72
+ This is essentially equivalent to
73
+
74
+ $ git fetch
75
+ $ git rebase origin/master
76
+
77
+ but I don't like having `master` and `origin/master` be different since it forces you to remember to run `git pull` on `master` some time down the line.
78
+
79
+ ### git story-merge
80
+
81
+ `git story-merge` merges the current branch into `master`. On a branch called `6283185-add-markdown-support`, `git story-merge` is equivalent to the following:
82
+
83
+ $ git checkout master
84
+ $ git merge 6283185-add-markdown-support
85
+
86
+ ## Configuration
87
+
88
+ In order to use the `pivotal-github` gem, you need to configure a [post-receive hook for Pivotal Tracker at GitHub](https://www.pivotaltracker.com/help/api?version=v3#github_hooks) for your repository. (To find your Pivotal Tracker API token, go to your user profile and scroll to the bottom.)
89
+
90
+ The `pivotal-github` command names follow the Git convention of being verbose (it's telling that, unlike Subversion, Git doesn't natively support `co` for `checkout`), but I recommend setting up aliases as necessary. Here are some suggestions:
91
+
92
+ $ git config --global alias.sc story-commit
93
+ $ git config --global alias.sp story-push
94
+ $ git config --global alias.sl story-pull
95
+ $ git config --global alias.sm story-merge
96
+
97
+ A single-developer workflow would then look like this:
98
+
99
+ $ git co -b 6283185-add-markdown-support
100
+ $ git sp
101
+ <work>
102
+ $ git sc -am "Added foo"
103
+ $ git push
104
+ <more work>
105
+ $ git sc -am "Added bar"
106
+ <complete story>
107
+ $ git sc -f -am "Added baz"
108
+ $ git push
109
+ $ git sl
110
+ $ git rebase master
111
+ $ git sm
112
+
113
+ Note that this workflow uses `git sp` (and subsequent invocations of `git push`) only to create a remote storage backup. The principal purpose of `git story-push` is to support the integrated code review workflow described below.
114
+
115
+ ## Workflow
116
+
117
+ The `pivotal-github` gem is degined to support a workflow that involves integrated code review, which has the usual advantages: at least two pairs of eyes see any committed code, and at least two brains know basically what the committed code does. Here's the process in detail:
118
+
119
+ ### Developer #1 (Alice)
120
+
121
+ 1. Start an issue at [Pivotal Tracker](http://pivotaltracker.com/)
122
+ 2. Create a branch in the local Git repository containing the story number and a brief description: `git checkout -b 6283185-add-markdown-support`
123
+ 3. Create a remote branch at [GitHub](http://github.com/) using `git story-push`
124
+ 3. Use `git story-commit` to make commits, which includes the story number in the commit message: `git story-commit -am "Add syntax highlighting"`
125
+ 4. Continue pushing up after each commit using `git push` as usual
126
+ 4. When done with the story, add `-f` to mark the story as finished: `git story-commit -f -am "Add paragraph breaks"`
127
+ 4. Rebase against `master` using `git story-pull` followed by `git rebase master` or `git rebase master --interactive` (optionally squashing commit messages as described in the article [A Git Workflow for Agile Teams](http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html))
128
+ 4. Push up with `git push`
129
+ 6. At the GitHub page for the repo, select "Branches" and submit a pull request
130
+ 7. **(experimental)** Add a story of type Chore to Pivotal Tracker and assign it to Developer #2 (Bob)
131
+
132
+
133
+ ### Developer #2 (Bob)
134
+
135
+ 1. Review the pull request diffs
136
+ 2. If acceptable, merge the branch
137
+ 3. If not acceptable, manually change the state at Pivotal Tracker to Rejected
138
+ 4. **(experimental)** If there are conflicts, make a Chore to resolve the conflicts and assign it to Alice
139
+
140
+ Until Bob accepts the pull request, Alice can continue working on new stories, taking care to branch off of the current branch if she needs its changes to continue. Note that the commits will appear on the story as soon as Alice creates a remote branch (and as she pushes to it), but it won't be marked 'finished' or 'delivered' until Bob merges the pull request into `master`.
141
+
142
+ ## Merge conflicts
143
+
144
+ This section contains some suggestions for resolving merge conflicts. First, set up a visual merge tool by installing [diffmerge](http://www.sourcegear.com/diffmerge/). Then add the following to the `.gitconfig` file in your home directory:
145
+
146
+ [mergetool "diffmerge"]
147
+ cmd = diffmerge --merge --result=$MERGED $LOCAL $BASE $REMOTE
148
+ trustExitCode = false
149
+
150
+ When the branch can't automatically be merged at GitHub, follow these steps:
151
+
152
+ ### Devleloper #1 (Alice)
153
+
154
+ 1. While on the story branch, run `git story-pull`
155
+ 2. Rebase against `master` with `git rebase master` **or** merge with `master` using `git merge master`
156
+ 4. Either handle resulting conflicts by hand or use the visual merge tool: `git mergetool`
157
+ 5. Commit the change: `git commit -a`
158
+ 6. Push up the modified branch: `git push`
159
+ 7. **(experimental)** Add a Chore to revisit the pull request and assign to Developer #2 (Bob)
160
+
161
+
162
+ Now Bob should be able to merge in the pull request automatically using the nice big green button at GitHub.
163
+
164
+ ## Contributing
165
+
166
+ 1. Fork it
167
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
168
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
169
+ 4. Push to the branch (`git push origin my-new-feature`)
170
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require 'pivotal-github/story_commit'
4
+
5
+ exit Command.run!(StoryCommit, ARGV.dup)
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ branch=`git rev-parse --abbrev-ref HEAD`
4
+ git checkout master
5
+ git merge $branch
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ branch=`git rev-parse --abbrev-ref HEAD`
4
+ git checkout master
5
+ git pull $@
6
+ git checkout $branch
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ git push $@ origin `git rev-parse --abbrev-ref HEAD`
@@ -0,0 +1,4 @@
1
+ require "pivotal-github/version"
2
+ require "pivotal-github/options"
3
+ require "pivotal-github/command"
4
+ require "pivotal-github/story_commit"
@@ -0,0 +1,52 @@
1
+ class Command
2
+ attr_accessor :args, :cmd, :options, :known_options, :unknown_options
3
+
4
+ def initialize(args = [])
5
+ self.args = args
6
+ parse
7
+ end
8
+
9
+ def parse
10
+ raise "Define in derived class"
11
+ end
12
+
13
+ def current_branch
14
+ `git rev-parse --abbrev-ref HEAD`.strip
15
+ end
16
+
17
+ def story_id
18
+ current_branch.scan(/\d+/).first
19
+ end
20
+
21
+ def options
22
+ @options ||= parse
23
+ end
24
+
25
+ # Runs a command
26
+ # If the argument array contains '--debug', returns the command that would
27
+ # have been run
28
+ def self.run!(command_class, args)
29
+ debug = args.delete('--debug')
30
+ command = command_class.new(args)
31
+ if debug
32
+ puts command.cmd
33
+ return 1
34
+ else
35
+ command.run!
36
+ return 0
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # Returns an argument string based on given arguments
43
+ # The main trick is to add in quotes for option
44
+ # arguments when necessary.
45
+ # For example, ['-a', '-m', 'foo bar'] becomes
46
+ # '-a -m "foo bar"'
47
+ def argument_string(args)
48
+ args.inject([]) do |opts, opt|
49
+ opts << (opt =~ /^-/ ? opt : opt.inspect)
50
+ end.join(' ')
51
+ end
52
+ end
@@ -0,0 +1,33 @@
1
+ require 'optparse'
2
+
3
+ module Options
4
+
5
+ # Returns a list of options unknown to a particular options parser
6
+ # For example, if '-a' is a known option but '-b' and '-c' are not,
7
+ # unknown_options(parser, ['-a', '-b', '-c']) returns ['-b', '-c'].
8
+ # It also preserves arguments, so
9
+ # unknown_options(parser, ['-a', '-b', '-c', 'foo bar']) returns
10
+ # ['-b', '-c', 'foo bar'].
11
+ def self.unknown_options(parser, args)
12
+ unknown = []
13
+ recursive_parse = Proc.new do |arg_list|
14
+ begin
15
+ parser.parse!(arg_list)
16
+ rescue OptionParser::InvalidOption => e
17
+ unknown.concat(e.args)
18
+ while !arg_list.empty? && arg_list.first[0] != "-"
19
+ unknown << arg_list.shift
20
+ end
21
+ recursive_parse.call(arg_list)
22
+ end
23
+ end
24
+ recursive_parse.call(args.dup)
25
+ unknown
26
+ end
27
+
28
+ # Returns a list of options with unknown options removed
29
+ def self.known_options(parser, args)
30
+ unknown = unknown_options(parser, args)
31
+ args.reject { |arg| unknown.include?(arg) }
32
+ end
33
+ end
@@ -0,0 +1,83 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+ require 'pivotal-github/options'
4
+ require 'pivotal-github/command'
5
+
6
+ class StoryCommit < Command
7
+
8
+ def parse
9
+ options = OpenStruct.new
10
+ parser = OptionParser.new do |opts|
11
+ opts.banner = "Usage: git story-commit [options]"
12
+ opts.on("-m", "--message MESSAGE",
13
+ "add a commit message (including story #)") do |m|
14
+ options.message = m
15
+ end
16
+ opts.on("-f", "--finish", "mark story as finished") do |f|
17
+ options.finish = f
18
+ end
19
+ opts.on("-d", "--deliver", "mark story as delivered") do |d|
20
+ options.deliver = d
21
+ end
22
+ opts.on("-a", "--all", "commit all changed files") do |a|
23
+ options.all = a
24
+ end
25
+ opts.on_tail("-h", "--help", "this usage guide") do
26
+ puts opts.to_s; exit 0
27
+ end
28
+ end
29
+ self.known_options = Options::known_options(parser, args)
30
+ self.unknown_options = Options::unknown_options(parser, args)
31
+ parser.parse(known_options)
32
+ options
33
+ end
34
+
35
+ def message
36
+ if story_id.nil?
37
+ # Arranges to fall through to regular 'git commit'
38
+ options.message
39
+ else
40
+ if finish?
41
+ label = "Finishes ##{story_id}"
42
+ elsif deliver?
43
+ label = "Delivers ##{story_id}"
44
+ else
45
+ label = "##{story_id}"
46
+ end
47
+ "[#{label}] #{options.message}"
48
+ end
49
+ end
50
+
51
+ # Returns a command appropriate for executing at the command line
52
+ # We take care to insert the story number and, if necessary, an indication
53
+ # that the commit finishes the story.
54
+ def cmd
55
+ c = ['git commit']
56
+ c << '-a' if all?
57
+ c << %(-m "#{message}") if message?
58
+ c << argument_string(unknown_options) unless unknown_options.empty?
59
+ c.join(' ')
60
+ end
61
+
62
+ def run!
63
+ system cmd
64
+ end
65
+
66
+ private
67
+
68
+ def finish?
69
+ options.finish
70
+ end
71
+
72
+ def deliver?
73
+ options.deliver
74
+ end
75
+
76
+ def message?
77
+ !options.message.nil?
78
+ end
79
+
80
+ def all?
81
+ options.all
82
+ end
83
+ end
@@ -0,0 +1,5 @@
1
+ module Pivotal
2
+ module Github
3
+ VERSION = "0.5.0"
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pivotal-github/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "pivotal-github"
8
+ gem.version = Pivotal::Github::VERSION
9
+ gem.authors = ["Michael Hartl"]
10
+ gem.email = ["michael@michaelhartl.com"]
11
+ gem.description = %q{Add commands for Pivotal Tracker–GitHub integration}
12
+ gem.summary = %q{See the README for full documentation}
13
+ gem.homepage = "https://github.com/mhartl/pivotal-github"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe StoryCommit do
4
+
5
+ before { command.stub(:current_branch).and_return('6283185-tau-manifesto') }
6
+ let(:command) { StoryCommit.new(['-m', 'message', '-a', '-z', '--foo']) }
7
+ subject { command }
8
+
9
+ it { should respond_to(:cmd) }
10
+ it { should respond_to(:args) }
11
+ it { should respond_to(:options) }
12
+ it { should respond_to(:parse) }
13
+ it { should respond_to(:message) }
14
+ it { should respond_to(:story_id) }
15
+
16
+ shared_examples "record with known options" do
17
+ subject { command }
18
+
19
+ its(:cmd) { should =~ /git commit/ }
20
+ its(:message) { should_not be_empty }
21
+ its(:message?) { should be_true }
22
+ its(:all?) { should be_true }
23
+
24
+ describe "parse" do
25
+ subject { command.options }
26
+
27
+ its(:message) { should == 'message' }
28
+ its(:all) { should be_true }
29
+ end
30
+ end
31
+
32
+ describe "with only known options" do
33
+ let(:command) { StoryCommit.new(['-m', 'message', '-a']) }
34
+ it_should_behave_like "record with known options"
35
+ end
36
+
37
+ describe "with a compound argument" do
38
+ let(:command) { StoryCommit.new(['-am', 'message']) }
39
+ it_should_behave_like "record with known options"
40
+ end
41
+
42
+ describe "with some unknown options" do
43
+ let(:command) { StoryCommit.new(['-m', 'message', '-a', '-z', '--foo']) }
44
+
45
+ it_should_behave_like "record with known options"
46
+
47
+ it "should not raise an error" do
48
+ expect { command.parse }.not_to raise_error(OptionParser::InvalidOption)
49
+ end
50
+ end
51
+
52
+ describe '#story_id' do
53
+ subject { command.story_id }
54
+ it { should == '6283185' }
55
+ end
56
+
57
+ describe "command with message" do
58
+ its(:cmd) do
59
+ should == %(git commit -a -m "[##{command.story_id}] message" -z --foo)
60
+ end
61
+ end
62
+
63
+ describe "command with no message" do
64
+ let(:command) { StoryCommit.new(['-a', '-z', '--foo']) }
65
+ its(:cmd) { should == %(git commit -a -z --foo) }
66
+ end
67
+
68
+ describe "command with finish flag" do
69
+ let(:command) { StoryCommit.new(['-m', 'message', '-f']) }
70
+ its(:cmd) do
71
+ should == %(git commit -m "[Finishes ##{command.story_id}] message")
72
+ end
73
+ end
74
+
75
+ describe "command with deliver flag" do
76
+ let(:command) { StoryCommit.new(['-m', 'message', '-d']) }
77
+ its(:cmd) do
78
+ should == %(git commit -m "[Delivers ##{command.story_id}] message")
79
+ end
80
+ end
81
+
82
+ describe "command with no story id" do
83
+ before { command.stub(:current_branch).and_return('tau-manifesto') }
84
+ its(:cmd) do
85
+ should == %(git commit -a -m "message" -z --foo)
86
+ end
87
+ end
88
+
89
+ describe "command-line command" do
90
+ let(:command) { `bin/git-story-commit -a -m "message" -z --debug` }
91
+ subject { command }
92
+ it { should =~ /git commit -a -m/ }
93
+ it { should =~ /message/ }
94
+ it { should =~ /-z/ }
95
+ it { should_not =~ /--debug/ }
96
+ end
97
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe Options do
5
+
6
+ let(:options) { OpenStruct.new }
7
+
8
+ let(:parser) do
9
+ OptionParser.new do |opts|
10
+ opts.banner = "Usage: git record [options]"
11
+ opts.on("-m", "--message MESSAGE",
12
+ "add a commit message (with ticket #)") do |m|
13
+ options.message = m
14
+ end
15
+ opts.on("-a", "--all", "commit all changed files") do |a|
16
+ options.all = a
17
+ end
18
+ opts.on("-f", "--finish", "mark story as finished") do |f|
19
+ options.finish = f
20
+ end
21
+ opts.on_tail("-h", "--help", "this usage guide") do
22
+ puts opts.to_s; exit 0
23
+ end
24
+ end
25
+ end
26
+
27
+ let(:args) { ['-a', '-m', '"A message"', '--finish', '-z', '--foo', 'b ar'] }
28
+
29
+ it { should respond_to(:unknown_options) }
30
+ it { should respond_to(:known_options) }
31
+
32
+ describe '#unknown_options' do
33
+ subject { Options::unknown_options(parser, args) }
34
+
35
+ it { should include('-z') }
36
+ it { should include('--foo') }
37
+ it { should include('b ar') }
38
+ it { should_not include('-a') }
39
+ it { should_not include('-m') }
40
+ it { should_not include('"A message"') }
41
+ it { should_not include('--finish') }
42
+ end
43
+
44
+ describe '#known_options' do
45
+ subject { Options::known_options(parser, args) }
46
+
47
+ it { should_not include('-z') }
48
+ it { should_not include('--foo') }
49
+ it { should_not include('b ar') }
50
+ it { should include('-a') }
51
+ it { should include('-m') }
52
+ it { should include('"A message"') }
53
+ it { should include('--finish') } end
54
+ end
@@ -0,0 +1,9 @@
1
+ require 'pivotal-github'
2
+
3
+ RSpec.configure do |config|
4
+ config.treat_symbols_as_metadata_keys_with_true_values = true
5
+ config.run_all_when_everything_filtered = true
6
+ config.filter_run :focus
7
+
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pivotal-github
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Hartl
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Add commands for Pivotal Tracker–GitHub integration
15
+ email:
16
+ - michael@michaelhartl.com
17
+ executables:
18
+ - git-story-commit
19
+ - git-story-merge
20
+ - git-story-pull
21
+ - git-story-push
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - .gitignore
26
+ - .rspec
27
+ - Gemfile
28
+ - LICENSE.txt
29
+ - README.md
30
+ - Rakefile
31
+ - bin/git-story-commit
32
+ - bin/git-story-merge
33
+ - bin/git-story-pull
34
+ - bin/git-story-push
35
+ - lib/pivotal-github.rb
36
+ - lib/pivotal-github/command.rb
37
+ - lib/pivotal-github/options.rb
38
+ - lib/pivotal-github/story_commit.rb
39
+ - lib/pivotal-github/version.rb
40
+ - pivotal-github.gemspec
41
+ - spec/commands/story_commit_spec.rb
42
+ - spec/options/options_spec.rb
43
+ - spec/spec_helper.rb
44
+ homepage: https://github.com/mhartl/pivotal-github
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.23
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: See the README for full documentation
68
+ test_files:
69
+ - spec/commands/story_commit_spec.rb
70
+ - spec/options/options_spec.rb
71
+ - spec/spec_helper.rb