ruby_service_helper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ == 0.1.0 / 2009-01-16
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
@@ -0,0 +1,20 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/ruby_service_helper.rb
6
+ spec/.bacon
7
+ spec/helper.rb
8
+ spec/runner
9
+ spec/spec_ruby_service_helper.rb
10
+ tasks/autospec.rake
11
+ tasks/bacon.rake
12
+ tasks/bones.rake
13
+ tasks/gem.rake
14
+ tasks/git.rake
15
+ tasks/manifest.rake
16
+ tasks/notes.rake
17
+ tasks/post_load.rake
18
+ tasks/rdoc.rake
19
+ tasks/rubyforge.rake
20
+ tasks/setup.rb
@@ -0,0 +1,58 @@
1
+ = ruby_service_helper
2
+ by James Tucker
3
+ http://ra66i.org
4
+ http://github.com/raggi/ruby_service_helper
5
+ http://libraggi.rubyforge.org/ruby_service_helper
6
+
7
+ == DESCRIPTION:
8
+
9
+ Simple declarative configuration for running ruby programs as win32 services
10
+ using win32/daemon.
11
+
12
+ == FEATURES/PROBLEMS:
13
+
14
+ * Simple.
15
+
16
+ == SYNOPSIS:
17
+
18
+ service = MyService.new
19
+ RubyServiceHelper.service = lambda do
20
+ service.start
21
+ end
22
+ RubyServiceHelper.shutdown = lambda do
23
+ service.stop
24
+ end
25
+ RubyServiceHelper.start
26
+
27
+ == REQUIREMENTS:
28
+
29
+ * gem inst win32-service
30
+
31
+ == INSTALL:
32
+
33
+ * gem install ruby_service_helper
34
+
35
+ == LICENSE:
36
+
37
+ (The MIT License)
38
+
39
+ Copyright (c) 2008 James Tucker
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining
42
+ a copy of this software and associated documentation files (the
43
+ 'Software'), to deal in the Software without restriction, including
44
+ without limitation the rights to use, copy, modify, merge, publish,
45
+ distribute, sublicense, and/or sell copies of the Software, and to
46
+ permit persons to whom the Software is furnished to do so, subject to
47
+ the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be
50
+ included in all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
53
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
56
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
57
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
58
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ load 'tasks/setup.rb'
2
+
3
+ ensure_in_path 'lib'
4
+ require 'ruby_service_helper'
5
+
6
+ task :default => :test
7
+
8
+ PROJ.name = 'ruby_service_helper'
9
+ PROJ.authors = 'James Tucker'
10
+ PROJ.email = 'raggi@rubyforge.org'
11
+ PROJ.url = 'http://github.com/raggi/ruby_service_helper'
12
+ PROJ.rubyforge.name = 'libraggi'
13
+ PROJ.version = RubyServiceHelper.version
14
+ PROJ.gem.dependencies << 'win32-service'
@@ -0,0 +1,28 @@
1
+ require 'win32/daemon' unless defined?(Win32) && defined?(Win32::Daemon) ||
2
+ RUBY_PLATFORM !~ /mingw|mswin/
3
+ module Win32; class Daemon; end; end
4
+
5
+ class RubyServiceHelper < Win32::Daemon
6
+
7
+ Version = VERSION = '0.1.0'
8
+
9
+ def self.version; Version; end
10
+
11
+ class << self; attr_accessor :service, :shutdown; end
12
+ # By default does nothing, will exit immediately
13
+ self.service = lambda {}
14
+ # By default does nothing.
15
+ self.shutdown = lambda {}
16
+
17
+ def self.start
18
+ self.mainloop
19
+ end
20
+
21
+ def service_main #:nodoc:
22
+ self.class.service.call
23
+ end
24
+
25
+ def service_stop #:nodoc:
26
+ self.class.shutdown.call
27
+ end
28
+ end
File without changes
@@ -0,0 +1,51 @@
1
+ # Disable test/unit and rspec from running, in case loaded by broken tools.
2
+ Test::Unit.run = false if defined?(Test) && defined?(Test::Unit)
3
+ Spec::run = false if defined?(Spec) && Spec::respond_to?(:run=)
4
+
5
+ # Setup a nice testing environment
6
+ $DEBUG, $TESTING = true, true
7
+ $:.push File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ $:.uniq!
9
+
10
+ %w[rubygems bacon].each { |r| require r }
11
+
12
+ # Bacon doesn't do any automagic, so lets tell it to!
13
+ Bacon.summary_on_exit
14
+
15
+ module Win32
16
+ class Daemon
17
+ def self.mainloop
18
+ @@object = self.new
19
+ @@object.service_main
20
+ end
21
+ def self.stop
22
+ @@object.service_stop
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "Win32::Daemon mock" do
28
+ should "create and run service_main on #mainloop" do
29
+ Class.new(Win32::Daemon) do
30
+ attr_accessor :a
31
+ def service_main
32
+ @a = 1
33
+ self
34
+ end
35
+ end.mainloop.a.should.eql 1
36
+ end
37
+ should "call service_stop on #stop" do
38
+ Class.new(Win32::Daemon) do
39
+ attr_accessor :b
40
+ def service_main; end
41
+ def service_stop
42
+ @b = 1
43
+ self
44
+ end
45
+ end.mainloop
46
+ Win32::Daemon.stop.b.should.eql 1
47
+ end
48
+ end
49
+
50
+ require File.expand_path(
51
+ File.join(File.dirname(__FILE__), %w[.. lib ruby_service_helper]))
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ __DIR__ = File.dirname(__FILE__)
3
+ __APP__ = File.expand_path(__DIR__ + '/../')
4
+
5
+ puts
6
+ Dir.chdir(__APP__) do
7
+ files = ARGV.empty? ? Dir.glob('{test,spec}/**/{test,spec}_*.rb') : ARGV
8
+ files.each { |f| require f }
9
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'RubyServiceHelper' do
4
+ should "#call the service when it starts" do
5
+ x = 0
6
+ RubyServiceHelper.service = lambda { x = 1 }
7
+ RubyServiceHelper.start
8
+ x.should.eql 1
9
+ end
10
+ should "#call the shutdown when it stops" do
11
+ x = 0
12
+ RubyServiceHelper.shutdown = lambda { x = 1 }
13
+ RubyServiceHelper.start
14
+ x.should.eql 0
15
+ Win32::Daemon.stop
16
+ x.should.eql 1
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # Poor mans autotest, for when you absolutely positively, just need an autotest.
2
+ # N.B. Uses a runner under test/ or spec/, so you can customize the runtime.
3
+ # Thanks to manveru for this!
4
+ desc "Run specs every time a file changes in lib or spec"
5
+ task :autospec do
6
+ rb = Gem.ruby rescue nil
7
+ rb ||= (require 'rbconfig'; File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']))
8
+ command = 'spec/runner' if test ?e, 'spec/runner'
9
+ command ||= 'test/runner' if test ?e, 'test/runner'
10
+ files = Dir.glob('{lib,spec,test}/**/*.rb')
11
+ mtimes = {}
12
+ sigtrap = proc { puts "\rDo that again, I dare you!"; trap(:INT){ exit 0 }; sleep 0.8; trap(:INT, &sigtrap) }
13
+ trap(:INT, &sigtrap)
14
+ system "#{rb} -I#{GSpec.require_path} #{command}"
15
+ while file = files.shift
16
+ begin
17
+ mtime = File.mtime(file)
18
+ mtimes[file] ||= mtime
19
+ if mtime > mtimes[file]
20
+ files = Dir.glob('{lib,spec,test}/**/*.rb') - [file] # refresh the file list.
21
+ puts
22
+ system "#{rb} -I#{GSpec.require_path} #{command} #{file}"
23
+ puts
24
+ end
25
+ mtimes[file] = mtime
26
+ files << file
27
+ rescue Exception
28
+ retry
29
+ end
30
+ # print "\rChecking: #{file.ljust((ENV['COLUMNS']||80)-11)}";$stdout.flush
31
+ sleep 0.2
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ desc "Run the executable test specifications"
2
+ task :spec do
3
+ ruby 'spec/runner'
4
+ end
5
+
6
+ desc "Run the executable test specifications"
7
+ task :test => :spec
@@ -0,0 +1,21 @@
1
+ # $Id$
2
+
3
+ if HAVE_BONES
4
+
5
+ namespace :bones do
6
+
7
+ desc 'Show the PROJ open struct'
8
+ task :debug do |t|
9
+ atr = if t.application.top_level_tasks.length == 2
10
+ t.application.top_level_tasks.pop
11
+ end
12
+
13
+ if atr then Bones::Debug.show_attr(PROJ, atr)
14
+ else Bones::Debug.show PROJ end
15
+ end
16
+
17
+ end # namespace :bones
18
+
19
+ end # HAVE_BONES
20
+
21
+ # EOF
@@ -0,0 +1,138 @@
1
+ # $Id$
2
+
3
+ require 'rake/gempackagetask'
4
+
5
+ namespace :gem do
6
+
7
+ PROJ.gem._spec = Gem::Specification.new do |s|
8
+ s.name = PROJ.name
9
+ s.version = PROJ.version
10
+ s.summary = PROJ.summary
11
+ s.authors = Array(PROJ.authors)
12
+ s.email = PROJ.email
13
+ s.homepage = Array(PROJ.url).first
14
+ s.rubyforge_project = PROJ.rubyforge.name
15
+
16
+ s.description = PROJ.description
17
+
18
+ PROJ.gem.dependencies.each do |dep|
19
+ s.add_dependency(*dep)
20
+ end
21
+ PROJ.gem.development_dependencies.each do |dep|
22
+ s.add_development_dependency(*dep)
23
+ end
24
+
25
+ s.files = PROJ.gem.files
26
+ s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
27
+ s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
28
+
29
+ s.bindir = 'bin'
30
+ dirs = Dir["{#{PROJ.libs.join(',')}}"]
31
+ s.require_paths = dirs unless dirs.empty?
32
+
33
+ incl = Regexp.new(PROJ.rdoc.include.join('|'))
34
+ excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
35
+ excl = Regexp.new(excl.join('|'))
36
+ rdoc_files = PROJ.gem.files.find_all do |fn|
37
+ case fn
38
+ when excl; false
39
+ when incl; true
40
+ else false end
41
+ end
42
+ s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
43
+ s.extra_rdoc_files = rdoc_files
44
+ s.has_rdoc = true
45
+
46
+ if test ?f, PROJ.test.file
47
+ s.test_file = PROJ.test.file
48
+ else
49
+ s.test_files = PROJ.test.files.to_a
50
+ end
51
+
52
+ # Do any extra stuff the user wants
53
+ PROJ.gem.extras.each do |msg, val|
54
+ case val
55
+ when Proc
56
+ val.call(s.send(msg))
57
+ else
58
+ s.send "#{msg}=", val
59
+ end
60
+ end
61
+ end # Gem::Specification.new
62
+
63
+ # A prerequisites task that all other tasks depend upon
64
+ task :prereqs
65
+
66
+ desc 'Show information about the gem'
67
+ task :debug => 'gem:prereqs' do
68
+ puts PROJ.gem._spec.to_ruby
69
+ end
70
+
71
+ pkg = Rake::PackageTask.new(PROJ.name, PROJ.version) do |pkg|
72
+ pkg.need_tar = PROJ.gem.need_tar
73
+ pkg.need_zip = PROJ.gem.need_zip
74
+ pkg.package_files += PROJ.gem._spec.files
75
+ end
76
+ Rake::Task['gem:package'].instance_variable_set(:@full_comment, nil)
77
+
78
+ gem_file = if PROJ.gem._spec.platform == Gem::Platform::RUBY
79
+ "#{pkg.package_name}.gem"
80
+ else
81
+ "#{pkg.package_name}-#{PROJ.gem._spec.platform}.gem"
82
+ end
83
+
84
+ desc "Build the gem file #{gem_file}"
85
+ task :package => ['gem:prereqs', "#{pkg.package_dir}/#{gem_file}"]
86
+
87
+ file "#{pkg.package_dir}/#{gem_file}" => [pkg.package_dir] + PROJ.gem._spec.files do
88
+ when_writing("Creating GEM") {
89
+ Gem::Builder.new(PROJ.gem._spec).build
90
+ verbose(true) {
91
+ mv gem_file, "#{pkg.package_dir}/#{gem_file}"
92
+ }
93
+ }
94
+ end
95
+
96
+ desc 'Install the gem'
97
+ task :install => [:clobber, 'gem:package'] do
98
+ sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
99
+
100
+ # use this version of the command for rubygems > 1.0.0
101
+ #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
102
+ end
103
+
104
+ desc 'Uninstall the gem'
105
+ task :uninstall do
106
+ installed_list = Gem.source_index.find_name(PROJ.name)
107
+ if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
108
+ sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
109
+ end
110
+ end
111
+
112
+ desc 'Reinstall the gem'
113
+ task :reinstall => [:uninstall, :install]
114
+
115
+ desc 'Cleanup the gem'
116
+ task :cleanup do
117
+ sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
118
+ end
119
+
120
+ file "#{PROJ.name}.gemspec" => PROJ.gem._spec.files do |t|
121
+ open(t.name, 'w') { |f| f.write PROJ.gem._spec.to_ruby }
122
+ end
123
+ CLOBBER.include("#{PROJ.name}.gemspec")
124
+
125
+ desc 'Generate gemspec'
126
+ task :spec => "#{PROJ.name}.gemspec"
127
+ task :release => :spec
128
+
129
+ end # namespace :gem
130
+
131
+ desc 'Alias to gem:package'
132
+ task :gem => 'gem:package'
133
+
134
+ task :clobber => 'gem:clobber_package'
135
+
136
+ remove_desc_for_task %w(gem:clobber_package)
137
+
138
+ # EOF
@@ -0,0 +1,41 @@
1
+ # $Id$
2
+
3
+ if HAVE_GIT
4
+
5
+ namespace :git do
6
+
7
+ # A prerequisites task that all other tasks depend upon
8
+ task :prereqs
9
+
10
+ desc 'Show tags from the Git repository'
11
+ task :show_tags => 'git:prereqs' do |t|
12
+ puts %x/git tag/
13
+ end
14
+
15
+ desc 'Create a new tag in the Git repository'
16
+ task :create_tag => 'git:prereqs' do |t|
17
+ v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
18
+ abort "Versions don't match #{v} vs #{PROJ.version}" if v != PROJ.version
19
+
20
+ tag = "%s-%s" % [PROJ.name, PROJ.version]
21
+ msg = "Creating tag for #{PROJ.name} version #{PROJ.version}"
22
+
23
+ puts "Creating Git tag '#{tag}'"
24
+ unless system "git tag -a -m '#{msg}' #{tag}"
25
+ abort "Tag creation failed"
26
+ end
27
+
28
+ if %x/git remote/ =~ %r/^origin\s*$/
29
+ unless system "git push origin #{tag}"
30
+ abort "Could not push tag to remote Git repository"
31
+ end
32
+ end
33
+ end
34
+
35
+ end # namespace :git
36
+
37
+ task 'gem:release' => 'git:create_tag'
38
+
39
+ end # if HAVE_GIT
40
+
41
+ # EOF
@@ -0,0 +1,49 @@
1
+ # $Id$
2
+
3
+ require 'find'
4
+
5
+ namespace :manifest do
6
+
7
+ desc 'Verify the manifest'
8
+ task :check do
9
+ fn = PROJ.manifest_file + '.tmp'
10
+ files = manifest_files
11
+
12
+ File.open(fn, 'w') {|fp| fp.puts files}
13
+ lines = %x(#{DIFF} -du #{PROJ.manifest_file} #{fn}).split("\n")
14
+ if HAVE_FACETS_ANSICODE and ENV.has_key?('TERM')
15
+ lines.map! do |line|
16
+ case line
17
+ when %r/^(-{3}|\+{3})/; nil
18
+ when %r/^@/; Console::ANSICode.blue line
19
+ when %r/^\+/; Console::ANSICode.green line
20
+ when %r/^\-/; Console::ANSICode.red line
21
+ else line end
22
+ end
23
+ end
24
+ puts lines.compact
25
+ rm fn rescue nil
26
+ end
27
+
28
+ desc 'Create a new manifest'
29
+ task :create do
30
+ files = manifest_files
31
+ unless test(?f, PROJ.manifest_file)
32
+ files << PROJ.manifest_file
33
+ files.sort!
34
+ end
35
+ File.open(PROJ.manifest_file, 'w') {|fp| fp.puts files}
36
+ end
37
+
38
+ task :assert do
39
+ files = manifest_files
40
+ manifest = File.read(PROJ.manifest_file).split($/)
41
+ raise "ERROR: #{PROJ.manifest_file} is out of date" unless files == manifest
42
+ end
43
+
44
+ end # namespace :manifest
45
+
46
+ desc 'Alias to manifest:check'
47
+ task :manifest => 'manifest:check'
48
+
49
+ # EOF
@@ -0,0 +1,28 @@
1
+ # $Id$
2
+
3
+ if HAVE_BONES
4
+
5
+ desc "Enumerate all annotations"
6
+ task :notes do |t|
7
+ id = if t.application.top_level_tasks.length > 1
8
+ t.application.top_level_tasks.slice!(1..-1).join(' ')
9
+ end
10
+ Bones::AnnotationExtractor.enumerate(
11
+ PROJ, PROJ.notes.tags.join('|'), id, :tag => true)
12
+ end
13
+
14
+ namespace :notes do
15
+ PROJ.notes.tags.each do |tag|
16
+ desc "Enumerate all #{tag} annotations"
17
+ task tag.downcase.to_sym do |t|
18
+ id = if t.application.top_level_tasks.length > 1
19
+ t.application.top_level_tasks.slice!(1..-1).join(' ')
20
+ end
21
+ Bones::AnnotationExtractor.enumerate(PROJ, tag, id)
22
+ end
23
+ end
24
+ end
25
+
26
+ end # if HAVE_BONES
27
+
28
+ # EOF
@@ -0,0 +1,39 @@
1
+ # $Id$
2
+
3
+ # This file does not define any rake tasks. It is used to load some project
4
+ # settings if they are not defined by the user.
5
+
6
+ PROJ.rdoc.main ||= PROJ.readme_file
7
+ PROJ.rdoc.dir ||= File.join('doc', PROJ.name)
8
+
9
+ PROJ.rdoc.exclude << "^#{Regexp.escape(PROJ.manifest_file)}$"
10
+ PROJ.exclude << ["^#{Regexp.escape(PROJ.rdoc.dir)}/",
11
+ "^#{Regexp.escape(PROJ.rcov.dir)}/"]
12
+
13
+ flatten_arrays = lambda do |this,os|
14
+ os.instance_variable_get(:@table).each do |key,val|
15
+ next if key == :dependencies
16
+ case val
17
+ when Array; val.flatten!
18
+ when OpenStruct; this.call(this,val)
19
+ end
20
+ end
21
+ end
22
+ flatten_arrays.call(flatten_arrays,PROJ)
23
+
24
+ PROJ.changes ||= paragraphs_of(PROJ.history_file, 0..1).join("\n\n")
25
+
26
+ PROJ.description ||= paragraphs_of(PROJ.readme_file, 'description').join("\n\n")
27
+
28
+ PROJ.summary ||= PROJ.description.split('.').first
29
+
30
+ PROJ.gem.files ||=
31
+ if test(?f, PROJ.manifest_file)
32
+ files = File.readlines(PROJ.manifest_file).map {|fn| fn.chomp.strip}
33
+ files.delete ''
34
+ files
35
+ else [] end
36
+
37
+ PROJ.gem.executables ||= PROJ.gem.files.find_all {|fn| fn =~ %r/^bin/}
38
+
39
+ # EOF
@@ -0,0 +1,55 @@
1
+ # $Id$
2
+
3
+ begin
4
+ require 'hanna/rdoctask'
5
+ rescue LoadError
6
+ require 'rake/rdoctask'
7
+ end
8
+
9
+ namespace :doc do
10
+
11
+ desc 'Generate RDoc documentation'
12
+ Rake::RDocTask.new do |rd|
13
+ rdoc = PROJ.rdoc
14
+ rd.main = rdoc.main
15
+ rd.rdoc_dir = rdoc.dir
16
+
17
+ incl = Regexp.new(rdoc.include.join('|'))
18
+ excl = Regexp.new(rdoc.exclude.join('|'))
19
+ files = PROJ.gem.files.find_all do |fn|
20
+ case fn
21
+ when excl; false
22
+ when incl; true
23
+ else false end
24
+ end
25
+ rd.rdoc_files.push(*files)
26
+
27
+ title = "#{PROJ.name}-#{PROJ.version} Documentation"
28
+
29
+ rf_name = PROJ.rubyforge.name
30
+ title = "#{rf_name}'s " + title if rf_name.valid? and rf_name != title
31
+
32
+ rd.options << "-t #{title}"
33
+ rd.options.concat(rdoc.opts)
34
+ end
35
+
36
+ desc 'Generate ri locally for testing'
37
+ task :ri => :clobber_ri do
38
+ sh "#{RDOC} --ri -o ri ."
39
+ end
40
+
41
+ task :clobber_ri do
42
+ rm_r 'ri' rescue nil
43
+ end
44
+
45
+ end # namespace :doc
46
+
47
+ desc 'Alias to doc:rdoc'
48
+ task :doc => 'doc:rdoc'
49
+
50
+ desc 'Remove all build products'
51
+ task :clobber => %w(doc:clobber_rdoc doc:clobber_ri)
52
+
53
+ remove_desc_for_task %w(doc:clobber_rdoc)
54
+
55
+ # EOF
@@ -0,0 +1,57 @@
1
+
2
+ if PROJ.rubyforge.name.valid? && HAVE_RUBYFORGE
3
+
4
+ require 'rubyforge'
5
+ require 'rake/contrib/sshpublisher'
6
+
7
+ namespace :gem do
8
+ desc 'Package and upload to RubyForge'
9
+ task :release => [:clobber, 'gem:package'] do |t|
10
+ v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
11
+ abort "Versions don't match #{v} vs #{PROJ.version}" if v != PROJ.version
12
+ pkg = "pkg/#{PROJ.gem._spec.full_name}"
13
+
14
+ if $DEBUG then
15
+ puts "release_id = rf.add_release #{PROJ.rubyforge.name.inspect}, #{PROJ.name.inspect}, #{PROJ.version.inspect}, \"#{pkg}.tgz\""
16
+ puts "rf.add_file #{PROJ.rubyforge.name.inspect}, #{PROJ.name.inspect}, release_id, \"#{pkg}.gem\""
17
+ end
18
+
19
+ rf = RubyForge.new
20
+ rf.configure rescue nil
21
+ puts 'Logging in'
22
+ rf.login
23
+
24
+ c = rf.userconfig
25
+ c['release_notes'] = PROJ.description if PROJ.description
26
+ c['release_changes'] = PROJ.changes if PROJ.changes
27
+ c['preformatted'] = true
28
+
29
+ files = [(PROJ.gem.need_tar ? "#{pkg}.tgz" : nil),
30
+ (PROJ.gem.need_zip ? "#{pkg}.zip" : nil),
31
+ "#{pkg}.gem"].compact
32
+
33
+ puts "Releasing #{PROJ.name} v. #{PROJ.version}"
34
+ rf.add_release PROJ.rubyforge.name, PROJ.name, PROJ.version, *files
35
+ end
36
+ end # namespace :gem
37
+
38
+
39
+ namespace :doc do
40
+ desc "Publish RDoc to RubyForge"
41
+ task :release => %w(doc:clobber_rdoc doc:rdoc) do
42
+ config = YAML.load(
43
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
44
+ )
45
+
46
+ host = "#{config['username']}@rubyforge.org"
47
+ remote_dir = "/var/www/gforge-projects/#{PROJ.rubyforge.name}/"
48
+ remote_dir << PROJ.rdoc.remote_dir if PROJ.rdoc.remote_dir
49
+ local_dir = File.dirname(PROJ.rdoc.dir)
50
+
51
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
52
+ end
53
+ end # namespace :doc
54
+
55
+ end # if HAVE_RUBYFORGE
56
+
57
+ # EOF
@@ -0,0 +1,238 @@
1
+ # $Id$
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'rake/clean'
6
+ require 'fileutils'
7
+ require 'ostruct'
8
+
9
+ class OpenStruct; undef :gem; end
10
+
11
+ PROJ = OpenStruct.new(
12
+ # Project Defaults
13
+ :name => nil,
14
+ :summary => nil,
15
+ :description => nil,
16
+ :changes => nil,
17
+ :authors => nil,
18
+ :email => nil,
19
+ :url => "\000",
20
+ :version => ENV['VERSION'] || '0.0.0',
21
+ :exclude => %w(tmp$ bak$ ~$ CVS \.git/ \.hg/ \.svn/ ^pkg/ ^doc/ \.DS_Store
22
+ \.hgignore \.gitignore \.dotest \.swp$ .*\.gemspec$),
23
+ :release_name => ENV['RELEASE'],
24
+
25
+ # System Defaults
26
+ :ruby_opts => %w(-w),
27
+ :libs => [],
28
+ :history_file => 'History.txt',
29
+ :manifest_file => 'Manifest.txt',
30
+ :readme_file => 'README.rdoc',
31
+
32
+ # Gem Packaging
33
+ :gem => OpenStruct.new(
34
+ :dependencies => [],
35
+ :development_dependencies => ['rake', 'bones', 'bacon'],
36
+ :executables => nil,
37
+ :extensions => FileList['ext/**/extconf.rb'],
38
+ :files => nil,
39
+ :need_tar => true,
40
+ :need_zip => false,
41
+ :extras => {}
42
+ ),
43
+
44
+ # File Annotations
45
+ :notes => OpenStruct.new(
46
+ :exclude => %w(^tasks/setup\.rb$),
47
+ :extensions => %w(.txt .rb .erb .rdoc) << '',
48
+ :tags => %w(FIXME OPTIMIZE TODO)
49
+ ),
50
+
51
+ # Rcov
52
+ :rcov => OpenStruct.new(
53
+ :dir => 'coverage',
54
+ :opts => %w[--sort coverage -T],
55
+ :threshold => 90.0,
56
+ :threshold_exact => false
57
+ ),
58
+
59
+ # Rdoc
60
+ :rdoc => OpenStruct.new(
61
+ :opts => [],
62
+ :include => %w(^lib/ ^bin/ ^ext/ \.txt$ \.rdoc$),
63
+ :exclude => %w(extconf\.rb$),
64
+ :main => nil,
65
+ :dir => nil,
66
+ :remote_dir => nil
67
+ ),
68
+
69
+ # Rubyforge
70
+ :rubyforge => OpenStruct.new(
71
+ :name => "\000"
72
+ ),
73
+
74
+ # Tests
75
+ :test => OpenStruct.new(
76
+ :files => FileList['{test,spec}/{{test,spec}_*.rb,*_spec.rb}'],
77
+ :file => '',
78
+ :opts => []
79
+ )
80
+ )
81
+
82
+ # Load the other rake files in the tasks folder
83
+ rakefiles = Dir.glob('tasks/*.rake').sort
84
+ rakefiles.unshift(rakefiles.delete('tasks/post_load.rake')).compact!
85
+ import(*rakefiles)
86
+
87
+ # Setup the project libraries
88
+ %w(lib ext).each {|dir| PROJ.libs << dir if test ?d, dir}
89
+
90
+ # Setup some constants
91
+ WIN32 = %r/djgpp|(cyg|ms|bcc)win|mingw/ =~ RUBY_PLATFORM unless defined? WIN32
92
+
93
+ DEV_NULL = WIN32 ? 'NUL:' : '/dev/null'
94
+
95
+ def quiet( &block )
96
+ io = [STDOUT.dup, STDERR.dup]
97
+ STDOUT.reopen DEV_NULL
98
+ STDERR.reopen DEV_NULL
99
+ block.call
100
+ ensure
101
+ STDOUT.reopen io.first
102
+ STDERR.reopen io.last
103
+ $stdout, $stderr = STDOUT, STDERR
104
+ end
105
+
106
+ DIFF = if WIN32 then 'diff.exe'
107
+ else
108
+ if quiet {system "gdiff", __FILE__, __FILE__} then 'gdiff'
109
+ else 'diff' end
110
+ end unless defined? DIFF
111
+
112
+ SUDO = if WIN32 then ''
113
+ else
114
+ if quiet {system 'which sudo'} then 'sudo'
115
+ else '' end
116
+ end
117
+
118
+ RCOV = WIN32 ? 'rcov.bat' : 'rcov'
119
+ RDOC = WIN32 ? 'rdoc.bat' : 'rdoc'
120
+ GEM = WIN32 ? 'gem.bat' : 'gem'
121
+
122
+ %w(rcov spec/rake/spectask rubyforge bones facets/ansicode).each do |lib|
123
+ begin
124
+ require lib
125
+ Object.instance_eval {const_set "HAVE_#{lib.tr('/','_').upcase}", true}
126
+ rescue LoadError
127
+ Object.instance_eval {const_set "HAVE_#{lib.tr('/','_').upcase}", false}
128
+ end
129
+ end
130
+ HAVE_SVN = (Dir.entries(Dir.pwd).include?('.svn') and
131
+ system("svn --version 2>&1 > #{DEV_NULL}"))
132
+ HAVE_GIT = (Dir.entries(Dir.pwd).include?('.git') and
133
+ system("git --version 2>&1 > #{DEV_NULL}"))
134
+
135
+ # Reads a file at +path+ and spits out an array of the +paragraphs+
136
+ # specified.
137
+ #
138
+ # changes = paragraphs_of('History.txt', 0..1).join("\n\n")
139
+ # summary, *description = paragraphs_of('README.rdoc', 3, 3..8)
140
+ #
141
+ def paragraphs_of( path, *paragraphs )
142
+ title = String === paragraphs.first ? paragraphs.shift : nil
143
+ ary = File.read(path).delete("\r").split(/\n\n+/)
144
+
145
+ result = if title
146
+ tmp, matching = [], false
147
+ rgxp = %r/^=+\s*#{Regexp.escape(title)}/i
148
+ paragraphs << (0..-1) if paragraphs.empty?
149
+
150
+ ary.each do |val|
151
+ if val =~ rgxp
152
+ break if matching
153
+ matching = true
154
+ rgxp = %r/^=+/i
155
+ elsif matching
156
+ tmp << val
157
+ end
158
+ end
159
+ tmp
160
+ else ary end
161
+
162
+ result.values_at(*paragraphs)
163
+ end
164
+
165
+ # Adds the given gem _name_ to the current project's dependency list. An
166
+ # optional gem _version_ can be given. If omitted, the newest gem version
167
+ # will be used.
168
+ #
169
+ def depend_on( name, version = nil )
170
+ spec = Gem.source_index.find_name(name).last
171
+ version = spec.version.to_s if version.nil? and !spec.nil?
172
+
173
+ PROJ.gem.dependencies << case version
174
+ when nil; [name]
175
+ when %r/^\d/; [name, ">= #{version}"]
176
+ else [name, version] end
177
+ end
178
+
179
+ # Adds the given arguments to the include path if they are not already there
180
+ #
181
+ def ensure_in_path( *args )
182
+ args.each do |path|
183
+ path = File.expand_path(path)
184
+ $:.unshift(path) if test(?d, path) and not $:.include?(path)
185
+ end
186
+ end
187
+
188
+ # Find a rake task using the task name and remove any description text. This
189
+ # will prevent the task from being displayed in the list of available tasks.
190
+ #
191
+ def remove_desc_for_task( names )
192
+ Array(names).each do |task_name|
193
+ task = Rake.application.tasks.find {|t| t.name == task_name}
194
+ next if task.nil?
195
+ task.instance_variable_set :@comment, nil
196
+ end
197
+ end
198
+
199
+ # Change working directories to _dir_, call the _block_ of code, and then
200
+ # change back to the original working directory (the current directory when
201
+ # this method was called).
202
+ #
203
+ def in_directory( dir, &block )
204
+ curdir = pwd
205
+ begin
206
+ cd dir
207
+ return block.call
208
+ ensure
209
+ cd curdir
210
+ end
211
+ end
212
+
213
+ # Scans the current working directory and creates a list of files that are
214
+ # candidates to be in the manifest.
215
+ #
216
+ def manifest_files
217
+ files = []
218
+ exclude = Regexp.new(PROJ.exclude.join('|'))
219
+ Find.find '.' do |path|
220
+ path.sub! %r/^(\.\/|\/)/o, ''
221
+ next unless test ?f, path
222
+ next if path =~ exclude
223
+ files << path
224
+ end
225
+ files.sort!
226
+ end
227
+
228
+ # We need a "valid" method thtat determines if a string is suitable for use
229
+ # in the gem specification.
230
+ #
231
+ class Object
232
+ def valid?
233
+ return !(self.empty? or self == "\000") if self.respond_to?(:to_str)
234
+ return false
235
+ end
236
+ end
237
+
238
+ # EOF
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_service_helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Tucker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-22 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: win32-service
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: bones
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: bacon
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ description: Simple declarative configuration for running ruby programs as win32 services using win32/daemon.
56
+ email: raggi@rubyforge.org
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - History.txt
63
+ - README.rdoc
64
+ files:
65
+ - History.txt
66
+ - Manifest.txt
67
+ - README.rdoc
68
+ - Rakefile
69
+ - lib/ruby_service_helper.rb
70
+ - spec/.bacon
71
+ - spec/helper.rb
72
+ - spec/runner
73
+ - spec/spec_ruby_service_helper.rb
74
+ - tasks/autospec.rake
75
+ - tasks/bacon.rake
76
+ - tasks/bones.rake
77
+ - tasks/gem.rake
78
+ - tasks/git.rake
79
+ - tasks/manifest.rake
80
+ - tasks/notes.rake
81
+ - tasks/post_load.rake
82
+ - tasks/rdoc.rake
83
+ - tasks/rubyforge.rake
84
+ - tasks/setup.rb
85
+ has_rdoc: true
86
+ homepage: http://github.com/raggi/ruby_service_helper
87
+ post_install_message:
88
+ rdoc_options:
89
+ - --main
90
+ - README.rdoc
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ requirements: []
106
+
107
+ rubyforge_project: libraggi
108
+ rubygems_version: 1.3.1
109
+ signing_key:
110
+ specification_version: 2
111
+ summary: Simple declarative configuration for running ruby programs as win32 services using win32/daemon
112
+ test_files:
113
+ - spec/spec_ruby_service_helper.rb