csscss 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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