compass-edge 0.9.1 → 0.9.2

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.
Files changed (34) hide show
  1. data/Rakefile +34 -1
  2. data/VERSION.yml +3 -2
  3. data/features/command_line.feature +219 -0
  4. data/features/step_definitions/command_line_steps.rb +199 -0
  5. data/lib/compass/app_integration/rails/installer.rb +3 -1
  6. data/lib/compass/app_integration/stand_alone/installer.rb +26 -11
  7. data/lib/compass/commands.rb +1 -1
  8. data/lib/compass/commands/create_project.rb +8 -1
  9. data/lib/compass/commands/installer_command.rb +6 -2
  10. data/lib/compass/commands/project_stats.rb +160 -0
  11. data/lib/compass/commands/update_project.rb +49 -1
  12. data/lib/compass/commands/validate_project.rb +56 -2
  13. data/lib/compass/commands/watch_project.rb +3 -1
  14. data/lib/compass/commands/write_configuration.rb +60 -2
  15. data/lib/compass/compiler.rb +4 -3
  16. data/lib/compass/configuration/helpers.rb +9 -0
  17. data/lib/compass/errors.rb +4 -1
  18. data/lib/compass/exec.rb +1 -0
  19. data/lib/compass/frameworks/compass/stylesheets/compass/utilities/general/_reset.sass +2 -2
  20. data/lib/compass/installers.rb +1 -1
  21. data/lib/compass/installers/bare_installer.rb +62 -0
  22. data/lib/compass/installers/base.rb +7 -51
  23. data/lib/compass/installers/manifest_installer.rb +59 -0
  24. data/lib/compass/sass_extensions/monkey_patches.rb +2 -2
  25. data/lib/compass/sass_extensions/monkey_patches/traversal.rb +23 -0
  26. data/lib/compass/stats.rb +92 -0
  27. data/lib/compass/validator.rb +2 -3
  28. data/test/command_line_helper.rb +6 -2
  29. data/test/fixtures/stylesheets/compass/css/reset.css +1 -1
  30. data/test/io_helper.rb +18 -1
  31. data/test/rails_helper.rb +40 -0
  32. data/test/rails_integration_test.rb +2 -40
  33. data/test/test_helper.rb +1 -0
  34. metadata +12 -3
@@ -2,11 +2,13 @@ module Compass
2
2
  module Installers
3
3
  class Base
4
4
  end
5
+ class ManifestInstaller < Base
6
+ end
5
7
  end
6
8
 
7
9
  module AppIntegration
8
10
  module Rails
9
- class Installer < Compass::Installers::Base
11
+ class Installer < Compass::Installers::ManifestInstaller
10
12
 
11
13
  def default_configuration
12
14
  Compass::Configuration::Data.new.extend(ConfigurationDefaults)
@@ -2,11 +2,13 @@ module Compass
2
2
  module Installers
3
3
  class Base
4
4
  end
5
+ class ManifestInstaller < Base
6
+ end
5
7
  end
6
8
 
7
9
  module AppIntegration
8
10
  module StandAlone
9
- class Installer < Compass::Installers::Base
11
+ class Installer < Compass::Installers::ManifestInstaller
10
12
 
11
13
  def init
12
14
  directory targetize("")
@@ -45,16 +47,29 @@ module Compass
45
47
  if options[:create]
46
48
  puts <<-NEXTSTEPS
47
49
 
48
- Congratulations! Your compass project has been created.
49
- You must recompile your sass stylesheets when they change.
50
- This can be done in one of the following ways:
51
- 1. From within your project directory run:
52
- compass
53
- 2. From any directory run:
54
- compass -u path/to/project
55
- 3. To monitor your project for changes and automatically recompile:
56
- compass --watch [path/to/project]
57
- NEXTSTEPS
50
+ *********************************************************************
51
+ Congratulations! Your compass project has been created.
52
+
53
+ You may now add and edit sass stylesheets in the #{Compass.configuration.sass_dir} subdirectory of your project.
54
+
55
+ Sass files beginning with an underscore are called partials and won't be
56
+ compiled to CSS, but they can be imported into other sass stylesheets.
57
+
58
+ You can configure your project by editing the config.rb configuration file.
59
+
60
+ You must compile your sass stylesheets into CSS when they change.
61
+ This can be done in one of the following ways:
62
+ 1. To compile on demand:
63
+ compass compile [path/to/project]
64
+ 2. To monitor your project for changes and automatically recompile:
65
+ compass watch [path/to/project]
66
+
67
+ More Resources:
68
+ * Wiki: http://wiki.github.com/chriseppstein/compass
69
+ * Sass: http://sass-lang.com
70
+ * Community: http://groups.google.com/group/compass-users/
71
+
72
+ NEXTSTEPS
58
73
  end
59
74
  if manifest.has_stylesheet?
60
75
  puts "\nTo import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:"
@@ -5,7 +5,7 @@ require 'compass/commands/registry'
5
5
 
6
6
  %w(base generate_grid_background help list_frameworks project_base
7
7
  update_project watch_project create_project installer_command
8
- print_version stamp_pattern validate_project
8
+ print_version project_stats stamp_pattern validate_project
9
9
  write_configuration).each do |lib|
10
10
  require "compass/commands/#{lib}"
11
11
  end
@@ -15,6 +15,10 @@ module Compass
15
15
 
16
16
  Options:
17
17
  }.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n")
18
+
19
+ opts.on_tail("--bare", "Don't generate any Sass or CSS files.") do
20
+ self.options[:bare] = true
21
+ end
18
22
  else
19
23
  opts.banner = %Q{
20
24
  Usage: compass init project_type path/to/project [options]
@@ -68,6 +72,9 @@ module Compass
68
72
  parser = option_parser(arguments)
69
73
  parse_options!(parser, arguments)
70
74
  parse_arguments!(parser, arguments)
75
+ if parser.options[:framework] && parser.options[:bare]
76
+ raise Compass::Error, "A bare project cannot be created when a framework is specified."
77
+ end
71
78
  set_default_arguments(parser)
72
79
  parser.options
73
80
  end
@@ -92,7 +99,7 @@ module Compass
92
99
  if arguments.size == 1
93
100
  parser.options[:project_name] = arguments.shift
94
101
  elsif arguments.size == 0
95
- raise Compass::Error, "Please specify a path to the project."
102
+ # default to the current directory.
96
103
  else
97
104
  raise Compass::Error, "Too many arguments were specified."
98
105
  end
@@ -16,8 +16,12 @@ module Compass
16
16
  end
17
17
 
18
18
  def installer
19
- project_type = options[:project_type] || Compass.configuration.project_type
20
- installer_class = "Compass::AppIntegration::#{camelize(project_type)}::Installer"
19
+ installer_class = if options[:bare]
20
+ "Compass::Installers::BareInstaller"
21
+ else
22
+ project_type = options[:project_type] || Compass.configuration.project_type
23
+ "Compass::AppIntegration::#{camelize(project_type)}::Installer"
24
+ end
21
25
  @installer = eval("#{installer_class}.new *installer_args")
22
26
  end
23
27
 
@@ -0,0 +1,160 @@
1
+ require 'compass/commands/project_base'
2
+ require 'compass/commands/update_project'
3
+
4
+ module Compass
5
+ module Commands
6
+ module StatsOptionsParser
7
+ def set_options(opts)
8
+ opts.banner = %Q{
9
+ Usage: compass stats [path/to/project] [options]
10
+
11
+ Description:
12
+ Compile project at the path specified (or the current
13
+ directory if not specified) and then compute statistics
14
+ for the sass and css files in the project.
15
+
16
+ Options:
17
+ }.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
18
+
19
+ super
20
+ end
21
+ end
22
+ class ProjectStats < UpdateProject
23
+
24
+ register :stats
25
+
26
+ def initialize(working_path, options)
27
+ super
28
+ assert_project_directory_exists!
29
+ end
30
+
31
+ def perform
32
+ super
33
+ require 'compass/stats'
34
+ compiler = new_compiler_instance
35
+ sass_files = sorted_sass_files(compiler)
36
+ rows = [[ :-, :-, :-, :-, :-, :-, :- ],
37
+ [ 'Filename', 'Rules', 'Properties', 'Mixins Defs', 'Mixins Used', 'CSS Rules', 'CSS Properties' ],
38
+ [ :-, :-, :-, :-, :-, :-, :- ]]
39
+ maximums = [ 8, 5, 10, 14, 11, 9, 14 ]
40
+ alignments = [ :left, :right, :right, :right, :right, :right, :right ]
41
+ delimiters = [ ['| ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'] ]
42
+ totals = [ "Total (#{sass_files.size} files):", 0, 0, 0, 0, 0, 0 ]
43
+
44
+ sass_files.each do |sass_file|
45
+ css_file = compiler.corresponding_css_file(sass_file) unless sass_file[0..0] == '_'
46
+ row = filename_columns(sass_file)
47
+ row += sass_columns(sass_file)
48
+ row += css_columns(css_file)
49
+ row.each_with_index do |c, i|
50
+ maximums[i] = [maximums[i].to_i, c.size].max
51
+ totals[i] = totals[i] + c.to_i if i > 0
52
+ end
53
+ rows << row
54
+ end
55
+ rows << [:-] * 7
56
+ rows << totals.map{|t| t.to_s}
57
+ rows << [:-] * 7
58
+ rows.each do |row|
59
+ row.each_with_index do |col, i|
60
+ print pad(col, maximums[i], :align => alignments[i], :left => delimiters[i].first, :right => delimiters[i].last)
61
+ end
62
+ print "\n"
63
+ end
64
+ if @missing_css_parser
65
+ puts "\nInstall css_parser to enable stats on your css files:\n\n\tgem install css_parser"
66
+ end
67
+ end
68
+
69
+ def pad(c, max, options = {})
70
+ options[:align] ||= :left
71
+ if c == :-
72
+ filler = '-'
73
+ c = ''
74
+ else
75
+ filler = ' '
76
+ end
77
+ spaces = max - c.size
78
+ filled = filler * [spaces,0].max
79
+ "#{options[:left]}#{filled if options[:align] == :right}#{c}#{filled if options[:align] == :left}#{options[:right]}"
80
+ end
81
+
82
+ def sorted_sass_files(compiler)
83
+ sass_files = compiler.sass_files(:exclude_partials => false)
84
+ sass_files.map! do |s|
85
+ filename = Compass.deprojectize(s, File.join(Compass.configuration.project_path, Compass.configuration.sass_dir))
86
+ [s, File.dirname(filename), File.basename(filename)]
87
+ end
88
+ sass_files = sass_files.sort_by do |s,d,f|
89
+ File.join(d, f[0] == ?_ ? f[1..-1] : f)
90
+ end
91
+ sass_files.map!{|s,d,f| s}
92
+ end
93
+
94
+ def filename_columns(sass_file)
95
+ filename = Compass.deprojectize(sass_file, working_path)
96
+ [filename]
97
+ end
98
+
99
+ def sass_columns(sass_file)
100
+ sf = Compass::Stats::SassFile.new(sass_file)
101
+ sf.analyze!
102
+ %w(rule_count prop_count mixin_def_count mixin_count).map do |t|
103
+ sf.send(t).to_s
104
+ end
105
+ end
106
+
107
+ def css_columns(css_file)
108
+ if File.exists?(css_file)
109
+ cf = Compass::Stats::CssFile.new(css_file)
110
+ cf.analyze!
111
+ %w(selector_count prop_count).map do |t|
112
+ cf.send(t).to_s
113
+ end
114
+ else
115
+ return [ '--', '--' ]
116
+ end
117
+ rescue LoadError
118
+ @missing_css_parser = true
119
+ return [ 'DISABLED', 'DISABLED' ]
120
+ end
121
+
122
+ class << self
123
+
124
+ def option_parser(arguments)
125
+ parser = Compass::Exec::CommandOptionParser.new(arguments)
126
+ parser.extend(Compass::Exec::GlobalOptionsParser)
127
+ parser.extend(Compass::Exec::ProjectOptionsParser)
128
+ parser.extend(StatsOptionsParser)
129
+ end
130
+
131
+ def usage
132
+ option_parser([]).to_s
133
+ end
134
+
135
+ def description(command)
136
+ "Report statistics about your stylesheets"
137
+ end
138
+
139
+ def parse!(arguments)
140
+ parser = option_parser(arguments)
141
+ parser.parse!
142
+ parse_arguments!(parser, arguments)
143
+ parser.options
144
+ end
145
+
146
+ def parse_arguments!(parser, arguments)
147
+ if arguments.size == 1
148
+ parser.options[:project_name] = arguments.shift
149
+ elsif arguments.size == 0
150
+ # default to the current directory.
151
+ else
152
+ raise Compass::Error, "Too many arguments were specified."
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ end
159
+ end
160
+ end
@@ -3,8 +3,25 @@ require 'compass/compiler'
3
3
 
4
4
  module Compass
5
5
  module Commands
6
+ module CompileProjectOptionsParser
7
+ def set_options(opts)
8
+ opts.banner = %Q{
9
+ Usage: compass compile [path/to/project] [options]
10
+
11
+ Description:
12
+ compile project at the path specified or the current director if not specified.
13
+
14
+ Options:
15
+ }.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n")
16
+
17
+ super
18
+ end
19
+ end
20
+
6
21
  class UpdateProject < ProjectBase
7
-
22
+
23
+ register :compile
24
+
8
25
  def initialize(working_path, options)
9
26
  super
10
27
  assert_project_directory_exists! unless dry_run?
@@ -33,6 +50,37 @@ module Compass
33
50
  :force => options[:force]).merge(additional_options))
34
51
  end
35
52
 
53
+ class << self
54
+ def option_parser(arguments)
55
+ parser = Compass::Exec::CommandOptionParser.new(arguments)
56
+ parser.extend(Compass::Exec::GlobalOptionsParser)
57
+ parser.extend(Compass::Exec::ProjectOptionsParser)
58
+ parser.extend(CompileProjectOptionsParser)
59
+ end
60
+
61
+ def usage
62
+ option_parser([]).to_s
63
+ end
64
+
65
+ def description(command)
66
+ "Compile Sass stylesheets to CSS"
67
+ end
68
+
69
+ def parse!(arguments)
70
+ parser = option_parser(arguments)
71
+ parser.parse!
72
+ parse_arguments!(parser, arguments)
73
+ parser.options
74
+ end
75
+
76
+ def parse_arguments!(parser, arguments)
77
+ if arguments.size == 1
78
+ parser.options[:project_name] = arguments.shift
79
+ elsif arguments.size > 1
80
+ raise Compass::Error, "Too many arguments were specified."
81
+ end
82
+ end
83
+ end
36
84
  end
37
85
  end
38
86
  end
@@ -3,8 +3,26 @@ require 'compass/commands/update_project'
3
3
 
4
4
  module Compass
5
5
  module Commands
6
+ module ValidationOptionsParser
7
+ def set_options(opts)
8
+ opts.banner = %Q{
9
+ Usage: compass validate [path/to/project] [options]
10
+
11
+ Description:
12
+ Compile project at the path specified or the current
13
+ directory if not specified and then validate the
14
+ generated CSS.
15
+
16
+ Options:
17
+ }.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
18
+
19
+ super
20
+ end
21
+ end
6
22
  class ValidateProject < ProjectBase
7
-
23
+
24
+ register :validate
25
+
8
26
  def initialize(working_path, options)
9
27
  super
10
28
  assert_project_directory_exists!
@@ -16,6 +34,42 @@ module Compass
16
34
  Validator.new(project_css_subdirectory).validate()
17
35
  end
18
36
 
37
+ class << self
38
+
39
+ def option_parser(arguments)
40
+ parser = Compass::Exec::CommandOptionParser.new(arguments)
41
+ parser.extend(Compass::Exec::GlobalOptionsParser)
42
+ parser.extend(Compass::Exec::ProjectOptionsParser)
43
+ parser.extend(ValidationOptionsParser)
44
+ end
45
+
46
+ def usage
47
+ option_parser([]).to_s
48
+ end
49
+
50
+ def description(command)
51
+ "Validate your generated css."
52
+ end
53
+
54
+ def parse!(arguments)
55
+ parser = option_parser(arguments)
56
+ parser.parse!
57
+ parse_arguments!(parser, arguments)
58
+ parser.options
59
+ end
60
+
61
+ def parse_arguments!(parser, arguments)
62
+ if arguments.size == 1
63
+ parser.options[:project_name] = arguments.shift
64
+ elsif arguments.size == 0
65
+ # default to the current directory.
66
+ else
67
+ raise Compass::Error, "Too many arguments were specified."
68
+ end
69
+ end
70
+
71
+ end
72
+
19
73
  end
20
74
  end
21
- end
75
+ end
@@ -7,6 +7,8 @@ module Compass
7
7
  module Commands
8
8
  class WatchProject < UpdateProject
9
9
 
10
+ register :watch
11
+
10
12
  attr_accessor :last_update_time, :last_sass_files
11
13
 
12
14
  def perform
@@ -66,4 +68,4 @@ module Compass
66
68
 
67
69
  end
68
70
  end
69
- end
71
+ end
@@ -2,8 +2,29 @@ require 'compass/commands/project_base'
2
2
 
3
3
  module Compass
4
4
  module Commands
5
+ module ConfigurationOptionsParser
6
+ def set_options(opts)
7
+ opts.banner = %Q{
8
+ Usage: compass config [path/to/config_file.rb] [options]
9
+
10
+ Description:
11
+ Generate a configuration file for the options specified.
12
+ Compass will recognize configuration files in the
13
+ following locations relative to the project root:
14
+ * #{Compass::Configuration::Helpers::KNOWN_CONFIG_LOCATIONS.join("
15
+ * ")}
16
+ Any other location, and you'll need to specify it when working with the command line tool using the -c option.
17
+
18
+ Options:
19
+ }.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
20
+
21
+ super
22
+ end
23
+ end
5
24
  class WriteConfiguration < ProjectBase
6
-
25
+
26
+ register :config
27
+
7
28
  include InstallerCommand
8
29
 
9
30
  def initialize(working_path, options)
@@ -16,6 +37,7 @@ module Compass
16
37
  end
17
38
 
18
39
  def perform
40
+ directory projectize(File.dirname(options[:configuration_file]))
19
41
  installer.write_configuration_files(options[:configuration_file])
20
42
  end
21
43
 
@@ -27,6 +49,42 @@ module Compass
27
49
  false
28
50
  end
29
51
 
52
+ class << self
53
+
54
+ def option_parser(arguments)
55
+ parser = Compass::Exec::CommandOptionParser.new(arguments)
56
+ parser.extend(Compass::Exec::GlobalOptionsParser)
57
+ parser.extend(Compass::Exec::ProjectOptionsParser)
58
+ parser.extend(ConfigurationOptionsParser)
59
+ end
60
+
61
+ def usage
62
+ option_parser([]).to_s
63
+ end
64
+
65
+ def description(command)
66
+ "Generate a configuration file for the provided command line options."
67
+ end
68
+
69
+ def parse!(arguments)
70
+ parser = option_parser(arguments)
71
+ parser.parse!
72
+ parse_arguments!(parser, arguments)
73
+ parser.options
74
+ end
75
+
76
+ def parse_arguments!(parser, arguments)
77
+ if arguments.size == 1
78
+ parser.options[:configuration_file] = arguments.shift
79
+ elsif arguments.size == 0
80
+ # default to the current directory.
81
+ else
82
+ raise Compass::Error, "Too many arguments were specified."
83
+ end
84
+ end
85
+
86
+ end
87
+
30
88
  end
31
89
  end
32
- end
90
+ end