bard 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ tmp
@@ -0,0 +1,3 @@
1
+ [submodule "fixtures/repo"]
2
+ path = fixtures/repo
3
+ url = staging@staging.botandrose.com:fuelcafe
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Micah Geisel
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ = BARD gem
2
+
3
+ This immaculate work of engineering genius allows mere mortals to collaborate with beings of transcendent intelligence like Micah, Michael, and Nick.
4
+
5
+ == Requirements
6
+ gem install thor
7
+ gem install systemu
8
+ gem install term-ansicolor
9
+ gem install git_remote_branch
10
+ git --version >= 1.6.0
11
+
12
+ == Note on Patches/Pull Requests
13
+
14
+ * Fork the project.
15
+ * Make your feature addition or bug fix.
16
+ * Add tests for it. This is important so I don't break it in a
17
+ future version unintentionally.
18
+ * Commit, do not mess with rakefile, version, or history.
19
+ (if you want to have your own version, that is fine but
20
+ bump version in a commit by itself I can ignore when I pull)
21
+ * Send me a pull request. Bonus points for topic branches.
22
+
23
+ == Copyright
24
+
25
+ Copyright (c) 2009 Micah Geisel. See LICENSE for details.
@@ -0,0 +1,92 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "bard"
8
+ gem.summary = %Q{Tools for collaborating with Bot and Rose Design.}
9
+ gem.description = %Q{This immaculate work of engineering genius allows mere mortals to collaborate with beings of transcendent intelligence like Micah, Michael, and Nick.}
10
+ gem.email = "info@botandrose.com"
11
+ gem.homepage = "http://github.com/botandrose/bard"
12
+ gem.authors = ["Micah Geisel", "Nick Hogle"]
13
+ gem.add_development_dependency "ruby-debug"
14
+ gem.add_development_dependency "rspec"
15
+ gem.add_development_dependency "cucumber"
16
+ gem.add_dependency(%q<rubygems-update>, [">= 1.3.2"])
17
+ gem.add_dependency(%q<thor>, [">= 0.11.7"])
18
+ gem.add_dependency(%q<grit>, [">= 1.1.1"])
19
+ gem.add_dependency(%q<git_remote_branch>, [">= 0.3.0"])
20
+ gem.add_dependency(%q<systemu>, [">= 1.2.0"])
21
+ gem.add_dependency(%q<term-ansicolor>, [">= 1.0.3"])
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ begin
43
+ require 'cucumber/rake/task'
44
+ Cucumber::Rake::Task.new(:features)
45
+
46
+ task :features => :check_dependencies
47
+ rescue LoadError
48
+ task :features do
49
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
50
+ end
51
+ end
52
+
53
+ begin
54
+ require 'reek/rake_task'
55
+ Reek::RakeTask.new do |t|
56
+ t.fail_on_error = true
57
+ t.verbose = false
58
+ t.source_files = 'lib/**/*.rb'
59
+ end
60
+ rescue LoadError
61
+ task :reek do
62
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
63
+ end
64
+ end
65
+
66
+ begin
67
+ require 'roodi'
68
+ require 'roodi_task'
69
+ RoodiTask.new do |t|
70
+ t.verbose = false
71
+ end
72
+ rescue LoadError
73
+ task :roodi do
74
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
75
+ end
76
+ end
77
+
78
+ task :default => :spec
79
+
80
+ require 'rake/rdoctask'
81
+ Rake::RDocTask.new do |rdoc|
82
+ if File.exist?('VERSION')
83
+ version = File.read('VERSION')
84
+ else
85
+ version = ""
86
+ end
87
+
88
+ rdoc.rdoc_dir = 'rdoc'
89
+ rdoc.title = "bard #{version}"
90
+ rdoc.rdoc_files.include('README*')
91
+ rdoc.rdoc_files.include('lib/**/*.rb')
92
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.1
@@ -0,0 +1,92 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{bard}
8
+ s.version = "0.3.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Micah Geisel", "Nick Hogle"]
12
+ s.date = %q{2009-09-30}
13
+ s.default_executable = %q{bard}
14
+ s.description = %q{This immaculate work of engineering genius allows mere mortals to collaborate with beings of transcendent intelligence like Micah, Michael, and Nick.}
15
+ s.email = %q{info@botandrose.com}
16
+ s.executables = ["bard"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ ".gitmodules",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "bard.gemspec",
30
+ "bin/bard",
31
+ "features/bard_pull.feature",
32
+ "features/bard_push.feature",
33
+ "features/step_definitions/git_steps.rb",
34
+ "features/step_definitions/global_steps.rb",
35
+ "features/step_definitions/rails_steps.rb",
36
+ "features/step_definitions/submodule_steps.rb",
37
+ "features/support/env.rb",
38
+ "features/support/grit_ext.rb",
39
+ "features/support/io.rb",
40
+ "lib/bard.rb",
41
+ "lib/bard/git.rb",
42
+ "lib/bard/io.rb",
43
+ "spec/bard_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+ s.homepage = %q{http://github.com/botandrose/bard}
47
+ s.rdoc_options = ["--charset=UTF-8"]
48
+ s.require_paths = ["lib"]
49
+ s.rubygems_version = %q{1.3.4}
50
+ s.summary = %q{Tools for collaborating with Bot and Rose Design.}
51
+ s.test_files = [
52
+ "spec/spec_helper.rb",
53
+ "spec/bard_spec.rb"
54
+ ]
55
+
56
+ if s.respond_to? :specification_version then
57
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
+ s.specification_version = 3
59
+
60
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
61
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
62
+ s.add_development_dependency(%q<rspec>, [">= 0"])
63
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
64
+ s.add_runtime_dependency(%q<rubygems-update>, [">= 1.3.2"])
65
+ s.add_runtime_dependency(%q<thor>, [">= 0.11.7"])
66
+ s.add_runtime_dependency(%q<grit>, [">= 1.1.1"])
67
+ s.add_runtime_dependency(%q<git_remote_branch>, [">= 0.3.0"])
68
+ s.add_runtime_dependency(%q<systemu>, [">= 1.2.0"])
69
+ s.add_runtime_dependency(%q<term-ansicolor>, [">= 1.0.3"])
70
+ else
71
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
72
+ s.add_dependency(%q<rspec>, [">= 0"])
73
+ s.add_dependency(%q<cucumber>, [">= 0"])
74
+ s.add_dependency(%q<rubygems-update>, [">= 1.3.2"])
75
+ s.add_dependency(%q<thor>, [">= 0.11.7"])
76
+ s.add_dependency(%q<grit>, [">= 1.1.1"])
77
+ s.add_dependency(%q<git_remote_branch>, [">= 0.3.0"])
78
+ s.add_dependency(%q<systemu>, [">= 1.2.0"])
79
+ s.add_dependency(%q<term-ansicolor>, [">= 1.0.3"])
80
+ end
81
+ else
82
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
83
+ s.add_dependency(%q<rspec>, [">= 0"])
84
+ s.add_dependency(%q<cucumber>, [">= 0"])
85
+ s.add_dependency(%q<rubygems-update>, [">= 1.3.2"])
86
+ s.add_dependency(%q<thor>, [">= 0.11.7"])
87
+ s.add_dependency(%q<grit>, [">= 1.1.1"])
88
+ s.add_dependency(%q<git_remote_branch>, [">= 0.3.0"])
89
+ s.add_dependency(%q<systemu>, [">= 1.2.0"])
90
+ s.add_dependency(%q<term-ansicolor>, [">= 1.0.3"])
91
+ end
92
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'thor'
6
+ require 'thor/runner'
7
+
8
+ THIS_FILE = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
9
+ require File.join(File.dirname(THIS_FILE), '..', 'lib', 'bard')
10
+
11
+ args = ARGV
12
+ if args[0] =~ /^[a-z]/i
13
+ args[0] = "bard:#{args[0]}"
14
+ else
15
+ args.unshift "bard"
16
+ end
17
+ Thor::Runner.start args
@@ -0,0 +1,82 @@
1
+ Feature: bard pull
2
+ Background:
3
+ Given a shared rails project
4
+
5
+ Scenario: Pulling down the latest changes from the remote integration branch
6
+ Given the remote integration branch has had a commit since I last pulled
7
+ When I type "bard pull"
8
+ Then the "integration" branch should match the "origin/integration" branch
9
+
10
+ Scenario: Pulling down when the latest changes include a submodule addition
11
+ Given the remote integration branch has had a commit that includes a new submodule
12
+ When I type "bard pull"
13
+ Then the "integration" branch should match the "origin/integration" branch
14
+ And there should be one new submodule
15
+ And the submodule should be checked out
16
+
17
+ Scenario: Pulling down when the latest changes include a submodule update
18
+ Given a submodule
19
+ And the remote integration branch has had a commit that includes a submodule update
20
+ When I type "bard pull"
21
+ Then the "integration" branch should match the "origin/integration" branch
22
+ And the submodule should be updated
23
+
24
+ Scenario: Pulling down when the latest changes include a submodule url change
25
+ Given a submodule
26
+ And the remote integration branch has had a commit that includes a submodule url change
27
+ When I type "bard pull"
28
+ Then the "integration" branch should match the "origin/integration" branch
29
+ And the submodule url should be changed
30
+ And the submodule should be checked out
31
+
32
+ # TODO
33
+ #Scenario: Pulling down when the latest changes include a submodule deletion
34
+ # Given a submodule
35
+ # And the remote integration branch has had a commit that includes a submodule deletion
36
+ # When I type "bard pull"
37
+ # Then the "integration" branch should match the "origin/integration" branch
38
+ # And the submodule should be deleted
39
+
40
+ Scenario: Pulling latest changes from the remote integration branch after committing locally
41
+ Given the remote integration branch has had a commit since I last pulled
42
+ And I have committed a set of changes to my local integration branch
43
+ When I type "bard pull"
44
+ Then I should see the warning "Someone has pushed some changes"
45
+ And the "integration" branch should be a fast-forward from the "origin/integration" branch
46
+
47
+ Scenario: Trying to bard pull with a dirty working directory
48
+ Given the remote integration branch has had a commit since I last pulled
49
+ And a dirty working directory
50
+ When I type "bard pull"
51
+ Then I should see the fatal error "You have uncommitted changes!"
52
+ And the "integration" branch should not match the "origin/integration" branch
53
+
54
+ Scenario: Trying to bard pull when not on the integration branch
55
+ Given the remote integration branch has had a commit since I last pulled
56
+ And I am on a non-integration branch
57
+ When I type "bard pull"
58
+ Then I should see the fatal error "not on the integration branch"
59
+ And the "integration" branch should not match the "origin/integration" branch
60
+
61
+ Scenario: Pulling in a change that includes a migration on a dev machine
62
+ Given the remote integration branch has had a commit that includes a new migration
63
+ And I have a development environment set up locally
64
+ When I type "bard pull"
65
+ Then the development database should include that migration
66
+
67
+ Scenario: Pulling in a change that includes a migration on a dev and testing machine
68
+ Given the remote integration branch has had a commit that includes a new migration
69
+ And I have development and test environments set up locally
70
+ When I type "bard pull"
71
+ Then both the development and test databases should include that migration
72
+
73
+ Scenario: Pulling in a change that includes a gem dependency change
74
+ Given I dont have the test gem installed
75
+ And the remote integration branch has had a commit that adds the test gem as a dependency
76
+ When I type "bard pull"
77
+ Then the test gem should be installed
78
+
79
+ Scenario: Pulling in a change should restart the rails server
80
+ Given the remote integration branch has had a commit since I last pulled
81
+ When I type "bard pull"
82
+ Then passenger should have been restarted
@@ -0,0 +1,89 @@
1
+ Feature: bard push
2
+ Background:
3
+ Given a shared rails project
4
+
5
+ Scenario: Uploading local changes onto the remote integration branch
6
+ Given I have committed a set of changes to my local integration branch
7
+ When I type "bard push"
8
+ Then the "integration" branch should match the "origin/integration" branch
9
+
10
+ Scenario: Pushing a change that includes a migration
11
+ Given I have committed a set of changes that includes a new migration
12
+ And the staging server has a staging and test environment set up
13
+ When I type "bard push"
14
+ Then the both the staging and test databases should include that migration
15
+
16
+ Scenario: Pushing a change that includes a gem dependency change
17
+ Given I dont have the test gem installed
18
+ And I have committed a set of changes that adds the test gem as a dependency
19
+ When I type "bard push"
20
+ Then the test gem should be installed
21
+
22
+ Scenario: Pushing a change should advance the staging HEAD and restart the staging rails server
23
+ Given I have committed a set of changes to my local integration branch
24
+ When I type "bard push"
25
+ Then the remote directory should not be dirty
26
+ And the staging passenger should have been restarted
27
+
28
+ Scenario: Pushing a change that includes a submodule addition
29
+ Given I have committed a set of changes that includes a new submodule
30
+ When I type "bard push"
31
+ Then there should be one new submodule on the remote
32
+ And the remote submodule should be checked out
33
+
34
+ Scenario: Pushing a change that includes a submodule update
35
+ Given a submodule
36
+ And I have committed a set of changes that includes a submodule update
37
+ When I type "bard push"
38
+ Then the remote submodule should be updated
39
+
40
+ Scenario: Pushing a change that includes a submodule url change
41
+ Given a submodule
42
+ Given I have committed a set of changes that includes a submodule url change
43
+ When I type "bard push"
44
+ Then the remote submodule url should be changed
45
+ And the remote submodule should be checked out
46
+
47
+ # TODO
48
+ #Scenario: Pushing a change that includes a submodule deletion
49
+ # Given a submodule
50
+ # Given I have committed a set of changes that includes a submodule deletion
51
+ # When I type "bard push"
52
+ # Then the remote submodule should be deleted
53
+
54
+ Scenario: Trying to bard push when not on the integration branch
55
+ Given I have committed a set of changes to my local integration branch
56
+ And I am on a non-integration branch
57
+ When I type "bard push"
58
+ Then I should see the fatal error "not on the integration branch"
59
+ And the "integration" branch should not match the "origin/integration" branch
60
+
61
+ Scenario: Trying to bard push with a dirty working directory
62
+ Given I have committed a set of changes to my local integration branch
63
+ And a dirty working directory
64
+ When I type "bard push"
65
+ Then I should see the fatal error "You have uncommitted changes!"
66
+ And the "integration" branch should not match the "origin/integration" branch
67
+
68
+ Scenario: Trying to bard push with a non-fast-foward changeset
69
+ Given I have committed a set of changes to my local integration branch
70
+ And the remote integration branch has had a commit since I last pulled
71
+ When I type "bard push"
72
+ Then I should see the fatal error "Someone has pushed some changes"
73
+ And the "integration" branch should not match the "origin/integration" branch
74
+
75
+ Scenario: Trying to bard push with an uncommitted change to a submodule
76
+ Given a submodule
77
+ And I have committed a set of changes to my local integration branch
78
+ And the submodule working directory is dirty
79
+ When I type "bard push"
80
+ Then I should see the fatal error "Micah"
81
+ And the "integration" branch should not match the "origin/integration" branch
82
+
83
+ Scenario: Trying to bard push with a committed but unpushed change to a submodule
84
+ Given a submodule
85
+ And I have committed a set of changes to the submodule
86
+ And I have committed a set of changes to my local integration branch
87
+ When I type "bard push"
88
+ Then I should see the fatal error "Micah"
89
+ And the "integration" branch should not match the "origin/integration" branch
@@ -0,0 +1,55 @@
1
+ Given /^I am on a non\-integration branch$/ do
2
+ type "git checkout -b bad_bad_bad"
3
+ end
4
+
5
+ Given /^a dirty working directory$/ do
6
+ File.open("dirty_file", "w") { |f| f.puts "dirty dirty" }
7
+ end
8
+
9
+ Given /^I have committed a set of changes to my local integration branch$/ do
10
+ type "echo 'fuck shit' > fuck_file"
11
+ type "git add ."
12
+ type "git commit -am'test commit to local integration branch.'"
13
+ end
14
+
15
+ Given /^the remote integration branch has had a commit since I last pulled$/ do
16
+ Dir.chdir "#{ROOT}/tmp/origin" do
17
+ type "git checkout integration"
18
+ type "echo 'zomg' > origin_change_file"
19
+ type "git add ."
20
+ type "git commit -am 'testing origin change'"
21
+ end
22
+ end
23
+
24
+ Then /^the directory should not be dirty$/ do
25
+ type("git status").should include "working directory clean"
26
+ end
27
+
28
+ Then /^the remote directory should not be dirty$/ do
29
+ Dir.chdir "#{ROOT}/tmp/origin" do
30
+ type("git status").should include "working directory clean"
31
+ end
32
+ end
33
+
34
+ Then /^I should be on the "([^\"]*)" branch$/ do |branch|
35
+ @repo.head.name.should == branch
36
+ end
37
+
38
+ Then /^there should not be a "([^\"]*)" branch$/ do |branch_name|
39
+ @repo.branches.any? { |branch| branch.name == branch_name }
40
+ end
41
+
42
+ Then /^the "([^\"]*)" branch (should|should not) match the "([^\"]*)" branch$/ do |local_branch, which, remote_branch|
43
+ type "git fetch origin"
44
+ local_sha = @repo.commits(local_branch).first.id
45
+ remote_sha = @repo.commits(remote_branch).first.id
46
+ which = which.gsub(/ /, '_').to_sym
47
+ local_sha.send(which) == remote_sha
48
+ end
49
+
50
+ Then /^the "([^\"]*)" branch should be a fast\-forward from the "([^\"]*)" branch$/ do |local_branch, remote_branch|
51
+ local_sha = @repo.commits(local_branch).first.id
52
+ remote_sha = @repo.commits(remote_branch).first.id
53
+ common_ancestor = @repo.find_common_ancestor local_sha, remote_sha
54
+ common_ancestor.should == remote_sha
55
+ end
@@ -0,0 +1,41 @@
1
+ Given /^a shared rails project$/ do
2
+ # TEARDOWN
3
+ Dir.chdir ROOT
4
+ type "rm -rf tmp"
5
+
6
+ # SETUP
7
+ Dir.chdir ROOT
8
+ Dir.mkdir 'tmp'
9
+ type "cp -R fixtures/repo tmp/origin"
10
+ Dir.chdir 'tmp/origin' do
11
+ File.open ".git/hooks/post-receive", "w" do |f|
12
+ f.puts <<-BASH
13
+ #!/bin/bash
14
+ RAILS_ENV=staging #{ROOT}/bin/bard stage
15
+ BASH
16
+ f.chmod 0775
17
+ end
18
+ type "cp config/database.yml.sample config/database.yml"
19
+ type "git checkout -b integration"
20
+ end
21
+ type "cp -R fixtures/repo tmp/submodule"
22
+ type "cp -R fixtures/repo tmp/submodule2"
23
+ type "git clone tmp/origin tmp/local"
24
+ Dir.chdir 'tmp/local'
25
+ @repo = Grit::Repo.new "."
26
+ type "grb fetch integration"
27
+ type "git checkout integration"
28
+ type "cp config/database.yml.sample config/database.yml"
29
+ end
30
+
31
+ When /^I type "([^\"]*)"$/ do |command|
32
+ type command
33
+ end
34
+
35
+ Then /^I should see the fatal error "([^\"]*)"$/ do |error_message|
36
+ @stderr.should include(error_message)
37
+ end
38
+
39
+ Then /^I should see the warning "([^\"]*)"$/ do |warning_message|
40
+ @stderr.should include(warning_message)
41
+ end
@@ -0,0 +1,104 @@
1
+ Given /^I have committed a set of changes that includes a new migration$/ do
2
+ Dir.chdir "#{ROOT}/tmp/local" do
3
+ type "script/generate migration test_migration"
4
+ type "git add ."
5
+ type "git commit -am'added test migration.'"
6
+ end
7
+ end
8
+
9
+ Given /^the remote integration branch has had a commit that includes a new migration$/ do
10
+ Dir.chdir "#{ROOT}/tmp/origin" do
11
+ type "script/generate migration test_migration"
12
+ type "git add ."
13
+ type "git commit -am'added test migration.'"
14
+ end
15
+ end
16
+
17
+ Given /^I have a development environment set up locally$/ do
18
+ Dir.chdir "#{ROOT}/tmp/local" do
19
+ type "rake db:create"
20
+ type "rake db:migrate"
21
+ end
22
+ end
23
+
24
+ Given /^the staging server has a staging and test environment set up$/ do
25
+ Dir.chdir "#{ROOT}/tmp/origin" do
26
+ type "rake db:create RAILS_ENV=staging && rake db:create RAILS_ENV=test"
27
+ type "rake db:migrate RAILS_ENV=staging && rake db:migrate RAILS_ENV=test"
28
+ end
29
+ end
30
+
31
+ Given /^I have development and test environments set up locally$/ do
32
+ Dir.chdir "#{ROOT}/tmp/local" do
33
+ type "rake db:create && rake db:create RAILS_ENV=test"
34
+ type "rake db:migrate && rake db:migrate RAILS_ENV=test"
35
+ end
36
+ end
37
+
38
+ Then /^the development database should include that migration$/ do
39
+ Dir.chdir "#{ROOT}/tmp/local" do
40
+ db_version = type("rake db:version")[/[0-9]{14}/]
41
+ test_migration_version = type("ls db/migrate/*_test_migration.rb")[/[0-9]{14}/]
42
+ db_version.should == test_migration_version
43
+ end
44
+ end
45
+
46
+ Then /^the both the staging and test databases should include that migration$/ do
47
+ Dir.chdir "#{ROOT}/tmp/origin" do
48
+ staging_db_version = type("rake db:version RAILS_ENV=staging")[/[0-9]{14}/]
49
+ test_db_version = type("rake db:version RAILS_ENV=test")[/[0-9]{14}/]
50
+ test_migration_version = type("ls db/migrate/*_test_migration.rb")[/[0-9]{14}/]
51
+ staging_db_version.should == test_migration_version
52
+ test_db_version.should == test_migration_version
53
+ end
54
+ end
55
+
56
+ Then /^both the development and test databases should include that migration$/ do
57
+ Dir.chdir "#{ROOT}/tmp/local" do
58
+ dev_db_version = type("rake db:version")[/[0-9]{14}/]
59
+ test_db_version = type("rake db:version RAILS_ENV=test")[/[0-9]{14}/]
60
+ test_migration_version = type("ls db/migrate/*_test_migration.rb")[/[0-9]{14}/]
61
+ dev_db_version.should == test_migration_version
62
+ test_db_version.should == test_migration_version
63
+ end
64
+ end
65
+
66
+ Given /^I dont have the test gem installed$/ do
67
+ type "gem uninstall rake-dotnet -v=0.0.1 -x"
68
+ end
69
+
70
+ Given /^I have committed a set of changes that adds the test gem as a dependency$/ do
71
+ Dir.chdir "#{ROOT}/tmp/local" do
72
+ file_inject "config/environment.rb", "
73
+ Rails::Initializer.run do |config|", <<-RUBY
74
+ config.gem "rake-dotnet", :version => "0.0.1"
75
+ RUBY
76
+ type "git add ."
77
+ type "git commit -am'added test gem dependency.'"
78
+ end
79
+ end
80
+
81
+ Given /^the remote integration branch has had a commit that adds the test gem as a dependency$/ do
82
+ Dir.chdir "#{ROOT}/tmp/origin" do
83
+ file_inject "config/environment.rb", "
84
+ Rails::Initializer.run do |config|", <<-RUBY
85
+ config.gem "rake-dotnet", :version => "0.0.1"
86
+ RUBY
87
+ type "git add ."
88
+ type "git commit -am'added test gem dependency.'"
89
+ end
90
+ end
91
+
92
+ Then /^the test gem should be installed$/ do
93
+ type("gem list rake-dotnet").should include "rake-dotnet (0.0.1)"
94
+ end
95
+
96
+ Then /^passenger should have been restarted$/ do
97
+ File.exist?("tmp/restart.txt").should be_true
98
+ end
99
+
100
+ Then /^the staging passenger should have been restarted$/ do
101
+ Dir.chdir "#{ROOT}/tmp/origin" do
102
+ File.exist?("tmp/restart.txt").should be_true
103
+ end
104
+ end
@@ -0,0 +1,172 @@
1
+ Given /^a submodule$/ do
2
+ Given 'the remote integration branch has had a commit that includes a new submodule'
3
+ Dir.chdir "#{ROOT}/tmp/local" do
4
+ type "git checkout integration"
5
+ type "git pull --rebase"
6
+ type "git submodule update --init"
7
+ @submodule_url = File.read(".gitmodules").match(/url = (.*)$/)[1]
8
+ @submodule_commit = type "git submodule status"
9
+ end
10
+ end
11
+
12
+ Given /^the submodule working directory is dirty$/ do
13
+ Dir.chdir "#{ROOT}/tmp/local/submodule" do
14
+ type "git checkout master"
15
+ type "echo 'submodule_update' > submodule_update"
16
+ end
17
+ end
18
+
19
+ Given /^I have committed a set of changes to the submodule$/ do
20
+ Dir.chdir "#{ROOT}/tmp/local/submodule" do
21
+ type "git checkout -b master"
22
+ type "echo 'submodule_update' > submodule_update"
23
+ type "git add ."
24
+ type "git commit -am 'update in submodule'"
25
+ end
26
+ end
27
+
28
+ Given /^the remote integration branch has had a commit that includes a new submodule$/ do
29
+ Dir.chdir "#{ROOT}/tmp/origin" do
30
+ type "git submodule add #{ROOT}/tmp/submodule submodule"
31
+ Dir.chdir "submodule" do
32
+ type "git checkout -b master"
33
+ type "grb track master"
34
+ end
35
+ type "git add ."
36
+ type "git commit -m 'added submodule'"
37
+ end
38
+ end
39
+
40
+ Given /^I have committed a set of changes that includes a new submodule$/ do
41
+ type "git submodule add #{ROOT}/tmp/submodule submodule"
42
+ Dir.chdir "submodule" do
43
+ type "git checkout -b master"
44
+ type "grb track master"
45
+ end
46
+ type "git add ."
47
+ type "git commit -m 'added submodule'"
48
+ end
49
+
50
+ Given /^I have committed a set of changes that includes a submodule update$/ do
51
+ type "git checkout integration"
52
+ Dir.chdir "submodule" do
53
+ type "git checkout master"
54
+ type "echo 'submodule_update' > submodule_update"
55
+ type "git add ."
56
+ type "git commit -m 'update in submodule'"
57
+ type "git push origin HEAD"
58
+ end
59
+ type "git add ."
60
+ type "git commit -m 'updated submodule'"
61
+ end
62
+
63
+ Given /^the remote integration branch has had a commit that includes a submodule update$/ do
64
+ Dir.chdir "#{ROOT}/tmp/origin" do
65
+ Dir.chdir "submodule" do
66
+ type "git checkout master"
67
+ type "echo 'submodule_update' > submodule_update"
68
+ type "git add ."
69
+ type "git commit -m 'update in submodule'"
70
+ type "git push origin HEAD"
71
+ end
72
+ type "git add ."
73
+ type "git commit -m 'updated submodule'"
74
+ end
75
+ end
76
+
77
+ Given /^I have committed a set of changes that includes a submodule url change$/ do
78
+ gsub_file ".gitmodules", /(url = .*submodule)$/ do |match| "#{match}2" end
79
+ type "git add ."
80
+ type "git commit -m 'updated submodule url'"
81
+ end
82
+
83
+ Given /^the remote integration branch has had a commit that includes a submodule url change$/ do
84
+ Dir.chdir "#{ROOT}/tmp/origin" do
85
+ gsub_file ".gitmodules", /(url = .*submodule)$/ do |match| "#{match}2" end
86
+ type "git add ."
87
+ type "git commit -m 'updated submodule url'"
88
+ end
89
+ end
90
+
91
+ Given /^I have committed a set of changes that includes a submodule deletion$/ do
92
+ type "rm .gitmodules"
93
+ type "rm -rf --cached submodule"
94
+ type "git add ."
95
+ type "git commit -am'removed submodule'"
96
+ end
97
+
98
+ Given /^the remote integration branch has had a commit that includes a submodule deletion$/ do
99
+ Dir.chdir "#{ROOT}/tmp/origin" do
100
+ type "rm .gitmodules"
101
+ type "rm -rf --cached submodule"
102
+ type "git add ."
103
+ type "git commit -am'removed submodule'"
104
+ end
105
+ end
106
+
107
+ Then /^there should be one new submodule$/ do
108
+ status = type "git submodule status"
109
+ status.should match /.[a-z0-9]{40} submodule/
110
+ end
111
+
112
+ Then /^there should be one new submodule on the remote$/ do
113
+ Dir.chdir "#{ROOT}/tmp/origin" do
114
+ status = type "git submodule status"
115
+ status.should match /.[a-z0-9]{40} submodule/
116
+ end
117
+ end
118
+
119
+ Then /^the submodule should be checked out$/ do
120
+ @submodule_url = File.read(".gitmodules").match(/url = (.*)$/)[1]
121
+ @submodule_commit = type "git submodule status"
122
+ @submodule_commit.should match %r( [a-z0-9]{40} submodule)
123
+ end
124
+
125
+ Then /^the remote submodule should be checked out$/ do
126
+ Dir.chdir "#{ROOT}/tmp/origin" do
127
+ @submodule_url = File.read(".gitmodules").match(/url = (.*)$/)[1]
128
+ @submodule_commit = type "git submodule status"
129
+ @submodule_commit.should match %r( [a-z0-9]{40} submodule)
130
+ end
131
+ end
132
+
133
+ Then /^the submodule should be updated$/ do
134
+ @submodule_commit[/[a-z0-9]{40}/].should_not == type("git submodule status")[/[a-z0-9]{40}/]
135
+ end
136
+
137
+ Then /^the remote submodule should be updated$/ do
138
+ Dir.chdir "#{ROOT}/tmp/origin" do
139
+ @submodule_commit[/[a-z0-9]{40}/].should_not == type("git submodule status")[/[a-z0-9]{40}/]
140
+ end
141
+ end
142
+
143
+ Then /^the submodule url should be changed$/ do
144
+ Dir.chdir "submodule" do
145
+ remote = type "git remote show origin"
146
+ remote.should_not match %r(Fetch URL: #{@submodule_url}$)
147
+ remote.should_not match %r(Push URL: #{@submodule_url}$)
148
+ end
149
+ end
150
+
151
+ Then /^the remote submodule url should be changed$/ do
152
+ Dir.chdir "#{ROOT}/tmp/origin/submodule" do
153
+ remote = type "git remote show origin"
154
+ remote.should_not match %r(Fetch URL: #{@submodule_url}$)
155
+ remote.should_not match %r(Push URL: #{@submodule_url}$)
156
+ end
157
+ end
158
+
159
+ Then /^the submodule should be deleted$/ do
160
+ Then 'the directory should not be dirty'
161
+ @submodule_commit = type "git submodule status"
162
+ @submodule_commit.should_not match /.[a-z0-9]{40} submodule/
163
+
164
+ end
165
+
166
+ Then /^the remote submodule should be deleted$/ do
167
+ Then 'the remote directory should not be dirty'
168
+ Dir.chdir "#{ROOT}/tmp/origin" do
169
+ @submodule_commit = type "git submodule status"
170
+ @submodule_commit.should_not match /.[a-z0-9]{40} submodule/
171
+ end
172
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'ruby-debug'
3
+ require 'grit'
4
+ require 'spec/expectations'
5
+ require 'systemu'
6
+
7
+ ENV["PATH"] += ":#{File.dirname(File.expand_path(__FILE__))}/../../bin"
8
+
9
+ ROOT = File.expand_path(File.dirname(__FILE__) + '/../..')
@@ -0,0 +1,16 @@
1
+ Grit::Repo.class_eval do
2
+ def remote_branches(remote = "origin")
3
+ branches = self.remotes
4
+ branches.reject! { |r| r.name !~ %r(^#{remote}/) }
5
+ branches.collect! { |r| r.name.split('/')[1] }
6
+ branches.reject! { |b| b == "HEAD" }
7
+ end
8
+
9
+ def submodules
10
+ Grit::Submodule.config self, self.head.name
11
+ end
12
+
13
+ def find_common_ancestor(head1, head2)
14
+ `git merge-base #{head1} #{head2}`.chomp
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ def type(command)
2
+ @status, @stdout, @stderr = systemu command
3
+ if ENV['DEBUG']
4
+ puts '-' * 20
5
+ puts "Executing command: #{command}"
6
+ puts " Status: #{@status}"
7
+ puts " Stdout:\n #{@stdout}"
8
+ puts " Stderr:\n #{@stderr}"
9
+ puts '-' * 20
10
+ end
11
+ @stdout || @stderr
12
+ end
13
+
14
+ def file_inject(file_name, sentinel, string, before_after=:after)
15
+ gsub_file file_name, /(#{Regexp.escape(sentinel)})/mi do |match|
16
+ if before_after == :after
17
+ "#{match}\n#{string}"
18
+ else
19
+ "#{string}\n#{match}"
20
+ end
21
+ end
22
+ end
23
+
24
+ def gsub_file(file_name, regexp, *args, &block)
25
+ content = File.read(file_name).gsub(regexp, *args, &block)
26
+ File.open(file_name, 'wb') { |file| file.write(content) }
27
+ end
@@ -0,0 +1,108 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'term/ansicolor'
3
+ require 'systemu'
4
+ require 'grit'
5
+
6
+ require 'bard/git'
7
+ require 'bard/io'
8
+
9
+ class Bard < Thor
10
+ include BardGit
11
+ include BardIO
12
+
13
+ desc "pull", "pull changes to your local machine"
14
+ def pull
15
+ ensure_integration_branch!
16
+ ensure_clean_working_directory!
17
+
18
+ unless fast_forward_merge?
19
+ warn "Someone has pushed some changes since you last pulled.\n Please ensure that your changes didnt break stuff."
20
+ end
21
+
22
+ run_crucial "git pull --rebase origin integration"
23
+
24
+ changed_files = run_crucial("git diff #{@common_ancestor} origin/integration --diff-filter=ACDMR --name-only").split("\n")
25
+ puts changed_files.inspect
26
+
27
+ if changed_files.any? { |f| f =~ %r(^db/migrate/.+) }
28
+ run_crucial "rake db:migrate"
29
+ run_crucial "rake db:migrate RAILS_ENV=test"
30
+ end
31
+
32
+ if changed_files.any? { |f| f == ".gitmodules" }
33
+ run_crucial "git submodule sync"
34
+ run_crucial "git submodule init"
35
+ end
36
+ run_crucial "git submodule update"
37
+
38
+ if changed_files.any? { |f| f =~ %r(^config/environment.+) }
39
+ run_crucial "rake gems:install"
40
+ end
41
+
42
+ system "touch tmp/restart.txt"
43
+ end
44
+
45
+ desc "push", "push local changes out to the remote"
46
+ def push
47
+ ensure_integration_branch!
48
+ ensure_clean_working_directory!
49
+
50
+ if submodule_dirty?
51
+ fatal "Cannot push changes: You have uncommitted changes to a submodule!\n Please see Micah about this."
52
+ end
53
+
54
+ if submodule_unpushed?
55
+ fatal "Cannot push changes: You have unpushed changes to a submodule!\n Please see Micah about this."
56
+ end
57
+
58
+ unless fast_forward_merge?
59
+ fatal "Someone has pushed some changes since you last pulled.\n Kindly run bard pull, ensure that your your changes still work.\n Then run bard push again."
60
+ end
61
+
62
+ run_crucial "git push origin integration", true
63
+
64
+ # git post-receive hook runs stage task below
65
+ end
66
+
67
+ if ENV['RAILS_ENV'] == "staging"
68
+ desc "stage", "!!! INTERNAL USE ONLY !!! reset HEAD to integration, update submodules, run migrations, install gems, restart server"
69
+ def stage
70
+ if ENV['GIT_DIR'] == '.'
71
+ # this means the script has been called as a hook, not manually.
72
+ # get the proper GIT_DIR so we can descend into the working copy dir;
73
+ # if we don't then `git reset --hard` doesn't affect the working tree.
74
+ Dir.chdir '..'
75
+ ENV['GIT_DIR'] = '.git'
76
+ end
77
+
78
+ run_crucial "git reset --hard"
79
+
80
+ # find out the current branch
81
+ head = File.read('.git/HEAD').chomp
82
+ # abort if we're on a detached head
83
+ exit unless head.sub! 'ref: ', ''
84
+
85
+ revs = gets.split ' '
86
+ old_rev, new_rev = revs if head == revs.pop
87
+
88
+ changed_files = run_crucial("git diff #{old_rev} #{new_rev} --diff-filter=ACMRD --name-only").split("\n")
89
+
90
+ if changed_files.any? { |f| f =~ %r(^db/migrate/.+) }
91
+ run_crucial "rake db:migrate RAILS_ENV=staging"
92
+ run_crucial "rake db:migrate RAILS_ENV=test"
93
+ end
94
+
95
+ if changed_files.any? { |f| f == ".gitmodules" }
96
+ run_crucial "git submodule sync"
97
+ run_crucial "git submodule init"
98
+ end
99
+ system "git submodule update"
100
+
101
+ if changed_files.any? { |f| f =~ %r(^config/environment.+) }
102
+ run_crucial "rake gems:install"
103
+ end
104
+
105
+ system "touch tmp/restart.txt"
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,47 @@
1
+ module BardGit
2
+ private
3
+ def ensure_integration_branch!
4
+ return if `git name-rev --name-only HEAD`.chomp == "integration"
5
+ fatal "You are not on the integration branch! Type `git checkout integration` to switch to it. If you have made changes to your current branch, please see Micah for assistance."
6
+ end
7
+
8
+ def ensure_clean_working_directory!
9
+ return if`git status`.include? "working directory clean"
10
+ fatal "Cannot upload changes: You have uncommitted changes!\n Please run git commit before attempting to push or pull."
11
+ end
12
+
13
+ def fast_forward_merge?
14
+ run_crucial "git fetch origin"
15
+ head = run_crucial "git rev-parse HEAD"
16
+ remote_head = run_crucial "git rev-parse origin/integration"
17
+ @common_ancestor = find_common_ancestor head, remote_head
18
+ @common_ancestor == remote_head
19
+ end
20
+
21
+ def find_common_ancestor(head1, head2)
22
+ run_crucial "git merge-base #{head1} #{head2}"
23
+ end
24
+
25
+ def submodule_dirty?
26
+ @repo ||= Grit::Repo.new "."
27
+ submodules = Grit::Submodule.config(@repo, @repo.head.name)
28
+ submodules.any? do |name, submodule|
29
+ Dir.chdir submodule["path"] do
30
+ not `git status`.include? "working directory clean"
31
+ end
32
+ end
33
+ end
34
+
35
+ def submodule_unpushed?
36
+ @repo ||= Grit::Repo.new "."
37
+ submodules = Grit::Submodule.config(@repo, @repo.head.name)
38
+ submodules.any? do |name, submodule|
39
+ Dir.chdir submodule["path"] do
40
+ branch = `git name-rev --name-only HEAD`.chomp
41
+ `git fetch`
42
+ submodule["id"] != `git rev-parse origin/#{branch}`.chomp
43
+ end
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,22 @@
1
+ module BardIO
2
+ include Term::ANSIColor
3
+ private
4
+
5
+ def warn(message)
6
+ $stderr.puts yellow("!!! ") + message
7
+ end
8
+
9
+ def fatal(message)
10
+ raise Thor::Error, red("!!! ") + message
11
+ end
12
+
13
+ def run_crucial(command, verbose = false)
14
+ status, stdout, stderr = systemu command
15
+ fatal "Running command: #{yellow(command)}: #{stderr}" if status.to_i.nonzero?
16
+ if verbose
17
+ $stdout.puts stdout
18
+ $stderr.puts stderr
19
+ end
20
+ stdout.chomp
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Bard" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'bard'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Micah Geisel
8
+ - Nick Hogle
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-09-30 00:00:00 -07:00
14
+ default_executable: bard
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: ruby-debug
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ type: :development
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: cucumber
38
+ type: :development
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubygems-update
48
+ type: :runtime
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.2
55
+ version:
56
+ - !ruby/object:Gem::Dependency
57
+ name: thor
58
+ type: :runtime
59
+ version_requirement:
60
+ version_requirements: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 0.11.7
65
+ version:
66
+ - !ruby/object:Gem::Dependency
67
+ name: grit
68
+ type: :runtime
69
+ version_requirement:
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.1.1
75
+ version:
76
+ - !ruby/object:Gem::Dependency
77
+ name: git_remote_branch
78
+ type: :runtime
79
+ version_requirement:
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 0.3.0
85
+ version:
86
+ - !ruby/object:Gem::Dependency
87
+ name: systemu
88
+ type: :runtime
89
+ version_requirement:
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 1.2.0
95
+ version:
96
+ - !ruby/object:Gem::Dependency
97
+ name: term-ansicolor
98
+ type: :runtime
99
+ version_requirement:
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.0.3
105
+ version:
106
+ description: This immaculate work of engineering genius allows mere mortals to collaborate with beings of transcendent intelligence like Micah, Michael, and Nick.
107
+ email: info@botandrose.com
108
+ executables:
109
+ - bard
110
+ extensions: []
111
+
112
+ extra_rdoc_files:
113
+ - LICENSE
114
+ - README.rdoc
115
+ files:
116
+ - .document
117
+ - .gitignore
118
+ - .gitmodules
119
+ - LICENSE
120
+ - README.rdoc
121
+ - Rakefile
122
+ - VERSION
123
+ - bard.gemspec
124
+ - bin/bard
125
+ - features/bard_pull.feature
126
+ - features/bard_push.feature
127
+ - features/step_definitions/git_steps.rb
128
+ - features/step_definitions/global_steps.rb
129
+ - features/step_definitions/rails_steps.rb
130
+ - features/step_definitions/submodule_steps.rb
131
+ - features/support/env.rb
132
+ - features/support/grit_ext.rb
133
+ - features/support/io.rb
134
+ - lib/bard.rb
135
+ - lib/bard/git.rb
136
+ - lib/bard/io.rb
137
+ - spec/bard_spec.rb
138
+ - spec/spec_helper.rb
139
+ has_rdoc: true
140
+ homepage: http://github.com/botandrose/bard
141
+ licenses: []
142
+
143
+ post_install_message:
144
+ rdoc_options:
145
+ - --charset=UTF-8
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: "0"
153
+ version:
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: "0"
159
+ version:
160
+ requirements: []
161
+
162
+ rubyforge_project:
163
+ rubygems_version: 1.3.4
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: Tools for collaborating with Bot and Rose Design.
167
+ test_files:
168
+ - spec/spec_helper.rb
169
+ - spec/bard_spec.rb