montage 0.2.1 → 0.3.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.
Files changed (56) hide show
  1. data/History.md +23 -0
  2. data/Rakefile +2 -4
  3. data/VERSION +1 -1
  4. data/bin/montage +11 -4
  5. data/lib/montage/commands/generate.rb +72 -11
  6. data/lib/montage/commands/init.rb +5 -11
  7. data/lib/montage/commands.rb +51 -18
  8. data/lib/montage/project.rb +54 -39
  9. data/lib/montage/source.rb +15 -44
  10. data/lib/montage/sprite.rb +25 -37
  11. data/lib/montage/sprite_definition.rb +127 -0
  12. data/lib/montage/templates/montage.yml +29 -19
  13. data/lib/montage/templates/sass_mixins.erb +1 -1
  14. data/lib/montage/templates/sources/{book.png → one/book.png} +0 -0
  15. data/lib/montage/templates/sources/{box-label.png → one/box-label.png} +0 -0
  16. data/lib/montage/templates/sources/{calculator.png → one/calculator.png} +0 -0
  17. data/lib/montage/templates/sources/{calendar-month.png → one/calendar-month.png} +0 -0
  18. data/lib/montage/templates/sources/{camera.png → one/camera.png} +0 -0
  19. data/lib/montage/templates/sources/{eraser.png → one/eraser.png} +0 -0
  20. data/lib/montage/templates/sources/two/inbox-image.png +0 -0
  21. data/lib/montage/templates/sources/two/magnet.png +0 -0
  22. data/lib/montage/templates/sources/two/newspaper.png +0 -0
  23. data/lib/montage/templates/sources/two/television.png +0 -0
  24. data/lib/montage/templates/sources/two/wand-hat.png +0 -0
  25. data/lib/montage/templates/sources/two/wooden-box-label.png +0 -0
  26. data/lib/montage.rb +10 -1
  27. data/montage.gemspec +17 -34
  28. data/spec/lib/project_helper.rb +41 -6
  29. data/spec/lib/shared_project_specs.rb +10 -11
  30. data/spec/montage/commands/generate_spec.rb +86 -132
  31. data/spec/montage/commands/init_spec.rb +18 -43
  32. data/spec/montage/project_spec.rb +77 -63
  33. data/spec/montage/sass_builder_spec.rb +33 -57
  34. data/spec/montage/source_spec.rb +10 -31
  35. data/spec/montage/sprite_definition_spec.rb +361 -0
  36. data/spec/montage/sprite_spec.rb +58 -57
  37. metadata +31 -70
  38. data/spec/fixtures/custom_dirs/montage.yml +0 -8
  39. data/spec/fixtures/default/montage.yml +0 -7
  40. data/spec/fixtures/default/public/images/sprites/src/one.png +0 -0
  41. data/spec/fixtures/default/public/images/sprites/src/three.png +0 -0
  42. data/spec/fixtures/default/public/images/sprites/src/two.png +0 -0
  43. data/spec/fixtures/directory_config/config/montage.yml +0 -5
  44. data/spec/fixtures/missing_source/montage.yml +0 -3
  45. data/spec/fixtures/missing_source_dir/montage.yml +0 -5
  46. data/spec/fixtures/root_config/montage.yml +0 -5
  47. data/spec/fixtures/root_config/public/images/sprites/src/source_one.png +0 -0
  48. data/spec/fixtures/root_config/public/images/sprites/src/source_three.jpg +0 -0
  49. data/spec/fixtures/root_config/public/images/sprites/src/source_two +0 -0
  50. data/spec/fixtures/sources/hundred.png +0 -0
  51. data/spec/fixtures/sources/mammoth.png +0 -0
  52. data/spec/fixtures/sources/other.png +0 -0
  53. data/spec/fixtures/sources/twenty.png +0 -0
  54. data/spec/fixtures/subdirs/montage.yml +0 -5
  55. data/spec/fixtures/subdirs/sub/sub/keep +0 -0
  56. data/spec/lib/fixtures.rb +0 -7
@@ -2,34 +2,30 @@ module Montage
2
2
  # Represents a collection of images which will be used to make a sprite.
3
3
  #
4
4
  class Sprite
5
- attr_reader :name
5
+ attr_reader :name, :save_path, :url, :padding, :sources
6
6
 
7
7
  # Creates a new Sprite instance.
8
8
  #
9
9
  # @param [String] name
10
10
  # The name of the sprite. Will be used as the sprite filename (with an
11
11
  # extension added).
12
- # @param [Array<String>] sources
12
+ # @param [Array(String, Pathname)] sources
13
13
  # The name of each source image.
14
- # @param [Project] Project
14
+ # @param [Pathname] save_path
15
+ # The location at which the sprite should be saved.
16
+ # @param [Montage::Project] project
15
17
  # The project to which the sprite belongs.
18
+ # @param [Hash] options
19
+ # Extra options where you wish to override project defaults.
16
20
  #
17
- def initialize(name, sources, project)
18
- @name, @project = name, project
21
+ def initialize(name, sources, save_path, project, options = {})
22
+ @name = name
23
+ @save_path = save_path
19
24
 
20
- @sources =
21
- sources.inject(ActiveSupport::OrderedHash.new) do |hash, source|
22
- hash[source] = Source.new(@project.paths.sources, source, @name)
23
- hash
24
- end
25
- end
25
+ @padding = options.fetch(:padding, project.padding)
26
+ @url = options.fetch(:url, project.paths.url)
26
27
 
27
- # Returns an array of Source instances held by this Sprite.
28
- #
29
- # @return [Array<Source>]
30
- #
31
- def sources
32
- @sources.map { |_, source| source }
28
+ @sources = sources.map { |path| Source.new(path) }
33
29
  end
34
30
 
35
31
  # Returns an array of RMagick image instances; one for each source.
@@ -41,23 +37,15 @@ module Montage
41
37
  sources.map { |source| source.image }
42
38
  end
43
39
 
44
- # Returns the path to the sprite on disk.
45
- #
46
- # @return [Pathname]
47
- #
48
- def path
49
- @project.paths.sprites + "#{@name}.png"
50
- end
51
-
52
40
  # Returns the y-position of a given source.
53
41
  #
54
42
  # @return [Integer, Source]
55
43
  # The vertical position of the source image.
56
44
  #
57
45
  def position_of(source)
58
- source = source.name if source.is_a?(Source)
46
+ source = source.name if source.is_a?(Montage::Source)
59
47
 
60
- unless @sources.keys.include?(source)
48
+ unless sources.detect { |src| src.name == source }
61
49
  raise MissingSource,
62
50
  "Source image '#{source}' is not present in the '#{@name}' sprite"
63
51
  end
@@ -69,9 +57,9 @@ module Montage
69
57
  # generating CSS), it works out faster to fetch each source height
70
58
  # just once.
71
59
  @positions = {}
72
- @sources.inject(0) do |offset, (name, src)|
73
- @positions[name] = offset
74
- offset + src.image.rows + 20
60
+ @sources.inject(0) do |offset, src|
61
+ @positions[src.name] = offset
62
+ offset + src.image.rows + @padding
75
63
  end
76
64
  end
77
65
 
@@ -96,22 +84,22 @@ module Montage
96
84
  # Raised when the output directory can not be written to.
97
85
  #
98
86
  def write
99
- unless @project.paths.sprites.writable?
87
+ unless @save_path.dirname.writable?
100
88
  raise TargetNotWritable, <<-MESSAGE
101
- Montage can't save the sprite in `#{@project.paths.sprites.to_s}'
89
+ Montage can't save the sprite in `#{@save_path.dirname.to_s}'
102
90
  as it isn't writable.
103
91
  MESSAGE
104
92
  end
105
93
 
106
- list = sources.inject(Magick::ImageList.new) do |list, source|
94
+ list = @sources.inject(Magick::ImageList.new) do |list, source|
107
95
  list << source.image
108
- list << Magick::Image.new(1, @project.padding) do
96
+ list << Magick::Image.new(1, @padding) do
109
97
  self.background_color = '#FFF0'
110
98
  end
111
99
  end
112
100
 
113
101
  # RMagick uses instance_eval, @set isn't available in the block below.
114
- sources_length = sources.length
102
+ sources_length = @sources.length
115
103
 
116
104
  montage = list.montage do
117
105
  self.gravity = Magick::NorthWestGravity
@@ -124,8 +112,8 @@ module Montage
124
112
  end
125
113
 
126
114
  # Remove the blank space from the bottom of the image.
127
- montage.crop!(0, 0, 0, (montage.first.rows) - @project.padding)
128
- montage.write("PNG32:#{path}")
115
+ montage.crop!(0, 0, 0, (montage.first.rows) - @padding)
116
+ montage.write("PNG32:#{@save_path}")
129
117
  end
130
118
 
131
119
  end # Set
@@ -0,0 +1,127 @@
1
+ module Montage
2
+ # Represents a pseudo-file system path, where a directory can be replaced
3
+ # with the :sprite named segment. :name will match any directory -- all
4
+ # files with the same :name value will be placed into the same sprite file.
5
+ #
6
+ # Where a sprite source defines a :name segment, no sprite name needs to be
7
+ # explicitly set in the .montage file.
8
+ #
9
+ # For example, given the following directory structure:
10
+ #
11
+ # /path/to/something/
12
+ # big/
13
+ # one.png
14
+ # two.png
15
+ # small/
16
+ # three.png
17
+ # four.png
18
+ #
19
+ # ... then segmented path "/path/to/something/:name/*" will match all four
20
+ # PNG files, with "one" and "two" being placed in the "big" sprite, "three"
21
+ # and "four" in the "small" sprite.
22
+ #
23
+ class SpriteDefinition
24
+ # Creates a new SpriteDefinition instance.
25
+ #
26
+ # @param [Montage::Project] project
27
+ # @param [String, Pathname] path
28
+ # @param [Hash{String => Object}] options
29
+ #
30
+ def initialize(project, path, options = {})
31
+ @project = project
32
+ @path = project.paths.root + path
33
+
34
+ # Symbolize option keys.
35
+ @options = options.inject({}) do |opts, (key, value)|
36
+ opts[key.to_sym] = value ; opts
37
+ end
38
+
39
+ @options[:to] = (@project.paths.root +
40
+ (@options[:to] || Project::DEFAULTS[:to])).to_s
41
+
42
+ @options[:url] ||= project.paths.url
43
+ @options[:padding] ||= project.padding
44
+
45
+ if has_name_segment? and @options.has_key?(:name)
46
+ raise Montage::DuplicateName, <<-ERROR.compress_lines
47
+ Sprite `#{path}' has both a :name path segment and a "name"
48
+ option; please use only one.
49
+ ERROR
50
+ elsif not has_name_segment? and not @options.has_key?(:name)
51
+ raise Montage::MissingName, <<-ERROR.compress_lines
52
+ Sprite `#{path}' requires a name. Add a :name path segment
53
+ or add a "name" option.
54
+ ERROR
55
+ elsif has_name_segment? and not @options[:to] =~ /:name/
56
+ raise Montage::MissingName, <<-ERROR.compress_lines
57
+ Sprite `#{path}' requires :name in the "to" option.
58
+ ERROR
59
+ end
60
+ end
61
+
62
+ # Returns an array of Sprites defined.
63
+ #
64
+ # @return [Array(Montage::Sprite)]
65
+ #
66
+ def to_sprites
67
+ matching_sources.map do |sprite_name, sources|
68
+ save_path = Pathname.new(@options[:to].gsub(/:name/, sprite_name))
69
+
70
+ url = @options[:url].dup # Since it may be the DEFAULT string
71
+ url.gsub!(/:name/, sprite_name)
72
+ url.gsub!(/:filename/, save_path.basename.to_s)
73
+
74
+ Montage::Sprite.new(sprite_name, sources, save_path, @project,
75
+ :url => url,
76
+ :padding => @options[:padding]
77
+ )
78
+ end
79
+ end
80
+
81
+ private # ================================================================
82
+
83
+ # Returns whether the path has a :name segment.
84
+ #
85
+ # @return [Boolean]
86
+ #
87
+ def has_name_segment?
88
+ @path.to_s =~ /:name/
89
+ end
90
+
91
+ # Returns a Hash containing source files which can be used when creating
92
+ # Sprites. Each key is sprite name with each value the path to a matching
93
+ # source file. When a SpriteDefinition doesn't have a :name segment, the
94
+ # Hash will contain a single key: nil.
95
+ #
96
+ # @return[Hash{String => Array(Pathname)}]
97
+ #
98
+ def matching_sources
99
+ @matching_sources ||= begin
100
+ if not has_name_segment?
101
+ { @options[:name] => Pathname.glob(@path.to_s) }
102
+ else
103
+ regexp = Regexp.escape(@path.to_s)
104
+ regexp.gsub!(/\\\*\\\*/, '.+')
105
+ regexp.gsub!(/\\\*/, '[^\\/]+')
106
+ regexp.gsub!(/:name/, '([^\\/]+)')
107
+
108
+ # Replace OR globs ({png,jpg,etc}).
109
+ regexp.gsub!(/\\\{([^\\\}]+)\\\}/) do |found|
110
+ "(?:#{found[2..-4].split(',').join('|')})"
111
+ end
112
+
113
+ all_files = Pathname.glob(@path.to_s.gsub(/:name/, '*'))
114
+ all_files.inject({}) do |sources, file|
115
+ if file.file? && match = file.to_s.match(regexp)
116
+ sources[match[1]] ||= []
117
+ sources[match[1]] << file
118
+ end
119
+
120
+ sources
121
+ end
122
+ end
123
+ end # begin
124
+ end # matching_sources
125
+
126
+ end # SpriteDefinition
127
+ end # Montage
@@ -1,26 +1,36 @@
1
1
  ---
2
2
 
3
- # If you need to specify non-standard locations for the source
4
- # files, or the output locations for the sprites or SASS, change
5
- # the relevant option below. Directories are relative to the
6
- # project root unless they have a leading slash.
3
+ config.root: "."
4
+ config.sass: "public/stylesheets/sass"
5
+ config.url: "/images/:filename"
7
6
 
8
- config.sources: <sources>
9
- config.sprites: <sprites>
10
- config.sass: "public/stylesheets/sass"
11
- config.sprite_url: "/images/sprites"
7
+ # --------------------------------------------------------------
12
8
 
13
- # --------------------------------------------------------------------------
9
+ # The sample definition below will search each sub-directory in
10
+ # the sources directory; a sprite will be created for each sub-
11
+ # directory containing the png, jpg, and gif files.
12
+ #
13
+ # All paths are relative to the project root file, unless they
14
+ # begin with a / in which case they are absolute. Add as many
15
+ # sprite definitions as you need.
14
16
 
15
- # The sample below will produce two sprites (one.png and two.png) with the
16
- # specified source images. You can omit file extensions.
17
+ "<sources>/:name/*.{png,jpg,jpeg,gif}":
18
+ to: "<sprites>/:name.png"
17
19
 
18
- one:
19
- - book
20
- - box-label
21
- - calculator
20
+ # You can override any of the default settings on a per-sprite
21
+ # basis. For example... (these are the defaults)
22
22
 
23
- two:
24
- - calendar-month
25
- - camera
26
- - eraser
23
+ # "public/images/sprites/src/:name/*.{png,jpg,jpeg,gif}":
24
+ # to: "public/images/:name.png"
25
+ #
26
+ # # The directory in which the sprite(s) are saved relative to
27
+ # # the web-root (used in Sass files to locate the image).
28
+ # url: "/images/:filename"
29
+ #
30
+ # # Puts 20 pixels of space between each source image.
31
+ # padding: 20
32
+
33
+ # # Alternatively, change the default settings for all sprites:
34
+ #
35
+ # config.url: "/omicron_persei_8/sprites"
36
+ # config.sass: false
@@ -8,7 +8,7 @@
8
8
  @<%= index == 0 ? '' : 'else ' %>if $icon == "<%= source.name %>"
9
9
  $y_offset: $y_offset - <%= sprite.position_of(source) %>px
10
10
  <% end %>
11
- background: url(<%= @project.paths.url + "/#{sprite.name}.png" %>) $x_offset $y_offset no-repeat
11
+ background: url(<%= sprite.url %>) $x_offset $y_offset no-repeat
12
12
 
13
13
  =<%= sprite.name %>-sprite-pos($icon, $x_offset: 0px, $y_offset: 0px)
14
14
  <% sprite.sources.each_with_index do |source, index| %>
data/lib/montage.rb CHANGED
@@ -4,7 +4,6 @@ require 'pathname'
4
4
  require 'yaml'
5
5
 
6
6
  # Gems.
7
- require 'active_support/ordered_hash'
8
7
  require 'rmagick'
9
8
 
10
9
  # On with the library...
@@ -13,6 +12,7 @@ require 'montage/project'
13
12
  require 'montage/sass_builder'
14
13
  require 'montage/source'
15
14
  require 'montage/sprite'
15
+ require 'montage/sprite_definition'
16
16
  require 'montage/version'
17
17
 
18
18
  module Montage
@@ -30,4 +30,13 @@ module Montage
30
30
 
31
31
  # Raised when a sprite can't be saved due to incorrect permissions.
32
32
  TargetNotWritable = Class.new(MontageError)
33
+
34
+ # Raised when a sprite defintion doesn't include a name.
35
+ MissingName = Class.new(MontageError)
36
+
37
+ # Raised when a sprite defines a :name path segment, and a name option.
38
+ DuplicateName = Class.new(MontageError)
39
+
40
+ # Raised when a sprite definition doesn't have a to option.
41
+ MissingTo = Class.new(MontageError)
33
42
  end
data/montage.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{montage}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Anthony Williams"]
12
- s.date = %q{2010-04-08}
12
+ s.date = %q{2010-04-12}
13
13
  s.default_executable = %q{montage}
14
14
  s.description = %q{Even Rocky had a montage.}
15
15
  s.email = %q{hi@antw.me}
@@ -36,36 +36,24 @@ Gem::Specification.new do |s|
36
36
  "lib/montage/sass_builder.rb",
37
37
  "lib/montage/source.rb",
38
38
  "lib/montage/sprite.rb",
39
+ "lib/montage/sprite_definition.rb",
39
40
  "lib/montage/templates/montage.yml",
40
41
  "lib/montage/templates/sass_mixins.erb",
41
- "lib/montage/templates/sources/book.png",
42
- "lib/montage/templates/sources/box-label.png",
43
- "lib/montage/templates/sources/calculator.png",
44
- "lib/montage/templates/sources/calendar-month.png",
45
- "lib/montage/templates/sources/camera.png",
46
- "lib/montage/templates/sources/eraser.png",
42
+ "lib/montage/templates/sources/one/book.png",
43
+ "lib/montage/templates/sources/one/box-label.png",
44
+ "lib/montage/templates/sources/one/calculator.png",
45
+ "lib/montage/templates/sources/one/calendar-month.png",
46
+ "lib/montage/templates/sources/one/camera.png",
47
+ "lib/montage/templates/sources/one/eraser.png",
48
+ "lib/montage/templates/sources/two/inbox-image.png",
49
+ "lib/montage/templates/sources/two/magnet.png",
50
+ "lib/montage/templates/sources/two/newspaper.png",
51
+ "lib/montage/templates/sources/two/television.png",
52
+ "lib/montage/templates/sources/two/wand-hat.png",
53
+ "lib/montage/templates/sources/two/wooden-box-label.png",
47
54
  "lib/montage/version.rb",
48
55
  "montage.gemspec",
49
- "spec/fixtures/custom_dirs/montage.yml",
50
- "spec/fixtures/default/montage.yml",
51
- "spec/fixtures/default/public/images/sprites/src/one.png",
52
- "spec/fixtures/default/public/images/sprites/src/three.png",
53
- "spec/fixtures/default/public/images/sprites/src/two.png",
54
- "spec/fixtures/directory_config/config/montage.yml",
55
- "spec/fixtures/missing_source/montage.yml",
56
- "spec/fixtures/missing_source_dir/montage.yml",
57
- "spec/fixtures/root_config/montage.yml",
58
- "spec/fixtures/root_config/public/images/sprites/src/source_one.png",
59
- "spec/fixtures/root_config/public/images/sprites/src/source_three.jpg",
60
- "spec/fixtures/root_config/public/images/sprites/src/source_two",
61
- "spec/fixtures/sources/hundred.png",
62
- "spec/fixtures/sources/mammoth.png",
63
- "spec/fixtures/sources/other.png",
64
- "spec/fixtures/sources/twenty.png",
65
- "spec/fixtures/subdirs/montage.yml",
66
- "spec/fixtures/subdirs/sub/sub/keep",
67
56
  "spec/lib/command_runner.rb",
68
- "spec/lib/fixtures.rb",
69
57
  "spec/lib/have_public_method_defined.rb",
70
58
  "spec/lib/project_helper.rb",
71
59
  "spec/lib/shared_project_specs.rb",
@@ -77,6 +65,7 @@ Gem::Specification.new do |s|
77
65
  "spec/montage/sass_builder_spec.rb",
78
66
  "spec/montage/source_spec.rb",
79
67
  "spec/montage/spec/have_public_method_defined_spec.rb",
68
+ "spec/montage/sprite_definition_spec.rb",
80
69
  "spec/montage/sprite_spec.rb",
81
70
  "spec/rcov.opts",
82
71
  "spec/spec.opts",
@@ -92,7 +81,6 @@ Gem::Specification.new do |s|
92
81
  s.summary = %q{Montage}
93
82
  s.test_files = [
94
83
  "spec/lib/command_runner.rb",
95
- "spec/lib/fixtures.rb",
96
84
  "spec/lib/have_public_method_defined.rb",
97
85
  "spec/lib/project_helper.rb",
98
86
  "spec/lib/shared_project_specs.rb",
@@ -104,6 +92,7 @@ Gem::Specification.new do |s|
104
92
  "spec/montage/sass_builder_spec.rb",
105
93
  "spec/montage/source_spec.rb",
106
94
  "spec/montage/spec/have_public_method_defined_spec.rb",
95
+ "spec/montage/sprite_definition_spec.rb",
107
96
  "spec/montage/sprite_spec.rb",
108
97
  "spec/spec_helper.rb"
109
98
  ]
@@ -113,30 +102,24 @@ Gem::Specification.new do |s|
113
102
  s.specification_version = 3
114
103
 
115
104
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
116
- s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0.beta"])
117
105
  s.add_runtime_dependency(%q<rmagick>, [">= 2.12"])
118
106
  s.add_runtime_dependency(%q<highline>, [">= 1.5"])
119
107
  s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
120
- s.add_development_dependency(%q<cucumber>, [">= 0.6"])
121
108
  s.add_development_dependency(%q<open4>, [">= 1.0"])
122
109
  s.add_development_dependency(%q<haml>, [">= 3.0.0.beta.1"])
123
110
  s.add_development_dependency(%q<yard>, [">= 0.5"])
124
111
  else
125
- s.add_dependency(%q<activesupport>, [">= 3.0.0.beta"])
126
112
  s.add_dependency(%q<rmagick>, [">= 2.12"])
127
113
  s.add_dependency(%q<highline>, [">= 1.5"])
128
114
  s.add_dependency(%q<rspec>, [">= 1.3.0"])
129
- s.add_dependency(%q<cucumber>, [">= 0.6"])
130
115
  s.add_dependency(%q<open4>, [">= 1.0"])
131
116
  s.add_dependency(%q<haml>, [">= 3.0.0.beta.1"])
132
117
  s.add_dependency(%q<yard>, [">= 0.5"])
133
118
  end
134
119
  else
135
- s.add_dependency(%q<activesupport>, [">= 3.0.0.beta"])
136
120
  s.add_dependency(%q<rmagick>, [">= 2.12"])
137
121
  s.add_dependency(%q<highline>, [">= 1.5"])
138
122
  s.add_dependency(%q<rspec>, [">= 1.3.0"])
139
- s.add_dependency(%q<cucumber>, [">= 0.6"])
140
123
  s.add_dependency(%q<open4>, [">= 1.0"])
141
124
  s.add_dependency(%q<haml>, [">= 3.0.0.beta.1"])
142
125
  s.add_dependency(%q<yard>, [">= 0.5"])
@@ -34,8 +34,8 @@ module Montage
34
34
  self.class.cleanup!
35
35
  project_dir.mkpath
36
36
 
37
- self.sources_path = "public/images/sprites/src"
38
- self.sprites_path = "public/images/sprites"
37
+ self.sources_path = "public/images/sprites"
38
+ self.sprites_path = "public/images"
39
39
  end
40
40
 
41
41
  def sources_path=(path)
@@ -86,17 +86,40 @@ module Montage
86
86
 
87
87
  # --- File Writers -----------------------------------------------------
88
88
 
89
- # Writes montage.yml file in the project root with the given contents.
89
+ # Writes .montage file in the project root with the given contents.
90
90
  #
91
+ # @param [String] to
92
+ # The path at which to save the config file. Or: The file contents if
93
+ # you want to save at the default location.
91
94
  # @param [String] contents
92
95
  # The contents to be saved as the config file.
93
96
  #
94
- def write_config(contents)
95
- File.open(project_dir + 'montage.yml', 'w') do |file|
97
+ def write_config(to, contents = nil)
98
+ if contents.nil?
99
+ # Sigh; if only 1.9 was more popular...
100
+ contents, to = to, '.montage'
101
+ else
102
+ (project_dir + to).dirname.mkpath
103
+ end
104
+
105
+ File.open(project_dir + to, 'w') do |file|
96
106
  file.puts contents.unindent
97
107
  end
98
108
  end
99
109
 
110
+ # Writes a simple config file.
111
+ #
112
+ # @param [String] to
113
+ # The path at which to save the config file.
114
+ #
115
+ def write_simple_config(to = '.montage')
116
+ write_config to, <<-CONFIG
117
+ ---
118
+ "public/images/sprites/:name/*.{png,jpg,jpeg,gif}":
119
+ to: "public/images/:name.png"
120
+ CONFIG
121
+ end
122
+
100
123
  # Writes a source image file to the src directory.
101
124
  #
102
125
  # @param [String] name
@@ -123,13 +146,25 @@ module Montage
123
146
 
124
147
  # Creates a directory in the project.
125
148
  #
126
- # @param [String] dir
149
+ # @param [String] path
127
150
  # Path to the directory, relative to the project root.
128
151
  #
129
152
  def mkdir(path)
130
153
  (project_dir + path).mkpath
131
154
  end
132
155
 
156
+ # Creates an empty file.
157
+ #
158
+ # @param [String] path
159
+ # Path to the file to be touched.
160
+ #
161
+ def touch(*paths)
162
+ paths.each do |path|
163
+ (project_dir + path).dirname.mkpath
164
+ FileUtils.touch(project_dir + path)
165
+ end
166
+ end
167
+
133
168
  end # ProjectHelper
134
169
  end # Spec
135
170
  end # Montage
@@ -2,9 +2,16 @@ describe 'a project with correct paths', :shared => true do
2
2
  # Requires:
3
3
  #
4
4
  # @project => Montage::Project
5
- # @root => Pathname (path to project root)
5
+ # @helper => Montage::Spec::ProjectHelper
6
6
  # @config => Pathname (path to config file)
7
7
  #
8
+ # (optional)
9
+ # @root => Pathname (path to the root of the project)
10
+ #
11
+
12
+ before(:all) do
13
+ @root ||= @helper.project_dir
14
+ end
8
15
 
9
16
  it 'should set the project root path' do
10
17
  @project.paths.root.should == @root
@@ -14,19 +21,11 @@ describe 'a project with correct paths', :shared => true do
14
21
  @project.paths.config.should == @config
15
22
  end
16
23
 
17
- it 'should set the sources path' do
18
- @project.paths.sources.should == @root + 'public/images/sprites/src'
19
- end
20
-
21
- it 'should set the sprite path' do
22
- @project.paths.sprites.should == @root + 'public/images/sprites'
23
- end
24
-
25
24
  it 'should set the SASS output path' do
26
25
  @project.paths.sass.should == @root + 'public/stylesheets/sass'
27
26
  end
28
27
 
29
28
  it 'should set the CSS sprite URL' do
30
- @project.paths.url.should == '/images/sprites'
29
+ @project.paths.url.should == '/images/:name.png'
31
30
  end
32
- end
31
+ end