ruby_service_helper 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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