1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# This set of tasks helps automate the workflow as described on
# http://projects.puppetlabs.com/projects/puppet/wiki/Development_Lifecycle
def find_start(start)
# This is a case statement, as we might want to map certain
# git tags to starting points that are not currently in git.
case start
when nil?:
when @next_release: return "master"
else return start
end
end
desc "Set up git for working with Puppet"
task :git_setup do
# This should be changed as new versions get released
@next_release = '0.26.x'
@remote = {}
default_remote = {}
default_remote[:url] = 'git://github.com/reductivelabs/puppet'
default_remote[:name] = 'origin'
@remote[:name] = %x{git config puppet.defaultremote}.chomp
@remote[:name] = @remote[:name].empty? ? default_remote[:name] : @remote[:name]
@remote[:url] = default_remote[:url] if @remote[:name] == default_remote[:name]
default_fetch = '+refs/heads/*:refs/remotes/puppet/*'
@remote[:fetch] = %x{git config puppet.#{@remote[:name]}.fetch}.chomp
@remote[:fetch] = @remote[:fetch].empty? ? default_fetch : @remote[:fetch]
end
desc "Start work on a feature"
task :start_feature, [:feature,:remote,:branch] => :git_setup do |t, args|
args.with_defaults(:remote => @remote[:name])
args.with_defaults(:branch => @next_release)
start_at = find_start(args.branch)
branch = "feature/#{start_at}/#{args.feature}"
sh "git checkout -b #{branch} #{start_at}" do |ok, res|
if ! ok
raise <<EOS
Was not able to create branch for #{args.feature} on branch #{args.branch}, starting at #{start_at}: error code was: #{res.exitstatus}
EOS
end
end
sh "git config branch.#{branch}.remote #{args.remote}" do |ok, res|
raise "Could not set remote: #{$?}" unless ok
end
sh "git config branch.#{branch}.merge refs/heads/#{branch}" do |ok, res|
raise "Could not configure merge: #{$?}" unless ok
end
end
desc "Do git prep to start work on a Redmine ticket"
task :start_ticket, [:ticket, :remote, :branch] => :git_setup do |t, args|
args.with_defaults(:remote => @remote[:name])
args.with_defaults(:branch => @next_release)
start_at = find_start(args.branch)
branch = "tickets/#{start_at}/#{args.ticket}"
sh "git checkout -b #{branch} #{start_at}" do |ok, res|
unless ok
raise <<EOS
Was not able to create branch for ticket #{args.ticket} on branch #{args.branch}, starting at #{start_at}: error code was: #{$?}
Git command used was: #{command}
EOS
end
end
sh "git config branch.#{branch}.remote #{args.remote}" do |ok, res|
raise "Could not set remote: #{$?}" unless ok
end
sh "git config branch.#{branch}.merge refs/heads/#{branch}" do |ok, res|
raise "Could not configure merge: #{$?}" unless ok
end
end
# This isn't very useful by itself, but we might enhance it later, or use it
# in a dependency for a more complex task.
desc "Push out changes"
task :push_changes, [:remote] do |t, arg|
branch = %x{git branch | grep "^" | awk '{print $2}'}
sh "git push #{arg.remote} #{branch}" do |ok, res|
raise "Unable to push to #{arg.remote}" unless ok
end
end
desc "Send patch information to the puppet-dev list"
task :mail_patches do
if Dir.glob("00*.patch").length > 0
raise "Patches already exist matching '00*.patch'; clean up first"
end
unless %x{git status} =~ /On branch (.+)/
raise "Could not get branch from 'git status'"
end
branch = $1
unless branch =~ %r{^([^\/]+)/([^\/]+)/([^\/]+)$}
raise "Branch name does not follow <type>/<parent>/<name> model; cannot autodetect parent branch"
end
type, parent, name = $1, $2, $3
# Create all of the patches
sh "git format-patch -C -M -s -n --subject-prefix='PATCH/puppet' #{parent}..HEAD"
# Add info to the patches
additional_info = "Local-branch: #{branch}\n"
files = Dir.glob("00*.patch")
files.each do |file|
contents = File.read(file)
contents.sub!(/^---\n/, "---\n#{additional_info}")
File.open(file, 'w') do |file_handle|
file_handle.print contents
end
end
# And then mail them out.
# If we've got more than one patch, add --compose
if files.length > 1
compose = "--compose"
else
compose = ""
end
# Now send the mail.
sh "git send-email #{compose} --no-signed-off-by-cc --suppress-from --to puppet-dev@googlegroups.com 00*.patch"
# Finally, clean up the patches
sh "rm 00*.patch"
end
|