Class: Sprockets::StaticNonDigestGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/sprockets/static_non_digest_generator.rb

Constant Summary collapse

DIGEST_REGEX =
/-([0-9a-f]{32})/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, target, paths, options = {}) ⇒ StaticNonDigestGenerator

Returns a new instance of StaticNonDigestGenerator.



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/sprockets/static_non_digest_generator.rb', line 10

def initialize(env, target, paths, options = {})
  @env = env
  @target = target
  @paths = paths
  @digests = options.fetch(:digests, {})

  # Parse digests from digests hash
  @asset_digests = Hash[*@digests.map {|file, digest_file|
    [file, digest_file[DIGEST_REGEX, 1]]
  }.flatten]
end

Instance Attribute Details

#envObject

Returns the value of attribute env.



8
9
10
# File 'lib/sprockets/static_non_digest_generator.rb', line 8

def env
  @env
end

#pathsObject

Returns the value of attribute paths.



8
9
10
# File 'lib/sprockets/static_non_digest_generator.rb', line 8

def paths
  @paths
end

#targetObject

Returns the value of attribute target.



8
9
10
# File 'lib/sprockets/static_non_digest_generator.rb', line 8

def target
  @target
end

Instance Method Details

#generateObject

Generate non-digest assets by making a copy of the digest asset, with digests stripped from js and css. The new files are also gzipped. Other assets are copied verbatim.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/sprockets/static_non_digest_generator.rb', line 26

def generate
  start_time = Time.now.to_f

  env.each_logical_path do |logical_path|
    if File.basename(logical_path)[/[^\.]+/, 0] == 'index'
      logical_path.sub!(/\/index\./, '.')
    end
    next unless compile_path?(logical_path)

    if digest_path = @digests[logical_path]
      abs_digest_path  = "#{@target}/#{digest_path}"
      abs_logical_path = "#{@target}/#{logical_path}"

      # Remove known digests from css & js
      if abs_digest_path.match(/\.(?:js|css)$/)
        mtime = File.mtime(abs_digest_path)

        asset_body = File.read(abs_digest_path)

        # Find all hashes in the asset body with a leading '-'
        asset_body.gsub!(DIGEST_REGEX) do |match|
          # Only remove if known digest
          $1.in?(@asset_digests.values) ? '' : match
        end

        # Write non-digest file
        File.open abs_logical_path, 'w' do |f|
          f.write asset_body
        end
        # Set modification and access times
        File.utime(File.atime(abs_digest_path), mtime, abs_logical_path)

        # Also write gzipped asset
        File.open("#{abs_logical_path}.gz", 'wb') do |f|
          gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
          gz.mtime = mtime.to_i
          gz.write asset_body
          gz.close
        end

        env.logger.debug "Stripped digests, copied to #{logical_path}, and created gzipped asset"

      else
        # Otherwise, treat file as binary and copy it.
        # Ignore paths that have no digests, such as READMEs
        unless !File.exist?(abs_digest_path) || abs_digest_path == abs_logical_path
          FileUtils.cp_r abs_digest_path, abs_logical_path, :remove_destination => true
          env.logger.debug "Copied binary asset to #{logical_path}"

          # Copy gzipped asset if exists
          if File.exist? "#{abs_digest_path}.gz"
            FileUtils.cp_r "#{abs_digest_path}.gz", "#{abs_logical_path}.gz", :remove_destination => true
            env.logger.debug "Copied gzipped asset to #{logical_path}.gz"
          end
        end
      end
    end
  end


  elapsed_time = ((Time.now.to_f - start_time) * 1000).to_i
  env.logger.debug "Generated non-digest assets in #{elapsed_time}ms"
end