style_stats 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7780214f096be1c28f03ea84b95e7d74bea2eedf
4
- data.tar.gz: 47a4b0a89188167f8612ba5dce3840f5c6f67120
3
+ metadata.gz: b9e2bb1732c0e4cdc94c37b106056de61bb4ba31
4
+ data.tar.gz: f48c01ac18fe8dd45dddce5484a196efd0908c9f
5
5
  SHA512:
6
- metadata.gz: 283051e8c0e4bbfc685de1c807be32f3bbadb2a4d2a0152cad6932fd424de9e9633efc85953be091dcbbc72593a4ef336b1ec148bb83808e741c3279c50a59b6
7
- data.tar.gz: 28adf7e15f5089a6ecc3ef7fd0924c68301d995c2f219ee5cf79f6801ab1c6d2747144561185d8645c3bb5f6c21c97867ba343c30d865e70df424ac6f6296f5e
6
+ metadata.gz: 0d22610c40f6a56429988720e4799dac8b7dbff11bdb2003a4e8ff1c74b4d7c1a3ac9f20caaf9a42de392f2b6bd91c9f1a03f3bdf858ab0e1a484220905082c6
7
+ data.tar.gz: 628ce17c2809742c77557c706ec86a8bd120de9aa14a0b6ee5eb02ea847e4700b7a0425a7853eb70461f13017b410cab2747c02c2c9f2f03f6cff970a9df8fd1
data/README.md CHANGED
@@ -131,6 +131,37 @@ $ style_stats http://example.com/
131
131
  $ style_stats foo.css -f <json|html|md>
132
132
  ```
133
133
 
134
+ :## CLI Reference
135
+
136
+ Help:
137
+
138
+ ```shell
139
+ $ style_stats --help
140
+ Usage: style_stats [options] <file ...>
141
+ -h, --help output usage information
142
+ -V, --version output the version number
143
+ -c, --config <path> set configurations
144
+ -f, --format <format> set the output format <json|html|md>
145
+ -m, --mobile [name] set the mobile user agent
146
+ --user-anget <string> set the user agent</string></format></path>
147
+ ```
148
+
149
+ Example:
150
+
151
+ ```shell
152
+ $ style_stats path/to/stylesheet.css -c style_stats.yml
153
+ ┌────────────────────────────┬────────┐
154
+ │ Style Sheets │ 1 │
155
+ ├────────────────────────────┼────────┤
156
+ │ Size │ 19.0KB │
157
+ ├────────────────────────────┼────────┤
158
+ │ Gzipped Size │ 3.7KB │
159
+ ├────────────────────────────┼────────┤
160
+ │ Total Unique Font Families │ 3 │
161
+ └────────────────────────────┴────────┘
162
+ ```
163
+
164
+
134
165
  ## Development
135
166
 
136
167
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec style_stats` to use the gem in this directory, ignoring other installed copies of this gem.
data/exe/style_stats CHANGED
@@ -17,6 +17,8 @@ opt.on('-V', '--version', 'output the version number') do |v|
17
17
  exit
18
18
  end
19
19
 
20
+
21
+ opt.on('-c', '--config <path>', 'set configurations') { |v| options[:config] = v }
20
22
  opt.on('-f', '--format <format>', 'set the output format <json|html|md>') { |v| options[:format] = v }
21
23
  opt.on('-m', '--mobile [name]', 'set the mobile user agent') { |v| options[:user_agent] = v || 'ios' }
22
24
  opt.on('--user-anget <string>', 'set the user agent') { |v| options[:user_agent] = v }
data/lib/style_stats.rb CHANGED
@@ -4,8 +4,17 @@ require 'open-uri'
4
4
  require 'css_parser'
5
5
  require 'json'
6
6
  require 'command_line_reporter'
7
+ require 'yaml'
7
8
 
8
9
  class StyleStats
10
+ def self.configure(&block)
11
+ yield(configuration)
12
+ end
13
+
14
+ def self.configuration
15
+ @_configuration ||= StyleStats::Configuration.new
16
+ end
17
+
9
18
  def initialize(paths, options = {})
10
19
  paths = [paths] unless paths.is_a?(Array)
11
20
 
@@ -16,22 +25,16 @@ class StyleStats
16
25
  end.flatten
17
26
 
18
27
  @css = files.inject(Css.new) do |css, file|
19
- css.merge!(Css.new(file, css_options))
28
+ css.merge!(Css.new(file))
20
29
  end
21
30
  end
22
31
 
23
32
  def render
24
- Template.new(@css, template_options).render
33
+ Template.new(@css, options).render
25
34
  end
26
35
 
27
36
  private
28
- def css_options
29
- {
30
- user_agent: @options[:user_agent]
31
- }
32
- end
33
-
34
- def template_options
37
+ def options
35
38
  {
36
39
  format: @options[:format]
37
40
  }
@@ -39,6 +42,7 @@ class StyleStats
39
42
  end
40
43
 
41
44
  require 'style_stats/version'
45
+ require 'style_stats/configuration'
42
46
  require 'style_stats/path_parser'
43
47
  require 'style_stats/css'
44
48
  require 'style_stats/template'
@@ -3,6 +3,11 @@ class StyleStats
3
3
  class << self
4
4
  def run(files, option)
5
5
  @options = option
6
+ StyleStats.configure do |config|
7
+ config.options[:requestOptions][:headers]['User-Agent'] = user_agent
8
+ config.options.merge!(configuration)
9
+ end
10
+
6
11
  stylestats = StyleStats.new(files, options)
7
12
  stylestats.render
8
13
  rescue StyleStats::RequestError
@@ -16,8 +21,7 @@ class StyleStats
16
21
  private
17
22
  def options
18
23
  {
19
- format: @options[:format],
20
- user_agent: user_agent
24
+ format: @options[:format]
21
25
  }
22
26
  end
23
27
 
@@ -31,6 +35,18 @@ class StyleStats
31
35
  @options[:user_agent]
32
36
  end
33
37
  end
38
+
39
+ def configuration
40
+ config = case File.extname(@options[:config].to_s)
41
+ when '.yml', '.yaml'
42
+ YAML.load_file(@options[:config])
43
+ when '.json'
44
+ json = File.read(@options[:config])
45
+ JSON.parse(json)
46
+ else
47
+ {}
48
+ end
49
+ end
34
50
  end
35
51
  end
36
52
  end
@@ -0,0 +1,43 @@
1
+ class StyleStats
2
+ class Configuration
3
+ def options
4
+ @options ||= {
5
+ published: true,
6
+ stylesheets: true,
7
+ paths: true,
8
+ stylesheets: true,
9
+ styleElements: true,
10
+ size: true,
11
+ dataUriSize: true,
12
+ ratioOfDataUriSize: true,
13
+ gzippedSize: true,
14
+ rules: true,
15
+ selectors: true,
16
+ declarations: true,
17
+ simplicity: true,
18
+ averageOfIdentifier: true,
19
+ mostIdentifier: true,
20
+ mostIdentifierSelector: true,
21
+ averageOfCohesion: true,
22
+ lowestCohesion: true,
23
+ lowestCohesionSelector: true,
24
+ totalUniqueFontSizes: true,
25
+ uniqueFontSizes: true,
26
+ totalUniqueFontFamilies: true,
27
+ uniqueFontFamilies: true,
28
+ totalUniqueColors: true,
29
+ uniqueColors: true,
30
+ idSelectors: true,
31
+ universalSelectors: true,
32
+ unqualifiedAttributeSelectors: true,
33
+ javascriptSpecificSelectors: "[#\\.]js\\-",
34
+ userSpecifiedSelectors: false,
35
+ importantKeywords: true,
36
+ floatProperties: true,
37
+ propertiesCount: 10,
38
+ mediaQueries: true,
39
+ requestOptions: { headers: {} }
40
+ }
41
+ end
42
+ end
43
+ end
@@ -8,7 +8,7 @@ class StyleStats
8
8
  class Css
9
9
  attr_accessor :path, :paths, :rules, :media_types, :selectors, :stylesheets, :elements
10
10
 
11
- def initialize(path = nil, options = {})
11
+ def initialize(path = nil)
12
12
  self.path = path
13
13
  self.paths = path ? [path] : []
14
14
  self.rules = []
@@ -17,7 +17,6 @@ class StyleStats
17
17
  self.stylesheets = []
18
18
  self.elements = []
19
19
 
20
- @options = options
21
20
  parse if path
22
21
  end
23
22
 
@@ -61,7 +60,17 @@ class StyleStats
61
60
  when :unqualified
62
61
  selectors.count { |selector| selector.name.match(/\[.+\]$/) }
63
62
  when :js
64
- selectors.count { |selector| selector.name.match(/[#\\.]js\\-/) }
63
+ if StyleStats.configuration.options[:javascriptSpecificSelectors]
64
+ selectors.count { |selector| selector.name.match(/#{StyleStats.configuration.options[:javascriptSpecificSelectors]}/) }
65
+ else
66
+ 0
67
+ end
68
+ when :user
69
+ if StyleStats.configuration.options[:userSpecifiedSelectors]
70
+ selectors.count { |selector| selector.name.match(/#{StyleStats.configuration.options[:userSpecifiedSelectors]}/) }
71
+ else
72
+ 0
73
+ end
65
74
  else
66
75
  selectors.count
67
76
  end
@@ -96,7 +105,7 @@ class StyleStats
96
105
 
97
106
  private
98
107
  def parse
99
- fetch = Fetch.new(self.path, @options)
108
+ fetch = Fetch.new(self.path)
100
109
 
101
110
  self.stylesheets = fetch.stylesheets
102
111
  self.elements = fetch.elements
@@ -1,42 +1,176 @@
1
1
  class StyleStats
2
2
  class Css
3
3
  def analyze
4
- selector = sort_selector_by_declarations_count.first
5
- most_indentifier_selector = selectors.first || StyleStats::Css::Selector.new
6
- {
7
- "Published" => Time.now,
8
- "Paths" => paths,
9
- "Style Sheets" => stylesheets.count,
10
- "Style Elements" => elements.count,
11
- "Size" => size,
12
- "Data URI Size" => data_uri_size,
13
- "Ratio of Data URI Size" => "#{data_uri_size.fdiv(size).round(1) * 100}%",
14
- "Gzipped Size" => gzipped_size,
15
- "Rules" => rules.count,
16
- "Selectors" => selectors.count,
17
- "Declarations" => declarations.count,
18
- "Simplicity" => "#{rules.count.fdiv(selectors.count).round(1) * 100}%",
19
- "Average of Identifier" => selectors.map(&:identifier_count).inject(0, :+).fdiv(selectors.count).round(3),
20
- "Most Identifier" => most_indentifier_selector.identifier_count,
21
- "Most Identifier Selector" => most_indentifier_selector.name,
22
- "Average of Cohesion" => declarations.count.fdiv(rules.count).round(3),
23
- "Lowest Cohesion" => selector.declarations.count,
24
- "Lowest Cohesion Selector" => selector.name,
25
- "Total Unique Font Sizes" => self["font-size"][:values].count,
26
- "Unique Font Sizes" => self["font-size"][:values],
27
- "Total Unique Font Families" => self["font-family"][:values].count,
28
- "Unique Font Families" => self["font-family"][:values],
29
- "Total Unique Colors" => self["color"][:values].count,
30
- "Unique Colors" => self["color"][:values],
31
- "ID Selectors" => selectors_count(:id),
32
- "Universal Selectors" => selectors_count(:universal),
33
- "Unqualified Attribute Selectors" => selectors_count(:unqualified),
34
- "JavaScript Specific Selectors" => selectors_count(:js),
35
- "Important Keywords" => declarations_count(:important),
36
- "Float Properties" => declarations_count(:float),
37
- "Properties Count" => aggregate_declaration.declarations.sort { |(_, v1), (_, v2)| v2[:count] <=> v1[:count] }.take(10).map{ |property, declaration| "#{property}: #{declaration[:count]}" },
38
- "Media Queries" => media_types.count
39
- }
4
+ @result = {}
5
+ @selector = sort_selector_by_declarations_count.first
6
+ @most_indentifier_selector = selectors.first || StyleStats::Css::Selector.new("")
7
+ analyze_published
8
+ analyze_paths
9
+ analyze_stylesheets
10
+ analyze_style_elements
11
+ analyze_size
12
+ analyze_data_uri_size
13
+ analyze_ratio_of_data_uri_size
14
+ analyze_gzipped_size
15
+ analyze_rules
16
+ analyze_selectors
17
+ analyze_declarations
18
+ analyze_simplicity
19
+ analyze_average_of_identifier
20
+ analyze_most_identifier
21
+ analyze_most_identifier_selector
22
+ analyze_average_of_cohesion
23
+ analyze_lowest_cohesion
24
+ analyze_lowest_cohesion_selector
25
+ analyze_total_unique_font_sizes
26
+ analyze_unique_font_sizes
27
+ analyze_total_unique_font_families
28
+ analyze_unique_font_families
29
+ analyze_total_unique_colors
30
+ analyze_unique_colors
31
+ analyze_id_selectors
32
+ analyze_universal_selectors
33
+ analyze_unqualified_attribute_selectors
34
+ analyze_javascript_specific_selectors
35
+ analyze_user_specific_selectors
36
+ analyze_important_keywords
37
+ analyze_fload_properties
38
+ analyze_properties_count
39
+ analyze_media_queries
40
+ @result
41
+ end
42
+
43
+ private
44
+ def analyze_published
45
+ @result["Published"] = Time.now if StyleStats.configuration.options[:published]
46
+ end
47
+
48
+ def analyze_paths
49
+ @result["Paths"] = paths if StyleStats.configuration.options[:paths]
50
+ end
51
+
52
+ def analyze_stylesheets
53
+ @result["Style Sheets"] = stylesheets.count if StyleStats.configuration.options[:stylesheets]
54
+ end
55
+
56
+ def analyze_style_elements
57
+ @result["Style Elements"] = elements.count if StyleStats.configuration.options[:styleElements]
58
+ end
59
+
60
+ def analyze_size
61
+ @result["Size"] = size if StyleStats.configuration.options[:size]
62
+ end
63
+
64
+ def analyze_data_uri_size
65
+ @result["Data URI Size"] = data_uri_size if StyleStats.configuration.options[:dataUriSize]
66
+ end
67
+
68
+ def analyze_ratio_of_data_uri_size
69
+ @result["Ratio of Data URI Size"] = "#{data_uri_size.fdiv(size).round(1) * 100}%" if StyleStats.configuration.options[:ratioOfDataUriSize]
70
+ end
71
+
72
+ def analyze_gzipped_size
73
+ @result["Gzipped Size"] = gzipped_size if StyleStats.configuration.options[:gzippedSize]
74
+ end
75
+
76
+ def analyze_rules
77
+ @result["Rules"] = rules.count if StyleStats.configuration.options[:rules]
78
+ end
79
+
80
+ def analyze_selectors
81
+ @result["Selectors"] = selectors.count if StyleStats.configuration.options[:selectors]
82
+ end
83
+
84
+ def analyze_declarations
85
+ @result["Declarations"] = declarations.count if StyleStats.configuration.options[:declarations]
86
+ end
87
+
88
+ def analyze_simplicity
89
+ @result["Simplicity"] = "#{rules.count.fdiv(selectors.count).round(1) * 100}%" if StyleStats.configuration.options[:simplicity]
90
+ end
91
+
92
+ def analyze_average_of_identifier
93
+ @result["Average of Identifier"] = selectors.map(&:identifier_count).inject(0, :+).fdiv(selectors.count).round(3) if StyleStats.configuration.options[:averageOfIdentifier]
94
+ end
95
+
96
+ def analyze_most_identifier
97
+ @result["Most Identifier"] = @most_indentifier_selector.identifier_count if StyleStats.configuration.options[:mostIdentifier]
98
+ end
99
+
100
+ def analyze_most_identifier_selector
101
+ @result["Most Identifier Selector"] = @most_indentifier_selector.name if StyleStats.configuration.options[:mostIdentifierSelector]
102
+ end
103
+
104
+ def analyze_average_of_cohesion
105
+ @result["Average of Cohesion"] = declarations.count.fdiv(rules.count).round(3) if StyleStats.configuration.options[:averageOfCohesion]
106
+ end
107
+
108
+ def analyze_lowest_cohesion
109
+ @result["Lowest Cohesion"] = @selector.declarations.count if StyleStats.configuration.options[:lowestCohesion]
110
+ end
111
+
112
+ def analyze_lowest_cohesion_selector
113
+ @result["Lowest Cohesion Selector"] = @selector.name if StyleStats.configuration.options[:lowestCohesionSelector]
114
+ end
115
+
116
+ def analyze_total_unique_font_sizes
117
+ @result["Total Unique Font Sizes"] = self["font-size"][:values].count if StyleStats.configuration.options[:totalUniqueFontSizes]
118
+ end
119
+
120
+ def analyze_unique_font_sizes
121
+ @result["Unique Font Sizes"] = self["font-size"][:values] if StyleStats.configuration.options[:uniqueFontSizes]
122
+ end
123
+
124
+ def analyze_total_unique_font_families
125
+ @result["Total Unique Font Families"] = self["font-family"][:values].count if StyleStats.configuration.options[:totalUniqueFontFamilies]
126
+ end
127
+
128
+ def analyze_unique_font_families
129
+ @result["Unique Font Families"] = self["font-family"][:values] if StyleStats.configuration.options[:uniqueFontFamilies]
130
+ end
131
+
132
+ def analyze_total_unique_colors
133
+ @result["Total Unique Colors"] = self["color"][:values].count if StyleStats.configuration.options[:totalUniqueColors]
134
+ end
135
+
136
+ def analyze_unique_colors
137
+ @result["Unique Colors"] = self["color"][:values] if StyleStats.configuration.options[:uniqueColors]
138
+ end
139
+
140
+ def analyze_id_selectors
141
+ @result["ID Selectors"] = selectors_count(:id) if StyleStats.configuration.options[:idSelectors]
142
+ end
143
+
144
+ def analyze_universal_selectors
145
+ @result["Universal Selectors"] = selectors_count(:universal) if StyleStats.configuration.options[:universalSelectors]
146
+ end
147
+
148
+ def analyze_unqualified_attribute_selectors
149
+ @result["Unqualified Attribute Selectors"] = selectors_count(:unqualified) if StyleStats.configuration.options[:unqualifiedAttributeSelectors]
150
+ end
151
+
152
+ def analyze_javascript_specific_selectors
153
+ @result["JavaScript Specific Selectors"] = selectors_count(:js) if StyleStats.configuration.options[:javascriptSpecificSelectors]
154
+ end
155
+
156
+ def analyze_user_specific_selectors
157
+ @result["User Specific Selectors"] = selectors_count(:user) if StyleStats.configuration.options[:userSpecificSelectors]
158
+ end
159
+
160
+ def analyze_important_keywords
161
+ @result["Important Keywords"] = declarations_count(:important) if StyleStats.configuration.options[:importantKeywords]
162
+ end
163
+
164
+ def analyze_fload_properties
165
+ @result["Float Properties"] = declarations_count(:float) if StyleStats.configuration.options[:floatProperties]
166
+ end
167
+
168
+ def analyze_properties_count
169
+ @result["Properties Count"] = aggregate_declaration.declarations.sort { |(_, v1), (_, v2)| v2[:count] <=> v1[:count] }.take(10).map{ |property, declaration| "#{property}: #{declaration[:count]}" } if StyleStats.configuration.options[:propertiesCount]
170
+ end
171
+
172
+ def analyze_media_queries
173
+ @result["Media Queries"] = media_types.count if StyleStats.configuration.options[:mediaQueries]
40
174
  end
41
175
  end
42
176
  end
@@ -2,10 +2,9 @@ class StyleStats::Css
2
2
  class Fetch
3
3
  attr_accessor :stylesheets, :elements
4
4
 
5
- def initialize(path, options={})
5
+ def initialize(path)
6
6
  self.stylesheets = []
7
7
  self.elements = []
8
- @options = options
9
8
  get(path)
10
9
  end
11
10
 
@@ -19,7 +18,7 @@ class StyleStats::Css
19
18
  end
20
19
 
21
20
  def request(path)
22
- file = open(path, "User-Agent" => user_agent)
21
+ file = open(path, headers)
23
22
  case file.content_type
24
23
  when 'text/css'
25
24
  self.stylesheets.push(file.read)
@@ -49,8 +48,12 @@ class StyleStats::Css
49
48
  end
50
49
  end
51
50
 
52
- def user_agent
53
- @options[:user_agent] || "Ruby/StyleStats #{StyleStats::VERSION}"
51
+ def headers
52
+ if StyleStats.configuration.options[:requestOptions][:headers]['User-Agent']
53
+ StyleStats.configuration.options[:requestOptions][:headers]
54
+ else
55
+ { 'User-Agent' => "Ruby/StyleStats #{StyleStats::VERSION}" }
56
+ end
54
57
  end
55
58
  end
56
59
  end
@@ -1,3 +1,3 @@
1
1
  class StyleStats
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: style_stats
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - shiro16
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-01 00:00:00.000000000 Z
11
+ date: 2015-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oga
@@ -116,6 +116,7 @@ files:
116
116
  - exe/style_stats
117
117
  - lib/style_stats.rb
118
118
  - lib/style_stats/cli.rb
119
+ - lib/style_stats/configuration.rb
119
120
  - lib/style_stats/css.rb
120
121
  - lib/style_stats/css/aggregate_declaration.rb
121
122
  - lib/style_stats/css/analyze.rb
@@ -155,4 +156,3 @@ signing_key:
155
156
  specification_version: 4
156
157
  summary: StyleStats is a library to collect CSS statistics!
157
158
  test_files: []
158
- has_rdoc: