module Hoe::Mercurial
def define_mercurial_tasks
def define_mercurial_tasks return unless File.exist?( ".hg" ) && !Rake::Task.task_defined?( 'hg:checkin' ) file COMMIT_MSG_FILE do |task| edit_commit_log( task.name ) end namespace :hg do desc "Prepare for a new release" task :prep_release do uncommitted_files = get_uncommitted_files() unless uncommitted_files.empty? log "Uncommitted files:\n", *uncommitted_files.map {|fn| " #{fn}\n" } ask_for_confirmation( "\nRelease anyway?", true ) do log "Okay, releasing with uncommitted versions." end end tags = get_tags() rev = get_current_rev() pkg_version_tag = "#{hg_release_tag_prefix}#{version}" # Look for a tag for the current release version, and if it exists abort if tags.include?( pkg_version_tag ) error "Version #{version} already has a tag." fail end # Ensure that the History file contains an entry for every release Rake::Task[ 'check_history' ].invoke if self.check_history_on_release # Sign the current rev if self.hg_sign_tags log "Signing rev #{rev}" run 'hg', 'sign' end # Tag the current rev log "Tagging rev #{rev} as #{pkg_version_tag}" run 'hg', 'tag', pkg_version_tag # Offer to push Rake::Task['hg:push'].invoke end desc "Check for new files and offer to add/ignore/delete them." task :newfiles do log "Checking for new files..." entries = get_unknown_files() unless entries.empty? files_to_add = [] files_to_ignore = [] files_to_delete = [] entries.each do |entry| action = prompt_with_default( " #{entry}: (a)dd, (i)gnore, (s)kip (d)elete", 's' ) case action when 'a' files_to_add << entry when 'i' files_to_ignore << entry when 'd' files_to_delete << entry end end unless files_to_add.empty? run 'hg', 'add', *files_to_add end unless files_to_ignore.empty? hg_ignore_files( *files_to_ignore ) end unless files_to_delete.empty? delete_extra_files( files_to_delete ) end end end task :add => :newfiles desc "Pull and update from the default repo" task :pull do paths = get_repo_paths() if origin_url = paths['default'] ask_for_confirmation( "Pull and update from '#{origin_url}'?", false ) do Rake::Task['hg:pull_without_confirmation'].invoke end else trace "Skipping pull: No 'default' path." end end desc "Pull and update without confirmation" task :pull_without_confirmation do run 'hg', 'pull', '-u' end desc "Update to tip" task :update do run 'hg', 'update' end desc "Clobber all changes (hg up -C)" task :update_and_clobber do run 'hg', 'update', '-C' end task :precheckin do trace "Pre-checkin hooks" end desc "Check the current code in if tests pass" task :checkin => [:pull, :newfiles, :precheckin, COMMIT_MSG_FILE] do targets = get_target_args() $stderr.puts '---', File.read( COMMIT_MSG_FILE ), '---' ask_for_confirmation( "Continue with checkin?" ) do run 'hg', 'ci', '-l', COMMIT_MSG_FILE, targets rm_f COMMIT_MSG_FILE end Rake::Task['hg:push'].invoke end task :commit => :checkin task :ci => :checkin CLEAN.include( COMMIT_MSG_FILE ) desc "Push to the default origin repo (if there is one)" task :push do paths = get_repo_paths() if origin_url = paths['default'] ask_for_confirmation( "Push to '#{origin_url}'?", false ) do Rake::Task['hg:push_without_confirmation'].invoke end else trace "Skipping push: No 'default' path." end end desc "Push to the default repo without confirmation" task :push_without_confirmation do run 'hg', 'push' end end # Add a top-level 'ci' task for checkin desc "Check in your changes" task :ci => 'hg:checkin' # Hook the release task and prep the repo first task :prerelease => 'hg:prep_release' desc "Check the history file to ensure it contains an entry for each release tag" task :check_history do log "Checking history..." missing_tags = get_unhistoried_version_tags() unless missing_tags.empty? abort "%s needs updating; missing entries for tags: %p" % [ self.history_file, missing_tags ] end end rescue ::Exception => err $stderr.puts "%s while defining Mercurial tasks: %s" % [ err.class.name, err.message ] raise end
def get_unhistoried_version_tags( include_pkg_version=true )
## Read the list of tags and return any that don't have a corresponding section
def get_unhistoried_version_tags( include_pkg_version=true ) prefix = self.hg_release_tag_prefix tag_pattern = /#{prefix}\d+(\.\d+)+/ release_tags = get_tags().grep( /^#{tag_pattern}$/ ) release_tags.unshift( "#{prefix}#{version}" ) if include_pkg_version IO.readlines( self.history_file ).each do |line| if line =~ /^(?:h\d\.|#+|=+)\s+(#{tag_pattern})\s+/ trace " found an entry for tag %p: %p" % [ $1, line ] release_tags.delete( $1 ) else trace " no tag on line %p" % [ line ] end end return release_tags end
def initialize_mercurial
def initialize_mercurial # Follow semantic versioning tagging specification (http://semver.org/) self.hg_release_tag_prefix = "v" self.hg_sign_tags = false self.check_history_on_release = false minor_version = VERSION[ /^\d+\.\d+/ ] self.extra_dev_deps << ['hoe-mercurial', "~> #{minor_version}"] unless self.name == 'hoe-mercurial' end