Created
October 31, 2016 23:08
-
-
Save the-michael-toy/24f2c79c0476f7c185d09e39a9a7135e to your computer and use it in GitHub Desktop.
create a big fake ruby project for testing purposes ...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ruby makebigfakerubyapp.rb /tmp/bfrp | |
# cd /tmp/bfrp | |
# time bin/require_everything | |
# warble | |
# time java -jar require_everything.jar | |
require 'securerandom' | |
require 'fileutils' | |
require 'set' | |
class BigFakeApp | |
CLASS_COUNT = 1500 | |
MAX_LEAF_SIZE = 15 | |
METHOD_COUNT = 20 | |
LOAD_DEPTH = 2 | |
class MockClass | |
def initialize | |
@name = "Class_#{SecureRandom.hex(16)}" | |
end | |
def to_s | |
methods = (1..METHOD_COUNT).to_a.map do |n| | |
m = <<~RUBY | |
def method#{n}(arg) | |
var = SecureRandom.hex(8) | |
RUBY | |
5.times do | |
case rand(4) | |
when 0 | |
m << "rand(n).times { var << 'x'}\n" | |
when 1 | |
m += <<~RUBY | |
if n == 0 | |
:zero | |
elsif n > 0 | |
:positive | |
else | |
:negative | |
end | |
RUBY | |
when 2 | |
m << Array.new(5) { " method_#{rand(METHOD_COUNT)+1}(arg)" }.join(" || ")+"\n" | |
when 3 | |
m += ' "var is now #{var} and arg is #{arg}"' + "\n" | |
end | |
end | |
m + "\n end" | |
end | |
<<~RUBY | |
module M1 | |
module M2 | |
class #{@name} | |
#{ methods.join("\n") } | |
end | |
end | |
end | |
RUBY | |
end | |
def file_name | |
@name.downcase + ".rb" | |
end | |
end | |
def initialize | |
buckets = [] | |
classes_left = CLASS_COUNT | |
while classes_left > 0 do | |
n_classes = [classes_left, MAX_LEAF_SIZE].min | |
buckets << Array.new(n_classes) { MockClass.new() } | |
classes_left -= n_classes | |
end | |
while buckets.size > MAX_LEAF_SIZE do | |
new_buckets = [] | |
new_buckets << buckets.shift(MAX_LEAF_SIZE) until buckets.size == 0 | |
buckets = new_buckets | |
end | |
@app = buckets | |
@requires = [] | |
@loads = Set.new | |
end | |
def materialize | |
walk_tree(@app, []) do |type, stuff, path| | |
if type == :leaf | |
rfile = File.join(*path, stuff.file_name) | |
File.write(rfile, stuff.to_s) | |
else | |
FileUtils.mkdir_p path.join('/') unless path.empty? | |
end | |
end | |
end | |
def require_list | |
walk_tree(@app, []) do |type, obj, path| | |
if type == :leaf | |
dir = path.drop(LOAD_DEPTH) | |
@requires << "require '#{File.join(*dir, obj.file_name)}'" | |
elsif type == :node | |
@loads.add(path.join('/')) if path.size == LOAD_DEPTH | |
end | |
end | |
end | |
def walk_tree(root, path, &blk) | |
if root.is_a? MockClass | |
yield :leaf, root, path | |
else | |
yield :node, root, path | |
root.each_index do |i| | |
child = root[i] | |
if child.is_a? MockClass | |
walk_tree(child, path, &blk) | |
else | |
walk_tree(child, [*path, "depth=#{path.size},index=#{i}"], &blk) | |
end | |
end | |
end | |
end | |
def write(dest) | |
FileUtils.mkdir_p dest + "/bin" | |
FileUtils.mkdir_p dest + "/config" | |
FileUtils.chdir dest | |
app_file = "bin/require_everything" | |
gems = { | |
"jruby-jars" => "jruby-jars", "jruby-openssl" => "openssl", "sequel" => "sequel", | |
"rack" => "rack", "rack-protection" => "rack-protection", "rack-rewrite" => "rack-rewrite", | |
"activesupport" => nil, "useragent" => "useragent", "uri_template" => "uri_template", | |
"thor" => "thor", "slim" => "slim", "mail" => "mail", "write_xlsx" => "write_xlsx", | |
"warden" => "warden", "bcrypt-ruby" => "bcrypt", "rqrcode" => "rqrcode", "rotp" => "rotp", "ruby-openid" => nil, | |
"tzinfo" => "tzinfo", "trollop" => "trollop", "net-ldap" => "net-ldap", "net-ssh" => "net/ssh", "ruby-saml" => "ruby-saml", "rubyzip" => "zip", "liquid" => "liquid", "parse-cron" => "parse-cron", "zip-zip" => nil, | |
"chronic_duration" => "chronic_duration", "kramdown" => "kramdown", "loofah" => "loofah", "rouge" => nil, "geokit" => "geokit", "prawn" => "prawn", "diffy" => "diffy", "snowplow-tracker" => "snowplow-tracker", "therubyrhino" => "rhino", | |
"safe_yaml" => "safe_yaml", "pmap" => "pmap", "uuidtools" => "uuidtools", "sentry-raven" => "sentry-raven", "newrelic_rpm" => "newrelic_rpm", "jruby-jms" => "jms", "jmx4r" => "jmx4r" | |
} | |
@requires = gems.values.compact.map {|g| "require '#{g}'"} | |
materialize | |
require_list | |
File.write app_file, <<~RUBY | |
#! /usr/bin/env ruby | |
require 'pathname' | |
require 'bundler/setup' | |
root = Pathname.new(__FILE__).dirname.parent.expand_path.to_s | |
loads = %w[ | |
#{@loads.to_a.join("\n ")} | |
] | |
$LOAD_PATH.concat(loads.map{|fn| File.join(root, fn)}) | |
#{@requires.join("\n")} | |
RUBY | |
File.chmod(0755, app_file) | |
File.write "config/warble.rb", <<~RUBY | |
Warbler::Config.new do |config| | |
config.features = %w(compiled) | |
config.dirs = FileList["d*"] | |
config.includes = [ 'bin/require_everything' ] | |
config.jar_name = "require_everything" | |
config.bytecode_version = "1.8" | |
config.override_gem_home = true | |
end | |
RUBY | |
File.write "Gemfile", <<~RUBY | |
source "https://rubygems.org" | |
platform :jruby do | |
#{gems.keys.map{|n| "gem '#{n}'"}.join("\n ")} | |
end | |
RUBY | |
end | |
end | |
if ARGV.size == 1 | |
b = BigFakeApp.new | |
b.write ARGV[0] | |
puts "app built, don't forget to bundle install in #{ARGV[0]}" | |
else | |
puts "usage: makebigfakerubyapp <directory>" | |
exit 1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment