Skip to content

Instantly share code, notes, and snippets.

@peperon
Created November 8, 2014 19:38
Show Gist options
  • Select an option

  • Save peperon/2279cc3d0ac8f92d41f4 to your computer and use it in GitHub Desktop.

Select an option

Save peperon/2279cc3d0ac8f92d41f4 to your computer and use it in GitHub Desktop.
require 'set'
module Able
class Paths
attr_reader :paths
def initialize(files, dir)
@paths = files.map { |file| dir + file }
end
def to_s
@paths.map(&:to_s).to_s
end
def join(other_paths)
@paths + other_paths.paths
end
def disjoin(other_paths)
@paths - other_paths.paths
end
def canonize(base)
@paths.map do |path|
begin
path.relative_path_from(base)
rescue
path
end
end
end
end
#example input_paths = Paths.new(in_files, in_dir)
class Task
attr_reader :dependencies
def initialize(project, rule, flags, in_paths, out_paths, depends, description)
@project = project
@rule = rule
@flags = flags
@description = description
@dependencies = Set.new(depends)
@executed = false
@visited = false
extra_input_paths = rule.extra_input_paths(in_paths, out_paths, @flags)
extra_output_paths = rule.extra_output_paths(in_paths, out_paths, @flags)
@in_paths = in_paths.join extra_input_paths
@out_paths = out_paths.join extra_output_paths
end
def dependencies=(new_deps)
@dependencies |= new_deps.values
in_path_deps = Paths.new(new_deps.keys, @project.src_root)
out_path_deps = Paths.new(new_deps.keys, @project.dst_root)
@in_paths = (@in_paths.disjoin in_path_deps).join out_path_deps
end
def input_paths
@in_paths.canonize @project.src_root
end
def output_paths
@out_paths.canonize @project.dst_root
end
def visited?()
@visited
end
def visit()
@visited = true
end
def description()
desc = @description
desc = @rule.description(@in_paths, @out_paths, @flags) unless desc
desc = "Building: #{@in_paths.to_s} => #{@out_paths.to_s}" unless desc
desc
end
def execute()
raise "Attempt to execute task '#{description}' again" if executed?
raise "Task '#{description}' is not yet executable!" unless executable?
if need_execution?
Logger.info(description)
@rule.build(@in_paths, @out_paths, @flags)
end
@executed = true
end
def executed?()
@executed
end
def executable?()
@dependencies.all? { |task| task.executed? }
end
def clean
Logger.info("Cleaning: #{@out_paths.to_s}")
@rule.clean(@in_paths, @out_paths, @flags)
end
private
def need_execution?()
@out_paths.paths.each do |op|
@in_paths.paths.each do |ip|
return true if File.mtime(op.to_s) < File.mtime(ip.to_s)
end
end
@in_paths.empty?
rescue
true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment