I've always used git to determine which files should go into the gem package:
gem.files = `git ls-files`.split "\n"
Unfortunately, this approach has recently proved to be inappropriate. I need a self-contained, pure-Ruby solution.
My first idea was to simply glob the entire directory, but that alone is likely to include unwanted files. So, after researching the problem, I came up with this:
# example.gemspec
directory = File.dirname File.expand_path __FILE__
dotfiles = %w(.gitignore .rvmrc)
ignore_file = '.gitignore'
file_list = []
Dir.chdir directory do
ignored = File.readlines(ignore_file).map(&:chomp).reject { |glob| glob =~ /\A(#|\s*\z)/ }
file_list.replace Dir['**/**'] + dotfiles
file_list.delete_if do |file|
File.directory?(file) or ignored.any? { |glob| File.fnmatch? glob, file }
end
end
# Later...
gem.files = file_list
That seems a bit complex for a gemspec. It also does not fully support gitignore's pattern format. It currently seems to work but I'd rather not run into problems later.
Is there a simpler but robust way to compute the gem's list of files? Most gems apparently use git ls-files, and the ones that don't either use a solution similar to mine or specify the files manually.