style_stats 0.1.0 → 0.2.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: 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: