sass-prof 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3a7b66c13e0f95d8d4bb9f8ca928986b6ef4fdc
4
- data.tar.gz: 2e1448e78d71372901d3903fc074e55fbf34f4fb
3
+ metadata.gz: 082e6bb8340e42960e64ca08611143d7674c3eb9
4
+ data.tar.gz: d09299a30a5afa8c6135a2720ce555f80f427663
5
5
  SHA512:
6
- metadata.gz: 063bbc7b1336ea3c2522c7083b5ed0d06f7edd13b45b264851699e70353cee38f46671af5a6d404bc9d00f1ded01284ee1b20741874f0f7aa643749e8c0592db
7
- data.tar.gz: b39122ed3ea99174aee1d0d48602ed6b55f973d40d015be155351ab672a1dc85d5deae99042814035bbb0bbeaa017a869d086d07e3c572bbfc46cd60d090885f
6
+ metadata.gz: 493f298da828e6533cd86bbe7a24b9b5667ecfca8a1e7760f764b424dd69daf7dd055bb64caca7778a54d5292e2070e9828a6e0221162f00c93aa36c3c9a69eb
7
+ data.tar.gz: 74a7821bd4ac37cbcc0789884bf534034ad7cf3aac55247173f0257f98d73e804ede70888072eba9e6f86f9485f991fdc3f2d69463505519eb407ad2100e586b
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ *.log
1
2
  .sass-cache/
2
3
  /spec/stylesheets/
3
4
  /.bundle/
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in sass-prof.gemspec
4
3
  gemspec
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  [![Gem](https://img.shields.io/gem/v/sass-prof.svg?style=flat-square)](https://rubygems.org/gems/sass-prof)
4
4
 
5
+ ![Sass Prof](screenshot.jpg)
6
+
5
7
  Sass Prof is a code profiler for [Sass](https://github.com/sass/sass). For each function, Sass Prof will show the execution time for the function, which file called it and what arguments were given when the function was called.
6
8
 
7
9
  ## Requirements
@@ -31,9 +33,9 @@ prof = Sass::Prof::Config
31
33
  # Default is `false`
32
34
  prof.output_file = "sass-prof.log"
33
35
 
34
- # Adjust output table column width
35
- # Default is `20`
36
- prof.col_width = 40
36
+ # Adjust max column width
37
+ # Default is `false`
38
+ prof.max_width = 40
37
39
 
38
40
  # Mutes all output to stdout
39
41
  # Default is `false`
@@ -43,9 +45,16 @@ prof.quiet = true
43
45
  # Default is `100`
44
46
  prof.t_max = 500
45
47
 
48
+ # Alias for `t_max`
49
+ prof.max_execution_time = 15
50
+
46
51
  # Enable colored output
47
52
  # Default is `true`
48
53
  prof.color = true
54
+
55
+ # Execution time precision
56
+ # Default is `15`
57
+ prof.precision = 5
49
58
  ```
50
59
 
51
60
  _Please note: your compile times **will be slower** due to the overhead of **Sass Prof**. This library was created to help you find potential bottlenecks within your code. If you find any bugs or inconsistencies, please file an [issue](https://github.com/ezekg/sass-prof/issues) or [pull request](https://github.com/ezekg/sass-prof/pulls)._
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sass
4
4
  module Prof
5
- VERSION = "0.2.1"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
data/lib/sass-prof.rb CHANGED
@@ -1,66 +1,124 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require "terminal-table"
4
+
3
5
  module Sass
4
6
  module Prof
5
7
 
6
8
  module Config
7
- attr_accessor :t_max, :col_width, :output_file, :quiet, :color
9
+ attr_accessor :t_max
10
+ attr_accessor :max_width
11
+ attr_accessor :output_file
12
+ attr_accessor :quiet
13
+ attr_accessor :color
14
+ attr_accessor :precision
15
+
16
+ alias_method :max_execution_time=, :t_max=
17
+ alias_method :max_execution_time, :t_max
8
18
 
9
19
  @t_max = 100
10
- @col_width = 20
20
+ @max_width = false
11
21
  @output_file = false
12
22
  @quiet = false
13
23
  @color = true
24
+ @precision = 15
14
25
 
15
26
  extend self
16
27
  end
17
28
 
18
29
  module Report
19
- attr_accessor :report
30
+ attr_accessor :rows
20
31
 
21
- @report = [
22
- ["File", "Execution Time", "Action", "Signature"]
23
- ]
32
+ @rows = []
24
33
 
25
- def add(value)
26
- @report << value
34
+ def add_row(row)
35
+ row = Prof::Formatter.truncate_row row if Prof::Config.max_width
36
+ @rows << row
37
+ end
38
+
39
+ def reset_report
40
+ @rows = []
27
41
  end
28
42
 
29
43
  def print_report
30
- puts to_table @report
44
+ log_report if Prof::Config.output_file
45
+ puts Prof::Formatter.to_table @rows
31
46
  end
32
47
 
33
- def reset_report
34
- @report = [
35
- ["File", "Execution Time", "Action", "Signature"]
36
- ]
48
+ def log_report
49
+ File.open(Prof::Config.output_file, "a+") do |f|
50
+ f.puts Prof::Formatter.to_table @rows.map { |r|
51
+ r.map { |col| col.gsub /\e\[(\d+)(;\d+)*m/, "" } }
52
+ end
53
+ end
54
+
55
+ extend self
56
+ end
57
+
58
+ module Formatter
59
+
60
+ def colorize(string, color)
61
+ return string.to_s unless Prof::Config.color
62
+
63
+ colors = Hash.new("37").merge({
64
+ :black => "30",
65
+ :red => "31",
66
+ :green => "32",
67
+ :yellow => "33",
68
+ :blue => "34",
69
+ :purple => "35",
70
+ :cyan => "36",
71
+ :white => "37",
72
+ })
73
+
74
+ "\e[0;#{colors.fetch(color)}m#{string}\e[0m"
37
75
  end
38
76
 
39
- def to_table(report)
40
- return unless report
77
+ def to_table(rows)
78
+ t_total_in_seconds = rows.map { |c|
79
+ c[1].gsub(/\e\[(\d+)(;\d+)*m/, "").to_f }.reduce(:+) / 1000 % 60
41
80
 
42
- table = report.map do |row|
43
- "[ %s ]" % row.map { |col|
44
- diff = col.length - col.gsub(/\e\[(\d+)(;\d+)*m/, "").length
45
- "%-#{Sass::Prof::Config.col_width + diff}s" % col }.join(" | ")
81
+ # Add total execution time footer
82
+ rows << :separator
83
+ rows << ["Total Execution Time", t_total_in_seconds]
84
+
85
+ table = Terminal::Table.new({
86
+ :headings => ["File", "Execution Time", "Action", "Signature"],
87
+ :rows => rows
88
+ })
89
+
90
+ table
91
+ end
92
+
93
+ def truncate_row(row)
94
+ max_width = Prof::Config.max_width
95
+ tr_row = []
96
+
97
+ row.map do |col|
98
+ clean_width = col.gsub(/\e\[(\d+)(;\d+)*m/, "").length
99
+ diff = col.length - clean_width
100
+
101
+ if clean_width > max_width
102
+ tr_row << (col[0..max_width + diff] << "\e[0m...")
103
+ else
104
+ tr_row << col
105
+ end
46
106
  end
47
107
 
48
- table.join "\n"
108
+ tr_row
49
109
  end
50
110
 
51
111
  extend self
52
112
  end
53
113
 
54
114
  class Profiler
55
- attr_accessor :config, :function, :action, :args, :env
115
+ attr_accessor :function, :action, :args, :env
56
116
 
57
117
  @@t_total = 0
58
118
  @@t_then = 0
59
119
  @@t_now = 0
60
120
 
61
121
  def initialize(function, action, args = nil, env = nil)
62
- @config = Sass::Prof::Config
63
- @report = Sass::Prof::Report
64
122
  @function = function
65
123
  @action = action
66
124
  @args = args
@@ -76,34 +134,28 @@ module Sass
76
134
  t_delta = (@@t_now.to_f - @@t_then.to_f) * 1000.0
77
135
  @@t_then, @@t_total = @@t_now, t_delta
78
136
 
79
- prep_fn_report
137
+ create_fn_report
80
138
  end
81
139
 
82
140
  private
83
141
 
84
- def prep_fn_report
142
+ def create_fn_report
85
143
  fn_report = [fn_source, fn_execution_time, fn_action,
86
144
  fn_signature]
87
145
 
88
- @report.add fn_report unless config.quiet
89
-
90
- if config.output_file
91
- File.open(config.output_file, "a+") do |f|
92
- f.puts @report.to_table [fn_report.map { |col|
93
- col.gsub /\e\[(\d+)(;\d+)*m/, "" }]
94
- end
95
- end
146
+ Prof::Report.add_row fn_report unless Prof::Config.quiet
96
147
 
97
- if @@t_total > config.t_max && action == :execute
98
- raise RuntimeError.new colorize(
99
- "Max execution time of #{config.t_max}ms reached for function"\
100
- " `#{fn_name}` (took #{@@t_total.round(3)}ms)", :red)
148
+ if @@t_total > Prof::Config.t_max && action == :execute
149
+ raise RuntimeError.new Prof::Formatter.colorize(
150
+ "Max execution time of #{Prof::Config.t_max}ms reached for function"\
151
+ " `#{fn_name}()` (took #{@@t_total.round(3)}ms)", :red)
101
152
  end
102
153
  end
103
154
 
104
155
  def fn_execution_time
105
- color = @@t_total > config.t_max ? :red : :green
106
- colorize @@t_total.to_s, color
156
+ color = @@t_total > Prof::Config.t_max ? :red : :green
157
+ Prof::Formatter.colorize @@t_total.round(
158
+ Prof::Config.precision).to_s, color
107
159
  end
108
160
 
109
161
  def fn_name
@@ -126,47 +178,32 @@ module Sass
126
178
  end
127
179
 
128
180
  def fn_source
129
- return colorize("Unknown file", :red) unless env
181
+ return Prof::Formatter.colorize("Unknown file", :red) unless env
130
182
 
131
183
  orig_filename = env.options.fetch :original_filename, "Unknown file"
132
184
  filename = env.options.fetch :filename, "Unknown file"
133
185
 
134
- colorize "#{File.basename(orig_filename)}:#{File.basename(filename)}",
135
- :yellow
186
+ Prof::Formatter.colorize "#{File.basename(orig_filename)}:"\
187
+ "#{File.basename(filename)}", :yellow
136
188
  end
137
189
 
138
190
  def fn_action
139
- colorize action.to_s, :yellow
191
+ Prof::Formatter.colorize action.capitalize, :yellow
140
192
  end
141
193
 
142
194
  def fn_signature
143
- colorize(fn_name, :blue) << "(" << colorize(fn_args, :purple) << ")"
144
- end
145
-
146
- def colorize(string, color)
147
- return string unless config.color
148
-
149
- colors = Hash.new("37").merge({
150
- :black => "30",
151
- :red => "31",
152
- :green => "32",
153
- :yellow => "33",
154
- :blue => "34",
155
- :purple => "35",
156
- :cyan => "36",
157
- :white => "37",
158
- })
159
-
160
- "\e[0;#{colors.fetch(color)}m#{string}\e[0m"
195
+ "#{Prof::Formatter.colorize(fn_name, :blue)}"\
196
+ "(#{Prof::Formatter.colorize(fn_args, :purple)})"
161
197
  end
162
198
  end
163
199
  end
164
200
 
201
+ # Monkey patch Sass to utilize Profiler
165
202
  class Tree::Visitors::Perform
166
203
  alias_method :__visit_function, :visit_function
167
204
 
168
205
  def visit_function(node)
169
- prof = Sass::Prof::Profiler.new(node.dup, :allocate)
206
+ prof = Prof::Profiler.new(node.dup, :allocate)
170
207
  prof.start
171
208
 
172
209
  value = __visit_function node
@@ -181,7 +218,7 @@ module Sass
181
218
  alias_method :__perform_sass_fn, :perform_sass_fn
182
219
 
183
220
  def perform_sass_fn(function, args, splat, environment)
184
- prof = Sass::Prof::Profiler.new(function.dup, :execute, args.dup,
221
+ prof = Prof::Profiler.new(function.dup, :execute, args.dup,
185
222
  environment.dup)
186
223
  prof.start
187
224
 
data/sass-prof.gemspec CHANGED
@@ -21,6 +21,8 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_development_dependency "compass", "~> 1.0"
23
23
  spec.add_development_dependency "bundler", "~> 1.9"
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_dependency "sass", "~> 3.4"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+
26
+ spec.add_dependency "terminal-table", "~> 1.5"
27
+ spec.add_dependency "sass", "~> 3.4"
26
28
  end
data/screenshot.jpg ADDED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ezekg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-21 00:00:00.000000000 Z
11
+ date: 2015-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: compass
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: terminal-table
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: sass
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -83,6 +97,7 @@ files:
83
97
  - lib/sass-prof.rb
84
98
  - lib/sass-prof/version.rb
85
99
  - sass-prof.gemspec
100
+ - screenshot.jpg
86
101
  homepage: https://github.com/ezekg/sass-prof
87
102
  licenses:
88
103
  - MIT