diff --git a/.gitignore b/.gitignore index 9f30a35..2d74f5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ pkg/* *.gem .bundle +.rvmrc diff --git a/Gemfile b/Gemfile index d737a66..fa7a7cd 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,5 @@ -source "http://rubygems.org" +source :rubygems -# Specify your gem's dependencies in hudson.war.gemspec -gemspec +gem "rake" +gem "rest-client" +gem "json" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..4d2f6fe --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,16 @@ +GEM + remote: http://rubygems.org/ + specs: + json (1.4.6) + mime-types (1.16) + rake (0.8.7) + rest-client (1.6.1) + mime-types (>= 1.16) + +PLATFORMS + ruby + +DEPENDENCIES + json + rake + rest-client diff --git a/README.md b/README.md new file mode 100644 index 0000000..5093550 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +## Hudson Wargemmer + +#### What? + +The hudson wargemmer consists of two parts: a Rake task for turning a hudson war file +(__W.__eb __A.__ __R.__chive for those not familiar with java lingo) into a distributable rubygem, and a cron task for creating +a new version of the gem, whenever a new hudson version comes out. + +The script polls the hudson update center and checks to see if there is a newer version of the hudson distribution that +has not yet been gemmed up and if not, then bundles it and pushes it to [rubygems.org](http://rubygems.org) as a gem named +hudson-war. + +The generated gem has the same version number as the hudson distribution itself. So if you want the 1.386 distribution, then you would do a + + gem install hudson-war --version 1.386 + +#### How? + +In addition to the war file long with the The hudson-war gem comes with an executable script `hudson.war` to help you leverage your hudson distribution. + +Without any arguments, it returns the location of the hudson warfile itself: + + $ hudson.war location + /path/to/hudson.war + +It can unpack itself to a given directory. This is useful if you want to extract certain assets such as classfiles, annotations, configurations from it. + + $ hudson.war unpack /tmp/hudson.war.exploded + +It can copy itself anywhere + + legolas: cowboyd$ hudson.war cp tmp + copied /Users/cowboyd/.rvm/gems/ruby-1.8.7-p174@hudson.war/gems/hudson-war-1.391/lib/hudson/hudson.war -> tmp + +Or if you want the classpath: + + $ hudson.war classpath + legolas:hudson.war cowboyd$ hudson.war classpath + /Users/cowboyd/.hudson/wars/1.391/WEB-INF/lib/hudson-core-1.391.jar + diff --git a/Rakefile b/Rakefile index 14cfe0b..83a64d9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,2 +1,73 @@ -require 'bundler' -Bundler::GemHelper.install_tasks +require 'bundler/setup' +require 'erb' + +INS = FileList['template/**/*.in'] + +def render(src, dest, use_binding = binding) + File.open(dest, "w", File.stat(src).mode) do |output| + result = ERB.new(File.read(src)).result(use_binding) + output.write(result) + end +end + +task :gem, :version do |t, options| + hudson_version = options.version + raise "invalid version number: #{options.version}" unless hudson_version.to_f > 0 + directory gem_dir = "pkg/#{hudson_version}" + outs = INS.map do |f| + filename = File.join(f.split('/')[1..-1]) + directory dest_dir = File.join(gem_dir, File.dirname(filename)) + file(File.join(dest_dir, File.basename(filename, '.in')) => [f, dest_dir]) do |out| + render f, out.name, binding + end + end + directory war_dir = "#{gem_dir}/lib/hudson" + warfile = file("#{war_dir}/hudson.war" => war_dir) do |f| + Dir.chdir(File.dirname(f.name)) do + sh "wget http://updates.hudson-labs.org/download/war/#{hudson_version}/hudson.war" + end + end + + gemspec = file("#{gem_dir}/hudson-war.gemspec" => outs + [warfile]) do |f| + Gem::Specification.new do |s| + s.name = "hudson-war" + s.version = hudson_version + s.platform = Gem::Platform::RUBY + s.authors = ["Charles Lowell"] + s.email = ["cowboyd@thefrontside.net"] + s.homepage = "http://rubygems.org/gems/hudson-war" + s.summary = "fetch and use a specific hudson version with rubygems" + s.description = "download and install a specific version of the hudson war file which can be used for either running a server, or for plugin development" + s.rubyforge_project = "hudson-war" + + # s.files = `git ls-files`.split("\n") + # s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = ['hudson.war'] + s.require_paths = ["lib"] + sh "touch #{f.name}" + sh "rm -rf #{gem_dir}/*.gem" + Dir.chdir(gem_dir) do + s.files = FileList['**/*'].to_a + File.open("#{s.name}.gemspec", "w") do |f| + f.write(s.to_ruby) + end + end + end + end + + gem = file "#{gem_dir}/hudson-war-#{hudson_version}.gem" => gemspec do + Dir.chdir(gem_dir) do + Gem::Builder.new(eval(File.read(File.basename(gemspec.name)))).build + end + end + gem.invoke +end + +task :install, :version do |t, options| + Rake::Task["gem"].invoke(options.version) + sh "gem install pkg/#{options.version}/hudson-war-#{options.version}.gem" +end + +task :clean do + sh "rm -rf pkg" +end \ No newline at end of file diff --git a/hudson.war.gemspec b/hudson.war.gemspec deleted file mode 100644 index 6e3dde2..0000000 --- a/hudson.war.gemspec +++ /dev/null @@ -1,21 +0,0 @@ -# -*- encoding: utf-8 -*- -$:.push File.expand_path("../lib", __FILE__) -require "hudson/war/version" - -Gem::Specification.new do |s| - s.name = "hudson.war" - s.version = Hudson::War::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ["Charles Lowell"] - s.email = ["cowboyd@thefrontside.net"] - s.homepage = "http://rubygems.org/gems/hudson.war" - s.summary = "get a specific hudson version with rubygems" - s.description = "this installs a known version of hudson. It also comes with a cron task to bundle versions of itself when a new version of hudson comes out" - - s.rubyforge_project = "hudson.war" - - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } - s.require_paths = ["lib"] -end diff --git a/lib/hudson/war/version.rb b/lib/hudson/war/version.rb deleted file mode 100644 index 2fbed2e..0000000 --- a/lib/hudson/war/version.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Hudson - module War - VERSION = "1.386" - end -end - diff --git a/template/bin/hudson.war.in b/template/bin/hudson.war.in new file mode 100755 index 0000000..2fb91b0 --- /dev/null +++ b/template/bin/hudson.war.in @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby + +require 'optparse' +require File.expand_path(File.dirname(__FILE__) + '/../lib/hudson/war') + + +war = Hudson::War +parser = OptionParser.new + +parser.on("-v", "--version", String, "Use this version of hudson") do |version| + puts war::VERSION + exit(1) +end + +parser.parse(ARGV) + +case cmd = ARGV.shift +when 'unpack' + dest = ARGV.first + war.unpack(dest) +when 'classpath' + puts war.classpath +when 'cp' + dest = ARGV.first + war.cp dest +else + puts war::LOCATION +end + diff --git a/template/lib/hudson/war.rb.in b/template/lib/hudson/war.rb.in new file mode 100644 index 0000000..a0b3798 --- /dev/null +++ b/template/lib/hudson/war.rb.in @@ -0,0 +1,76 @@ +require 'fileutils' +module Hudson + module War + VERSION = '<%= hudson_version %>' + LOCATION = File.expand_path(File.join(File.dirname(__FILE__), "hudson.war")) + + module_function + + def unpack(dest_dir, output = $stdout) + target = File.dirname(dest_dir).tap do |dir_of_dest_dir| + raise "'#{dir_of_dest_dir}' is not a directory" unless File.directory?(dir_of_dest_dir) + end + FileUtils.mkdir_p dest_dir + Dir.chdir(dest_dir) do + sh "jar xvf #{LOCATION}", output + end + end + + def cp(dest, output = $stdout) + FileUtils.cp(LOCATION, dest) + output << "copied #{LOCATION} -> #{dest}\n" + end + + # desc "server [options]", "run a hudson server" + # method_option :home, :desc => "use this directory to store server data", :type => :string, :default => File.join(ENV['HOME'], ".hudson", "server"), :banner => "PATH" + # method_option :port, :desc => "run hudson server on this port", :type => :numeric, :default => 3001, :aliases => "-p" + # method_option :control, :desc => "set the shutdown/control port", :type => :numeric, :default => 3002, :aliases => "-c" + # method_option :daemon, :desc => "fork into background and run as a daemon", :type => :boolean, :default => false + # method_option :kill, :desc => "send shutdown signal to control port", :type => :boolean, :aliases => "-k" + # method_option :logfile, :desc => "redirect log messages to this file", :type => :string, :banner => "PATH" + + def server(output, options) + home = options.home || File.join(ENV['HOME'], ".hudson", "server") + port = options.port.to_i || 3001 + control = options.control.to_i || 3002 + daemon = options.daemon + kill = options.kill + logfile = options.logfile + + if kill + require 'socket' + TCPSocket.open("localhost", control) do |sock| + sock.write("0") + end + else + javatmp = File.join(home, "javatmp") + FileUtils.mkdir_p javatmp + ENV['HUDSON_HOME'] = serverhome + cmd = ["java", "-Djava.io.tmpdir=#{javatmp}", "-jar", LOCATION] + cmd << "--daemon" if daemon + cmd << "--logfile=#{File.expand_path(logfile)}" if logfile + cmd << "--httpPort=#{port}" + cmd << "--controlPort=#{control}" + output << cmd.join(" ") + exec(*cmd) + end + end + + def classpath + dest_dir = File.join(ENV['HOME'], '.hudson', 'wars', VERSION) + if File.directory?(dest_dir) + "#{dest_dir}/WEB-INF/lib/hudson-core-#{VERSION}.jar" + else + FileUtils.mkdir_p(dest_dir) + unpack(dest_dir, []) + classpath + end + end + + def sh(command, output = $stdout) + output << command + "\n" + output << result = `#{command}` + raise result unless $?.success? + end + end +end \ No newline at end of file diff --git a/wargemmer b/wargemmer new file mode 100755 index 0000000..44f0eed --- /dev/null +++ b/wargemmer @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +require 'bundler/setup' + +require 'restclient' +require 'json' + +print "latest hudson version..." +hudson_metadata = JSON.parse RestClient.get("http://updates.hudson-labs.org/update-center.json").split("\n")[1..-2].join("\n") + +puts current_hudson_version = hudson_metadata['core']['version'] + +print "latest gem version..." + +gem_metadata = JSON.parse RestClient.get("http://rubygems.org/api/v1/gems/hudson-war.json") + +puts current_gem_version = gem_metadata['version'] + +if current_hudson_version > current_gem_version + puts "upgrading..." + exec "rake clean version[#{current_hudson_version}] gem" +end + + +