On Aug 26, 2009, at 9:27 AM, Steven Jenkins wrote: > Recently, Luke, James and I were discussing adding some tasks to help > people stay consisent with the workflow documented at > > http://reductivelabs.com/trac/puppet/wiki/Development/DevelopmentLifecycle > > This patch adds subsumes the existing mail_patches task, and adds > three new ones: > > rake start_feature[feature,branch] # Do git setup to start work on > a feature > > Will set up your git repo to have the correct branch (based on > 'branch', > with 'master' as the default starting point). Note that you can > invoke it > with or without a branch: e.g., > > rake start_feature[events]
I'm a little confused by this syntax -- is it literally 'start_feature[events]'? If so, doesn't the shell expand that weirdly? Or at least, couldn't it? Is this a rake thing? > > creates a branch named feature/master/events, starting at the > current HEAD of master > > while > > rake start_feature[events,0.24.8] > > creates a branch named feature/0.24.8/events, starting at the 0.24.8 > ref. > > rake start_ticket[ticket,branch] # Do git setup to start work on > a Redmine ticket > > Will set up your git repo to have the correct branch (based on > 'branch', > with 'master' as the default starting point). This task also takes > an optional branch as it's starting point. > > rake push_changes[remote] # Push out changes > > Will push out the current branch to the specified remote -- it's a > pretty > trivial task, but I put it there so that we might add more complex > tasks down the road (e.g., add a dependency for the rake spec task to > this task so that before pushes are done, all spec tests pass). > Also, I toyed with using the git-ruby library (http://git.rubyforge.org/ > ) > and replacing the shell invocations with Ruby code, but I thought > that would be more appropriate for a later version. If someone > would like > to see that, feel free to let me know (or, better yet, submit > code..). I was > also a little hesitant to add another gem dependency. I like the idea of using this - it's something we'd probably start to use a lot more of. > > Comments, feedback welcome. Also, this patch is available on my > github account > at http://github.com/stevenjenkins/puppet/tree/rake_git_branch > > Thanks, > Steven Jenkins > End Point Corporation > > > > From 1c7110a672371e62466a2142e9a4e4e41fe0086f Mon Sep 17 00:00:00 2001 > From: Steven Jenkins <[email protected]> > Date: Tue, 25 Aug 2009 20:41:11 -0400 > Subject: [PATCH/puppet] Implement tasks for git-based workflow > > > Signed-off-by: Steven Jenkins <[email protected]> > --- > tasks/rake/git_workflow.rake | 93 +++++++++++++++++++++++++++++++++ > +++++++++ > tasks/rake/mail_patches.rake | 35 ---------------- > 2 files changed, 93 insertions(+), 35 deletions(-) > create mode 100644 tasks/rake/git_workflow.rake > delete mode 100644 tasks/rake/mail_patches.rake Does the Rakefile automatically load all rake task files, or should there be a require in here, or what? It seems weird you can move the mail_patches task without having to change a require. Either way, though, I'm all for this kind of thing -- adding automation around our process is great. > > diff --git a/tasks/rake/git_workflow.rake b/tasks/rake/ > git_workflow.rake > new file mode 100644 > index 0000000..98f487a > --- /dev/null > +++ b/tasks/rake/git_workflow.rake > @@ -0,0 +1,93 @@ > +# This set of tasks helps automate the workflow as described on > +# http://reductivelabs.com/trac/puppet/wiki/Development/DevelopmentLifecycle > + > +# This should be changed as new versions get released > +...@next_release = "0.26.x" We often won't actually know this. E.g., I actually hope the next release (after 0.25) is 1.0, but we're going to start on the assumption it'll be 0.26. > > +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 @next_release: return "master" > + else return start > + end > +end > + > +desc "Do git setup to start work on a feature" > +task :start_feature, [:feature,:branch] do |t, args| I take it this is how rake deals with the start_feature[events] syntax? > > + args.with_defaults(:branch => @next_release) > + start_at = find_start(args.branch) > + command = "git checkout -b feature/#{start_at}/#{args.feature} > #{start_at}" > + %x{#{command}} > + if $? != 0 > + raise <<EOS > +Was not able to create branch for #{args.feature} on branch > #{args.branch}, starting at #{start_at}: error code was: #{$?} > +Git command used was: #{command} > + > +The most common error is to specify a non-existent starting point. > +EOS > + end > +end > + > +desc "Do git setup to start work on a Redmine ticket" > +task :start_ticket, [:ticket, :branch] do |t, args| > + args.with_defaults(:branch => @next_release) > + > + start_at = find_start(args.branch) > + command = "git checkout -b ticket/#{args.branch}/#{args.ticket} > #{start_at}" > + %x{#{command}} > + if $? != 0 > + 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} > + > +The most common error is to specify a non-existent starting point. > +EOS > + end > +end I like the idea of these tasks, but I think it'd be nice if they made the corresponding remote setups. E.g., adding something like the following to the git config: [branch "tickets/master/2296"] remote = luke merge = refs/heads/tickets/master/2296 I think there are git commands to do so. We could easily require a git config option that specified the default remote, and then set these up. That way all of the 'git push' stuff works just fine. I've also got a 'git-cleanup-branch' script that cleans up things like this by looking through the git history to see if a given commit (as determined by its summary, rather than its commit, since that will change on a rebase) is merged, and if so removes the local and remote branches. 90% of its code is abstracting git into an OO interface, so it makes sense to start using the lib at that point. > > +# 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}'} > + %x{git push #{arg.remote} #{branch}} > + raise "Unable to push to #{arg.remote}" if $? != 0 > +end With the above setup, this becomes a bit unnecessary. > > +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" > + > + # And then mail them out. > + > + # If we've got more than one patch, add --compose > + if Dir.glob("00*.patch").length > 1 > + compose = "--compose" > + else > + compose = "" > + end > + > + # Now send the mail. > + sh "git send-email #{compose} --no-signed-off-by-cc --suppress- > from --to [email protected] 00*.patch" > + > + # Finally, clean up the patches > + sh "rm 00*.patch" > +end > + > diff --git a/tasks/rake/mail_patches.rake b/tasks/rake/ > mail_patches.rake > deleted file mode 100644 > index 82455e8..0000000 > --- a/tasks/rake/mail_patches.rake > +++ /dev/null > @@ -1,35 +0,0 @@ > -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" > - > - # And then mail them out. > - > - # If we've got more than one patch, add --compose > - if Dir.glob("00*.patch").length > 1 > - compose = "--compose" > - else > - compose = "" > - end > - > - # Now send the mail. > - sh "git send-email #{compose} --no-signed-off-by-cc --suppress- > from --to [email protected] 00*.patch" > - > - # Finally, clean up the patches > - sh "rm 00*.patch" > -end > -- > 1.6.1.rc3 > -- The only really good place to buy lumber is at a store where the lumber has already been cut and attached together in the form of furniture, finished, and put inside boxes. --Dave Barry --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en -~----------~----~----~----~------~----~------~--~---
