I want to enumerate through the contents of a tar file in alphabetical order of the filenames contained in the tar file. The following dies with the error Error: closed Gem::Package::TarReader::Entry
.
Gem::Package::TarReader.new io do |tar|
tar.sort_by{ |e| e.full_name }.each.map do |tar_entry|
file_contents = tar_entry.read
# more code here, not shown for clarity
file_contents
end
end
Here is the stack trace:
Liquid Exception: closed Gem::Package::TarReader::Entry in /var/sitesUbuntu/www.mslinn.com/_drafts/2020-09-28-using-aws-cloud9-with-jump-server.html
jekyll 3.8.7 | Error: closed Gem::Package::TarReader::Entry
/usr/lib/ruby/2.7.0/rubygems/package/tar_reader/entry.rb:30:in `check_closed': closed Gem::Package::TarReader::Entry (IOError)
from /usr/lib/ruby/2.7.0/rubygems/package/tar_reader/entry.rb:133:in `read'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:14:in `block (2 levels) in untar_contents'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:13:in `each'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:13:in `each'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:13:in `map'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:13:in `block in untar_contents'
from /usr/lib/ruby/2.7.0/rubygems/package/tar_reader.rb:29:in `new'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:12:in `untar_contents'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:25:in `block in render'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:24:in `open'
from /var/sitesUbuntu/www.mslinn.com/_plugins/archive_display.rb:24:in `render'
from /var/lib/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/block_body.rb:103:in `render_node_to_output'
from /var/lib/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/block_body.rb:91:in `render'
from /var/lib/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/template.rb:208:in `block in render'
from /var/lib/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/template.rb:242:in `with_profiling'
from /var/lib/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/template.rb:207:in `render'
from /var/lib/gems/2.7.0/gems/liquid-4.0.3/lib/liquid/template.rb:220:in `render!'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/liquid_renderer/file.rb:30:in `block (2 levels) in render!'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/liquid_renderer/file.rb:42:in `measure_bytes'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/liquid_renderer/file.rb:29:in `block in render!'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/liquid_renderer/file.rb:49:in `measure_time'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/liquid_renderer/file.rb:28:in `render!'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/renderer.rb:126:in `render_liquid'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/renderer.rb:79:in `render_document'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/renderer.rb:62:in `run'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:479:in `render_regenerated'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:464:in `block (2 levels) in render_docs'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:463:in `each'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:463:in `block in render_docs'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:462:in `each_value'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:462:in `render_docs'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:191:in `render'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/site.rb:71:in `process'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/command.rb:28:in `process_site'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/commands/build.rb:65:in `build'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/commands/build.rb:36:in `process'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/commands/serve.rb:93:in `block in start'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/commands/serve.rb:93:in `each'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/commands/serve.rb:93:in `start'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/lib/jekyll/commands/serve.rb:75:in `block (2 levels) in init_with_program'
from /var/lib/gems/2.7.0/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in `block in execute'
from /var/lib/gems/2.7.0/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in `each'
from /var/lib/gems/2.7.0/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in `execute'
from /var/lib/gems/2.7.0/gems/mercenary-0.3.6/lib/mercenary/program.rb:42:in `go'
from /var/lib/gems/2.7.0/gems/mercenary-0.3.6/lib/mercenary.rb:19:in `program'
from /var/lib/gems/2.7.0/gems/jekyll-3.8.7/exe/jekyll:15:in `<top (required)>'
from /home/mslinn/gems/bin/jekyll:23:in `load'
from /home/mslinn/gems/bin/jekyll:23:in `<main>'
I just had to sort the result:
require 'rubygems/package'
File.open(tar_name, "rb") do |file|
Gem::Package::TarReader.new(file) do |tar|
return tar.each.map { |tar_entry|
if tar_entry.file?
file_contents = tar_entry.read.strip
"<div class='codeLabel'>#{tar_entry.full_name}</div><pre data-lt-active='false'>#{file_contents}</pre>"
else
""
end
}.sort_by{ |e| e.full_name }
end
end
Here is how I actually wrote the code in production:
def traverse_tar(tar_name)
require 'rubygems/package'
File.open(tar_name, "rb") do |file|
Gem::Package::TarReader.new(file) do |tar|
return tar.each.map { |entry|
if entry.file? then { :name => entry.full_name, :content => entry.read.strip } else nil end
}.compact.sort_by { |entry| entry[:name] }.map { |entry|
"<div class='codeLabel'>#{entry[:name]}</div><pre data-lt-active='false'>#{entry[:content]}</pre>"
}
end
end
end
This code is used in my jekyll_archive_display
plugin.