Fetching contributors…
Cannot retrieve contributors at this time
209 lines (176 sloc) 5.94 KB
require 'pathname'
# Public: A Class containing all the metadata and utilities needed to manage a
# ruby project.
class ThisProject
# The name of this project
attr_accessor :name
# The author's name
attr_accessor :author
# The email address of the author(s)
attr_accessor :email
# The homepage of this project
attr_accessor :homepage
# The regex of files to exclude from the manifest
attr_accessor :exclude_from_manifest
# The hash of Gem::Specifications keyed' by platform
attr_accessor :gemspecs
# Public: Initialize ThisProject
# Yields self
def initialize(&block)
@exclude_from_manifest = Regexp.union(/\.(git|DS_Store)/,
@gemspecs =
yield self if block_given?
# Public: return the version of ThisProject
# Search the ruby files in the project looking for the one that has the
# version string in it. This does not eval any code in the project, it parses
# the source code looking for the string.
# Returns a String version
def version
[ "lib/#{ name }.rb", "lib/#{ name }/version.rb" ].each do |v|
path = project_path( v )
line =[/^\s*VERSION\s*=\s*.*/]
if line then
return line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
# Internal: Return a section of an RDoc file with the given section name
# path - the relative path in the project of the file to parse
# section_name - the section out of the file from which to parse data
# Retuns the text of the section as an array of paragrphs.
def section_of( file, section_name )
re = /^[=#]+ (.*)$/
sectional = project_path( file )
parts = re )[1..-1]! { |p| p.strip }
sections =
Hash[*parts].each do |k,v|
sections[k] = v.split("\n\n")
return sections[section_name]
# Internal: print out a warning about the give task
def task_warning( task )
warn "WARNING: '#{task}' tasks are not defined. Please run 'rake develop'"
# Internal: Return the full path to the file that is relative to the project
# root.
# path - the relative path of the file from the project root
# Returns the Pathname of the file
def project_path( *relative_path )
project_root.join( *relative_path )
# Internal: The absolute path of this file
# Returns the Pathname of this file.
def this_file_path __FILE__ ).expand_path
# Internal: The root directory of this project
# This is defined as being the directory that is in the path of this project
# that has the first Rakefile
# Returns the Pathname of the directory
def project_root
this_file_path.ascend do |p|
rakefile = p.join( 'Rakefile' )
return p if rakefile.exist?
# Internal: Returns the contents of the Manifest.txt file as an array
# Returns an Array of strings
def manifest
manifest_file = project_path( "Manifest.txt" )
abort "You need a Manifest.txt" unless manifest_file.readable? { |l| l.strip }
# Internal: Return the files that define the extensions
# Returns an Array
def extension_conf_files
manifest.grep( /extconf.rb\Z/ )
# Internal: Returns the gemspace associated with the current ruby platform
def platform_gemspec
gemspecs.fetch(platform) { This.ruby_gemspec }
def core_gemspec do |spec| = name
spec.version = version = author = email
spec.homepage = homepage
spec.summary = summary
spec.description = description
spec.license = license
spec.files = manifest
spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
spec.test_files = spec.files.grep(/^spec/)
spec.extra_rdoc_files += spec.files.grep(/(txt|rdoc|md)$/)
spec.rdoc_options = [ "--main" , '',
"--markup", "tomdoc" ]
spec.required_ruby_version = '>= 2.2.2'
# Internal: Return the gemspec for the ruby platform
def ruby_gemspec( core = core_gemspec, &block )
yielding_gemspec( 'ruby', core, &block )
# Internal: Return the gemspec for the jruby platform
def java_gemspec( core = core_gemspec, &block )
yielding_gemspec( 'java', core, &block )
# Internal: give an initial spec and a key, create a new gemspec based off of
# it.
# This will force the new gemspecs 'platform' to be that of the key, since the
# only reason you would have multiple gemspecs at this point is to deal with
# different platforms.
def yielding_gemspec( key, core )
spec = gemspecs[key] ||= core.dup
spec.platform = key
yield spec if block_given?
return spec
# Internal: Return the platform of ThisProject at the current moment in time.
def platform
(RUBY_PLATFORM == "java") ? 'java' : Gem::Platform::RUBY
# Internal: Return the DESCRIPTION section of the README.rdoc file
def description_section
section_of( '', 'DESCRIPTION')
# Internal: Return the summary text from the README
def summary
# Internal: Return the full description text from the README
def description
description_section.join(" ").tr("\n", ' ').gsub(/[{}]/,'').gsub(/\[[^\]]+\]/,'') # strip rdoc
def license
license_file = project_path("LICENSE")
line = license_file.readlines.first
# Internal: The path to the gemspec file
def gemspec_file
project_path( "#{ name }.gemspec" )
This =