diff --git a/.boring b/.boring new file mode 100644 index 0000000..7bac693 --- /dev/null +++ b/.boring @@ -0,0 +1,44 @@ +# Boring file regexps: +\.hi$ +\.o$ +\.o\.cmd$ +# *.ko files aren't boring by default because they might +# be Korean translations rather than kernel modules. +# \.ko$ +\.ko\.cmd$ +\.mod\.c$ +(^|/)\.tmp_versions($|/) +(^|/)CVS($|/) +(^|/)RCS($|/) +~$ +#(^|/)\.[^/] +(^|/)_darcs($|/) +\.bak$ +\.BAK$ +\.orig$ +(^|/)vssver\.scc$ +\.swp$ +(^|/)MT($|/) +(^|/)\{arch\}($|/) +(^|/).arch-ids($|/) +(^|/), +\.class$ +\.prof$ +(^|/)\.DS_Store$ +(^|/)BitKeeper($|/) +(^|/)ChangeSet($|/) +(^|/)\.svn($|/) +\.py[co]$ +\# +\.cvsignore$ +(^|/)Thumbs\.db$ +(^|/)autom4te\.cache($|/) + +# project specific items +^doc\/* +^pkg/* +^log/* +\.swo$ +\.swp$ +email.txt + diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..7a53311 --- /dev/null +++ b/CHANGES @@ -0,0 +1,4 @@ += launchy Changelog +=== Version 0.0.1 + +* Initial public release diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3f15384 --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2007, Jeremy Hinegardner + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + + * Neither the name of Jeremy Hinegardner nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README b/README new file mode 100644 index 0000000..bc74466 --- /dev/null +++ b/README @@ -0,0 +1,15 @@ +== launchy + +* Homepage +* rubyforge project +* email + +== DESCRIPTION + +== FEATURES + +== SYNOPSIS + +== CREDITS + +== LICENSE diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..8e578a1 --- /dev/null +++ b/Rakefile @@ -0,0 +1,65 @@ +require 'rubygems' +require 'rake/gempackagetask' +require 'rake/clean' +require 'rake/rdoctask' + +$: << File.join(File.dirname(__FILE__),"lib") +require 'launchy' + +# load all the extra tasks for the project +TASK_DIR = File.join(File.dirname(__FILE__),"tasks") +FileList[File.join(TASK_DIR,"*.rb")].each do |tasklib| + require "tasks/#{File.basename(tasklib)}" +end + +task :default => "test:default" + +#----------------------------------------------------------------------- +# Documentation +#----------------------------------------------------------------------- +namespace :doc do + + # generating documentation locally + Rake::RDocTask.new do |rdoc| + rdoc.rdoc_dir = Launchy::SPEC.local_rdoc_dir + rdoc.options = Launchy::SPEC.rdoc_options + rdoc.rdoc_files = Launchy::SPEC.rdoc_files + end + + desc "View the RDoc documentation locally" + task :view => :rdoc do + show_files Launchy::SPEC.local_rdoc_dir + end + +end + +#----------------------------------------------------------------------- +# Packaging and Distribution +#----------------------------------------------------------------------- +namespace :dist do + + Rake::GemPackageTask.new(Launchy::SPEC) do |pkg| + pkg.need_tar = Launchy::SPEC.need_tar + pkg.need_zip = Launchy::SPEC.need_zip + end + + desc "Install as a gem" + task :install => [:clobber, :package] do + sh "sudo gem install pkg/#{Launchy::SPEC.full_name}.gem" + end + + # uninstall the gem and all executables + desc "Uninstall gem" + task :uninstall do + sh "sudo gem uninstall #{Launchy::SPEC.name} -x" + end + + desc "dump gemspec" + task :gemspec do + puts Launchy::SPEC.to_ruby + end + + desc "reinstall gem" + task :reinstall => [:install, :uninstall] + +end diff --git a/bin/.git-darcs-dir b/bin/.git-darcs-dir new file mode 100644 index 0000000..e69de29 diff --git a/bin/launchy b/bin/launchy new file mode 100644 index 0000000..7dfc330 --- /dev/null +++ b/bin/launchy @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby + +begin + require 'launchy' +rescue LoadError + path = File.expand_path(File.join(File.dirname(__FILE__),"..","lib")) + raise if $:.include? path + $: << path + retry +end + +Launchy.do_magic(*ARGV) diff --git a/lib/.git-darcs-dir b/lib/.git-darcs-dir new file mode 100644 index 0000000..e69de29 diff --git a/lib/launchy.rb b/lib/launchy.rb new file mode 100644 index 0000000..62141d2 --- /dev/null +++ b/lib/launchy.rb @@ -0,0 +1,31 @@ +module Launchy + + ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__),"..")) + LIB_DIR = File.join(ROOT_DIR,"lib").freeze + RESOURCE_DIR = File.join(ROOT_DIR,"resources").freeze + + # + # Utility method to require all files ending in .rb in the directory + # with the same name as this file minus .rb + # + def require_all_libs_relative_to(fname) + prepend = File.basename(fname,".rb") + search_me = File.join(File.dirname(fname),prepend) + + Dir.entries(search_me).each do |rb| + if File.extname(rb) == ".rb" then + require "#{prepend}/#{File.basename(rb,".rb")}" + end + end + end + module_function :require_all_libs_relative_to + + class << self + def do_magic(*params) + klass = Launchy::Spawnable::Application.find_application_class_for(*params) + klass.run(*params) + end + end +end + +Launchy.require_all_libs_relative_to(__FILE__) diff --git a/lib/launchy/.git-darcs-dir b/lib/launchy/.git-darcs-dir new file mode 100644 index 0000000..e69de29 diff --git a/lib/launchy/gemspec.rb b/lib/launchy/gemspec.rb new file mode 100644 index 0000000..7cd8834 --- /dev/null +++ b/lib/launchy/gemspec.rb @@ -0,0 +1,48 @@ +require 'rubygems' +require 'launchy/specification' +require 'launchy/version' +require 'rake' + +# The Gem Specification plus some extras for launchy. +module Launchy + SPEC = Launchy::Specification.new do |spec| + spec.name = "launchy" + spec.version = Launchy::VERSION + spec.rubyforge_project = "launchy" + spec.author = "Jeremy Hinegardner" + spec.email = "jeremy@hinegardner.org" + spec.homepage = "http://launchy.rubyforge.org/" + + spec.summary = "A Summary of launchy." + spec.description = <<-DESC + A longer more detailed description of launchy. + DESC + + spec.extra_rdoc_files = FileList["[A-Z]*"] + spec.has_rdoc = true + spec.rdoc_main = "README" + spec.rdoc_options = [ "--line-numbers" , "--inline-source" ] + + spec.test_files = FileList["spec/**/*.rb", "test/**/*.rb"] + spec.files = spec.test_files + spec.extra_rdoc_files + + FileList["lib/**/*.rb", "resources/**/*"] + + spec.executable = spec.name + + + # add dependencies + spec.add_dependency("systemu") + + spec.platform = Gem::Platform::RUBY + + spec.local_rdoc_dir = "doc/rdoc" + spec.remote_rdoc_dir = "#{spec.name}/rdoc" + spec.local_coverage_dir = "doc/coverage" + spec.remote_coverage_dir= "#{spec.name}/coverage" + + spec.remote_site_dir = "#{spec.name}/" + + end +end + + diff --git a/lib/launchy/spawnable.rb b/lib/launchy/spawnable.rb new file mode 100644 index 0000000..f56c3af --- /dev/null +++ b/lib/launchy/spawnable.rb @@ -0,0 +1,2 @@ +require 'launchy/spawnable/application' +require 'launchy/spawnable/browser' diff --git a/lib/launchy/spawnable/.git-darcs-dir b/lib/launchy/spawnable/.git-darcs-dir new file mode 100644 index 0000000..e69de29 diff --git a/lib/launchy/spawnable/application.rb b/lib/launchy/spawnable/application.rb new file mode 100644 index 0000000..909052d --- /dev/null +++ b/lib/launchy/spawnable/application.rb @@ -0,0 +1,72 @@ +require 'launchy/spawnable' +require 'rbconfig' +require 'systemu' + +module Launchy + module Spawnable + class Application + + KNOWN_OS_FAMILIES = [ :windows, :darwin, :nix ] + + class << self + def inherited(sub_class) + application_classes << sub_class + end + def application_classes + @application_classes ||= [] + end + + def find_application_class_for(*args) + application_classes.find { |klass| klass.handle?(*args) } + end + end + + # find an executable in the available paths + # mkrf did such a good job on this I had to borrow it. + def find_executable(bin,*paths) + paths = ENV['PATH'].split(File::PATH_SEPARATOR) if paths.empty? + paths.each do |path| + file = File.join(path,bin) + return file if File.executable?(file) + end + return nil + end + + # return the current 'host_os' string from ruby's configuration + def my_os + ::Config::CONFIG['host_os'] + end + + # detect what the current os is and return :windows, :darwin, :nix or :java + def my_os_family(test_os = my_os) + case test_os + when /mswin/i + family = :windows + when /windows/i + family = :windows + when /darwin/i + family = :darwin + when /mac os/i + family = :darwin + when /solaris/i + family = :nix + when /bsd/i + family = :nix + when /linux/i + family = :nix + when /cygwin/i + family = :nix + else + $stderr.puts "Unknown OS familiy for '#{test_os}'. Please report this bug." + family = :unknown + end + end + + # run the command via systemu + def run(cmd,*args) + args.unshift(cmd) + systemu args.join(' ') + end + end + end +end \ No newline at end of file diff --git a/lib/launchy/spawnable/browser.rb b/lib/launchy/spawnable/browser.rb new file mode 100644 index 0000000..5220dbb --- /dev/null +++ b/lib/launchy/spawnable/browser.rb @@ -0,0 +1,50 @@ +require 'launchy/spawnable/application' +require 'uri' + +module Launchy + module Spawnable + class Browser < Application + APP_LIST = { + :windows => %w[ firefox iexplore ], + :darwin => %w[ open ], + :nix => %w[ firefox ], + :unknown => [], + } + class << self + def run(*args) + Browser.new.visit(args[0]) + end + + # return true if this class can handle the given parameter(s) + def handle?(*args) + begin + uri = URI.parse(args[0]) + return [URI::HTTP, URI::HTTPS, URI::FTP].include?(uri.class) + rescue Exception + return false + end + end + end + + def initialize + raise "Unable to find browser to launch for os family '#{my_os_family}'." unless browser + end + + # returns the list of command line application names for the current os + def app_list + APP_LIST[my_os_family] + end + + # return the full command line path to the browser or nil + def browser + @browser ||= app_list.collect { |bin| find_executable(bin) }.reject { |x| x.nil? }.first + end + + # launch the browser at the appointed url + def visit(url) + run(browser,url) + end + + end + end +end \ No newline at end of file diff --git a/lib/launchy/specification.rb b/lib/launchy/specification.rb new file mode 100644 index 0000000..07a0bc0 --- /dev/null +++ b/lib/launchy/specification.rb @@ -0,0 +1,128 @@ +require 'rubygems' +require 'rubygems/specification' +require 'rake' + +module Launchy + # Add some additional items to Gem::Specification + # A Launchy::Specification adds additional pieces of information the + # typical gem specification + class Specification + + RUBYFORGE_ROOT = "/var/www/gforge-projects/" + + # user that accesses remote site + attr_accessor :remote_user + + # remote host, default 'rubyforge.org' + attr_accessor :remote_host + + # name the rdoc main + attr_accessor :rdoc_main + + # local directory in development holding the generated rdoc + # default 'doc' + attr_accessor :local_rdoc_dir + + # remote directory for storing rdoc, default 'doc' + attr_accessor :remote_rdoc_dir + + # local directory for coverage report + attr_accessor :local_coverage_dir + + # remote directory for storing coverage reports + # This defaults to 'coverage' + attr_accessor :remote_coverage_dir + + # local directory for generated website, default +site/public+ + attr_accessor :local_site_dir + + # remote directory relative to +remote_root+ for the website. + # website. + attr_accessor :remote_site_dir + + # is a .tgz to be created?, default 'true' + attr_accessor :need_tar + + # is a .zip to be created, default 'true' + attr_accessor :need_zip + + + def initialize + @remote_user = nil + @remote_host = "rubyforge.org" + + @rdoc_main = "README" + @local_rdoc_dir = "doc" + @remote_rdoc_dir = "doc" + @local_coverage_dir = "coverage" + @remote_coverage_dir = "coverage" + @local_site_dir = "site/public" + @remote_site_dir = "." + + @need_tar = true + @need_zip = true + + @spec = Gem::Specification.new + + yield self if block_given? + + # update rdoc options to take care of the rdoc_main if it is + # there, and add a default title if one is not given + if not @spec.rdoc_options.include?("--main") then + @spec.rdoc_options.concat(["--main", rdoc_main]) + end + + if not @spec.rdoc_options.include?("--title") then + @spec.rdoc_options.concat(["--title","'#{name} -- #{summary}'"]) + end + end + + # if this gets set then it overwrites what would be the + # rubyforge default. If rubyforge project is not set then use + # name. If rubyforge project and name are set, but they are + # different then assume that name is a subproject of the + # rubyforge project + def remote_root + if rubyforge_project.nil? or + rubyforge_project == name then + return RUBYFORGE_ROOT + "#{name}/" + else + return RUBYFORGE_ROOT + "#{rubyforge_project}/#{name}/" + end + end + + # rdoc files is the same as what would be generated during gem + # installation. That is, everything in the require paths plus + # the rdoc_extra_files + # + def rdoc_files + flist = extra_rdoc_files.dup + @spec.require_paths.each do |rp| + flist << FileList["#{rp}/**/*.rb"] + end + flist.flatten.uniq + end + + # calculate the remote directories + def remote_root_location + "#{remote_user}@#{remote_host}:#{remote_root}" + end + + def remote_rdoc_location + remote_root_location + @remote_rdoc_dir + end + + def remote_coverage_location + remote_root_loation + @remote_coverage_dir + end + + def remote_site_location + remote_root_location + @remote_site_dir + end + + # we delegate any other calls to spec + def method_missing(method_id,*params,&block) + @spec.send method_id, *params, &block + end + end +end diff --git a/lib/launchy/version.rb b/lib/launchy/version.rb new file mode 100644 index 0000000..de58ff9 --- /dev/null +++ b/lib/launchy/version.rb @@ -0,0 +1,18 @@ +module Launchy + class Version + MAJOR = 0 + MINOR = 0 + BUILD = 1 + + class << self + def to_a + [MAJOR, MINOR, BUILD] + end + + def to_s + to_a.join(".") + end + end + end + VERSION = Version.to_s +end diff --git a/spec/.git-darcs-dir b/spec/.git-darcs-dir new file mode 100644 index 0000000..e69de29 diff --git a/spec/browser_spec.rb b/spec/browser_spec.rb new file mode 100644 index 0000000..18ca8fc --- /dev/null +++ b/spec/browser_spec.rb @@ -0,0 +1,23 @@ +require File.join(File.dirname(__FILE__),"spec_helper.rb") + +describe Launchy::Spawnable::Browser do + it "should find a path to a executable" do + File.executable?(Launchy::Spawnable::Browser.new.browser).should == true + end + + it "should handle an http url" do + Launchy::Spawnable::Browser.handle?("http://www.example.com") == true + end + + it "should handle an https url" do + Launchy::Spawnable::Browser.handle?("https://www.example.com") == true + end + + it "should handle an ftp url" do + Launchy::Spawnable::Browser.handle?("ftp://download.example.com") == true + end + + it "should not handle a mailto url" do + Launchy::Spawnable::Browser.handle?("mailto:jeremy@example.com") == false + end +end \ No newline at end of file diff --git a/spec/spawnable_application_spec.rb b/spec/spawnable_application_spec.rb new file mode 100644 index 0000000..8889704 --- /dev/null +++ b/spec/spawnable_application_spec.rb @@ -0,0 +1,38 @@ +require File.join(File.dirname(__FILE__),"spec_helper.rb") +require 'yaml' + +describe Launchy::Spawnable::Application do + before(:each) do + yml = YAML::load(IO.read(File.join(File.dirname(__FILE__),"tattle-host-os.yml"))) + @host_os = yml['host_os'] + @app = Launchy::Spawnable::Application.new + + end + + it "should find all tattled os" do + @host_os.keys.each do |os| + Launchy::Spawnable::Application::KNOWN_OS_FAMILIES.should include(@app.my_os_family(os)) + end + end + + it "should not find os of 'dos'" do + @app.my_os_family('dos').should == :unknown + end + + it "my os should have a value" do + @app.my_os.should_not == '' + @app.my_os.should_not == nil + end + + it "should find open" do + @app.find_executable('open').should == "/usr/bin/open" + end + + it "should not find app xyzzy" do + @app.find_executable('xyzzy').should == nil + end + + it "should find the correct class to launch an ftp url" do + Launchy::Spawnable::Application.find_application_class_for("ftp://download.fedora.redhat.com").should == Launchy::Spawnable::Browser + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..c2e7cbb --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,5 @@ +require 'rubygems' +require 'spec' + +$: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib")) +require 'launchy' diff --git a/spec/tattle-host-os.yml b/spec/tattle-host-os.yml new file mode 100644 index 0000000..95ea4d6 --- /dev/null +++ b/spec/tattle-host-os.yml @@ -0,0 +1,46 @@ +# SOURCE: http://tattle.rubygarden.org +--- +host_os: + freebsd6.1: 1 + darwin8.5.3: 4 + solaris2.9: 8 + darwin7.9.0: 12 + darwin8.6.2: 14 + darwin8.7.1: 31 + darwin8.8.0: 52 + freebsd4.11: 1 + darwin8.7.2: 2 + darwin8.9.0: 6 + darwin8.0: 10 + darwin8.8.1: 136 + darwin8.7.3: 3 + darwin9.0: 4 + linux: 7 + darwin8.9.1: 21 + darwin8.8.2: 53 + Windows XP: 1 + openbsd3.9: 1 + cygwin: 10 + darwin8.8.3: 15 + darwin8.2.0: 3 + darwin8.8.4: 5 + darwin8.8.5: 3 + darwin8.3.0: 3 + openbsd4.0: 6 + Mac OS X: 13 + darwin: 1 + freebsd5: 3 + darwin8.4.0: 6 + darwin8.4.1: 1 + darwin8.5.0: 8 + freebsd6: 22 + darwin8.5.1: 1 + darwin8.6.0: 24 + freebsd6.0: 2 + solaris2.8: 5 + darwin8.5.2: 10 + solaris2.10: 13 + darwin8.7.0: 39 + darwin8.6.1: 81 + mswin32: 290 + linux-gnu: 479 diff --git a/spec/version_spec.rb b/spec/version_spec.rb new file mode 100644 index 0000000..ed4c5da --- /dev/null +++ b/spec/version_spec.rb @@ -0,0 +1,11 @@ +require File.join(File.dirname(__FILE__),"spec_helper.rb") +require 'yaml' + +describe "Launchy::VERSION" do + it "should have 2 dots and have 3 numbers" do + Launchy::VERSION.split('.').size.should == 3 + Launchy::Version.to_a.each do |n| + n.to_i.should >= 0 + end + end +end \ No newline at end of file diff --git a/tasks/.git-darcs-dir b/tasks/.git-darcs-dir new file mode 100644 index 0000000..e69de29 diff --git a/tasks/rspec.rb b/tasks/rspec.rb new file mode 100644 index 0000000..0eadc8d --- /dev/null +++ b/tasks/rspec.rb @@ -0,0 +1,20 @@ +require 'spec/rake/spectask' + +#----------------------------------------------------------------------- +# Testing - this is either test or spec, include the appropriate one +#----------------------------------------------------------------------- +namespace :test do + + task :default => :spec + + Spec::Rake::SpecTask.new do |r| + r.rcov = true + r.rcov_dir = Launchy::SPEC.local_coverage_dir + r.libs = Launchy::SPEC.require_paths + r.spec_opts = %w(--format specdoc) + end + + task :coverage => [:spec] do + show_files Launchy::SPEC.local_coverage_dir + end +end diff --git a/tasks/rubyforge b/tasks/rubyforge new file mode 100644 index 0000000..bec2784 --- /dev/null +++ b/tasks/rubyforge @@ -0,0 +1,105 @@ +require 'rubyforge' + +#----------------------------------------------------------------------- +# Documentation - pushing documentation to rubyforge +#----------------------------------------------------------------------- +namespace :doc do + desc "Deploy the RDoc documentation to rubyforge" + task :deploy => :rerdoc do + sh "rsync -zav --delete #{Launchy::SPEC.local_rdoc_dir}/ #{Launchy::SPEC.rubyforge_rdoc_dest}" + end +end + +#----------------------------------------------------------------------- +# Packaging and Distribution - push to rubyforge +#----------------------------------------------------------------------- +namespace :dist do + desc "Release files to rubyforge" + task :release => [:clean, :package] do + + rubyforge = RubyForge.new + + # make sure this release doesn't already exist + releases = rubyforge.autoconfig['release_ids'] + if releases.has_key?(Launchy::SPEC.name) and releases[Launchy::SPEC.name][Launchy::VERSION] then + abort("Release #{Launchy::VERSION} already exists!") + end + + config = rubyforge.userconfig + config["release_notes"] = Launchy::SPEC.description + config["release_changes"] = last_changeset + config["Prefomatted"] = true + + + puts "Uploading to rubyforge..." + files = FileList[File.join("pkg","#{Launchy::SPEC.name}-#{Launchy::VERSION}.*")].to_a + rubyforge.login + #rubyforge.add_release(Launchy::SPEC.rubyforge_project, Launchy::SPEC.name, Launchy::VERSION, *files) + puts "done." + end +end + +#----------------------------------------------------------------------- +# Announcements - Create an email text file, and post news to rubyforge +#----------------------------------------------------------------------- +def changes + change_file = File.expand_path(File.join(File.basename(__FILE__),"..","CHANGES")) + sections = File.read(change_file).split(/^(?===)/) +end +def last_changeset + changes[1] +end + +def announcement + urls = " #{Launchy::SPEC.homepage}" + subject = "#{Launchy::SPEC.name} #{Launchy::VERSION} Released" + title = "#{Launchy::SPEC.name} version #{Launchy::VERSION} has been released." + body = <" + mail.puts "To: ruby-talk@ruby-lang.org" + mail.puts "Date: #{Time.now.rfc2822}" + mail.puts "Subject: [ANN] #{subject}" + mail.puts + mail.puts title + mail.puts + mail.puts urls + mail.puts + mail.puts body + mail.puts + mail.puts urls + end + puts "Created the following as email.txt:" + puts "-" * 72 + puts File.read("email.txt") + puts "-" * 72 + end + + CLOBBER << "email.txt" + + desc "Post news of #{Launchy::SPEC.name} to #{Launchy::SPEC.rubyforge_project} on rubyforge" + task :post_news do + subject, title, body, urls = announcement + rubyforge = RubyForge.new + rubyforge.login + rubyforge.post_news(Launchy::SPEC.rubyforge_project, subject, "#{title}\n\n#{urls}\n\n#{body}") + puts "Posted to rubyforge" + end + +end