aboutsummaryrefslogtreecommitdiff
path: root/rubymake.rb
blob: e8349e92aff19a3e429fe2e31e4e6ab611ff7b6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
$makes = []
$default = nil

class Make
  def initialize(target, froms, args, block)
    @target = target
    @froms = froms
    @args = args
    @block = block
  end

  def string_target?
    @target.class == String
  end

  def match?(target)
    if string_target?
      @target == target
    else
      @target.match?(target)
    end
  end

  def try_build(target)
    reified_froms = string_target? ? @froms : reify_froms(target)

    reified_froms.each do |from|
      Make.make!(from)
    end

    if !!@args[:phony] ||
       !File.exist?(target) ||
       reified_froms.any? { |from| File.mtime(target) < File.mtime(from) }
      @block.call(target, reified_froms, @args)
    end
  end

  def reify_froms(target)
    match = @target.match(target)

    @froms.map do |from|
      if match.names.empty?
        from.gsub(/\$(\d+)/) {|m| match[m[1..].to_i]}
      else
        from.gsub(/\$#{match.names.join(?|)}/) {|m| match[m[1..]]}
      end
    end
  end

  def self.make!(target = nil)
    print "Making: "
    pp target

    if target.nil?
      target = ARGV.shift
      if target.nil?
        if $default.nil?
          puts "No target given and no default set"
          exit 1
        else
          target = $default
          puts "Using default target: #{target}"
        end
      end
    end

    makes = $makes.select { |make| make.match?(target) }

    if makes.empty?
      puts "No valid target"
    else
      string_makes = makes.select(&:string_target?)
      if string_makes.empty?
        makes.first.try_build(target)
      else
        string_makes.first.try_build(target)
      end
    end
  end
end

def to(target, *froms, **args, &block)
  $makes << Make.new(target, froms, args, block)
end

def default(target)
  $default = target
end