aaronp-meow 1.0.0

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