metric_fu 2.1.1 → 2.1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/.gitignore +20 -0
  2. data/.travis.yml +5 -0
  3. data/Gemfile +5 -0
  4. data/HISTORY +21 -1
  5. data/Manifest.txt +25 -0
  6. data/README.md +61 -0
  7. data/Rakefile +15 -9
  8. data/TODO +2 -0
  9. data/bin/metric_fu +4 -0
  10. data/config/roodi_config.yml +22 -0
  11. data/home_page/back_all.jpg +0 -0
  12. data/home_page/churn.gif +0 -0
  13. data/home_page/flay.gif +0 -0
  14. data/home_page/flog.gif +0 -0
  15. data/home_page/footer.gif +0 -0
  16. data/home_page/header.jpg +0 -0
  17. data/home_page/hotspot.gif +0 -0
  18. data/home_page/img09.gif +0 -0
  19. data/home_page/index.html +305 -0
  20. data/home_page/rcov.gif +0 -0
  21. data/home_page/reek.gif +0 -0
  22. data/home_page/roodi.gif +0 -0
  23. data/home_page/saikuro.gif +0 -0
  24. data/home_page/stats.gif +0 -0
  25. data/home_page/styles.css +245 -0
  26. data/home_page/title.gif +0 -0
  27. data/home_page/title_back.gif +0 -0
  28. data/lib/{base/configuration.rb → configuration.rb} +45 -17
  29. data/lib/data_structures/careful_array.rb +9 -0
  30. data/lib/{base → data_structures}/code_issue.rb +17 -16
  31. data/lib/data_structures/grouping.rb +40 -0
  32. data/lib/{base → data_structures}/line_numbers.rb +23 -14
  33. data/lib/{base → data_structures}/location.rb +3 -1
  34. data/lib/{base → data_structures}/ranking.rb +0 -0
  35. data/lib/data_structures/record.rb +43 -0
  36. data/lib/{base → data_structures}/table.rb +6 -2
  37. data/lib/errors/analysis_error.rb +1 -0
  38. data/lib/initial_requires.rb +25 -0
  39. data/lib/load_files.rb +39 -0
  40. data/lib/logging/mf_debugger.rb +24 -0
  41. data/lib/{base/md5_tracker.rb → md5_tracker.rb} +0 -0
  42. data/lib/metric_fu.rb +55 -37
  43. data/lib/{base → metrics}/base_template.rb +47 -16
  44. data/lib/{generators → metrics/churn}/churn.rb +0 -0
  45. data/lib/{base → metrics/churn}/churn_analyzer.rb +0 -0
  46. data/lib/{templates/awesome → metrics/churn/template_awesome}/churn.html.erb +0 -0
  47. data/lib/{templates/standard → metrics/churn/template_standard}/churn.html.erb +0 -0
  48. data/lib/{generators → metrics/flay}/flay.rb +0 -0
  49. data/lib/{base → metrics/flay}/flay_analyzer.rb +0 -0
  50. data/lib/{graphs → metrics/flay}/flay_grapher.rb +0 -0
  51. data/lib/{templates/awesome → metrics/flay/template_awesome}/flay.html.erb +0 -0
  52. data/lib/{templates/standard → metrics/flay/template_standard}/flay.html.erb +0 -0
  53. data/lib/{generators → metrics/flog}/flog.rb +2 -0
  54. data/lib/{base → metrics/flog}/flog_analyzer.rb +0 -0
  55. data/lib/{graphs → metrics/flog}/flog_grapher.rb +0 -0
  56. data/lib/{templates/awesome → metrics/flog/template_awesome}/flog.html.erb +0 -0
  57. data/lib/{templates/standard → metrics/flog/template_standard}/flog.html.erb +0 -0
  58. data/lib/{base → metrics}/generator.rb +0 -0
  59. data/lib/{base → metrics}/graph.rb +0 -0
  60. data/lib/{generators → metrics/hotspots}/hotspots.rb +0 -0
  61. data/lib/{templates/awesome → metrics/hotspots/template_awesome}/hotspots.html.erb +0 -0
  62. data/lib/{templates/standard → metrics/hotspots/template_standard}/hotspots.html.erb +0 -0
  63. data/lib/{base → metrics}/metric_analyzer.rb +4 -80
  64. data/lib/{generators → metrics/rails_best_practices}/rails_best_practices.rb +0 -0
  65. data/lib/{graphs → metrics/rails_best_practices}/rails_best_practices_grapher.rb +0 -0
  66. data/lib/{templates/awesome → metrics/rails_best_practices/template_awesome}/rails_best_practices.html.erb +1 -1
  67. data/lib/{templates/standard → metrics/rails_best_practices/template_standard}/rails_best_practices.html.erb +1 -1
  68. data/lib/{generators → metrics/rcov}/rcov.rb +5 -3
  69. data/lib/{base → metrics/rcov}/rcov_analyzer.rb +1 -1
  70. data/lib/{graphs → metrics/rcov}/rcov_grapher.rb +0 -0
  71. data/lib/{templates/awesome → metrics/rcov/template_awesome}/rcov.html.erb +0 -0
  72. data/lib/{templates/standard → metrics/rcov/template_standard}/rcov.html.erb +0 -0
  73. data/lib/{generators → metrics/reek}/reek.rb +3 -2
  74. data/lib/{base → metrics/reek}/reek_analyzer.rb +1 -0
  75. data/lib/{graphs → metrics/reek}/reek_grapher.rb +0 -0
  76. data/lib/{templates/awesome → metrics/reek/template_awesome}/reek.html.erb +0 -0
  77. data/lib/{templates/standard → metrics/reek/template_standard}/reek.html.erb +0 -0
  78. data/lib/{generators → metrics/roodi}/roodi.rb +0 -0
  79. data/lib/{base → metrics/roodi}/roodi_analyzer.rb +0 -0
  80. data/lib/{graphs → metrics/roodi}/roodi_grapher.rb +0 -0
  81. data/lib/{templates/awesome → metrics/roodi/template_awesome}/roodi.html.erb +0 -0
  82. data/lib/{templates/standard → metrics/roodi/template_standard}/roodi.html.erb +0 -0
  83. data/lib/{generators → metrics/saikuro}/saikuro.rb +4 -2
  84. data/lib/{base → metrics/saikuro}/saikuro_analyzer.rb +0 -0
  85. data/lib/{templates/awesome → metrics/saikuro/template_awesome}/saikuro.html.erb +0 -0
  86. data/lib/{templates/standard → metrics/saikuro/template_standard}/saikuro.html.erb +0 -0
  87. data/lib/{generators → metrics/stats}/stats.rb +0 -0
  88. data/lib/{base → metrics/stats}/stats_analyzer.rb +0 -0
  89. data/lib/{graphs → metrics/stats}/stats_grapher.rb +0 -0
  90. data/lib/{templates/awesome → metrics/stats/template_awesome}/stats.html.erb +0 -0
  91. data/lib/{templates/standard → metrics/stats/template_standard}/stats.html.erb +0 -0
  92. data/lib/{graphs → reporting/graphs}/engines/bluff.rb +0 -0
  93. data/lib/{graphs → reporting/graphs}/engines/gchart.rb +0 -0
  94. data/lib/{graphs → reporting/graphs}/grapher.rb +0 -0
  95. data/lib/{base → reporting}/report.rb +2 -0
  96. data/lib/{templates → reporting/templates}/awesome/awesome_template.rb +28 -7
  97. data/lib/{templates → reporting/templates}/awesome/css/buttons.css +0 -0
  98. data/lib/{templates → reporting/templates}/awesome/css/default.css +0 -0
  99. data/lib/{templates → reporting/templates}/awesome/css/integrity.css +0 -0
  100. data/lib/{templates → reporting/templates}/awesome/css/reset.css +0 -0
  101. data/lib/{templates → reporting/templates}/awesome/css/syntax.css +0 -0
  102. data/lib/{templates → reporting/templates}/awesome/index.html.erb +0 -0
  103. data/lib/{templates → reporting/templates}/awesome/layout.html.erb +0 -0
  104. data/lib/{templates → reporting/templates}/javascripts/bluff-min.js +0 -0
  105. data/lib/{templates → reporting/templates}/javascripts/excanvas.js +0 -0
  106. data/lib/{templates → reporting/templates}/javascripts/js-class.js +0 -0
  107. data/lib/{templates → reporting/templates}/standard/default.css +0 -0
  108. data/lib/{templates → reporting/templates}/standard/index.html.erb +0 -0
  109. data/lib/{templates → reporting/templates}/standard/standard_template.rb +3 -3
  110. data/lib/{base/scoring_strategies.rb → scoring_strategies.rb} +0 -0
  111. data/lib/tasks/metric_fu.rake +36 -0
  112. data/lib/version.rb +3 -0
  113. data/metric_fu.gemspec +65 -0
  114. data/spec/base/base_template_spec.rb +19 -2
  115. data/spec/base/configuration_spec.rb +4 -3
  116. data/spec/base/generator_spec.rb +2 -2
  117. data/spec/base/line_numbers_spec.rb +2 -2
  118. data/spec/base/location_spec.rb +127 -0
  119. data/spec/base/metric_analyzer_spec.rb +452 -0
  120. data/spec/base/ranking_spec.rb +42 -0
  121. data/spec/base/report_spec.rb +1 -1
  122. data/spec/base/table_spec.rb +36 -0
  123. data/spec/generators/hotspots_spec.rb +88 -0
  124. data/spec/generators/rails_best_practices_spec.rb +1 -1
  125. data/spec/generators/rcov_spec.rb +3 -3
  126. data/spec/generators/stats_spec.rb +1 -1
  127. data/spec/spec_helper.rb +4 -1
  128. metadata +466 -309
  129. data/README +0 -29
  130. data/tasks/metric_fu.rake +0 -22
@@ -2,21 +2,27 @@ require 'ruby_parser'
2
2
  module MetricFu
3
3
  class LineNumbers
4
4
 
5
- def initialize(contents)
6
- rp = RubyParser.new
7
- @locations = {}
8
- file_sexp = rp.parse(contents)
9
- case file_sexp[0]
10
- when :class
11
- process_class(file_sexp)
12
- when :module
13
- process_module(file_sexp)
14
- when :block
15
- file_sexp.each_of_type(:class) { |sexp| process_class(sexp) }
5
+ def initialize(contents,file_path='')
6
+ if contents.to_s.size.zero?
7
+ puts "NON PARSEABLE INPUT: File is empty at path #{file_path.inspect}\n\t#{caller.join("\n\t")}"
16
8
  else
9
+ rp = RubyParser.new
10
+ @locations = {}
11
+ file_sexp = rp.parse(contents)
12
+ case file_sexp[0]
13
+ when :class
14
+ process_class(file_sexp)
15
+ when :module
16
+ process_module(file_sexp)
17
+ when :block
18
+ file_sexp.each_of_type(:class) { |sexp| process_class(sexp) }
19
+ else
20
+ puts "Unexpected sexp_type #{file_sexp[0].inspect}"
21
+ end
17
22
  end
18
- rescue Exception
23
+ rescue Exception => e
19
24
  #catch errors for files ruby_parser fails on
25
+ puts "RUBY PARSE FAILURE: #{e.class}\t#{e.message}\tCONTENT:#{contents.inspect}\SEXP:#{file_sexp.inspect}\tn#{e.backtrace}"
20
26
  @locations
21
27
  end
22
28
 
@@ -30,8 +36,11 @@ module MetricFu
30
36
  found_method_and_range = @locations.detect do |method_name, line_number_range|
31
37
  line_number_range.include?(line_number)
32
38
  end
33
- return nil unless found_method_and_range
34
- found_method_and_range.first
39
+ if found_method_and_range
40
+ found_method_and_range.first
41
+ else
42
+ nil
43
+ end
35
44
  end
36
45
 
37
46
  def start_line_for_method(method)
@@ -31,7 +31,9 @@ module MetricFu
31
31
 
32
32
  # TODO - we need this method (and hash accessor above) as a temporary hack where we're using Location as a hash key
33
33
  def eql?(other)
34
- [self.file_path.to_s, self.class_name.to_s, self.method_name.to_s] == [other.file_path.to_s, other.class_name.to_s, other.method_name.to_s]
34
+ # REMOVED per https://github.com/jscruggs/metric_fu/pull/67/files
35
+ # [self.file_path.to_s, self.class_name.to_s, self.method_name.to_s] == [other.file_path.to_s, other.class_name.to_s, other.method_name.to_s]
36
+ @hash == other.hash
35
37
  end
36
38
  # END we need these methods as a temporary hack where we're using Location as a hash key
37
39
 
File without changes
@@ -0,0 +1,43 @@
1
+ module MetricFu
2
+ class Record
3
+
4
+ attr_reader :data
5
+
6
+ def initialize(data, columns)
7
+ @data = data
8
+ @columns = columns
9
+ end
10
+
11
+ def method_missing(name, *args, &block)
12
+ key = name.to_s
13
+ if @data.has_key?(key)
14
+ @data[key]
15
+ elsif @columns.member?(key)
16
+ nil
17
+ else
18
+ super(name, *args, &block)
19
+ end
20
+ end
21
+
22
+ def []=(key, value)
23
+ @data[key]=value
24
+ end
25
+
26
+ def [](key)
27
+ @data[key]
28
+ end
29
+
30
+ def keys
31
+ @data.keys
32
+ end
33
+
34
+ def has_key?(key)
35
+ @data.has_key?(key)
36
+ end
37
+
38
+ def attributes
39
+ @columns
40
+ end
41
+
42
+ end
43
+ end
@@ -1,3 +1,7 @@
1
+ %w(record).each do |path|
2
+ MetricFu.data_structures_require { path }
3
+ end
4
+
1
5
  class Table
2
6
 
3
7
  def initialize(opts = {})
@@ -10,10 +14,10 @@ class Table
10
14
 
11
15
  def <<(row)
12
16
  record = nil
13
- if row.is_a?(Record) || row.is_a?(CodeIssue)
17
+ if row.is_a?(MetricFu::Record) || row.is_a?(CodeIssue)
14
18
  record = row
15
19
  else
16
- record = Record.new(row, @columns)
20
+ record = MetricFu::Record.new(row, @columns)
17
21
  end
18
22
  @rows << record
19
23
  updated_key_index(record) if @make_index
@@ -0,0 +1 @@
1
+ class AnalysisError < RuntimeError; end;
@@ -0,0 +1,25 @@
1
+ require 'rake'
2
+ require 'yaml'
3
+ begin
4
+ require 'psych'
5
+ YAML::ENGINE.yamler = 'syck'
6
+ rescue LoadError
7
+ #nothing to report
8
+ end
9
+ # def with_syck(&block)
10
+ # current_engine = YAML::ENGINE.yamler
11
+ # YAML::ENGINE.yamler = 'syck'
12
+ # block.call
13
+ # YAML::ENGINE.yamler = current_engine
14
+ # end
15
+ begin
16
+ require 'active_support'
17
+ require 'active_support/core_ext/object/to_json'
18
+ require 'active_support/core_ext/object/blank'
19
+ require 'active_support/inflector'
20
+ rescue LoadError
21
+ require 'activesupport' unless defined?(ActiveSupport)
22
+ end
23
+ MetricFu.logging_require { 'mf_debugger' }
24
+ include MfDebugger
25
+ MfDebugger::Logger.debug_on = !!(ENV['MF_DEBUG'] =~ /true/i)
data/lib/load_files.rb ADDED
@@ -0,0 +1,39 @@
1
+ # require these first because others depend on them
2
+ MetricFu.reporting_require { 'report' }
3
+ MetricFu.metrics_require { 'generator' }
4
+ MetricFu.metrics_require { 'graph' }
5
+ MetricFu.reporting_require { 'graphs/grapher' }
6
+ MetricFu.lib_require { 'scoring_strategies' }
7
+
8
+ # prevent the task from being run multiple times.
9
+ unless Rake::Task.task_defined? "metrics:all"
10
+ # Load the rakefile so users of the gem get the default metric_fu task
11
+ MetricFu.tasks_load 'metric_fu.rake'
12
+ end
13
+
14
+ # Now load everything else that's in the directory
15
+ Dir.glob(File.join(MetricFu.lib_dir, '*.rb')).each do |file|
16
+ require file
17
+ end
18
+ Dir.glob(File.join(MetricFu.data_structures_dir, '**/*.rb')).each do |file|
19
+ require file
20
+ end
21
+ Dir.glob(File.join(MetricFu.logging_dir, '**/*.rb')).each do |file|
22
+ require file
23
+ end
24
+ Dir.glob(File.join(MetricFu.errors_dir, '**/*.rb')).each do |file|
25
+ require file
26
+ end
27
+ Dir.glob(File.join(MetricFu.metrics_dir, '**/*.rb')).each do |file|
28
+ require file
29
+ end
30
+ Dir.glob(File.join(MetricFu.reporting_dir, '**/*.rb')).each do |file|
31
+ require file
32
+ end
33
+ # Dir[File.expand_path File.join(base_dir, '*.rb')].each{|l| require l }
34
+ # Dir[File.expand_path File.join(generator_dir, '*.rb')].each {|l| require l }
35
+ # Dir[File.expand_path File.join(template_dir, 'standard/*.rb')].each {|l| require l}
36
+ # Dir[File.expand_path File.join(template_dir, 'awesome/*.rb')].each {|l| require l}
37
+ # require graph_dir + "/grapher"
38
+ # Dir[File.expand_path File.join(graph_dir, '*.rb')].each {|l| require l}
39
+ # Dir[File.expand_path File.join(graph_dir, 'engines', '*.rb')].each {|l| require l}
@@ -0,0 +1,24 @@
1
+ module MfDebugger
2
+ class Logger
3
+ class << self
4
+ attr_accessor :debug_on
5
+ @debug_on = false
6
+ end
7
+ end
8
+
9
+ def self.mf_debug(msg,&block)
10
+ if MfDebugger::Logger.debug_on
11
+ if block_given?
12
+ block.call
13
+ end
14
+ STDOUT.puts msg
15
+ end
16
+ end
17
+ def mf_debug(msg,&block)
18
+ if block_given?
19
+ MfDebugger.mf_debug(msg,&block)
20
+ else
21
+ MfDebugger.mf_debug(msg)
22
+ end
23
+ end
24
+ end
File without changes
data/lib/metric_fu.rb CHANGED
@@ -1,40 +1,58 @@
1
- require 'rake'
2
- require 'yaml'
3
- begin
4
- require 'active_support/core_ext/object/to_json'
5
- require 'active_support/core_ext/object/blank'
6
- require 'active_support/inflector'
7
- rescue LoadError
8
- require 'activesupport'
9
- end
10
-
11
- # Load a few things to make our lives easier elsewhere.
12
1
  module MetricFu
13
- LIB_ROOT = File.dirname(__FILE__)
14
- end
15
- base_dir = File.join(MetricFu::LIB_ROOT, 'base')
16
- generator_dir = File.join(MetricFu::LIB_ROOT, 'generators')
17
- template_dir = File.join(MetricFu::LIB_ROOT, 'templates')
18
- graph_dir = File.join(MetricFu::LIB_ROOT, 'graphs')
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__),'..'))
3
+ LIB_ROOT = File.join(APP_ROOT,'lib')
4
+ @loaded_files = []
5
+ class << self
6
+ attr_reader :loaded_files
7
+ end
8
+ def self.lib_require(base='',&block)
9
+ paths = []
10
+ base_path = File.join(LIB_ROOT, base)
11
+ Array((yield paths, base_path)).each do |path|
12
+ file = File.join(base_path, *Array(path))
13
+ require file
14
+ if @loaded_files.include?(file)
15
+ puts "!!!\tAlready loaded #{file}" if !!(ENV['MF_DEBUG'] =~ /true/i)
16
+ else
17
+ @loaded_files << file
18
+ end
19
+ end
20
+ end
21
+ def self.root_dir
22
+ APP_ROOT
23
+ end
24
+ def self.lib_dir
25
+ LIB_ROOT
26
+ end
27
+ class << self
28
+ %w(metrics reporting logging errors data_structures tasks).each do |dir|
29
+ define_method("#{dir}_dir") do
30
+ File.join(lib_dir,dir)
31
+ end
32
+ module_eval(%Q(def #{dir}_require(&block); lib_require('#{dir}', &block); end))
33
+ end
34
+ end
35
+ def self.tasks_load(tasks_relative_path)
36
+ load File.join(LIB_ROOT, 'tasks', *Array(tasks_relative_path))
37
+ end
38
+ # path is relative to where the task is being run,
39
+ # not to the metric_fu library
40
+ def self.artifact_dir
41
+ (ENV['CC_BUILD_ARTIFACTS'] || 'tmp/metric_fu')
42
+ end
43
+ class << self
44
+ %w(scratch output _data).each do |dir|
45
+ define_method("#{dir.gsub(/[^A-Za-z0-9]/,'')}_dir") do
46
+ File.join(artifact_dir,dir)
47
+ end
48
+ end
19
49
 
20
- # We need to require these two things first because our other classes
21
- # depend on them.
22
- require File.join(base_dir, 'report')
23
- require File.join(base_dir, 'generator')
24
- require File.join(base_dir, 'graph')
25
- require File.join(base_dir, 'scoring_strategies')
26
-
27
- # prevent the task from being run multiple times.
28
- unless Rake::Task.task_defined? "metrics:all"
29
- # Load the rakefile so users of the gem get the default metric_fu task
30
- load File.join(MetricFu::LIB_ROOT, '..', 'tasks', 'metric_fu.rake')
50
+ end
51
+ # def const_missing(name)
52
+ #
53
+ # end
31
54
  end
32
-
33
- # Now load everything else that's in the directory
34
- Dir[File.join(base_dir, '*.rb')].each{|l| require l }
35
- Dir[File.join(generator_dir, '*.rb')].each {|l| require l }
36
- Dir[File.join(template_dir, 'standard/*.rb')].each {|l| require l}
37
- Dir[File.join(template_dir, 'awesome/*.rb')].each {|l| require l}
38
- require graph_dir + "/grapher"
39
- Dir[File.join(graph_dir, '*.rb')].each {|l| require l}
40
- Dir[File.join(graph_dir, 'engines', '*.rb')].each {|l| require l}
55
+ MetricFu.lib_require { 'version' }
56
+ MetricFu.lib_require { 'initial_requires' }
57
+ # Load a few things to make our lives easier elsewhere.
58
+ MetricFu.lib_require { 'load_files' }
@@ -1,3 +1,5 @@
1
+ require 'pathname'
2
+ require 'erb'
1
3
  module MetricFu
2
4
 
3
5
  # The Template class is intended as an abstract class for concrete
@@ -19,23 +21,10 @@ module MetricFu
19
21
  # @return String
20
22
  # The erb evaluated string
21
23
  def erbify(section)
22
- require 'erb'
23
24
  erb_doc = File.read(template(section))
24
25
  ERB.new(erb_doc).result(binding)
25
26
  end
26
27
 
27
- # Determines whether a template file exists for a given section
28
- # of the full template.
29
- #
30
- # @param section String
31
- # The section of the template to check against
32
- #
33
- # @return Boolean
34
- # Does a template file exist for this section or not?
35
- def template_exists?(section)
36
- File.exist?(template(section))
37
- end
38
-
39
28
  # Copies an instance variable mimicing the name of the section
40
29
  # we are trying to render, with a value equal to the passed in
41
30
  # constant. Allows the concrete template classes to refer to
@@ -61,7 +50,31 @@ module MetricFu
61
50
  # @return String
62
51
  # A file path
63
52
  def template(section)
64
- File.join(this_directory, section.to_s + ".html.erb")
53
+ if MetricFu::AVAILABLE_METRICS.include?(section) # expects a symbol
54
+ File.join(template_dir(section.to_s), "#{section}.html.erb")
55
+ else
56
+ File.join(template_directory, section.to_s + ".html.erb")
57
+ end
58
+ end
59
+ def template_dir(metric)
60
+ File.join(MetricFu.metrics_dir, metric, metric_template_dir)
61
+ end
62
+ # e.g. template_awesome, template_standard
63
+ def metric_template_dir
64
+ template_name = self.class.name.sub('Template', '')[/^([A-Z][a-z]+)+/].downcase
65
+ "template_#{template_name}"
66
+ end
67
+
68
+ # Determines whether a template file exists for a given section
69
+ # of the full template.
70
+ #
71
+ # @param section String
72
+ # The section of the template to check against
73
+ #
74
+ # @return Boolean
75
+ # Does a template file exist for this section or not?
76
+ def template_exists?(section)
77
+ File.exist?(template(section))
65
78
  end
66
79
 
67
80
  # Returns the filename that the template will render into for
@@ -85,7 +98,7 @@ module MetricFu
85
98
  # @return String
86
99
  # The contents of the css file
87
100
  def inline_css(css)
88
- open(File.join(this_directory, css)) { |f| f.read }
101
+ open(File.join(template_directory, css)) { |f| f.read }
89
102
  end
90
103
 
91
104
  # Provides a link to open a file through the textmate protocol
@@ -137,8 +150,13 @@ module MetricFu
137
150
  def file_url(name, line) # :nodoc:
138
151
  return '' unless name
139
152
  filename = File.expand_path(name.gsub(/^\//, ''))
140
- if render_as_txmt_protocol?
153
+ link_prefix = MetricFu.configuration.link_prefix
154
+ if link_prefix
155
+ "#{link_prefix}/#{name.gsub(/:.*$/, '')}"
156
+ elsif render_as_txmt_protocol?
141
157
  "txmt://open/?url=file://#{filename}" << (line ? "&line=#{line}" : "")
158
+ # elsif render_as_mvim_protocol?
159
+ # "mvim://open/?url=file://#{filename}" << (line ? "&line=#{line}" : "")
142
160
  else
143
161
  "file://#{filename}"
144
162
  end
@@ -149,6 +167,11 @@ module MetricFu
149
167
  return false unless config.platform.include?('darwin')
150
168
  return !config.darwin_txmt_protocol_no_thanks
151
169
  end
170
+ def render_as_mvim_protocol? # :nodoc:
171
+ config = MetricFu.configuration
172
+ return false unless config.platform.include?('darwin')
173
+ return !config.darwin_mvim_protocol_no_thanks
174
+ end
152
175
 
153
176
  # Provides a brain dead way to cycle between two values during
154
177
  # an iteration of some sort. Pass in the first_value, the second_value,
@@ -168,5 +191,13 @@ module MetricFu
168
191
  return first_value if iteration % 2 == 0
169
192
  return second_value
170
193
  end
194
+ # belive me, I tried to meta program this with an inherited hook
195
+ # I couldn't get it working
196
+ def template_directory
197
+ raise "you need to define this method in each subclass with File.dirname(__FILE__)"
198
+ # def template_directory
199
+ # File.dirname(__FILE__)
200
+ # end
201
+ end
171
202
  end
172
203
  end
File without changes
File without changes