bard 0.6.6 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bard.gemspec +3 -2
- data/bin/bard +5 -13
- data/lib/bard.rb +40 -70
- data/lib/bard/check.rb +6 -9
- data/lib/bard/error.rb +21 -0
- data/lib/bard/git.rb +9 -14
- data/lib/bard/io.rb +3 -2
- metadata +3 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.7
|
data/bard.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bard}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Micah Geisel", "Nick Hogle"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-11-05}
|
13
13
|
s.default_executable = %q{bard}
|
14
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
15
|
s.email = %q{info@botandrose.com}
|
@@ -42,6 +42,7 @@ Gem::Specification.new do |s|
|
|
42
42
|
"features/support/io.rb",
|
43
43
|
"lib/bard.rb",
|
44
44
|
"lib/bard/check.rb",
|
45
|
+
"lib/bard/error.rb",
|
45
46
|
"lib/bard/git.rb",
|
46
47
|
"lib/bard/io.rb",
|
47
48
|
"spec/bard_spec.rb",
|
data/bin/bard
CHANGED
@@ -1,17 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# -*- mode: ruby -*-
|
3
2
|
|
4
3
|
require 'rubygems'
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
args = ARGV
|
12
|
-
if args[0] =~ /^[a-z]/i
|
13
|
-
args[0] = "bard:#{args[0]}"
|
14
|
-
else
|
15
|
-
args.unshift "bard"
|
4
|
+
require 'bard'
|
5
|
+
begin
|
6
|
+
Bard.start ARGV
|
7
|
+
rescue BardError => e
|
8
|
+
fatal e.message
|
16
9
|
end
|
17
|
-
Thor::Runner.start args
|
data/lib/bard.rb
CHANGED
@@ -5,6 +5,7 @@ require 'systemu'
|
|
5
5
|
require 'grit'
|
6
6
|
require 'thor'
|
7
7
|
|
8
|
+
require 'bard/error'
|
8
9
|
require 'bard/git'
|
9
10
|
require 'bard/io'
|
10
11
|
|
@@ -27,58 +28,22 @@ class Bard < Thor
|
|
27
28
|
|
28
29
|
desc "pull", "pull changes to your local machine"
|
29
30
|
def pull
|
30
|
-
|
31
|
-
|
32
|
-
ensure_project_root!
|
33
|
-
ensure_integration_branch!
|
34
|
-
ensure_clean_working_directory!
|
31
|
+
ensure_sanity!
|
35
32
|
|
36
|
-
unless fast_forward_merge?
|
37
|
-
warn "Someone has pushed some changes since you last pulled.\n Please ensure that your changes didnt break stuff."
|
38
|
-
end
|
33
|
+
warn NonFastForwardError unless fast_forward_merge?
|
39
34
|
|
40
35
|
run_crucial "git pull --rebase origin integration"
|
41
36
|
|
42
|
-
|
43
|
-
|
44
|
-
if changed_files.any? { |f| f =~ %r(^db/migrate/.+) }
|
45
|
-
run_crucial "rake db:migrate"
|
46
|
-
run_crucial "rake db:migrate RAILS_ENV=test"
|
47
|
-
end
|
48
|
-
|
49
|
-
if changed_files.any? { |f| f == ".gitmodules" }
|
50
|
-
run_crucial "git submodule sync"
|
51
|
-
run_crucial "git submodule init"
|
52
|
-
end
|
53
|
-
run_crucial "git submodule update --merge"
|
54
|
-
run_crucial "git submodule foreach 'git reset --hard'"
|
55
|
-
|
56
|
-
if changed_files.any? { |f| f =~ %r(^config/environment.+) }
|
57
|
-
run_crucial "rake gems:install"
|
58
|
-
end
|
59
|
-
|
60
|
-
system "touch tmp/restart.txt"
|
37
|
+
prepare_environment = changed_files(@common_ancestor, "origin/integration")
|
61
38
|
end
|
62
39
|
|
63
40
|
desc "push", "push local changes out to the remote"
|
64
41
|
def push
|
65
|
-
|
42
|
+
ensure_sanity!
|
66
43
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
if submodule_dirty?
|
72
|
-
fatal "Cannot push changes: You have uncommitted changes to a submodule!\n Please see Micah about this."
|
73
|
-
end
|
74
|
-
|
75
|
-
if submodule_unpushed?
|
76
|
-
fatal "Cannot push changes: You have unpushed changes to a submodule!\n Please see Micah about this."
|
77
|
-
end
|
78
|
-
|
79
|
-
unless fast_forward_merge?
|
80
|
-
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."
|
81
|
-
end
|
44
|
+
raise SubmoduleDirtyError if submodule_dirty?
|
45
|
+
raise SubmoduleUnpushedError if submodule_unpushed?
|
46
|
+
raise NonFastFowardError unless fast_forward_merge?
|
82
47
|
|
83
48
|
run_crucial "git push origin integration", true
|
84
49
|
|
@@ -92,8 +57,7 @@ class Bard < Thor
|
|
92
57
|
run_crucial "git fetch origin"
|
93
58
|
run_crucial "git checkout master"
|
94
59
|
run_crucial "git pull --rebase origin master"
|
95
|
-
if not fast_forward_merge? "master", "integration"
|
96
|
-
fatal "master has advanced since last deploy, probably due to a bugfix. rebase your integration branch on top of it, and check for breakage."
|
60
|
+
raise MasterNonFastForwardError if not fast_forward_merge? "master", "integration"
|
97
61
|
end
|
98
62
|
|
99
63
|
run_crucial "git merge integration"
|
@@ -116,35 +80,41 @@ class Bard < Thor
|
|
116
80
|
ENV['GIT_DIR'] = '.git'
|
117
81
|
end
|
118
82
|
|
119
|
-
|
120
|
-
|
121
|
-
# abort if we're on a detached head
|
122
|
-
exit unless head.sub! 'ref: ', ''
|
123
|
-
revs = gets.split ' '
|
124
|
-
old_rev, new_rev, branch = revs
|
83
|
+
raise StagingDetachedHeadError unless current_branch
|
84
|
+
old_rev, new_rev, branch = revs.split(' ') # get the low down about the commit from the git hook
|
125
85
|
|
126
|
-
if
|
86
|
+
if current_branch == branch
|
127
87
|
run_crucial "git reset --hard"
|
88
|
+
prepare_environment changed_files(old_rev, new_rev)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
128
92
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
if changed_files.any? { |f| f == ".gitmodules" }
|
137
|
-
run_crucial "git submodule sync"
|
138
|
-
run_crucial "git submodule init"
|
139
|
-
end
|
140
|
-
system "git submodule update"
|
141
|
-
|
142
|
-
if changed_files.any? { |f| f =~ %r(^config/environment.+) }
|
143
|
-
run_crucial "rake gems:install"
|
144
|
-
end
|
93
|
+
private
|
94
|
+
def ensure_sanity!
|
95
|
+
check_dependencies
|
96
|
+
raise NotInProjectRootError unless File.directory? ".git"
|
97
|
+
raise NotOnIntegrationError if current_branch == "integration"
|
98
|
+
raise WorkingTreeDirtyError unless `git status`.include? "working directory clean"
|
99
|
+
end
|
145
100
|
|
146
|
-
|
101
|
+
def prepare_environment(changed_files)
|
102
|
+
if changed_files.any? { |f| f =~ %r(^db/migrate/.+) }
|
103
|
+
run_crucial "rake db:migrate RAILS_ENV=staging"
|
104
|
+
run_crucial "rake db:migrate RAILS_ENV=test"
|
147
105
|
end
|
106
|
+
|
107
|
+
if changed_files.any? { |f| f == ".gitmodules" }
|
108
|
+
run_crucial "git submodule sync"
|
109
|
+
run_crucial "git submodule init"
|
110
|
+
end
|
111
|
+
run_crucial "git submodule update --merge"
|
112
|
+
run_crucial "git submodule foreach 'git reset --hard'"
|
113
|
+
|
114
|
+
if changed_files.any? { |f| f =~ %r(^config/environment.+) }
|
115
|
+
run_crucial "rake gems:install"
|
116
|
+
end
|
117
|
+
|
118
|
+
system "touch tmp/restart.txt"
|
148
119
|
end
|
149
|
-
end
|
150
120
|
end
|
data/lib/bard/check.rb
CHANGED
@@ -35,7 +35,6 @@ class Bard < Thor
|
|
35
35
|
|
36
36
|
def check_project(project)
|
37
37
|
errors = []
|
38
|
-
warnings = []
|
39
38
|
Dir.chdir project do
|
40
39
|
status, stdout, stderr = systemu "rake db:abort_if_pending_migrations"
|
41
40
|
errors << "missing config/database.yml, adapt from config/database.sample.yml." if stderr.include? "config/database.yml"
|
@@ -44,13 +43,15 @@ class Bard < Thor
|
|
44
43
|
errors << "pending migrations, please run `rake db:migrate`" if stdout.include? "pending migrations"
|
45
44
|
|
46
45
|
errors << "missing submodule, please run git submodule update --init" if `git submodule status` =~ /^-/
|
47
|
-
errors << "submodule has a detached head, please complain to micah" unless system 'git submodule foreach "git symbolic-ref HEAD"'
|
46
|
+
errors << "submodule has a detached head, please complain to micah" unless system 'git submodule foreach "git symbolic-ref HEAD 1>/dev/null 2>/dev/null"'
|
48
47
|
|
49
48
|
errors << "missing gems, please run `rake gems:install`" if `rake gems` =~ /\[ \]/
|
50
49
|
|
51
50
|
errors << "missing integration branch, please complain to micah" if `git branch` !~ /\bintegration\b/
|
52
|
-
|
53
|
-
|
51
|
+
unless ENV['RAILS_ENV'] == "staging"
|
52
|
+
errors << "integration branch isnt tracking the remote integration branch, please run `grb track integration`" if `git config branch.integration.merge` !~ %r%\brefs/heads/integration\b%
|
53
|
+
end
|
54
|
+
errors << "you shouldn't be working on the master branch, please work on the integration branch" if current_branch == "master"
|
54
55
|
|
55
56
|
if ENV['RAILS_ENV'] == "staging"
|
56
57
|
if not File.exist? ".git/hooks/post-receive"
|
@@ -61,17 +62,13 @@ class Bard < Thor
|
|
61
62
|
end
|
62
63
|
errors << "the git config variable receive.denyCurrentBranch is not set to ignore, please complain to micah" if `git config receive.denyCurrentBranch`.chomp != "ignore"
|
63
64
|
end
|
64
|
-
|
65
|
-
warnings << "RAILS_ENV is not set, please complain to micah" if ENV['RAILS_ENV'].nil? or ENV['RAILS_ENV'].empty?
|
66
65
|
end
|
67
66
|
|
68
67
|
if not errors.empty?
|
69
68
|
fatal "#{errors.length} problems detected:\n #{errors.join("\n ")}"
|
70
|
-
elsif not warnings.empty?
|
71
|
-
warn "#{warnings.length} potential problems detected:\n #{warnings.join("\n ")}"
|
72
69
|
else
|
73
70
|
puts green("No problems detected in project: #{project}")
|
74
|
-
|
71
|
+
unless ENV['RAILS_ENV'] == "staging"
|
75
72
|
puts "please run it on the staging server by typing `cap shell` and then `bard check [PROJECT_NAME]`"
|
76
73
|
end
|
77
74
|
end
|
data/lib/bard/error.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
class Bard < Thor
|
2
|
+
class BardError < StandardError; end
|
3
|
+
{
|
4
|
+
"SubmoduleDirtyError" => "You have uncommitted changes to a submodule!\n Please see Micah about this.",
|
5
|
+
"SubmoduleUnpushedError" => "You have unpushed changes to a submodule!\n Please see Micah about this.",
|
6
|
+
"NonFastForwardError" => "Someone has pushed some changes since you last pulled.\n Kindly run bard pull, ensure that your your changes still work, and try again",
|
7
|
+
"MasterNonFastForwardError" => "The master branch has advanced since last deploy, probably due to a bugfix.\n Rebase your integration branch on top of it, and check for breakage.",
|
8
|
+
"NotInProjectRootError" => "You are not in the project's root directory!",
|
9
|
+
"NotOnIntegrationError" => "You are not on the integration branch!\n Type `git checkout integration` to switch to it. If you have made changes to your current branch, please see Micah for assistance.",
|
10
|
+
"WorkingTreeDirtyError" => "You have uncommitted changes!\n Please run git commit before attempting to push or pull.",
|
11
|
+
"StagingDetachedHeadError" => "The staging server is on a detached HEAD!\n Please see Micah for assistance."
|
12
|
+
}.each do |error, message|
|
13
|
+
eval <<-RUBY
|
14
|
+
class #{error} < BardError
|
15
|
+
def message
|
16
|
+
%q{#{message}}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
end
|
21
|
+
end
|
data/lib/bard/git.rb
CHANGED
@@ -1,17 +1,9 @@
|
|
1
1
|
module BardGit
|
2
2
|
private
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def ensure_integration_branch!
|
8
|
-
return if `git name-rev --name-only HEAD`.chomp == "integration"
|
9
|
-
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."
|
10
|
-
end
|
11
|
-
|
12
|
-
def ensure_clean_working_directory!
|
13
|
-
return if`git status`.include? "working directory clean"
|
14
|
-
fatal "Cannot upload changes: You have uncommitted changes!\n Please run git commit before attempting to push or pull."
|
3
|
+
def current_branch
|
4
|
+
ref = `git symbolic-ref HEAD 2>&1`.chomp
|
5
|
+
return false if ref =~ /^fatal:/
|
6
|
+
rev.split('/').last # /refs/heads/master ... we want "master"
|
15
7
|
end
|
16
8
|
|
17
9
|
def fast_forward_merge?(root = "origin/integration", branch = "HEAD")
|
@@ -26,6 +18,10 @@ module BardGit
|
|
26
18
|
run_crucial "git merge-base #{head1} #{head2}"
|
27
19
|
end
|
28
20
|
|
21
|
+
def changed_files(old_rev, new_rev)
|
22
|
+
run_crucial("git diff #{old_rev} #{new_rev} --diff-filter=ACMRD --name-only").split("\n")
|
23
|
+
end
|
24
|
+
|
29
25
|
def submodule_dirty?
|
30
26
|
@repo ||= Grit::Repo.new "."
|
31
27
|
submodules = Grit::Submodule.config(@repo, @repo.head.name)
|
@@ -41,9 +37,8 @@ module BardGit
|
|
41
37
|
submodules = Grit::Submodule.config(@repo, @repo.head.name)
|
42
38
|
submodules.any? do |name, submodule|
|
43
39
|
Dir.chdir submodule["path"] do
|
44
|
-
branch = `git name-rev --name-only HEAD`.chomp
|
45
40
|
`git fetch origin`
|
46
|
-
submodule["id"] != `git rev-parse origin/#{
|
41
|
+
submodule["id"] != `git rev-parse origin/#{current_branch}`.chomp
|
47
42
|
end
|
48
43
|
end
|
49
44
|
end
|
data/lib/bard/io.rb
CHANGED
@@ -3,11 +3,12 @@ module BardIO
|
|
3
3
|
private
|
4
4
|
|
5
5
|
def warn(message)
|
6
|
-
|
6
|
+
message = message.message if message.is_a? BardError
|
7
|
+
$stderr.puts yellow("! ") + message
|
7
8
|
end
|
8
9
|
|
9
10
|
def fatal(message)
|
10
|
-
raise
|
11
|
+
raise red("!!! ") + message
|
11
12
|
end
|
12
13
|
|
13
14
|
def run_crucial(command, verbose = false)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Geisel
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-11-05 00:00:00 -08:00
|
14
14
|
default_executable: bard
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -136,6 +136,7 @@ files:
|
|
136
136
|
- features/support/io.rb
|
137
137
|
- lib/bard.rb
|
138
138
|
- lib/bard/check.rb
|
139
|
+
- lib/bard/error.rb
|
139
140
|
- lib/bard/git.rb
|
140
141
|
- lib/bard/io.rb
|
141
142
|
- spec/bard_spec.rb
|