lib/jeweler/gemspec_helper.rb
class Jeweler
class GemSpecHelper
attr_accessor :spec, :base_dir
def initialize(spec, base_dir = nil)
self.spec = spec
self.base_dir = base_dir || ''
yield spec if block_given?
end
def valid?
parse
true
rescue
false
end
def write
File.open(path, 'w') do |f|
f.write to_ruby
end
end
def to_ruby
normalize_files(:files)
normalize_files(:extra_rdoc_files)
gemspec_ruby = @spec.to_ruby
gemspec_ruby = prettyify_array(gemspec_ruby, :files)
gemspec_ruby = prettyify_array(gemspec_ruby, :extra_rdoc_files)
gemspec_ruby = <<-END
# Generated by jeweler
# DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in #{Rake.application.rakefile}, and run 'rake gemspec'
#{gemspec_ruby}
END
end
def path
denormalized_path = File.join(@base_dir, "#{@spec.name}.gemspec")
absolute_path = File.expand_path(denormalized_path)
absolute_path.gsub(Dir.getwd + File::SEPARATOR, '')
end
PARSE_SAFE = (RUBY_VERSION >= '2.3') ? 1 : 3
def parse
data = to_ruby
parsed_gemspec = nil
Thread.new { parsed_gemspec = eval("$SAFE = #{PARSE_SAFE}\n#{data}", binding, path) }.join
# Need to reset $SAFE to 0 as it is process global since ruby 2.6
$SAFE = 0 if $SAFE == 1
parsed_gemspec
end
def normalize_files(array_attribute)
array = @spec.send(array_attribute)
# only keep files, no directories, and sort
array = array.select do |path|
File.file? File.join(@base_dir, path)
end.sort
@spec.send("#{array_attribute}=", array)
end
# Adds extra space when outputting an array. This helps create better version control diffs, because otherwise it is all on the same line.
def prettyify_array(gemspec_ruby, array_name)
gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
leadin, files = match[0..-2].split('[')
leadin + "[\n #{files.gsub(%(", "), %(",\n "))}\n ]"
end
end
def gem_path
File.join(@base_dir, 'pkg', parse.file_name)
end
def update_version(version)
@spec.version = version.to_s
end
# Checks whether it uses the version helper or the users defined version.
def has_version?
!@spec.version.nil?
end
end
end