css-spriter 0.9.2 → 1.0.1
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/README.rdoc +7 -9
- data/Rakefile +7 -8
- data/VERSION +1 -1
- data/bin/css-spriter +1 -1
- data/css-spriter.gemspec +106 -0
- data/lib/css-spriter.rb +2 -11
- data/lib/css-spriter/directory_processor.rb +82 -78
- data/lib/css-spriter/image.rb +13 -0
- data/lib/css-spriter/mtime_tracker.rb +64 -61
- data/lib/css-spriter/sprite.rb +39 -31
- data/lib/css-spriter/stylesheet_builder.rb +19 -17
- data/spec/builders/image_builder.rb +3 -8
- data/spec/integration_spec.rb +27 -50
- data/spec/lib/css_spriter_image_spec.rb +8 -0
- data/spec/lib/sprite_spec.rb +4 -6
- data/spec/mtime_tracking_spec.rb +33 -19
- data/spec/spec_helper.rb +5 -5
- metadata +50 -40
- data/.gitignore +0 -12
- data/bin/png_info +0 -61
- data/examples/filter_util.rb +0 -17
- data/lib/css-spriter/image_data.rb +0 -128
- data/lib/css-spriter/png/chunk.rb +0 -12
- data/lib/css-spriter/png/file_header.rb +0 -7
- data/lib/css-spriter/png/filters.rb +0 -80
- data/lib/css-spriter/png/idat.rb +0 -26
- data/lib/css-spriter/png/iend.rb +0 -9
- data/lib/css-spriter/png/ihdr.rb +0 -34
- data/lib/css-spriter/png/image.rb +0 -153
- data/lib/css-spriter/png/parser.rb +0 -54
- data/spec/image_data_spec.rb +0 -63
- data/spec/lib/file_header_spec.rb +0 -10
- data/spec/lib/idat_spec.rb +0 -31
- data/spec/lib/ihdr_spec.rb +0 -43
- data/spec/lib/image_spec.rb +0 -42
- data/spec/lib/parser_spec.rb +0 -12
data/README.rdoc
CHANGED
@@ -15,6 +15,10 @@ It takes your PNG's, chews them up and spits out sprites!
|
|
15
15
|
|
16
16
|
point bin/css-spriter at a directory, and watch it sprite away!
|
17
17
|
|
18
|
+
CSS-Spriter uses Chunky PNG for it's PNG manipulation. Not only is it super fast, but the library is a great example of fast, efficient ruby programming.
|
19
|
+
|
20
|
+
Chunky PNG is written in pure ruby, this means you can sprite up anything using MRI, JRuby, or Rubinius.
|
21
|
+
|
18
22
|
== Installation - standalone
|
19
23
|
|
20
24
|
sudo gem install css-spriter
|
@@ -35,7 +39,7 @@ For a full list of options:
|
|
35
39
|
|
36
40
|
=== Usage - Rails plugin
|
37
41
|
|
38
|
-
|
42
|
+
CSS-Spriter assumes all of your sprites are located in the directory public/images/sprites. This directory should contain sub-directories for each sprite you wish to create. The css class names for an image in a sprite will take the form <directory_name>_<image_name>. Here is an example:
|
39
43
|
|
40
44
|
sprites /
|
41
45
|
cars /
|
@@ -45,14 +49,10 @@ Spittle assumes all of your sprites are located in the directory public/images/s
|
|
45
49
|
boeing.png
|
46
50
|
cesna.png
|
47
51
|
|
48
|
-
Running sprite:generate does all the work. Each sprite directory (cars, planes) will now contain a sprite.png. Spittle will also generate a sprites.css stylesheet in public/stylesheets/ that you should include in your layout. If you wished to use the ford image from the cars sprite you would give the 'cars_ford' class to the desired element in the view. That's it!
|
49
|
-
|
50
|
-
Check out examples/sprites if you want to see what spriter can do without doing any work.
|
52
|
+
Running the sprite:generate task does all the work. Each sprite directory (cars, planes) will now contain a sprite.png. Spittle will also generate a sprites.css stylesheet in public/stylesheets/ that you should include in your layout. If you wished to use the ford image from the cars sprite you would give the 'cars_ford' class to the desired element in the view. That's it!
|
51
53
|
|
52
|
-
|
54
|
+
Check out examples/sprites if you want to see what CSS-Spriter can do without doing any work.
|
53
55
|
|
54
|
-
- does not support color profiles (can cause a slight change in color from the source image)
|
55
|
-
- does not support reading interlaced PNGs.
|
56
56
|
|
57
57
|
== Features
|
58
58
|
|
@@ -62,12 +62,10 @@ Check out examples/sprites if you want to see what spriter can do without doing
|
|
62
62
|
- Rails plugin & rake tasks (sprite:generate & sprite:cleanup)
|
63
63
|
- Supports varying dimensions in source images
|
64
64
|
- Does not regenerate sprites that have not changed
|
65
|
-
- Supports all PNG filter types to improve image compression
|
66
65
|
- supports mixing RGB and RGBA color types
|
67
66
|
|
68
67
|
== Roadmap - by priority
|
69
68
|
|
70
|
-
- Reading interlaced images
|
71
69
|
- allow a global css template override
|
72
70
|
- allow per-sprite and global configuration
|
73
71
|
|
data/Rakefile
CHANGED
@@ -6,11 +6,12 @@ begin
|
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "css-spriter"
|
8
8
|
gem.summary = %Q{pure ruby PNG spriting library}
|
9
|
-
gem.description = %Q{
|
9
|
+
gem.description = %Q{CSS-Spriter is a pure ruby PNG spriting library. It can be used standalone or as a Rails plugin, see the readme for details.}
|
10
10
|
gem.email = ["qzzzq1@gmail.com", "tyler.jennings@gmail.com"]
|
11
11
|
gem.homepage = "http://github.com/aberant/css-spriter"
|
12
12
|
gem.authors = ["aberant", "tjennings"]
|
13
13
|
gem.add_development_dependency "rspec" #, ">= 1.2.9"
|
14
|
+
gem.add_dependency "chunky_png", "~> 1.1.0"
|
14
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
16
|
end
|
16
17
|
Jeweler::GemcutterTasks.new
|
@@ -18,14 +19,12 @@ rescue LoadError
|
|
18
19
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
20
|
end
|
20
21
|
|
21
|
-
require '
|
22
|
-
|
23
|
-
|
24
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
22
|
+
require 'rspec/core/rake_task'
|
23
|
+
RSpec::Core::RakeTask.new do |task|
|
24
|
+
task.pattern = 'spec/**/*_spec.rb'
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
spec.libs << 'lib' << 'spec'
|
27
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
29
28
|
spec.pattern = 'spec/**/*_spec.rb'
|
30
29
|
spec.rcov = true
|
31
30
|
end
|
@@ -39,7 +38,7 @@ Rake::RDocTask.new do |rdoc|
|
|
39
38
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
39
|
|
41
40
|
rdoc.rdoc_dir = 'rdoc'
|
42
|
-
rdoc.title = "
|
41
|
+
rdoc.title = "css-spriter #{version}"
|
43
42
|
rdoc.rdoc_files.include('README*')
|
44
43
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
44
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.1
|
data/bin/css-spriter
CHANGED
data/css-spriter.gemspec
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{css-spriter}
|
8
|
+
s.version = "1.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["aberant", "tjennings"]
|
12
|
+
s.date = %q{2011-03-23}
|
13
|
+
s.default_executable = %q{css-spriter}
|
14
|
+
s.description = %q{CSS-Spriter is a pure ruby PNG spriting library. It can be used standalone or as a Rails plugin, see the readme for details.}
|
15
|
+
s.email = ["qzzzq1@gmail.com", "tyler.jennings@gmail.com"]
|
16
|
+
s.executables = ["css-spriter"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"MIT-LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"bin/css-spriter",
|
26
|
+
"css-spriter.gemspec",
|
27
|
+
"examples/sprites/.mtimes",
|
28
|
+
"examples/sprites/README",
|
29
|
+
"examples/sprites/fragment.css",
|
30
|
+
"examples/sprites/index.html",
|
31
|
+
"examples/sprites/many_sized_cats/.mtimes",
|
32
|
+
"examples/sprites/many_sized_cats/cat-on-keyboard.png",
|
33
|
+
"examples/sprites/many_sized_cats/darth_cat.png",
|
34
|
+
"examples/sprites/many_sized_cats/fragment.css",
|
35
|
+
"examples/sprites/many_sized_cats/music-keyboard-cat.png",
|
36
|
+
"examples/sprites/many_sized_cats/sprite.css",
|
37
|
+
"examples/sprites/many_sized_cats/sprite.png",
|
38
|
+
"examples/sprites/server.rb",
|
39
|
+
"examples/sprites/sprite.css",
|
40
|
+
"examples/sprites/words/.mtimes",
|
41
|
+
"examples/sprites/words/fragment.css",
|
42
|
+
"examples/sprites/words/latitude.png",
|
43
|
+
"examples/sprites/words/of.png",
|
44
|
+
"examples/sprites/words/set.png",
|
45
|
+
"examples/sprites/words/specified.png",
|
46
|
+
"examples/sprites/words/sprite.css",
|
47
|
+
"examples/sprites/words/sprite.png",
|
48
|
+
"init.rb",
|
49
|
+
"lib/css-spriter.rb",
|
50
|
+
"lib/css-spriter/directory_processor.rb",
|
51
|
+
"lib/css-spriter/image.rb",
|
52
|
+
"lib/css-spriter/mtime_tracker.rb",
|
53
|
+
"lib/css-spriter/processor.rb",
|
54
|
+
"lib/css-spriter/sprite.rb",
|
55
|
+
"lib/css-spriter/stylesheet_builder.rb",
|
56
|
+
"spec/builders/image_builder.rb",
|
57
|
+
"spec/css_fragments/deep/style/fragment.css",
|
58
|
+
"spec/css_fragments/some/fragment.css",
|
59
|
+
"spec/expected_output/merge_right_test.png",
|
60
|
+
"spec/expected_output/write_test.png",
|
61
|
+
"spec/images/lightening.png",
|
62
|
+
"spec/integration_spec.rb",
|
63
|
+
"spec/lib/css_spriter_image_spec.rb",
|
64
|
+
"spec/lib/sprite_spec.rb",
|
65
|
+
"spec/mtime_tracking_spec.rb",
|
66
|
+
"spec/spec.opts",
|
67
|
+
"spec/spec_helper.rb",
|
68
|
+
"spec/sprite_dirs/words/latitude.png",
|
69
|
+
"spec/sprite_dirs/words/of.png",
|
70
|
+
"spec/sprite_dirs/words/set.png",
|
71
|
+
"spec/sprite_dirs/words/specified.png",
|
72
|
+
"spec/tmp/merge_right_test.png",
|
73
|
+
"spec/tmp/write_test.png",
|
74
|
+
"tasks/spriter_tasks.rake"
|
75
|
+
]
|
76
|
+
s.homepage = %q{http://github.com/aberant/css-spriter}
|
77
|
+
s.require_paths = ["lib"]
|
78
|
+
s.rubygems_version = %q{1.3.7}
|
79
|
+
s.summary = %q{pure ruby PNG spriting library}
|
80
|
+
s.test_files = [
|
81
|
+
"examples/sprites/server.rb",
|
82
|
+
"spec/builders/image_builder.rb",
|
83
|
+
"spec/integration_spec.rb",
|
84
|
+
"spec/lib/css_spriter_image_spec.rb",
|
85
|
+
"spec/lib/sprite_spec.rb",
|
86
|
+
"spec/mtime_tracking_spec.rb",
|
87
|
+
"spec/spec_helper.rb"
|
88
|
+
]
|
89
|
+
|
90
|
+
if s.respond_to? :specification_version then
|
91
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
92
|
+
s.specification_version = 3
|
93
|
+
|
94
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
95
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
96
|
+
s.add_runtime_dependency(%q<chunky_png>, ["~> 1.1.0"])
|
97
|
+
else
|
98
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
99
|
+
s.add_dependency(%q<chunky_png>, ["~> 1.1.0"])
|
100
|
+
end
|
101
|
+
else
|
102
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
103
|
+
s.add_dependency(%q<chunky_png>, ["~> 1.1.0"])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
data/lib/css-spriter.rb
CHANGED
@@ -1,16 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'css-spriter/png/file_header'
|
4
|
-
require 'css-spriter/png/parser'
|
5
|
-
require 'css-spriter/png/filters'
|
6
|
-
require 'css-spriter/png/chunk'
|
7
|
-
require 'css-spriter/png/ihdr'
|
8
|
-
require 'css-spriter/png/idat'
|
9
|
-
require 'css-spriter/png/iend'
|
10
|
-
require 'css-spriter/png/image'
|
1
|
+
require 'chunky_png'
|
11
2
|
require 'css-spriter/sprite'
|
3
|
+
require 'css-spriter/image'
|
12
4
|
require 'css-spriter/directory_processor'
|
13
5
|
require 'css-spriter/stylesheet_builder'
|
14
6
|
require 'css-spriter/processor'
|
15
7
|
require 'css-spriter/mtime_tracker'
|
16
|
-
require 'css-spriter/image_data'
|
@@ -1,94 +1,98 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
DEFAULT_TEMPLATE = <<-EOF
|
4
|
-
.<name>_<image_name> {
|
5
|
-
background: transparent url(<image_loc>) <offset>px 0px no-repeat;
|
6
|
-
width:<width>;
|
7
|
-
height:<height>;
|
8
|
-
text-indent:-5000px;
|
9
|
-
}
|
10
|
-
|
11
|
-
EOF
|
12
|
-
|
13
|
-
def initialize(dir, options = {})
|
14
|
-
@options = options
|
15
|
-
@dir = dir
|
16
|
-
@sprite = Sprite.new
|
17
|
-
@tracker = MtimeTracker.new(@dir,
|
18
|
-
:exclude => ['sprite.css', 'fragment.css', 'sprite.png'])
|
19
|
-
end
|
1
|
+
module CssSpriter
|
2
|
+
class DirectoryProcessor
|
20
3
|
|
21
|
-
|
22
|
-
|
23
|
-
|
4
|
+
DEFAULT_TEMPLATE = <<-EOF
|
5
|
+
.<name>_<image_name> {
|
6
|
+
background: transparent url(<image_loc>) <offset>px 0px no-repeat;
|
7
|
+
width:<width>;
|
8
|
+
height:<height>;
|
9
|
+
text-indent:-5000px;
|
10
|
+
}
|
24
11
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
12
|
+
EOF
|
13
|
+
|
14
|
+
def initialize(dir, options = {})
|
15
|
+
@options = options
|
16
|
+
@dir = dir
|
17
|
+
@sprite = Sprite.new
|
18
|
+
@tracker = MtimeTracker.new(@dir,
|
19
|
+
:exclude => ['sprite.css', 'fragment.css', 'sprite.png'])
|
31
20
|
end
|
32
|
-
@tracker.update
|
33
|
-
end
|
34
21
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@tracker.cleanup
|
39
|
-
end
|
22
|
+
def images
|
23
|
+
Dir.glob(@dir + "/*.png").reject{|i| i.match /sprite\.png/}
|
24
|
+
end
|
40
25
|
|
41
|
-
|
42
|
-
|
43
|
-
|
26
|
+
def write
|
27
|
+
return unless @tracker.has_changes?
|
28
|
+
images.each {|f| @sprite.append_file(f)}
|
44
29
|
|
45
|
-
|
46
|
-
@dir + "/fragment.css"
|
47
|
-
end
|
30
|
+
@sprite.write(sprite_file)
|
48
31
|
|
49
|
-
|
50
|
-
|
51
|
-
|
32
|
+
File.open(css_file, 'w') do |f|
|
33
|
+
f.write(css)
|
34
|
+
end
|
35
|
+
@tracker.update
|
36
|
+
end
|
52
37
|
|
53
|
-
|
54
|
-
|
38
|
+
def cleanup
|
39
|
+
File.delete(sprite_file) rescue nil
|
40
|
+
File.delete(css_file) rescue nil
|
41
|
+
@tracker.cleanup
|
42
|
+
end
|
55
43
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
base = base.gsub(source, "") if source && source != "."
|
60
|
-
base = @options[:path_prefix] + base if @options[:path_prefix]
|
61
|
-
base
|
62
|
-
end
|
44
|
+
def sprite_file
|
45
|
+
@dir + "/sprite.png"
|
46
|
+
end
|
63
47
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
path_elements.pop #we want to remove everything above the root
|
68
|
-
to_truncate = path_elements.join("/")
|
69
|
-
@dir.gsub(to_truncate, "")
|
70
|
-
end
|
48
|
+
def css_file
|
49
|
+
@dir + "/fragment.css"
|
50
|
+
end
|
71
51
|
|
72
|
-
|
73
|
-
|
74
|
-
|
52
|
+
def dir_name
|
53
|
+
@dir.split('/').last
|
54
|
+
end
|
55
|
+
|
56
|
+
def image_loc
|
57
|
+
#TODO: Lame!
|
75
58
|
|
76
|
-
|
77
|
-
|
78
|
-
|
59
|
+
dir = truncate_abs_path
|
60
|
+
base = ("/" + dir + "/sprite.png").gsub(/^\/.\//, "/").gsub("//", "/")
|
61
|
+
source = @options[:source]
|
62
|
+
base = base.gsub(source, "") if source && source != "."
|
63
|
+
base = @options[:path_prefix] + base if @options[:path_prefix]
|
64
|
+
base
|
65
|
+
end
|
66
|
+
|
67
|
+
def truncate_abs_path
|
68
|
+
return @dir unless @options[:source]
|
69
|
+
path_elements = @options[:source].split('/')
|
70
|
+
path_elements.pop #we want to remove everything above the root
|
71
|
+
to_truncate = path_elements.join("/")
|
72
|
+
@dir.gsub(to_truncate, "")
|
73
|
+
end
|
74
|
+
|
75
|
+
def template_file
|
76
|
+
@dir + "/template.css"
|
77
|
+
end
|
78
|
+
|
79
|
+
def template
|
80
|
+
if File.exists?(template_file)
|
81
|
+
return File.read(template_file)
|
82
|
+
end
|
83
|
+
return DEFAULT_TEMPLATE
|
79
84
|
end
|
80
|
-
return DEFAULT_TEMPLATE
|
81
|
-
end
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
def css
|
87
|
+
@sprite.locations.inject("") do |out, image|
|
88
|
+
image_name, properties = image
|
89
|
+
out << template.gsub("<name>", dir_name).
|
90
|
+
gsub("<image_name>", image_name.to_s).
|
91
|
+
gsub("<width>", properties[:width].to_s).
|
92
|
+
gsub("<height>", properties[:height].to_s).
|
93
|
+
gsub("<offset>", properties[:x].to_s).
|
94
|
+
gsub("<image_loc>", image_loc)
|
95
|
+
end
|
92
96
|
end
|
93
97
|
end
|
94
|
-
end
|
98
|
+
end
|
@@ -1,79 +1,82 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module CssSpriter
|
2
|
+
class MtimeTracker
|
3
|
+
def initialize(dir, options = {})
|
4
|
+
@dir = dir
|
5
|
+
@options = options
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def cleanup
|
9
|
+
File.delete(mtime_file) rescue nil
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def fresh?
|
13
|
+
not File.exists?(mtime_file)
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
16
|
+
def files
|
17
|
+
@files = without_exclusions(Dir.glob(@dir + "/**/*"))
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
def without_exclusions(files)
|
21
|
+
return files unless @options[:exclude]
|
22
|
+
exclusions = [@options[:exclude]].flatten
|
23
|
+
files.select{|f| not exclusions.any?{|e| f.match e}}
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
def current_mtimes
|
27
|
+
@current ||= files.inject({}) do |map, f|
|
28
|
+
map[f] = File.mtime(f).to_i; map
|
29
|
+
end
|
29
30
|
end
|
30
|
-
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def file_changed?(file)
|
33
|
+
mtimes[file] != current_mtimes[file]
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def mtimes
|
37
|
+
return @mtimes if @mtimes
|
38
|
+
return {} unless File.exists?(mtime_file)
|
39
|
+
@mtimes = read_mtimes
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
def read_mtimes
|
43
|
+
mtimes = {}
|
44
|
+
File.open(mtime_file) do |f|
|
45
|
+
f.each do |line|
|
46
|
+
name, time = line.split("\t")
|
47
|
+
mtimes[name] = time.to_i
|
48
|
+
end
|
48
49
|
end
|
50
|
+
mtimes
|
49
51
|
end
|
50
|
-
mtimes
|
51
|
-
end
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
def changeset
|
54
|
+
changed = files.select{|f| file_changed?(f)}
|
55
|
+
deleted = without_exclusions(mtimes.keys) - current_mtimes.keys
|
56
|
+
changed + deleted
|
57
|
+
end
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
def has_changes?
|
60
|
+
not changeset.empty?
|
61
|
+
end
|
60
62
|
|
61
|
-
|
62
|
-
|
63
|
-
|
63
|
+
def mtime_file
|
64
|
+
@dir + "/.mtimes"
|
65
|
+
end
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
def update
|
68
|
+
File.open(mtime_file, 'w') do |f|
|
69
|
+
current = current_mtimes
|
70
|
+
flat = current.map{|k, v| "#{k}\t#{v}\n"}.join
|
71
|
+
f.write flat
|
72
|
+
end
|
73
|
+
reset
|
70
74
|
end
|
71
|
-
reset
|
72
|
-
end
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
76
|
+
def reset
|
77
|
+
@mtimes = nil
|
78
|
+
@current = nil
|
79
|
+
@files = nil
|
80
|
+
end
|
78
81
|
end
|
79
|
-
end
|
82
|
+
end
|