From 0c07ea043769938653d26b15b123fa784e31fdee Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 14 Apr 2019 15:26:28 -0400 Subject: [PATCH] compress rscons script like waf - close #76 --- Rakefile.rb | 6 +++-- rb/build_dist.rb | 68 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/Rakefile.rb b/Rakefile.rb index c03ddb9..b047d5f 100644 --- a/Rakefile.rb +++ b/Rakefile.rb @@ -23,16 +23,18 @@ RSpec::Core::RakeTask.new(:spec, :example_string) do |task, args| task.rspec_opts = %W[-e "#{args.example_string}" -f documentation] end end - task :spec => :build_dist +# dspec task is useful to test the distributable release script, but is not +# useful for coverage information. desc "Dist Specs" -task :dspec, [:example_string] do |task, args| +task :dspec, [:example_string] => :build_dist do |task, args| FileUtils.mkdir_p("test") FileUtils.cp("dist/rscons", "test/rscons.rb") ENV["dist_specs"] = "1" Rake::Task["spec"].invoke(args.example_string) ENV.delete("dist_specs") + FileUtils.rm_f(Dir.glob(".rscons-*")) end YARD::Rake::YardocTask.new do |yard| diff --git a/rb/build_dist.rb b/rb/build_dist.rb index cebfeba..a2db88c 100755 --- a/rb/build_dist.rb +++ b/rb/build_dist.rb @@ -2,14 +2,25 @@ require "fileutils" +if File.read("lib/rscons/version.rb") =~ /VERSION = "(.+)"/ + VERSION = $1 +else + raise "Could not determine version." +end +if `git show | head -n 1` =~ /commit\s+([0-9a-f]{7})/i + GIT = $1 +else + raise "Could not determine git revision." +end PROG_NAME = "rscons" START_FILE = "bin/#{PROG_NAME}" LIB_DIR = "lib" DIST = "dist" files_processed = {} +combined_file = [] -process_file = lambda do |file, fh| +combine_files = lambda do |file| File.read(file, mode: "rb").each_line do |line| if line =~ /^\s*require(?:_relative)?\s*"(.*)"$/ require_name = $1 @@ -18,22 +29,65 @@ process_file = lambda do |file, fh| if File.exists?(path) unless files_processed[path] files_processed[path] = true - process_file[path, fh] + combine_files[path] end else raise "require path #{path.inspect} not found" end else - fh.write(line) + combined_file << line end else - fh.write(line) + combined_file << line end end end -FileUtils.mkdir_p(DIST) +combine_files[START_FILE] -File.open("#{DIST}/#{PROG_NAME}", "wb", 0755) do |fh| - process_file[START_FILE, fh] +# Strip Ruby comment lines and empty lines to save some space, but do not +# remove lines that are in heredoc sections. This isn't terribly robust to be +# used in the wild, but works for the heredoc instances for this project. +stripped_comments = [] +heredoc_end = nil +combined_file.each do |line| + if line =~ /<<-?([A-Z]+)/ + heredoc_end = $1 + end + if heredoc_end and line =~ /^\s*#{heredoc_end}/ + heredoc_end = nil + end + if heredoc_end or not (line =~ /^\s*(#[^!].*)?$/) + stripped_comments << line + end +end + +require "zlib" +compressed_script = Zlib::Deflate.deflate(stripped_comments.join) +escaped_compressed_script = compressed_script.gsub("#", "#1").gsub("\n", "#2").gsub("\r", "#3").gsub("\0", "#4") + +FileUtils.mkdir_p(DIST) +File.open("#{DIST}/#{PROG_NAME}", "wb", 0755) do |fh| + fh.write(<(.*)/ + escaped_compressed = $1 + unescaped_compressed = escaped_compressed.gsub("#4", "\\0").gsub("#3", "\\r").gsub("#2", "\\n").gsub("#1", "#") + require "zlib" + inflated = Zlib::Inflate.inflate(unescaped_compressed) + File.open(script, "wb") do |fh| + fh.write(inflated) + end + else + raise "Could not decompress." + end +end +load script +if __FILE__ == $0 + Rscons::Cli.run(ARGV) +end +#==>#{escaped_compressed_script} +EOF end