#!/usr/bin/env rash require “rash”
module Genius
@@build_tools = {} @@build_groups = {} def self.build_tools @@build_tools.dup end def self.build_groups @@build_groups.dup end # Build tool methods def self.register_build_tool(name, *files, &command) @@build_tools[name.to_s] = BuildTool.new(name, *files, &command) end def self.define_build_tool_files(name, *files) @@build_tools[name.to_s].files = files.flatten.map(&:to_s) end def self.add_build_tool_file(name, file) @@build_tools[name.to_s].files << file.to_s end def self.define_build_tool_command(name, &command) @@build_tools[name.to_s].commands = [command] end def self.add_build_tool_command(name, &command) @@build_tools[name.to_s].commands << command end # Build group methods def self.register_group(name, *extensions, &command) @@build_groups[name.to_s] = BuildGroup.new(name, *extensions, &command) end def self.define_group_extensions(name, *exts) @@build_groups[name.to_s].extensions = exts.flatten.map {|e| e.to_s.delete_prefiox(".")} end def self.add_group_extension(name, ext) # requires 2.5 @@build_groups[name.to_s].extensions << ext.to_s.delete_prefix(".") end def self.define_group_command(name, &command) @@build_groups[name.to_s].commands = [command] end def self.add_group_command(name, &command) @@build_groups[name.to_s].commands << command end private class BuildTool attr_accessor :name, :files, :commands def initialize(name, *files, &command) @name = name # @files = files.flatten.map{|f| /^#{f.gsub("*", ".*")}$/} @files = files.flatten.map(&:to_s) @commands = [command] end def build(files) @commands.each do |command| command.call(files) end end end class BuildGroup attr_accessor :name, :extensions, :commands def initialize(name, *extensions, &command) @name = name @extensions = extensions.flatten.map(&:to_s) @commands = [command] end def build(files) @commands.each do |command| command.call(files) end end end
end
$GENIUS_HOME = File.expand_path(“~/.genius”)
# Sanity check for if genius's dependencies exist. if !Dir.exist?($GENIUS_HOME)
with_stdout_as_stderr do puts ".genius - No such directory" puts "\nTo use genius builder, put config files in the ~/.genius directory." puts "Documentation for creating a genius config file can be found at <insert URL here>" end exit 1
end
# Load all config files in .genius, assuming all non-directory files are config files. Dir[$GENIUS_HOME + “/*”].each do |config|
next if File.directory?(config) exit unless load config
end
# Sort files by extension. Only files that have a name and extension are considered. # i.e. Files that have no extension or are only extensions (including extensionless # dotfiles) will not be considered. The final extension is used if multiple are # present. file_set = Hash.new {|h,k| h = []} Dir[“*/”].each do |file|
split_name = file.split(".") if split_name.size > 1 file_set[split_name.last] << file end
end
# If given the name of an existing pattern, run that instead if Genius.build_tools.key? ARGV
Genius.build_tools[ARGV[0]].build(file_set) exit
elsif Genius.build_groups.key? ARGV
group = Genius.build_groups[ARGV[0]] group.build(file_set.filter{|k,v| group.extensions.include?(k)}) exit
end
# Check for build tool patterns, terminating after build completion if one is matched Genius.build_tools.each do |name, tool|
files = tool.files.flat_map {|f| Dir[f]} if files.any? {|f| File.exist?(f) && !File.directory?(f)} puts "Matched build tool pattern: #{tool.name}" tool.build(file_set) # Does not contain all files, so may not be useful. exit end
end
# Get counts of files matching each build group. group_counts = Genius.build_groups.map do |name, group|
file_count = group.extensions.inject(0) {|acc, ext| acc += file_set[ext].size} [group, file_count]
end
# check if all patterns match if group_counts.all? {|k,v| v.zero?}
with_stdout_as_stderr do puts "No matching build patterns for the current directory" exit 1 end
end
# Build based on commands specified by most populous build group, # passing only the files with extensions specified by that group. group = group_counts.max_by{|k,v| v}[0] group.build(file_set.filter{|k,v| group.extensions.include?(k)})