Class: Bagger::Packager

Inherits:
Object
  • Object
show all
Defined in:
lib/bagger/packager.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Packager

Returns a new instance of Packager.



12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/bagger/packager.rb', line 12

def initialize(options)
  @options = options
  @source_dir = @options[:source_dir]
  @target_dir = @options[:target_dir]
  @manifest_path = @options[:manifest_path] || File.join(@source_dir, 'manifest.json')
  @cache_manifest_path = @options[:cache_manifest_path] || 'cache.manifest'
  @path_prefix = @options[:path_prefix] || ''
  @css_path_prefix = @options[:css_path_prefix] || ''
  @exclude_files = Array(@options[:exclude_files])
  @exclude_pattern = @options[:exclude_pattern]
  @manifest_key = @options[:manifest_key]
  @manifest = {}
end

Instance Method Details

#add_selfObject



73
74
75
# File 'lib/bagger/packager.rb', line 73

def add_self
  add_to_manifest(@manifest_key, File.basename(@manifest_path)) if @manifest_key
end

#add_to_manifest(key, path) ⇒ Object



26
27
28
29
30
31
32
33
34
35
# File 'lib/bagger/packager.rb', line 26

def add_to_manifest(key, path)
  if @options[:extended_manifest]
    @manifest[key] = {
      :path => File.expand_path(@path_prefix + "/" + path),
      :size => File.size(File.join(@target_dir, path))
    }
  else
    @manifest[key] = File.expand_path(@path_prefix + "/" + path)
  end
end

#combine_cssObject



97
98
99
100
101
102
103
104
105
# File 'lib/bagger/packager.rb', line 97

def combine_css
  stylesheets.each do |config|
    combine_files(config[:files], config[:target_path])
    rewrite_urls_in_css(config[:target_path])
    compress_css(config[:target_path])
    to_manifest(config[:target_path], false)
    gzip_target(config[:target_path]) if @options[:gzip]
  end
end

#combine_jsObject



138
139
140
141
142
143
144
145
# File 'lib/bagger/packager.rb', line 138

def combine_js
  javascripts.each do |config|
    combine_files(config[:files], config[:target_path])
    compress_js(config[:target_path])
    to_manifest(config[:target_path], false)
    gzip_target(config[:target_path]) if @options[:gzip]
  end
end

#compress_css(stylesheet_path) ⇒ Object



130
131
132
133
134
135
136
# File 'lib/bagger/packager.rb', line 130

def compress_css(stylesheet_path)
  css = File.open(File.join(@target_dir, stylesheet_path)){|f| f.read}
  compressed = Rainpress.compress(css)
  File.open(File.join(@target_dir, stylesheet_path), 'w') do |f|
    f.write compressed
  end
end

#compress_js(javascript_path) ⇒ Object



147
148
149
150
151
# File 'lib/bagger/packager.rb', line 147

def compress_js(javascript_path)
  javascript = File.open(File.join(@target_dir, javascript_path)){|f| f.read}
  compressed = Uglifier.compile(javascript)
  File.open(File.join(@target_dir, javascript_path), 'w'){|f| f.write compressed}
end

#generate_cache_manifest(cache_manifest) ⇒ Object

IMPORTANT:html 5 cache manifest should not be cached because that would treat it as a new manifest with new resources discarding the ones already downloaded diveintohtml5.org/offline.html



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/bagger/packager.rb', line 170

def generate_cache_manifest(cache_manifest)
  path = File.join(@target_dir, cache_manifest[:target_path])
  FileUtils.mkdir_p(File.dirname(path))
  File.open(path, 'w') do |f|
    f.puts 'CACHE MANIFEST'
    f.puts ''
    f.puts '# Explicitely cached entries'
    cache_manifest[:files].each do |relative_path|
      f.puts @manifest[File.join('/', relative_path)]
    end
    f.puts ''
    f.puts 'NETWORK:'
    f.puts '*'
  end
  add_to_manifest(File.join("/", cache_manifest[:target_path]), cache_manifest[:target_path])
end

#generate_cache_manifestsObject



153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/bagger/packager.rb', line 153

def generate_cache_manifests
  cache_manifests = @options[:cache_manifests] || []
  if @cache_manifest_path
    cache_manifests << {
      :target_path => @cache_manifest_path,
      :files => @manifest.keys
    }
  end
  cache_manifests.each do |cache_manifest|
    generate_cache_manifest(cache_manifest)
  end
end

#javascriptsObject



57
58
59
# File 'lib/bagger/packager.rb', line 57

def javascripts
  @javascripts ||= calculate_javascripts
end

#rewrite_urls_in_css(stylesheet_path) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/bagger/packager.rb', line 107

def rewrite_urls_in_css(stylesheet_path)
  url_regex = /(url\(\s*['"]?)([^#].*?)(['"]?\s*\).*?)/ui
  data_regex = /^\s*data:/ui
  input = File.open(File.join(@target_dir, stylesheet_path)){|f| f.read}
  output = input.gsub(url_regex) do |full_match|
    pre, url_match, post = $1, $2, $3
    if data_regex.match(url_match)
      full_match
    else
      path = Addressable::URI.parse('/') + url_match
      target_url = @manifest[path.to_s]
      if target_url
        pre + @css_path_prefix + target_url + post
      else
        full_match
      end
    end
  end
  File.open(File.join(@target_dir, stylesheet_path), 'w') do |f|
    f.write output
  end
end

#runObject



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/bagger/packager.rb', line 61

def run
  debug "reading files from #{@source_dir}"
  validate
  version_files
  combine_css
  combine_js
  generate_cache_manifests
  add_self
  write_manifest
  debug "files written to #{@target_dir}"
end

#stylesheetsObject



53
54
55
# File 'lib/bagger/packager.rb', line 53

def stylesheets
  @stylesheets ||= calculate_stylesheets
end

#to_manifest(path, keep_original = true) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/bagger/packager.rb', line 37

def to_manifest(path, keep_original = true)
   debug "adding: #{path}"
   content = File.open(File.join(@target_dir, path)) { |f| f.read }
   extension = File.extname(path)
   basename = File.basename(path, extension)
   dirname = File.dirname(path)
   FileUtils.mkdir_p(File.join(@target_dir, dirname))
   md5 = Digest::MD5.hexdigest(content)
   new_file_name = "#{basename}.#{md5}#{extension}"
   new_file_path = File.join(@target_dir, dirname, new_file_name)
   File.open(new_file_path, 'w') { |f| f.write content }
   FileUtils.rm(File.join(@target_dir, path)) unless keep_original
   manifest_key_path = File.expand_path("/#{dirname}/#{basename}#{extension}")
   add_to_manifest(manifest_key_path, File.join(dirname, new_file_name))
end

#version_filesObject



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/bagger/packager.rb', line 83

def version_files
  FileUtils.cd(@source_dir) do
    Dir["**/*"].reject{ |f| exclude_file?(f) }.each do |path|
      if File.directory? path
        FileUtils.mkdir_p(File.join(@target_dir, path))
        next
      end

      FileUtils.cp(path, File.join(@target_dir, path))
      to_manifest(path, false)
    end
  end
end

#write_manifestObject



77
78
79
80
81
# File 'lib/bagger/packager.rb', line 77

def write_manifest
  File.open(@manifest_path, 'w') do |f|
    f.write JSON.pretty_generate(@manifest)
  end
end