Class: Gem_packer

Inherits:
Object
  • Object
show all
Defined in:
lib/knut_tools/rake/gempackager.rb

Overview

Class to define an “extended” gemspec.

Defines all tasks to admin the gem (build, install, push to gemcutter…) Details see #build_tasks.

Defined Under Namespace

Classes: BlockError, FTP_DATA, VersionError

Constant Summary collapse

Template =

Template for a new gem.

<<-TEMPLATE
  require 'knut_tools/rake/#{File.basename(__FILE__)}'
  require 'knut_tools/rake/testtask.rb'

  Gem_packer.new('my_gem', '0.1.0', {
        :verbose => nil,
        :versions => [],
        :public => false,
      }){|gemdef, spec|
    #http://docs.rubygems.org/read/chapter/20
    spec.author = "Knut Lickert"
    spec.email = "[email protected]"
    spec.homepage = "http://www.rubypla.net/"
    #~ spec.rubyforge_project = ''
    spec.platform = Gem::Platform::RUBY
    spec.summary = ""
    spec.description = spec.summary
    #~ spec.require_path = "lib"
    spec.files = %w{
    }
    spec.test_files  = %w{
    }
    #~ spec.test_files   << Dir['unittest/expected/*']
    spec.test_files.flatten!

    spec.has_rdoc	= true  
    #~ spec.rdoc_options << '--main' << 'lib/???'
    
    #~ spec.add_dependency()
    #~ spec.add_development_dependency('more_unit_test', '> 0.0.2')  #assert_equal_filecontent
    #~ spec.requirements << 'A (La)TeX-system'
    
    #~ gemdef.versions << ??
    #Define the tests (parameter: directory, test files)
    #~ gemdef.define_test( 'unittest', FileList['test*.rb'])

    #~ gemdef.public = true
    #~ gemdef.add_ftp_connection(host, account, passwort, directory)
    
  }

  require 'creole/creole2doc'  #needed for readme.html, readme.txt
  #Build the html-readme from creole-source
  rule '.html' => '.creole' do |t|
    doc = Creole_document.new()
    File.open(t.source){|f| doc << f }
    doc.save(t.name)
  end
  #Build the text-readme from creole-source
  rule '.txt' => '.creole' do |t|
    doc = Creole_document.new()
    File.open(t.source){|f| doc << f }
    doc.save(t.name)
  end
  #~ task :default => 'readme.html'
  #~ task :default => 'readme.txt'
  
  desc "Copy the created gems to archive"
  task :archive do
    Dir["*-#{$version}.gem"].each{|gem_file|
      FileUtils.copy(gem_file, "archive/File.basename(gem_file)")
    }
  end
  
  #~ task :default => 'mygem:check'
  task :default => :check
  #~ task :default => :test
  #~ task :default => :gem
  #~ task :default => :install
  #~ task :default => :ftp_rdoc
  #~ task :default => 
  #~ task :default => 
  
  
  if $0 == __FILE__
    app = Rake.application
    app[:default].invoke
  end

TEMPLATE
TASKLIST =

Tasks defined by this class. See #build_tasks().

Test tasks are defined with #define_test.

[ :default, 
  :check, :check_version, :check_gemspec,
  :gem,
  :install, :ftp_rdoc, :push,
  :links,
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, version, options = {}) {|_self, @spec| ... } ⇒ Gem_packer

Create a new gem definition.

Usage:

Gem_packer.new('test', '0.1.0', { ...options... })   do |gem_packer, spec|
  spec.email = '[email protected]'
  # ...
end

Options may be:

  • verbose

  • public - allow push, ftp…

  • versions - variables, which should be same as version.

Effects:

  • Defines the tasks inside a namespace (see Gem_packer#build_tasks )

  • Add the ‘namespaced’-tasks to standard tasks.

Yields:

Yield Parameters:

  • _self (Gem_packer)

    the object that the method was called on

Raises:

  • (ArgumentError)


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/knut_tools/rake/gempackager.rb', line 172

def initialize( name, version, options = {} )
  @name = name
  @version = version
  @spec = Gem::Specification.new{ |spec|
    spec.name = name
    spec.version = version
  }
  
  @ftp_connections = []
  
  raise ArgumentError unless options.is_a?(Hash)
  #Copy all options to class settings.
  @versions = options.delete(:versions)
  @versions ||= [] 
  @verbose = options.delete(:verbose)
  @public = options.delete(:public)
    #~ gemdef.add_ftp_connection(host, account, passwort, directory)

  raise ArgumentError unless options.empty?
  
  yield self, @spec if block_given?
  
  puts "Build the tasks for #{@name}" if @verbose    
  build_tasks()
end

Instance Attribute Details

#nameObject (readonly)

Name of the gem



219
220
221
# File 'lib/knut_tools/rake/gempackager.rb', line 219

def name
  @name
end

#publicObject

Flag, if the gem is public (block “push” if false)



226
227
228
# File 'lib/knut_tools/rake/gempackager.rb', line 226

def public
  @public
end

#specObject (readonly)

Spec-definition



217
218
219
# File 'lib/knut_tools/rake/gempackager.rb', line 217

def spec
  @spec
end

#versionObject (readonly)

Version of the gem



221
222
223
# File 'lib/knut_tools/rake/gempackager.rb', line 221

def version
  @version
end

#versionsObject (readonly)

Collection (Array) of version-elements. Have to be identic with version. Example: mygem_def.versions << Knut_tools::VERSION



224
225
226
# File 'lib/knut_tools/rake/gempackager.rb', line 224

def versions
  @versions
end

Instance Method Details

#add_ftp_connection(host, account, passwort, directory) ⇒ Object

Add a ftp-connection to copy the documentation.

The complete content of the rdoc-directory will be copied to the ftp-destination.



233
234
235
236
# File 'lib/knut_tools/rake/gempackager.rb', line 233

def add_ftp_connection(host, , passwort, directory)
  puts "Add ftp-connection to #{host} for ftp_doc" if @verbose
  @ftp_connections << FTP_DATA.new(host, , passwort, directory)
end

#build_tasksObject

Build all the tasks from TASKLIST inside a namespace.

Tasks outside the namespace get the “namespaced” tasks as prerequisite.

Test tasks are defined with #define_test.

The tasks

default

Includes:

  • check

check

Includes:

  • check_version

  • check_gemspec

check_version

The gem has a defined version.

Inside your code you have VERSION-definition you can add with Gem_packer#versions

This tasks checks, if all VERSION fit to the gem-version.

Example:

mygem_def = Gem_packer.new('mygem', '1.0.0')
mygem_def.versions << Mygem::VERSION
mygem_def.versions << Mygem::Firstclass::VERSION
mygem_def.versions << Mygem::Secondclass::VERSION

check_gemspec

Makes some tests on the gemspec-definition.

  • File existence (files, test files, executables

gem

Build the gem.

ftp_rdoc

Copy the rdoc-files to a ftp-destination. The destionations must be defined with Gem_packer#add_ftp_connection.

You can block this task with Gem_packer#public = false.

push

Push the gem to gemcutter.

You can block this task with Gem_packer#public = false.



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/knut_tools/rake/gempackager.rb', line 289

def build_tasks()
  
  #Define the namespace for the gem.
  namespace @name do
    desc "Run default tasks for #{name}"
    task :default => :check do
      #empty, only prerequisites needed
    end

    desc "Run check tasks for #{name}"
    task :check => [:check_version, :check_gemspec ] do |t|
      #empty, only prerequisites needed
      #~ puts t.comment if @verbose
    end

    desc "Check version for #{@name}"
    task :check_version do |t|
      puts t.comment if @verbose
      check_version()
    end

    desc "Check gemspec for #{@name}"
    task :check_gemspec do |t|
      puts t.comment if @verbose
      check_gemspec()
    end

    desc "Build #{@name}-#{@version}.gem"
    task :gem do |t|
      puts t.comment if @verbose
      Gem::Builder.new(@spec).build
    end

=begin
Remark 2010-07-20:
gem uses ruby 1.9-branch 
-> Use pik to update all branches
=end
    desc "Install #{@name}-#{@version}.gem"
    task :install => [:check, :gem ] do |t|
      puts t.comment if @verbose
      puts `call gem install #{@name}-#{@version}.gem -l`
      #~ puts `call pik gem install #{@name}-#{@version}.gem -l`
    end

    desc "Push documentation to gems.rubypla.net"
    task :ftp_rdoc do |t|
      raise BlockError, "Task ftp_rdoc blocked for #{@spec.full_name}" unless @public
      
      puts t.comment if @verbose
      gemdir = %x{call gem environment gemdir}.strip
      
      source = File.join( gemdir, 'doc', @spec.full_name, 'rdoc' )
      
      raise "#{source} not found" unless File.exist?(source)
      raise "#{source} no directory " unless File.directory?(source)

      raise "No ftp-connection defined" if @ftp_connections.empty?
        
      Dir.chdir(source){
        @ftp_connections.each{|ftp|
          puts "Upload rdoc to #{ftp.host}/#{ftp.target_dir}"
          #Copy the data into target dir 
          #The target directory is created if it doesn't exist.
          Rake::FtpUploader.connect(ftp.target_dir, ftp.host, ftp., ftp.password){|uploader|
            uploader.upload_files('**/*')
          }
        }
      }
    end  #ftp_rdoc

    desc "Push #{@name} gem to gemcutter"
    task :push => :gem do |t|
      raise BlockError, "Task push blocked for #{@spec.full_name}" unless @public
      
      puts t.comment if @verbose
      puts `call gem push #{@name}-#{@version}.gem`
    end #push

    desc "Create Links to directory and rdoc for #{@name}"
    task :links do |t|
      # Klappt leider nicht auf dir --> 
      gemdir = %x{call gem environment gemdir}.strip
        mk_link( File.join( gemdir, 'gems', @spec.full_name ), 
                    "dir_#{@spec.full_name}.dir.lnk",
                    "#{@name} version #{@version}"
                  )
        mk_link(File.join( gemdir, 'doc', @spec.full_name, 'rdoc', 'index.html' ), 
                    "rdoc_#{@spec.full_name}.lnk",
                    "rdoc #{@spec.name} version #{@spec.version}"
                  )
    end

  end
  
  #Tasks outside the namespace
  task :default => @name
  task @name => "#{@name}:default"
  #Add prerequisites
  TASKLIST.each{|task|
    task task => "#{@name}:#{task}"
  }
  
end

#check_gemspecObject

Check the gemspec.



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/knut_tools/rake/gempackager.rb', line 410

def check_gemspec()
  #~ check obligatory fields?
  files = []
  
  #Check file existence
  #spec.files includes testfiles.
  @spec.files.each{|file|
    puts "\t#{file} missing" unless File.exist?(file)
    files << file
  }
  @spec.test_files.each{|file|
    puts "\t#{file} missing" unless File.exist?(file)
    files << file
  }
  @spec.executables.each{|file|
    puts "\t#{file} missing" unless File.exist?(File.join(@spec.bindir, file))
    files << File.join(@spec.bindir, file)
  }
  files.sort!
  files.uniq!
  
  #~ fixme: compare files with manifest.
  #~ puts files.to_yaml
end

#check_versionObject

Check the version.

Each value from #versions must be equal to #version.

Raises:



398
399
400
401
402
403
404
405
# File 'lib/knut_tools/rake/gempackager.rb', line 398

def check_version()
  raise VersionError, "Gemspec#version != Gem_packer#version" unless @spec.version.to_s == @version
  @versions.each{|version|
  #fixme --> Name rauszubekommen?
  #~ puts version.object_id
    raise VersionError, "#{@version} != #{version}" unless version == @version
  }
end

#define_test(testdir = "unittest", glob = ) ⇒ Object

Define tests.

Raises:

  • (ArgumentError)


438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/knut_tools/rake/gempackager.rb', line 438

def define_test( testdir = "unittest", glob = FileList['test*.rb'] )
  
  raise ArgumentError, "Testdirectory #{testdir} missing" unless File.exist?(testdir)
  raise ArgumentError, "Testdirectory #{testdir} missing" unless File.directory?(testdir)
  
  lib = ("../" * (testdir.count('/') + 1) ) + @spec.require_path
  raise ArgumentError, "Require path #{@spec.require_path} missing from #{testdir}" unless File.exist?("#{testdir}/#{lib}")
  raise ArgumentError, "Require path #{@spec.require_path} missing from #{testdir}" unless File.directory?("#{testdir}/#{lib}")
  
  #Check if test files exist
  Dir.chdir(testdir){
    raise ArgumentError, "Test files missing in #{testdir}" unless glob.existing.size > 0
  }
  
  #Define the test tasks
  testcase = Rake::TestTask.new("#{@name}:test") do |t|
    t.dir = testdir #possible with 'knut_tools/rake/testtask.rb'
    #Get 'lib' directory relative to test directory.
    t.libs << lib
    t.test_files = glob
    t.verbose = true
  end
  
  task :test => "#{@name}:test"
  
  testcase
end