Mat*_*ira 7 ruby gem packaging file-listing
我总是习惯于git确定哪些文件应该进入gem包:
gem.files = `git ls-files`.split "\n"
Run Code Online (Sandbox Code Playgroud)
不幸的是,这种方法最近被证明是不合适的.我需要一个独立的纯Ruby解决方案.
我的第一个想法是简单地整理整个目录,但仅此一项可能包括不需要的文件.所以,在研究了这个问题之后,我想出了这个:
# 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
Run Code Online (Sandbox Code Playgroud)
这似乎有点复杂gemspec.它也不完全支持gitignore模式格式.它目前似乎有效,但我宁愿以后再遇到问题.
是否有一种更简单但更健壮的方法来计算gem的文件列表?大多数宝石显然都在使用git ls-files,而那些没有使用类似于我的解决方案或手动指定文件.
嗨,
您可以使用纯Ruby列出项目的所有文件:
gem.files = Dir['**/*'].keep_if { |file| File.file?(file) }
Run Code Online (Sandbox Code Playgroud)
或者你可以手动完成,这个解决方案由Ruby on Rails宝石使用:
gem.files = Dir['lib/**/*'] + %w(.yardopts Gemfile LICENSE README.md Rakefile my_gem.gemspec)
Run Code Online (Sandbox Code Playgroud)
最简单的解决方案依赖于 rake 列出目录中的所有文件,但排除.gitignore文件中的所有内容:
require 'rake/file_list'
Rake::FileList['**/*'].exclude(*File.read('.gitignore').split)
Run Code Online (Sandbox Code Playgroud)
官方 rubygems 解决方案,手动列出和排除:
require 'rake'
spec.files = FileList['lib/*.rb',
'bin/*',
'[A-Z]*',
'test/*'].to_a
# or without Rake...
spec.files = Dir['lib/*.rb'] + Dir['bin/*']
spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
spec.files.reject! { |fn| fn.include? "CVS" }
Run Code Online (Sandbox Code Playgroud)
Bundler解决方案,手动列出:
s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
Run Code Online (Sandbox Code Playgroud)
注意:拒绝目录是没有用的,因为 gem 默认会忽略它们。
在纯红宝石中模仿git ls-files和处理的Vagrant 解决方案.gitignore:
# The following block of code determines the files that should be included
# in the gem. It does this by reading all the files in the directory where
# this gemspec is, and parsing out the ignored files from the gitignore.
# Note that the entire gitignore(5) syntax is not supported, specifically
# the "!" syntax, but it should mostly work correctly.
root_path = File.dirname(__FILE__)
all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
all_files.reject! { |file| file.start_with?("website/") }
all_files.reject! { |file| file.start_with?("test/") }
gitignore_path = File.join(root_path, ".gitignore")
gitignore = File.readlines(gitignore_path)
gitignore.map! { |line| line.chomp.strip }
gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
unignored_files = all_files.reject do |file|
# Ignore any directories, the gemspec only cares about files
next true if File.directory?(file)
# Ignore any paths that match anything in the gitignore. We do
# two tests here:
#
# - First, test to see if the entire path matches the gitignore.
# - Second, match if the basename does, this makes it so that things
# like '.DS_Store' will match sub-directories too (same behavior
# as git).
#
gitignore.any? do |ignore|
File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
end
end
Run Code Online (Sandbox Code Playgroud)
使用路径规范 gemMatch Path Specifications, such as .gitignore, in Ruby!
请参阅https://github.com/highb/pathspec-ruby
参考: Bundler Vagrant RubyGems Rake 简单解决方案
| 归档时间: |
|
| 查看次数: |
1549 次 |
| 最近记录: |