meow 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2008-06-05
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,9 @@
1
+ CHANGELOG.rdoc
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/meow.rb
6
+ meow.gemspec
7
+ test/helper.rb
8
+ test/test_meow.rb
9
+ vendor/hoe.rb
@@ -0,0 +1,50 @@
1
+ = meow
2
+
3
+ * http://meow.rubyforge.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Send Growl notifications via Ruby.
8
+
9
+ == SYNOPSIS:
10
+
11
+ meep = Meow.new('Meow Test')
12
+ meep.notify('Title', 'Description')
13
+
14
+ == REQUIREMENTS:
15
+
16
+ * Growl: http://growl.info
17
+
18
+ == INSTALL:
19
+
20
+ * install Growl: http://growl.info
21
+ * sudo gem install meow
22
+
23
+ == THANKS:
24
+
25
+ Thanks to the Growl team! This code is heavily based on their ruby example.
26
+
27
+ == LICENSE:
28
+
29
+ (The MIT License)
30
+
31
+ Copyright (c) 2008 Aaron Patterson
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining
34
+ a copy of this software and associated documentation files (the
35
+ 'Software'), to deal in the Software without restriction, including
36
+ without limitation the rights to use, copy, modify, merge, publish,
37
+ distribute, sublicense, and/or sell copies of the Software, and to
38
+ permit persons to whom the Software is furnished to do so, subject to
39
+ the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be
42
+ included in all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
45
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
47
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
48
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
49
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
50
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require './vendor/hoe.rb'
5
+ require './lib/meow.rb'
6
+
7
+ Hoe.new('meow', Meow::VERSION) do |p|
8
+ p.readme = 'README.rdoc'
9
+ p.history = 'CHANGELOG.rdoc'
10
+ p.developer('Aaron Patterson', 'aaronp@rubyforge.org')
11
+ end
12
+
13
+ # vim: syntax=Ruby
@@ -0,0 +1,103 @@
1
+ require 'osx/cocoa'
2
+
3
+ class Meow
4
+ VERSION = '1.0.0'
5
+ PRIORITIES = { :very_low => -2,
6
+ :moderate => -1,
7
+ :normal => 0,
8
+ :high => 1,
9
+ :emergency => 2,
10
+ }
11
+
12
+ class << self
13
+ ###
14
+ # Send a message in one call.
15
+ #
16
+ # Example:
17
+ # Meow.notify('Meow', 'Title', 'Description', :priority => :very_high)
18
+ def notify(name, title, description, opts = {})
19
+ new(name).notify(title, description, opts)
20
+ end
21
+ end
22
+
23
+ attr_accessor :name, :note_type, :icon
24
+
25
+ ###
26
+ # Create a new Meow object.
27
+ #
28
+ # * +name+ is the application name.
29
+ # * +note_type+ is the type of note you send.
30
+ # * +icon+ is the icon displayed in the notification.
31
+ #
32
+ # Example:
33
+ # note = Meow.new('My Application')
34
+ def initialize(name, note_type = 'Note', icon = OSX::NSWorkspace.sharedWorkspace().iconForFileType_('rb'))
35
+ @name = name
36
+ @icon = icon
37
+ @note_type = note_type
38
+ @registered = []
39
+ end
40
+
41
+ ###
42
+ # Send a notification to growl.
43
+ #
44
+ # * +title+ will be the title of the message.
45
+ # * +description+ is the description of the message
46
+ # * +opts+ is a hash of options.
47
+ #
48
+ # Possible values for +opts+ are:
49
+ # * :priority => Set the note priority
50
+ # * :icon => Override the current icon
51
+ # * :note_type => Override the current note type
52
+ #
53
+ # See Meow::PRIORITIES for the possible priorities.
54
+ #
55
+ # Example:
56
+ # note.notify('title', 'description', :priority => :very_low)
57
+ def notify(title, description, opts = {})
58
+ opts = {
59
+ :icon => icon,
60
+ :sticky => false,
61
+ :note_type => note_type,
62
+ }.merge(opts)
63
+
64
+ register(opts[:note_type]) unless @registered.include?(opts[:note_type])
65
+
66
+ notification = {
67
+ 'NotificationName' => opts[:note_type],
68
+ 'ApplicationName' => name,
69
+ 'NotificationTitle' => title,
70
+ 'NotificationDescription' => description,
71
+ 'NotificationIcon' => opts[:icon].TIFFRepresentation(),
72
+ }
73
+
74
+ notification['NotificationAppIcon'] = opts[:app_icon].TIFFRepresentation if opts[:app_icon]
75
+ notification['NotificationSticky'] = OSX::NSNumber.numberWithBool_(true) if opts[:stick]
76
+
77
+ if opts[:priority]
78
+ notification['NotificationPriority'] = OSX::NSNumber.numberWithInt_(PRIORITIES[opts[:priority]])
79
+ end
80
+
81
+ d = OSX::NSDictionary.dictionaryWithDictionary_(notification)
82
+ notify_center = OSX::NSDistributedNotificationCenter.defaultCenter
83
+ notify_center.postNotificationName_object_userInfo_deliverImmediately_('GrowlNotification', nil, d, true)
84
+ end
85
+
86
+ private
87
+
88
+ def register(types, default_types = nil)
89
+ types = [types].flatten
90
+ default_types ||= types
91
+
92
+ @registered = [@registered, types, default_types].flatten.uniq
93
+
94
+ dictionary = OSX::NSDictionary.dictionaryWithDictionary({
95
+ 'ApplicationName' => name,
96
+ 'AllNotifications' => OSX::NSArray.arrayWithArray(types),
97
+ 'DefaultNotifications' => OSX::NSArray.arrayWithArray(default_types),
98
+ 'ApplicationIcon' => icon.TIFFRepresentation
99
+ })
100
+ notify_center = OSX::NSDistributedNotificationCenter.defaultCenter
101
+ notify_center.postNotificationName_object_userInfo_deliverImmediately_('GrowlApplicationRegistrationNotification', nil, dictionary, true)
102
+ end
103
+ end
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{meow}
3
+ s.version = "1.0.0"
4
+
5
+ s.specification_version = 2 if s.respond_to? :specification_version=
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Aaron Patterson"]
9
+ s.date = %q{2008-06-05}
10
+ s.description = %q{Send Growl notifications via Ruby.}
11
+ s.email = ["aaronp@rubyforge.org"]
12
+ s.extra_rdoc_files = ["Manifest.txt"]
13
+ s.files = ["CHANGELOG.rdoc", "Manifest.txt", "README.rdoc", "Rakefile", "lib/meow.rb", "meow.gemspec", "test/helper.rb", "test/test_meow.rb", "vendor/hoe.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://meow.rubyforge.org/}
16
+ s.rdoc_options = ["--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{meow}
19
+ s.rubygems_version = %q{1.1.1}
20
+ s.summary = %q{Send Growl notifications via Ruby.}
21
+ s.test_files = ["test/test_meow.rb"]
22
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'meow'
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
2
+
3
+ class MeowTest < Test::Unit::TestCase
4
+ def test_initialize
5
+ meep = nil
6
+ assert_nothing_raised {
7
+ meep = Meow.new('Meow Test')
8
+ }
9
+ assert_not_nil(meep)
10
+ end
11
+
12
+ def test_meow_has_static_method
13
+ assert_nothing_raised {
14
+ Meow.notify('Meow Test', 'Title', 'Description', :priority => :very_high)
15
+ }
16
+ end
17
+
18
+ def test_meow_can_notify_with_type
19
+ meep = Meow.new('Meow Test')
20
+ assert_nothing_raised {
21
+ meep.notify('Title', 'Description', :type => 'Awesome')
22
+ }
23
+ end
24
+
25
+ def test_meow_can_notify_with_priority
26
+ meep = Meow.new('Meow Test')
27
+ assert_nothing_raised {
28
+ meep.notify('Title', 'Description', :priority => :very_high)
29
+ }
30
+ end
31
+
32
+ def test_meow_can_notify_without_register
33
+ meep = Meow.new('Meow Test')
34
+ assert_nothing_raised {
35
+ meep.notify('Title', 'Description')
36
+ }
37
+ end
38
+ end
@@ -0,0 +1,848 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'rake/gempackagetask'
6
+ require 'rake/rdoctask'
7
+ require 'rake/testtask'
8
+ require 'rbconfig'
9
+ require 'rubyforge'
10
+ require 'yaml'
11
+
12
+ ##
13
+ # hoe - a tool to help rake
14
+ #
15
+ # Hoe is a simple rake/rubygems helper for project Rakefiles. It
16
+ # generates all the usual tasks for projects including rdoc generation,
17
+ # testing, packaging, and deployment.
18
+ #
19
+ # == Using Hoe
20
+ #
21
+ # === Basics
22
+ #
23
+ # Use this as a minimal starting point:
24
+ #
25
+ # require 'hoe'
26
+ #
27
+ # Hoe.new("project_name", '1.0.0') do |p|
28
+ # p.rubyforge_name = "rf_project"
29
+ # # add other details here
30
+ # end
31
+ #
32
+ # # add other tasks here
33
+ #
34
+ # === Tasks Provided:
35
+ #
36
+ # announce:: Create news email file and post to rubyforge.
37
+ # audit:: Run ZenTest against the package.
38
+ # check_manifest:: Verify the manifest.
39
+ # clean:: Clean up all the extras.
40
+ # config_hoe:: Create a fresh ~/.hoerc file.
41
+ # debug_gem:: Show information about the gem.
42
+ # default:: Run the default tasks.
43
+ # docs:: Build the docs HTML Files
44
+ # email:: Generate email announcement file.
45
+ # gem:: Build the gem file hoe-1.5.0.gem
46
+ # generate_key:: Generate a key for signing your gems.
47
+ # install_gem:: Install the package as a gem.
48
+ # multi:: Run the test suite using multiruby.
49
+ # package:: Build all the packages
50
+ # post_blog:: Post announcement to blog.
51
+ # post_news:: Post announcement to rubyforge.
52
+ # publish_docs:: Publish RDoc to RubyForge.
53
+ # release:: Package and upload the release to rubyforge.
54
+ # ridocs:: Generate ri locally for testing.
55
+ # test:: Run the test suite.
56
+ # test_deps:: Show which test files fail when run alone.
57
+ #
58
+ # === Extra Configuration Options:
59
+ #
60
+ # Run +config_hoe+ to generate a new ~/.hoerc file. The file is a
61
+ # YAML formatted config file with the following settings:
62
+ #
63
+ # exclude:: A regular expression of files to exclude from
64
+ # +check_manifest+.
65
+ # publish_on_announce:: Run +publish_docs+ when you run +release+.
66
+ # signing_key_file:: Signs your gems with this private key.
67
+ # signing_cert_file:: Signs your gem with this certificate.
68
+ # blogs:: An array of hashes of blog settings.
69
+ #
70
+ # Run +config_hoe+ and see ~/.hoerc for examples.
71
+ #
72
+ # === Signing Gems:
73
+ #
74
+ # Run the 'generate_key' task. This will:
75
+ #
76
+ # 1. Configure your ~/.hoerc.
77
+ # 2. Generate a signing key and certificate.
78
+ # 3. Install the private key and public certificate files into ~/.gem.
79
+ # 4. Upload the certificate to RubyForge.
80
+ #
81
+ # Hoe will now generate signed gems when the package task is run. If you have
82
+ # multiple machines you build gems on, be sure to install your key and
83
+ # certificate on each machine.
84
+ #
85
+ # Keep your private key secret! Keep your private key safe!
86
+ #
87
+ # To make sure your gems are signed run:
88
+ #
89
+ # rake package; tar tf pkg/yourproject-1.2.3.gem
90
+ #
91
+ # If your gem is signed you will see:
92
+ #
93
+ # data.tar.gz
94
+ # data.tar.gz.sig
95
+ # metadata.gz
96
+ # metadata.gz.sig
97
+ #
98
+ # === Platform awareness
99
+ #
100
+ # Hoe allows bundling of pre-compiled extensions in the +package+ task.
101
+ #
102
+ # To create a package for your current platform:
103
+ #
104
+ # rake package INLINE=1
105
+ #
106
+ # This will force Hoe analize your +Inline+ already compiled
107
+ # extensions and include them in your gem.
108
+ #
109
+ # If somehow you need to force a specific platform:
110
+ #
111
+ # rake package INLINE=1 FORCE_PLATFORM=mswin32
112
+ #
113
+ # This will set the +Gem::Specification+ platform to the one indicated in
114
+ # +FORCE_PLATFORM+ (instead of default Gem::Platform::CURRENT)
115
+ #
116
+
117
+ class Hoe
118
+ VERSION = '1.5.3'
119
+
120
+ ruby_prefix = Config::CONFIG['prefix']
121
+ sitelibdir = Config::CONFIG['sitelibdir']
122
+
123
+ ##
124
+ # Used to specify a custom install location (for rake install).
125
+
126
+ PREFIX = ENV['PREFIX'] || ruby_prefix
127
+
128
+ ##
129
+ # Used to add extra flags to RUBY_FLAGS.
130
+
131
+ RUBY_DEBUG = ENV['RUBY_DEBUG']
132
+
133
+ default_ruby_flags = "-w -I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}" +
134
+ (RUBY_DEBUG ? " #{RUBY_DEBUG}" : '')
135
+
136
+ ##
137
+ # Used to specify flags to ruby [has smart default].
138
+
139
+ RUBY_FLAGS = ENV['RUBY_FLAGS'] || default_ruby_flags
140
+
141
+ ##
142
+ # Used to add flags to test_unit (e.g., -n test_borked).
143
+
144
+ FILTER = ENV['FILTER'] # for tests (eg FILTER="-n test_blah")
145
+
146
+ # :stopdoc:
147
+
148
+ RUBYLIB = if PREFIX == ruby_prefix then
149
+ sitelibdir
150
+ else
151
+ File.join(PREFIX, sitelibdir[ruby_prefix.size..-1])
152
+ end
153
+
154
+ DLEXT = Config::CONFIG['DLEXT']
155
+
156
+ WINDOZE = /djgpp|(cyg|ms|bcc)win|mingw/ =~ RUBY_PLATFORM unless defined? WINDOZE
157
+
158
+ DIFF = if WINDOZE
159
+ 'diff.exe'
160
+ else
161
+ if system("gdiff", __FILE__, __FILE__)
162
+ 'gdiff' # solaris and kin suck
163
+ else
164
+ 'diff'
165
+ end
166
+ end unless defined? DIFF
167
+
168
+ # :startdoc:
169
+
170
+ ##
171
+ # *Recommended*: The author(s) of the package. (can be array)
172
+ # Really. Set this or we'll tease you.
173
+
174
+ attr_accessor :author
175
+
176
+ ##
177
+ # Populated automatically from the manifest. List of executables.
178
+
179
+ attr_accessor :bin_files # :nodoc:
180
+
181
+ ##
182
+ # Optional: A description of the release's latest changes. Auto-populates.
183
+
184
+ attr_accessor :changes
185
+
186
+ ##
187
+ # Optional: An array of file patterns to delete on clean.
188
+
189
+ attr_accessor :clean_globs
190
+
191
+ ##
192
+ # Optional: A description of the project. Auto-populates.
193
+
194
+ attr_accessor :description
195
+
196
+ ##
197
+ # Optional: What sections from the readme to use for auto-description. Defaults to %w(description).
198
+
199
+ attr_accessor :description_sections
200
+
201
+ ##
202
+ # *Recommended*: The author's email address(es). (can be array)
203
+
204
+ attr_accessor :email
205
+
206
+ ##
207
+ # Optional: An array of rubygem dependencies.
208
+
209
+ attr_accessor :extra_deps
210
+
211
+ ##
212
+ # Populated automatically from the manifest. List of library files.
213
+
214
+ attr_accessor :lib_files # :nodoc:
215
+
216
+ ##
217
+ # Optional: Array of incompatible versions for multiruby filtering. Used as a regex.
218
+
219
+ attr_accessor :multiruby_skip
220
+
221
+ ##
222
+ # *MANDATORY*: The name of the release.
223
+
224
+ attr_accessor :name
225
+
226
+ ##
227
+ # Optional: Should package create a tarball? [default: true]
228
+
229
+ attr_accessor :need_tar
230
+
231
+ ##
232
+ # Optional: Should package create a zipfile? [default: false]
233
+
234
+ attr_accessor :need_zip
235
+
236
+ ##
237
+ # Optional: A post-install message to be displayed when gem is installed.
238
+
239
+ attr_accessor :post_install_message
240
+
241
+ ##
242
+ # Optional: A regexp to match documentation files against the manifest.
243
+
244
+ attr_accessor :rdoc_pattern
245
+
246
+ ##
247
+ # Optional: Name of RDoc destination directory on Rubyforge. [default: +name+]
248
+
249
+ attr_accessor :remote_rdoc_dir
250
+
251
+ ##
252
+ # Optional: Flags for RDoc rsync. [default: "-av --delete"]
253
+
254
+ attr_accessor :rsync_args
255
+
256
+ ##
257
+ # Optional: The name of the rubyforge project. [default: name.downcase]
258
+
259
+ attr_accessor :rubyforge_name
260
+
261
+ ##
262
+ # The Gem::Specification.
263
+
264
+ attr_accessor :spec # :nodoc:
265
+
266
+ ##
267
+ # Optional: A hash of extra values to set in the gemspec. Value may be a proc.
268
+
269
+ attr_accessor :spec_extras
270
+
271
+ ##
272
+ # Optional: A short summary of the project. Auto-populates.
273
+
274
+ attr_accessor :summary
275
+
276
+ ##
277
+ # Optional: Number of sentences from description for summary. Defaults to 1.
278
+
279
+ attr_accessor :summary_sentences
280
+
281
+ ##
282
+ # Populated automatically from the manifest. List of tests.
283
+
284
+ attr_accessor :test_files # :nodoc:
285
+
286
+ ##
287
+ # Optional: An array of test file patterns [default: test/**/test_*.rb]
288
+
289
+ attr_accessor :test_globs
290
+
291
+ ##
292
+ # Optional: The url(s) of the project. (can be array). Auto-populates.
293
+
294
+ attr_accessor :url
295
+
296
+ ##
297
+ # *MANDATORY*: The version. Don't hardcode! use a constant in the project.
298
+
299
+ attr_accessor :version
300
+
301
+ ##
302
+ # Optional: The README filename
303
+
304
+ attr_accessor :readme
305
+
306
+ ##
307
+ # Optional: The History filename
308
+
309
+ attr_accessor :history
310
+
311
+ def initialize(name, version) # :nodoc:
312
+ self.name = name
313
+ self.version = version
314
+
315
+ # Defaults
316
+ self.author = []
317
+ self.clean_globs = %w(diff diff.txt email.txt ri
318
+ *.gem *~ **/*~ *.rbc **/*.rbc)
319
+ self.description_sections = %w(description)
320
+ self.email = []
321
+ self.extra_deps = []
322
+ self.multiruby_skip = []
323
+ self.need_tar = true
324
+ self.need_zip = false
325
+ self.rdoc_pattern = /^(lib|bin|ext)|(txt|rdoc)$/
326
+ self.remote_rdoc_dir = name
327
+ self.rsync_args = '-av --delete'
328
+ self.rubyforge_name = name.downcase
329
+ self.spec_extras = {}
330
+ self.summary_sentences = 1
331
+ self.test_globs = ['test/**/test_*.rb']
332
+ self.readme = 'README.txt'
333
+ self.history = 'History.txt'
334
+ self.post_install_message = nil
335
+
336
+ yield self if block_given?
337
+
338
+ # Intuit values:
339
+
340
+ def missing name
341
+ warn "** #{name} is missing or in the wrong format for auto-intuiting."
342
+ warn " run `sow blah` and look at its text files"
343
+ end
344
+
345
+ readme = File.read(self.readme).split(/^(=+ .*)$/)[1..-1] rescue ''
346
+ unless readme.empty? then
347
+ sections = readme.map { |s|
348
+ s =~ /^=/ ? s.strip.downcase.chomp(':').split.last : s.strip
349
+ }
350
+ sections = Hash[*sections]
351
+ desc = sections.values_at(*description_sections).join("\n\n")
352
+ summ = desc.split(/\.\s+/).first(summary_sentences).join(". ")
353
+
354
+ self.description ||= desc
355
+ self.summary ||= summ
356
+ self.url ||= readme[1].gsub(/^\* /, '').split(/\n/).grep(/\S+/)
357
+ else
358
+ missing 'README.txt'
359
+ end
360
+
361
+ self.changes ||= begin
362
+ h = File.read(self.history)
363
+ h.split(/^(===.*)/)[1..2].join.strip
364
+ rescue
365
+ missing 'History.txt'
366
+ ''
367
+ end
368
+
369
+ %w(email author).each do |field|
370
+ value = self.send(field)
371
+ if value.nil? or value.empty? then
372
+ if Time.now < Time.local(2008, 4, 1) then
373
+ warn "Hoe #{field} value not set - Fix by 2008-04-01!"
374
+ self.send "#{field}=", "doofus"
375
+ else
376
+ abort "Hoe #{field} value not set. aborting"
377
+ end
378
+ end
379
+ end
380
+
381
+ hoe_deps = {
382
+ 'rake' => ">= #{RAKEVERSION}",
383
+ 'rubyforge' => ">= #{::RubyForge::VERSION}",
384
+ }
385
+
386
+ self.extra_deps = Array(extra_deps).map { |o| String === o ? [o] : o }
387
+
388
+ if name == 'hoe' then
389
+ hoe_deps.each do |pkg, vers|
390
+ extra_deps << [pkg, vers]
391
+ end
392
+ end
393
+
394
+ define_tasks
395
+ end
396
+
397
+ def developer name, email
398
+ self.author << name
399
+ self.email << email
400
+ end
401
+
402
+ def define_tasks # :nodoc:
403
+ def with_config # :nodoc:
404
+ rc = File.expand_path("~/.hoerc")
405
+ exists = File.exist? rc
406
+ config = exists ? YAML.load_file(rc) : {}
407
+ yield(config, rc)
408
+ end
409
+
410
+ desc 'Run the default tasks.'
411
+ task :default => :test
412
+
413
+ desc 'Run the test suite. Use FILTER to add to the command line.'
414
+ task :test do
415
+ run_tests
416
+ end
417
+
418
+ desc 'Show which test files fail when run alone.'
419
+ task :test_deps do
420
+ tests = Dir["test/**/test_*.rb"] + Dir["test/**/*_test.rb"]
421
+
422
+ tests.each do |test|
423
+ if not system "ruby -Ibin:lib:test #{test} &> /dev/null" then
424
+ puts "Dependency Issues: #{test}"
425
+ end
426
+ end
427
+ end
428
+
429
+ desc 'Run the test suite using multiruby.'
430
+ task :multi do
431
+ run_tests :multi
432
+ end
433
+
434
+ ############################################################
435
+ # Packaging and Installing
436
+
437
+ signing_key = nil
438
+ cert_chain = []
439
+
440
+ with_config do |config, path|
441
+ break unless config['signing_key_file'] and config['signing_cert_file']
442
+ key_file = File.expand_path config['signing_key_file'].to_s
443
+ signing_key = key_file if File.exist? key_file
444
+
445
+ cert_file = File.expand_path config['signing_cert_file'].to_s
446
+ cert_chain << cert_file if File.exist? cert_file
447
+ end
448
+
449
+ self.spec = Gem::Specification.new do |s|
450
+ s.name = name
451
+ s.version = version
452
+ s.summary = summary
453
+ case author
454
+ when Array
455
+ s.authors = author
456
+ else
457
+ s.author = author
458
+ end
459
+ s.email = email
460
+ s.homepage = Array(url).first
461
+ s.rubyforge_project = rubyforge_name
462
+
463
+ s.description = description
464
+
465
+ extra_deps.each do |dep|
466
+ s.add_dependency(*dep)
467
+ end
468
+
469
+ s.files = File.read("Manifest.txt").delete("\r").split(/\n/)
470
+ s.executables = s.files.grep(/^bin/) { |f| File.basename(f) }
471
+
472
+ s.bindir = "bin"
473
+ dirs = Dir['{lib,ext}']
474
+ s.require_paths = dirs unless dirs.empty?
475
+
476
+ s.rdoc_options = ['--main', self.readme]
477
+ s.extra_rdoc_files = s.files.grep(/txt$/)
478
+ s.has_rdoc = true
479
+
480
+ s.post_install_message = post_install_message
481
+
482
+ if test ?f, "test/test_all.rb" then
483
+ s.test_file = "test/test_all.rb"
484
+ else
485
+ s.test_files = Dir[*test_globs]
486
+ end
487
+
488
+ if signing_key and cert_chain then
489
+ s.signing_key = signing_key
490
+ s.cert_chain = cert_chain
491
+ end
492
+
493
+ ############################################################
494
+ # Allow automatic inclusion of compiled extensions
495
+ if ENV['INLINE'] then
496
+ s.platform = ENV['FORCE_PLATFORM'] || Gem::Platform::CURRENT
497
+ # name of the extension is CamelCase
498
+ alternate_name = if name =~ /[A-Z]/ then
499
+ name.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, '')
500
+ elsif name =~ /_/ then
501
+ name.capitalize.gsub(/_([a-z])/) { $1.upcase }
502
+ end
503
+
504
+ # Try collecting Inline extensions for +name+
505
+ if defined?(Inline) then
506
+ directory 'lib/inline'
507
+
508
+ extensions = Dir.chdir(Inline::directory) {
509
+ Dir["Inline_{#{name},#{alternate_name}}_*.#{DLEXT}"]
510
+ }
511
+ extensions.each do |ext|
512
+ # add the inlined extension to the spec files
513
+ s.files += ["lib/inline/#{ext}"]
514
+
515
+ # include the file in the tasks
516
+ file "lib/inline/#{ext}" => ["lib/inline"] do
517
+ cp File.join(Inline::directory, ext), "lib/inline"
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ # Do any extra stuff the user wants
524
+ spec_extras.each do |msg, val|
525
+ case val
526
+ when Proc
527
+ val.call(s.send(msg))
528
+ else
529
+ s.send "#{msg}=", val
530
+ end
531
+ end
532
+ end
533
+
534
+ desc 'Show information about the gem.'
535
+ task :debug_gem do
536
+ puts spec.to_ruby
537
+ end
538
+
539
+ self.lib_files = spec.files.grep(/^(lib|ext)/)
540
+ self.bin_files = spec.files.grep(/^bin/)
541
+ self.test_files = spec.files.grep(/^test/)
542
+
543
+ Rake::GemPackageTask.new spec do |pkg|
544
+ pkg.need_tar = @need_tar
545
+ pkg.need_zip = @need_zip
546
+ end
547
+
548
+ desc 'Install the package as a gem.'
549
+ task :install_gem => [:clean, :package] do
550
+ sh "#{'sudo ' unless WINDOZE}gem install --local pkg/*.gem"
551
+ end
552
+
553
+ desc 'Package and upload the release to rubyforge.'
554
+ task :release => [:clean, :package] do |t|
555
+ v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
556
+ abort "Versions don't match #{v} vs #{version}" if v != version
557
+ pkg = "pkg/#{name}-#{version}"
558
+
559
+ if $DEBUG then
560
+ puts "release_id = rf.add_release #{rubyforge_name.inspect}, #{name.inspect}, #{version.inspect}, \"#{pkg}.tgz\""
561
+ puts "rf.add_file #{rubyforge_name.inspect}, #{name.inspect}, release_id, \"#{pkg}.gem\""
562
+ end
563
+
564
+ rf = RubyForge.new.configure
565
+ puts "Logging in"
566
+ rf.login
567
+
568
+ c = rf.userconfig
569
+ c["release_notes"] = description if description
570
+ c["release_changes"] = changes if changes
571
+ c["preformatted"] = true
572
+
573
+ files = [(@need_tar ? "#{pkg}.tgz" : nil),
574
+ (@need_zip ? "#{pkg}.zip" : nil),
575
+ "#{pkg}.gem"].compact
576
+
577
+ puts "Releasing #{name} v. #{version}"
578
+ rf.add_release rubyforge_name, name, version, *files
579
+ end
580
+
581
+ ############################################################
582
+ # Doco
583
+
584
+ Rake::RDocTask.new(:docs) do |rd|
585
+ rd.main = self.readme
586
+ rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/ and not ENV['NODOT']
587
+ rd.rdoc_dir = 'doc'
588
+ files = spec.files.grep(rdoc_pattern)
589
+ files -= ['Manifest.txt']
590
+ rd.rdoc_files.push(*files)
591
+
592
+ title = "#{name}-#{version} Documentation"
593
+ title = "#{rubyforge_name}'s " + title if rubyforge_name != name
594
+
595
+ rd.options << "-t #{title}"
596
+ end
597
+
598
+ desc 'Generate ri locally for testing.'
599
+ task :ridocs => :clean do
600
+ sh %q{ rdoc --ri -o ri . }
601
+ end
602
+
603
+ desc 'Publish RDoc to RubyForge.'
604
+ task :publish_docs => [:clean, :docs] do
605
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
606
+ host = "#{config["username"]}@rubyforge.org"
607
+
608
+ remote_dir = "/var/www/gforge-projects/#{rubyforge_name}/#{remote_rdoc_dir}"
609
+ local_dir = 'doc'
610
+
611
+ sh %{rsync #{rsync_args} #{local_dir}/ #{host}:#{remote_dir}}
612
+ end
613
+
614
+ # no doco for this one
615
+ task :publish_on_announce do
616
+ with_config do |config, _|
617
+ Rake::Task['publish_docs'].invoke if config["publish_on_announce"]
618
+ end
619
+ end
620
+
621
+ ############################################################
622
+ # Misc/Maintenance:
623
+
624
+ desc 'Run ZenTest against the package.'
625
+ task :audit do
626
+ libs = %w(lib test ext).join(File::PATH_SEPARATOR)
627
+ sh "zentest -I=#{libs} #{spec.files.grep(/^(lib|test)/).join(' ')}"
628
+ end
629
+
630
+ desc 'Clean up all the extras.'
631
+ task :clean => [ :clobber_docs, :clobber_package ] do
632
+ clean_globs.each do |pattern|
633
+ files = Dir[pattern]
634
+ rm_rf files, :verbose => true unless files.empty?
635
+ end
636
+ end
637
+
638
+ desc 'Create a fresh ~/.hoerc file.'
639
+ task :config_hoe do
640
+ with_config do |config, path|
641
+ default_config = {
642
+ "exclude" => /tmp$|CVS|\.svn/,
643
+ "publish_on_announce" => false,
644
+ "signing_key_file" => "~/.gem/gem-private_key.pem",
645
+ "signing_cert_file" => "~/.gem/gem-public_cert.pem",
646
+ "blogs" => [ {
647
+ "user" => "user",
648
+ "url" => "url",
649
+ "extra_headers" => {
650
+ "mt_convert_breaks" => "markdown"
651
+ },
652
+ "blog_id" => "blog_id",
653
+ "password"=>"password",
654
+ } ],
655
+ }
656
+ File.open(path, "w") do |f|
657
+ YAML.dump(default_config.merge(config), f)
658
+ end
659
+
660
+ editor = ENV['EDITOR'] || 'vi'
661
+ system "#{editor} #{path}" if ENV['SHOW_EDITOR'] != 'no'
662
+ end
663
+ end
664
+
665
+ desc 'Generate email announcement file.'
666
+ task :email do
667
+ require 'rubyforge'
668
+ subject, title, body, urls = announcement
669
+
670
+ File.open("email.txt", "w") do |mail|
671
+ mail.puts "Subject: [ANN] #{subject}"
672
+ mail.puts
673
+ mail.puts title
674
+ mail.puts
675
+ mail.puts urls
676
+ mail.puts
677
+ mail.puts body
678
+ mail.puts
679
+ mail.puts urls
680
+ end
681
+ puts "Created email.txt"
682
+ end
683
+
684
+ desc 'Post announcement to blog.'
685
+ task :post_blog do
686
+ require 'xmlrpc/client'
687
+
688
+ with_config do |config, path|
689
+ break unless config['blogs']
690
+
691
+ subject, title, body, urls = announcement
692
+ body += "\n\n#{urls}"
693
+
694
+ config['blogs'].each do |site|
695
+ server = XMLRPC::Client.new2(site['url'])
696
+ content = site['extra_headers'].merge(:title => title,
697
+ :description => body)
698
+ result = server.call('metaWeblog.newPost',
699
+ site['blog_id'],
700
+ site['user'],
701
+ site['password'],
702
+ content,
703
+ true)
704
+ end
705
+ end
706
+ end
707
+
708
+ desc 'Post announcement to rubyforge.'
709
+ task :post_news do
710
+ require 'rubyforge'
711
+ subject, title, body, urls = announcement
712
+
713
+ rf = RubyForge.new.configure
714
+ rf.login
715
+ rf.post_news(rubyforge_name, subject, "#{title}\n\n#{body}")
716
+ puts "Posted to rubyforge"
717
+ end
718
+
719
+ desc 'Create news email file and post to rubyforge.'
720
+ task :announce => [:email, :post_news, :post_blog, :publish_on_announce ]
721
+
722
+ desc 'Verify the manifest.'
723
+ task :check_manifest => :clean do
724
+ f = "Manifest.tmp"
725
+ require 'find'
726
+ files = []
727
+ with_config do |config, _|
728
+ exclusions = config["exclude"]
729
+ abort "exclude entry missing from .hoerc. Aborting." if exclusions.nil?
730
+ Find.find '.' do |path|
731
+ next unless File.file? path
732
+ next if path =~ exclusions
733
+ files << path[2..-1]
734
+ end
735
+ files = files.sort.join "\n"
736
+ File.open f, 'w' do |fp| fp.puts files end
737
+ system "#{DIFF} -du Manifest.txt #{f}"
738
+ rm f
739
+ end
740
+ end
741
+
742
+ desc 'Generate a key for signing your gems.'
743
+ task :generate_key do
744
+ email = spec.email
745
+ abort "No email in your gemspec" if email.nil? or email.empty?
746
+
747
+ key_file = with_config { |config, _| config['signing_key_file'] }
748
+ cert_file = with_config { |config, _| config['signing_cert_file'] }
749
+
750
+ if key_file.nil? or cert_file.nil? then
751
+ ENV['SHOW_EDITOR'] ||= 'no'
752
+ Rake::Task['config_hoe'].invoke
753
+
754
+ key_file = with_config { |config, _| config['signing_key_file'] }
755
+ cert_file = with_config { |config, _| config['signing_cert_file'] }
756
+ end
757
+
758
+ key_file = File.expand_path key_file
759
+ cert_file = File.expand_path cert_file
760
+
761
+ unless File.exist? key_file or File.exist? cert_file then
762
+ sh "gem cert --build #{email}"
763
+ mv "gem-private_key.pem", key_file, :verbose => true
764
+ mv "gem-public_cert.pem", cert_file, :verbose => true
765
+
766
+ puts "Installed key and certificate."
767
+
768
+ rf = RubyForge.new.configure
769
+ rf.login
770
+
771
+ cert_package = "#{rubyforge_name}-certificates"
772
+
773
+ begin
774
+ rf.lookup 'package', cert_package
775
+ rescue
776
+ rf.create_package rubyforge_name, cert_package
777
+ end
778
+
779
+ begin
780
+ rf.lookup('release', cert_package)['certificates']
781
+ rf.add_file rubyforge_name, cert_package, 'certificates', cert_file
782
+ rescue
783
+ rf.add_release rubyforge_name, cert_package, 'certificates', cert_file
784
+ end
785
+
786
+ puts "Uploaded certificate to release \"certificates\" in package #{cert_package}"
787
+ else
788
+ puts "Keys already exist."
789
+ end
790
+ end
791
+
792
+ end # end define
793
+
794
+ def announcement # :nodoc:
795
+ changes = self.changes.rdoc_to_markdown
796
+
797
+ subject = "#{name} #{version} Released"
798
+ title = "#{name} version #{version} has been released!"
799
+ body = "#{description}\n\nChanges:\n\n#{changes}".rdoc_to_markdown
800
+ urls = Array(url).map { |s| "* <#{s.strip.rdoc_to_markdown}>" }.join("\n")
801
+
802
+ return subject, title, body, urls
803
+ end
804
+
805
+ def run_tests(multi=false) # :nodoc:
806
+ msg = multi ? :sh : :ruby
807
+ cmd = if test ?f, 'test/test_all.rb' then
808
+ "#{RUBY_FLAGS} test/test_all.rb #{FILTER}"
809
+ else
810
+ tests = ['test/unit'] + test_globs.map { |g| Dir.glob(g) }.flatten
811
+ tests.map! {|f| %Q(require "#{f}")}
812
+ "#{RUBY_FLAGS} -e '#{tests.join("; ")}' #{FILTER}"
813
+ end
814
+
815
+ excludes = multiruby_skip.join(":")
816
+ ENV['EXCLUDED_VERSIONS'] = excludes
817
+ cmd = "multiruby #{cmd}" if multi
818
+
819
+ send msg, cmd
820
+ end
821
+
822
+ ##
823
+ # Reads a file at +path+ and spits out an array of the +paragraphs+ specified.
824
+ #
825
+ # changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
826
+ # summary, *description = p.paragraphs_of('README.txt', 3, 3..8)
827
+
828
+ def paragraphs_of(path, *paragraphs)
829
+ File.read(path).delete("\r").split(/\n\n+/).values_at(*paragraphs)
830
+ end
831
+ end
832
+
833
+ # :enddoc:
834
+
835
+ class ::Rake::SshDirPublisher # :nodoc:
836
+ attr_reader :host, :remote_dir, :local_dir
837
+ end
838
+
839
+ class String
840
+ def rdoc_to_markdown
841
+ self.gsub(/^mailto:/, '').gsub(/^(=+)/) { "#" * $1.size }
842
+ end
843
+ end
844
+
845
+ if $0 == __FILE__ then
846
+ out = `rake -T | egrep -v "redocs|repackage|clobber|trunk"`
847
+ puts out.gsub(/\#/, '-').gsub(/^rake /, '# * ')
848
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meow
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Patterson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-06 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Send Growl notifications via Ruby.
17
+ email:
18
+ - aaronp@rubyforge.org
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - Manifest.txt
25
+ files:
26
+ - CHANGELOG.rdoc
27
+ - Manifest.txt
28
+ - README.rdoc
29
+ - Rakefile
30
+ - lib/meow.rb
31
+ - meow.gemspec
32
+ - test/helper.rb
33
+ - test/test_meow.rb
34
+ - vendor/hoe.rb
35
+ has_rdoc: true
36
+ homepage: http://meow.rubyforge.org/
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --main
40
+ - README.rdoc
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project: meow
58
+ rubygems_version: 1.1.1
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Send Growl notifications via Ruby.
62
+ test_files:
63
+ - test/test_meow.rb