module Reap class Project # Make a release announcement. Generates and can email release # announcements. The announcement if built from the README file # unless another file is specified. # # This will subsititue the first line mathing /please see notes/i # for the notelog. And /please see change/i for the changelog. # # The following settings apply: # # title Project title. # subtitle Brief one-line description. # version Project version. # description Long description of project. # homepage Project homepage web address. # slogan Motto for you project. # memo File that contains announcement message. # template Announcement template file, rather then README. # mail_to Email address(es) to send announcemnt. # # If mail_to is set then these also apply: # # from Message FROM address [email]. # subject Subject of email message ([ANN] title verison). # server Email server to route message. # port Email server's port. # domain Email server's domain name. # account Email account name [email]. # login Login type: plain, cram_md5 or login. # secure Uses TLS security, true or false? # # A template file can be specified that uses "$setting" as # substitutes for poject information. def announce(options=nil) options = configure_options(options, 'announce', 'mail') message = announce_message(options) options = options.to_ostruct mail_to = options.mail_to mail_from = options.mail_from subject = options.subject # Subject line (default is "ANN: project version"). server = options.server # Email server port = options.port # Emails server port (default is usually correct). account = options.account # Email account name (defaults to mail_from). domain = options.domain # User domain (not sure why SMTP requires this?) login = options.login # Login type (plain, login) secure = options.secure # Use TLS/SSL true or false? password = options.password || ENV['EMAIL_PASSWORD'] title = options.title || metadata.title version = options.versoin || metadata.version # defaults subject ||= "%s, v%s release" account ||= mail_from subject = subject % [title, version] if dryrun? puts "email '#{subject}'" puts "\n#{message}\n\n" if verbose? else puts "\n#{message}\n\n" if mail_to ans = ask("Would you like to email this announcement?", "yN") case ans.downcase when 'y', 'yes' email(message, :to => mail_to, :from => mail_from, :subject => subject, :server => server, :port => port, :domain => domain, :account => account, :login => login, :secure => secure, :password => password ) end end end end # Make a release announcement. Generates and can email a release # announcements. These are nicely formated message and can # email the message to the specified address(es). # # The following settings apply: # # template Announcement file/template. # cutoff Max number of lines of changelog to show. # # A template file can be specified that uses "$setting" as # substitutes for poject information. def announce_message(options={}) config = settings['announce'] || {} options = config.merge(options).to_ostruct cutoff = options.cutoff || 30 template = options.template || "{ANNOUNCE}{,.txt}" #config['mail_to'] = nil if keys['mail_to'].empty? # Build message # template template = Dir.glob(options.template.to_s, File::FNM_CASEFOLD).first if template readme = File.read(template) readme = unfold_paragraphs(readme) else readme = '' readme << "= #{metadata.title} v#{metadata.version}\n\n" readme << " #{metadata.homepage}\n\n" readme << "#{metadata.description}\n\n" readme << "Please see the NOTES file.\n\n" readme << "== CHANGES\n\n" readme << "Please see the CHANGES file.\n" end # changelog file = Dir.glob('change{s,log}{,.txt}', File::FNM_CASEFOLD)[0] changelog = file ? File.read(file).strip : '' #changelog = unfold_paragraphs(changelog) changelog = changelog.split("\n")[0..cutoff].join("\n") # noteslog file = Dir.glob('note{s,log}{,.txt}', File::FNM_CASEFOLD)[0] notelog = file ? File.read(file).strip : '' notelog = unfold_paragraphs(notelog) # Strip tiny version zero. #if keys['version'] =~ /[.].*?[.]/ # keys['version'] = keys['version'].chomp('.0') #end # Make announcement message message = readme.dup #message.gsub!('$readme$', readme || '') message.sub!(/^\s*please\ see(\ the)?\ notes(.*?)$/i, "\n" + notelog) if notelog message.sub!(/^\s*please\ see(\ the)?\ change(.*?)$/i, "\n" + changelog) if changelog template = message.dup template.scan(/\$(\w+?)\$/m) do |key| #key = key.strip name = $1.strip #key[1..-1] if metadata.respond_to?(name.downcase) value = metadata.send(name.downcase) message.gsub!("$#{name}$", value.to_s.strip) else puts "Warning: Unknown project field -- #{name}." end end message.gsub!(/(^|[ ])[$].*?(?=[ ]|$)/,'') # remove unused vars message.gsub!(/\n\s*\n\s*\n/m,"\n\n") # remove any triple blank lines message.rstrip! return message end def unfold_paragraphs(string) blank = false text = '' string.split(/\n/).each do |line| if /\S/ !~ line text << "\n\n" blank = true else if /^(\s+|[*])/ =~ line text << (line.rstrip + "\n") else text << (line.rstrip + " ") end blank = false end end return text end end end # keys = {} # keys['from'] = info.email # keys.update info.gather('mail') # keys.update info.gather('announce') # keys.update info.select( # :project, :version, :title, :subtitle, :description, # :homepage, :download, :slogan # ) # keys.update override if override