File: Rakefile

package info (click to toggle)
ruby-immutable-ruby 0.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,852 kB
  • sloc: ruby: 16,556; makefile: 4
file content (112 lines) | stat: -rw-r--r-- 3,012 bytes parent folder | download
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env rake
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'yard'
require 'pathname'

IMMUTABLE_ROOT = Pathname.new(__FILE__).dirname

desc 'Run all the tests in spec/'
RSpec::Core::RakeTask.new(:spec) do |config|
  config.verbose = false
end

desc 'Generate all of the docs'
YARD::Rake::YardocTask.new do |config|
  config.files = Dir['lib/**/*.rb']
end

def bench_suites
  Dir[IMMUTABLE_ROOT.join('bench/*')].map(&method(:Pathname)).select(&:directory?)
end

def bench_files(suite)
  Dir[File.join(suite, '/**/*.rb')].map(&method(:Pathname))
end

def bench_task_name(file_name)
  file_name.relative_path_from(IMMUTABLE_ROOT).sub(/\_bench.rb$/, '').to_s.tr('/', ':')
end

bench_suites.each do |suite|
  bench_files(suite).each do |bench_file|
    name = bench_task_name(bench_file)

    desc "Benchmark #{name}"
    task name do
      begin
        $LOAD_PATH.unshift IMMUTABLE_ROOT.join('lib')
        load bench_file
      rescue LoadError => e
        if e.message == /benchmark\/ips/
          $stderr.puts 'Please install the benchmark-ips gem'
        else
          $stderr.puts e
        end
        exit 69
      end
    end
  end

  desc "Benchmark #{bench_task_name(suite)}"
  task bench_task_name(suite) => bench_files(suite).map(&method(:bench_task_name))
end

desc 'Run all benchmarks'
task bench: bench_suites.map(&method(:bench_task_name))

desc 'Generate file dependency graph'
task :dependency_graph do
  if `which dot`.empty?
    raise 'dot is not installed or not on your system path'
  end

  dependencies = Hash.new { |h,k| h[k] = Set.new }
  trim_fn = ->(fn) { fn.sub(/^lib\//, '').sub(/\.rb$/, '') }

  Dir['lib/**/*.rb'].each do |path|
    File.readlines(path).each do |line|
      if line =~ /^\s*require\s+('|")([^'"]*)('|")/
         dependency = $2
         dependencies[trim_fn[path]] << dependency
      end
    end
  end

  require 'set'
  cycles    = Set.new
  reachable = Hash.new { |h,k| h[k] = Set.new }
  find_reachable = ->(from, to, pathsofar) do
    to.each do |t|
      if t == from
        reachable[from].add(t)
        pathsofar.push(t).each_cons(2) { |vector| cycles << vector }
      elsif reachable[from].add?(t) && dependencies.key?(t)
        find_reachable[from, dependencies[t], pathsofar.dup.push(t)]
      end
    end
  end
  dependencies.each { |from,to| find_reachable[from,to,[from]] }

  dot = %|digraph { graph [label="Immutable srcfile dependencies"]\n|
  dependencies.each do |from,to|
    dot << %|"#{from}" [color=red]\n| if reachable[from].include?(from)
    to.each do |t|
      dot << %|"#{from}" -> "#{t}" #{'[color=red]' if cycles.include?([from,t])}\n|
    end
  end
  dot << "\n}"

  require 'tempfile'
  Tempfile.open('immutable-depgraph') do |f|
    f.write(dot)
    f.flush
    message = `dot -Tgif #{f.path} -o depgraph.gif`
    f.unlink
    puts message unless message.empty?
    puts 'Dependency graph is in depgraph.gif'
  end
end

desc 'Default: run tests and generate docs'
task default: [ :spec, :yard ]