From 90d08e35542afefcd363f73e471c78cc0b83f972 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 4 Jan 2023 20:41:58 -0500 Subject: [PATCH] Add script to build distributable propane script --- .gitignore | 1 + Rakefile | 4 ++ rb/build_dist.rb | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 rb/build_dist.rb diff --git a/.gitignore b/.gitignore index 23a4b94..22ef80f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.yardoc /_yardoc/ /coverage/ +/dist/ /gen/ /pkg/ /spec/reports/ diff --git a/Rakefile b/Rakefile index 6cb1447..9696595 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,9 @@ require "rspec/core/rake_task" +task :build_dist do + sh "ruby rb/build_dist.rb" +end + RSpec::Core::RakeTask.new(:spec, :example_pattern) do |task, args| if args.example_pattern task.rspec_opts = %W[-e "#{args.example_pattern}" -f documentation] diff --git a/rb/build_dist.rb b/rb/build_dist.rb new file mode 100644 index 0000000..df995b0 --- /dev/null +++ b/rb/build_dist.rb @@ -0,0 +1,106 @@ +#!/usr/bin/env ruby + +require "fileutils" +require "digest/md5" + +if File.read("lib/propane/version.rb") =~ /VERSION = "(.+)"/ + VERSION = $1 +else + raise "Could not determine version." +end +PROG_NAME = "propane" +START_FILE = "bin/#{PROG_NAME}" +LIB_DIR = "lib" +DIST = "dist" + +files_processed = {} +combined_file = [] + +combine_files = lambda do |file| + File.read(file, mode: "rb").each_line do |line| + if line =~ /^\s*require(?:_relative)?\s*"(.*)"$/ + require_name = $1 + if require_name =~ %r{^#{PROG_NAME}(?:/.*)?$} + path = "#{LIB_DIR}/#{require_name}.rb" + if File.exist?(path) + unless files_processed[path] + files_processed[path] = true + combine_files[path] + end + else + raise "require path #{path.inspect} not found" + end + else + combined_file << line + end + else + combined_file << line + end + end +end + +combine_files[START_FILE] + +# 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 = [] +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 line !~ /#\sspecs/ + if heredoc_end or line !~ /^\s*(#[^!].*)?$/ + stripped << line + end + end +end + +license = File.read("LICENSE.txt").gsub(/^(.*?)$/) do |line| + if line.size > 0 + "# #{line}" + else + "#" + end +end + +require "zlib" +require "base64" +compressed_script = Zlib::Deflate.deflate(stripped.join) +encoded_compressed_script = Base64.encode64(compressed_script).gsub("\n", "") +hash = Digest::MD5.hexdigest(encoded_compressed_script) + +FileUtils.rm_rf(DIST) +FileUtils.mkdir_p(DIST) +File.open("#{DIST}/#{PROG_NAME}", "wb", 0755) do |fh| + fh.write(<(.*)/ + require "zlib" + require "base64" + encoded_compressed = $1 + unescaped_compressed = Base64.decode64(encoded_compressed) + 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 + Propane::CLI.new.run(ARGV) +end +#==>#{encoded_compressed_script} +EOF +end