csscss 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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
- ## 0.1.0 ##
1
+ ## 0.2.0 - 3/24/2013 ##
2
+
3
+ * Colorizes text output.
4
+ * Supports scss/sass files.
5
+ * Fixes newline output bug when there are no redundancies
6
+ * Downloads remote css files if passed a URL
7
+ * Fixes bug with double semicolons (blank attributes)
8
+
9
+ ## 0.1.0 - 3/21/2013 ##
2
10
 
3
11
  * Initial project release.
data/Gemfile CHANGED
@@ -3,6 +3,10 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in csscss.gemspec
4
4
  gemspec
5
5
 
6
+ # optional runtime dependencies
7
+ gem "sass"
8
+ gem "compass"
9
+
6
10
  gem "rake", :require => false
7
11
  gem "debugger"
8
12
 
data/Gemfile.lock CHANGED
@@ -1,20 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- csscss (0.1.0)
4
+ csscss (0.2.0)
5
+ colorize
5
6
  parslet (~> 1.5)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
10
11
  blankslate (2.1.2.4)
12
+ chunky_png (1.2.7)
13
+ colorize (0.5.8)
11
14
  columnize (0.3.6)
15
+ compass (0.12.2)
16
+ chunky_png (~> 1.2)
17
+ fssm (>= 0.2.7)
18
+ sass (~> 3.1)
12
19
  debugger (1.5.0)
13
20
  columnize (>= 0.3.1)
14
21
  debugger-linecache (~> 1.2.0)
15
22
  debugger-ruby_core_source (~> 1.2.0)
16
23
  debugger-linecache (1.2.0)
17
24
  debugger-ruby_core_source (1.2.0)
25
+ fssm (0.2.10)
18
26
  m (1.3.1)
19
27
  method_source (>= 0.6.7)
20
28
  rake (>= 0.9.2.2)
@@ -25,11 +33,13 @@ GEM
25
33
  blankslate (~> 2.0)
26
34
  rake (10.0.3)
27
35
  ruby-prof (0.13.0)
36
+ sass (3.2.7)
28
37
 
29
38
  PLATFORMS
30
39
  ruby
31
40
 
32
41
  DEPENDENCIES
42
+ compass
33
43
  csscss!
34
44
  debugger
35
45
  m
@@ -37,3 +47,4 @@ DEPENDENCIES
37
47
  minitest-rg
38
48
  rake
39
49
  ruby-prof
50
+ sass
data/README.md CHANGED
@@ -24,15 +24,30 @@ Then you can run it in at the command line against CSS files.
24
24
 
25
25
  $ csscss path/to/styles.css path/to/other-styles.css
26
26
 
27
+ {.contact .content .primary} and {article, #comments} share 5 rules
28
+ {.profile-picture}, {.screenshot img} and {a.blurb img} share 4 rules
29
+ {.work h2:first-child, .archive h2:first-child, .missing h2:first-child, .about h2, .contact h2} and {body.home h2} share 4 rules
30
+ {article.blurb:hover} and {article:hover} share 3 rules
31
+
27
32
  Run it in a verbose mode to see all the duplicated styles.
28
33
 
29
34
  $ csscss -v path/to/styles.css
30
35
 
36
+ Run it against remote files by passing a valid URL.
37
+
38
+ $ csscss -v http://example.com/css/main.css
39
+
31
40
  You can also choose a minimum number of matches, which will ignore any
32
41
  rulesets that have fewer matches.
33
42
 
34
43
  $ csscss -n 10 -v path/to/style.css # ignores rulesets with < 10 matches
35
44
 
45
+ If you prefer writing in sass, you can also parse your sass/scss files.
46
+
47
+ $ gem install sass
48
+ $ csscss path/to/style.scss
49
+
50
+
36
51
  ## I found bugs ##
37
52
 
38
53
  This is still a new and evolving project. I heartily welcome feedback.
@@ -45,8 +60,8 @@ output you expect to see.
45
60
  ## Who are you? ##
46
61
 
47
62
  My name is [Zach Moazeni](https://twitter.com/zmoazeni). I work for [an
48
- awesome company](http://www.getharvest.com/), which [is
49
- hiring!](http://www.getharvest.com/careers).
63
+ awesome company](http://www.getharvest.com/). And [we're
64
+ hiring!](http://www.getharvest.com/careers)
50
65
 
51
66
  ## I'm a dev, I can help ##
52
67
 
data/csscss.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Csscss::VERSION
9
9
  gem.authors = ["Zach Moazeni"]
10
10
  gem.email = ["zach.moazeni@gmail.com"]
11
- gem.description = %q{A CSS redundancy analyzer that analyzes redundancy.}
12
- gem.summary = %q{csscss will parse any CSS files you give it and let you know which rulesets have duplicated declarations.}
11
+ gem.summary = %q{A CSS redundancy analyzer that analyzes redundancy.}
12
+ gem.description = %q{csscss will parse any CSS files you give it and let you know which rulesets have duplicated declarations.}
13
13
  gem.homepage = "http://zmoazeni.github.com/csscss/"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -18,4 +18,5 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ["lib"]
19
19
 
20
20
  gem.add_dependency "parslet", "~> 1.5"
21
+ gem.add_dependency "colorize"
21
22
  end
data/lib/csscss/cli.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  module Csscss
2
2
  class CLI
3
3
  def initialize(argv)
4
- @argv = argv
4
+ @argv = argv
5
5
  @verbose = false
6
+ @color = true
6
7
  @minimum = 3
8
+ @compass = false
7
9
  end
8
10
 
9
11
  def run
@@ -12,8 +14,32 @@ module Csscss
12
14
  end
13
15
 
14
16
  def execute
17
+
15
18
  all_redundancies = @argv.map do |filename|
16
- contents = File.read(filename)
19
+ contents = if %w(.scss .sass).include?(File.extname(filename).downcase) && !(filename =~ URI.regexp)
20
+ begin
21
+ require "sass"
22
+ rescue LoadError
23
+ puts "Must install sass gem before parsing sass/scss files"
24
+ exit 1
25
+ end
26
+
27
+ sass_options = {cache:false}
28
+ sass_options[:load_paths] = Compass.configuration.sass_load_paths if @compass
29
+ begin
30
+ Sass::Engine.for_file(filename, sass_options).render
31
+ rescue Sass::SyntaxError => e
32
+ if e.message =~ /compass/ && !@compass
33
+ puts "Enable --compass option to use compass's extensions"
34
+ exit 1
35
+ else
36
+ raise e
37
+ end
38
+ end
39
+ else
40
+ open(filename) {|f| f.read }
41
+ end
42
+
17
43
  RedundancyAnalyzer.new(contents).redundancies(@minimum)
18
44
  end
19
45
 
@@ -30,7 +56,8 @@ module Csscss
30
56
  if @json
31
57
  puts JSONReporter.new(combined_redundancies).report
32
58
  else
33
- puts Reporter.new(combined_redundancies).report(@verbose)
59
+ report = Reporter.new(combined_redundancies).report(verbose:@verbose, color:true)
60
+ puts report unless report.empty?
34
61
  end
35
62
 
36
63
  rescue Parslet::ParseFailed => e
@@ -48,6 +75,10 @@ module Csscss
48
75
  @verbose = v
49
76
  end
50
77
 
78
+ opts.on("--[no-]color", "Colorizes output") do |c|
79
+ @color = c
80
+ end
81
+
51
82
  opts.on("-n", "--num N", Integer, "Print matches with at least this many rules. Defaults to 3") do |n|
52
83
  @minimum = n
53
84
  end
@@ -57,6 +88,17 @@ module Csscss
57
88
  exit
58
89
  end
59
90
 
91
+ opts.on("--[no-]compass", "Enables compass extensions when parsing sass/scss") do |compass|
92
+ if @compass = compass
93
+ begin
94
+ require "compass"
95
+ rescue LoadError
96
+ puts "Must install compass gem before enabling its extensions"
97
+ exit 1
98
+ end
99
+ end
100
+ end
101
+
60
102
  opts.on("-j", "--[no-]json", "Output results in JSON") do |j|
61
103
  @json = j
62
104
  end
@@ -20,6 +20,8 @@ module Csscss
20
20
  comment.repeat(1) | space?
21
21
  }
22
22
 
23
+ rule(:blank_attribute) { str(";") >> space? }
24
+
23
25
  rule(:attribute) {
24
26
  match["^:{}"].repeat(1).as(:property) >>
25
27
  str(":") >>
@@ -33,7 +35,7 @@ module Csscss
33
35
  match["^{}"].repeat(1).as(:selector) >>
34
36
  str("{") >>
35
37
  space? >>
36
- (comment | attribute).repeat(0).as(:properties) >>
38
+ (comment | attribute | blank_attribute).repeat(0).as(:properties) >>
37
39
  str("}") >>
38
40
  space?
39
41
  ).as(:ruleset)
@@ -50,7 +52,6 @@ module Csscss
50
52
  ).as(:nested_ruleset)
51
53
  }
52
54
 
53
- #rule(:blocks) { (nested_ruleset.as(:nested) | ruleset).repeat(0).as(:blocks) }
54
55
  rule(:blocks) {
55
56
  space? >> (comment | nested_ruleset | ruleset).repeat(1).as(:blocks) >> space?
56
57
  }
@@ -1,3 +1,4 @@
1
+ # TODO: this class really needs some work. It works, but it is horrid.
1
2
  module Csscss
2
3
  class RedundancyAnalyzer
3
4
  def initialize(raw_css)
@@ -4,20 +4,28 @@ module Csscss
4
4
  @redundancies = redundancies
5
5
  end
6
6
 
7
- def report(verbose = false)
7
+ def report(options = {})
8
+ verbose = options.fetch(:verbose, false)
9
+ should_color = options.fetch(:color, true)
10
+
8
11
  io = StringIO.new
9
12
  @redundancies.each do |selector_groups, declarations|
10
- selector_groups = selector_groups.map {|selectors| "{#{selectors}}" }
13
+ selector_groups = selector_groups.map {|selectors| maybe_color("{#{selectors}}", :red, should_color) }
11
14
  last_selector = selector_groups.pop
12
15
  count = declarations.size
13
- io.puts %Q(#{selector_groups.join(", ")} and #{last_selector} share #{count} rule#{"s" if count > 1})
16
+ io.puts %Q(#{selector_groups.join(", ")} AND #{last_selector} share #{maybe_color(count, :red, should_color)} rule#{"s" if count > 1})
14
17
  if verbose
15
- declarations.each {|dec| io.puts " - #{dec}" }
18
+ declarations.each {|dec| io.puts(maybe_color(" - #{dec}", :yellow, should_color)) }
16
19
  end
17
20
  end
18
21
 
19
22
  io.rewind
20
23
  io.read
21
24
  end
25
+
26
+ private
27
+ def maybe_color(string, color, condition)
28
+ condition ? string.to_s.colorize(color) : string
29
+ end
22
30
  end
23
31
  end
@@ -1,3 +1,3 @@
1
1
  module Csscss
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/csscss.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require "stringio"
2
2
  require "optparse"
3
3
  require "json"
4
+ require "open-uri"
4
5
 
6
+ require "colorize"
5
7
  require "parslet"
6
8
  require "csscss/parslet_optimizations"
7
9
 
@@ -128,6 +128,12 @@ module Csscss::Parser
128
128
  rs(sel("h1"), [dec("outline", "1px")])
129
129
  ])
130
130
  end
131
+
132
+ it "ignores double semicolons" do
133
+ trans("h1 { display:none;;}").must_equal([
134
+ rs(sel("h1"), [dec("display", "none")])
135
+ ])
136
+ end
131
137
  end
132
138
  end
133
139
  end
@@ -12,22 +12,27 @@ module Csscss
12
12
  })
13
13
 
14
14
  expected =<<-EXPECTED
15
- {.foo} and {.bar} share 2 rules
16
- {h1, h2}, {.foo} and {.baz} share 1 rule
17
- {h1, h2} and {.bar} share 1 rule
15
+ {.foo} AND {.bar} share 2 rules
16
+ {h1, h2}, {.foo} AND {.baz} share 1 rule
17
+ {h1, h2} AND {.bar} share 1 rule
18
18
  EXPECTED
19
- reporter.report.must_equal expected
19
+ reporter.report(color:false).must_equal expected
20
20
 
21
21
  expected =<<-EXPECTED
22
- {.foo} and {.bar} share 2 rules
22
+ {.foo} AND {.bar} share 2 rules
23
23
  - width: 1px
24
24
  - border: black
25
- {h1, h2}, {.foo} and {.baz} share 1 rule
25
+ {h1, h2}, {.foo} AND {.baz} share 1 rule
26
26
  - display: none
27
- {h1, h2} and {.bar} share 1 rule
27
+ {h1, h2} AND {.bar} share 1 rule
28
28
  - position: relative
29
29
  EXPECTED
30
- reporter.report(true).must_equal expected
30
+ reporter.report(verbose:true, color:false).must_equal expected
31
+ end
32
+
33
+ it "prints a new line if there is nothing" do
34
+ reporter = Reporter.new({})
35
+ reporter.report().must_equal ""
31
36
  end
32
37
  end
33
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csscss
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-21 00:00:00.000000000 Z
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parslet
@@ -27,7 +27,24 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: '1.5'
30
- description: A CSS redundancy analyzer that analyzes redundancy.
30
+ - !ruby/object:Gem::Dependency
31
+ name: colorize
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: csscss will parse any CSS files you give it and let you know which rulesets
47
+ have duplicated declarations.
31
48
  email:
32
49
  - zach.moazeni@gmail.com
33
50
  executables:
@@ -103,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
120
  version: '0'
104
121
  segments:
105
122
  - 0
106
- hash: -4598443269162371706
123
+ hash: -2897207436893680163
107
124
  required_rubygems_version: !ruby/object:Gem::Requirement
108
125
  none: false
109
126
  requirements:
@@ -112,14 +129,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
129
  version: '0'
113
130
  segments:
114
131
  - 0
115
- hash: -4598443269162371706
132
+ hash: -2897207436893680163
116
133
  requirements: []
117
134
  rubyforge_project:
118
135
  rubygems_version: 1.8.25
119
136
  signing_key:
120
137
  specification_version: 3
121
- summary: csscss will parse any CSS files you give it and let you know which rulesets
122
- have duplicated declarations.
138
+ summary: A CSS redundancy analyzer that analyzes redundancy.
123
139
  test_files:
124
140
  - test/csscss/json_reporter_test.rb
125
141
  - test/csscss/parser/background_test.rb