propshaft 0.6.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bee1e0c2fcf39062df053618528b93dd5977bd8968fea03a67d31b7196f04f9
4
- data.tar.gz: ad9c5f3b7bc878a359931d2c1edc2a2ecb98004b8cfba38dd226acd0a19e43ff
3
+ metadata.gz: 0cec588585c21b06e765dbf70ac6f0d3a4b9ad2826c8a11120553a8db0931559
4
+ data.tar.gz: dde9f2d2a7095731ea93585e237421b73adc4acc71218ef574e566468796d1eb
5
5
  SHA512:
6
- metadata.gz: 41a54360ed2d9424f1c190af2606c5d2bc88a2d01d61a1396ed60fc64ba1531e815cc259ac41904fe3a49053d057ee2f838be0c8763b37a1ebbe79067f52301f
7
- data.tar.gz: be6381394ff2c2dfa9bf0ca23d2023b196492d83012970091eca5ce03822ee127fa40103382dd85d6093ae1edc5b91545a59be21beb0a9736fa3037a322d5678
6
+ metadata.gz: c372a207074f656261b8be407d224780678fd68e6caf645323c898ca06cb04f4cc0e1b2ab2ac2d59179162bb3a6c1e137297635aef8c49d1a0e4b3d279e609c6
7
+ data.tar.gz: 80c3963e4963ae52b19793b8de066a173b1227a5b6ea1d1ff4420f88b1939a09f2a476fd55e52a4a18fe688c53bc0862756700723557a108d052441ade893259
data/README.md CHANGED
@@ -27,6 +27,16 @@ These assets can be referenced through their logical path using the normal helpe
27
27
 
28
28
  If you need to put multiple files that refer to each other through Propshaft, like a JavaScript file and its source map, you have to digest these files in advance to retain stable file names. Propshaft looks for the specific pattern of `-[digest].digested.js` as the postfix to any asset file as an indication that the file has already been digested.
29
29
 
30
+ ## Improving performance in development
31
+
32
+ Before every request Propshaft checks if any asset was updated to decide if a cache sweep is needed. This verification is done using the application's configured file watcher which, by default, is `ActiveSupport::FileUpdateChecker`.
33
+
34
+ If you have a lot of assets in your project, you can improve performance by adding the `listen` gem to the development group in your Gemfile, and this line to the `development.rb` environment file:
35
+
36
+ ```ruby
37
+ config.file_watcher = ActiveSupport::EventedFileUpdateChecker
38
+ ```
39
+
30
40
 
31
41
  ## Migrating from Sprockets
32
42
 
@@ -39,7 +49,7 @@ But for greenfield apps using the default import-map approach, Propshaft can als
39
49
 
40
50
  ## Will Propshaft replace Sprockets as the Rails default?
41
51
 
42
- Most likely, but Sprockets need to be supported as well for a long time to come. Plenty of apps and gems were built on Sprocket features, and they won't be migrating soon. Still working out the compatibility story. This is very much alpha software at the moment.
52
+ Most likely, but Sprockets needs to be supported as well for a long time to come. Plenty of apps and gems were built on Sprocket features, and they won't be migrating soon. Still working out the compatibility story. This is very much beta software at the moment.
43
53
 
44
54
 
45
55
  ## License
@@ -4,8 +4,8 @@ require "propshaft/resolver/static"
4
4
  require "propshaft/server"
5
5
  require "propshaft/processor"
6
6
  require "propshaft/compilers"
7
- require "propshaft/compilers/css_asset_urls"
8
- require "propshaft/compilers/source_mapping_urls"
7
+ require "propshaft/compiler/css_asset_urls"
8
+ require "propshaft/compiler/source_mapping_urls"
9
9
 
10
10
  class Propshaft::Assembly
11
11
  attr_reader :config
@@ -15,7 +15,7 @@ class Propshaft::Assembly
15
15
  end
16
16
 
17
17
  def load_path
18
- @load_path ||= Propshaft::LoadPath.new(config.paths, version: config.version)
18
+ @load_path ||= Propshaft::LoadPath.new(config.paths, compilers: compilers, version: config.version)
19
19
  end
20
20
 
21
21
  def resolver
@@ -2,10 +2,10 @@ require "digest/sha1"
2
2
  require "action_dispatch/http/mime_type"
3
3
 
4
4
  class Propshaft::Asset
5
- attr_reader :path, :logical_path, :version
5
+ attr_reader :path, :logical_path, :load_path
6
6
 
7
- def initialize(path, logical_path:, version: nil)
8
- @path, @logical_path, @version = path, Pathname.new(logical_path), version
7
+ def initialize(path, logical_path:, load_path:)
8
+ @path, @logical_path, @load_path = path, Pathname.new(logical_path), load_path
9
9
  end
10
10
 
11
11
  def content
@@ -21,14 +21,14 @@ class Propshaft::Asset
21
21
  end
22
22
 
23
23
  def digest
24
- @digest ||= Digest::SHA1.hexdigest("#{content}#{version}")
24
+ @digest ||= Digest::SHA1.hexdigest("#{content_with_compile_references}#{load_path.version}").first(8)
25
25
  end
26
26
 
27
27
  def digested_path
28
28
  if already_digested?
29
29
  logical_path
30
30
  else
31
- logical_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" }
31
+ logical_path.sub(/\.(\w+(\.map)?)$/) { |ext| "-#{digest}#{ext}" }
32
32
  end
33
33
  end
34
34
 
@@ -41,7 +41,11 @@ class Propshaft::Asset
41
41
  end
42
42
 
43
43
  private
44
+ def content_with_compile_references
45
+ content + load_path.find_referenced_by(self).collect(&:content).join
46
+ end
47
+
44
48
  def already_digested?
45
- logical_path.to_s =~ /-([0-9a-zA-Z]{7,128})\.digested/
49
+ logical_path.to_s =~ /-([0-9a-zA-Z_-]{7,128})\.digested/
46
50
  end
47
51
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "propshaft/compiler"
4
+
5
+ class Propshaft::Compiler::CssAssetUrls < Propshaft::Compiler
6
+ ASSET_URL_PATTERN = /url\(\s*["']?(?!(?:\#|%23|data|http|\/\/))([^"'\s?#)]+)([#?][^"')]+)?\s*["']?\)/
7
+
8
+ def compile(asset, input)
9
+ input.gsub(ASSET_URL_PATTERN) { asset_url resolve_path(asset.logical_path.dirname, $1), asset.logical_path, $2, $1 }
10
+ end
11
+
12
+ def referenced_by(asset, references: Set.new)
13
+ asset.content.scan(ASSET_URL_PATTERN).each do |referenced_asset_url, _|
14
+ referenced_asset = load_path.find(resolve_path(asset.logical_path.dirname, referenced_asset_url))
15
+
16
+ if referenced_asset && references.exclude?(referenced_asset)
17
+ references << referenced_asset
18
+ references.merge referenced_by(referenced_asset, references: references)
19
+ end
20
+ end
21
+
22
+ references
23
+ end
24
+
25
+ private
26
+ def resolve_path(directory, filename)
27
+ if filename.start_with?("../")
28
+ Pathname.new(directory + filename).relative_path_from("").to_s
29
+ elsif filename.start_with?("/")
30
+ filename.delete_prefix("/").to_s
31
+ else
32
+ (directory + filename.delete_prefix("./")).to_s
33
+ end
34
+ end
35
+
36
+ def asset_url(resolved_path, logical_path, fingerprint, pattern)
37
+ if asset = load_path.find(resolved_path)
38
+ %[url("#{url_prefix}/#{asset.digested_path}#{fingerprint}")]
39
+ else
40
+ Propshaft.logger.warn "Unable to resolve '#{pattern}' for missing asset '#{resolved_path}' in #{logical_path}"
41
+ %[url("#{pattern}")]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "propshaft/compiler"
4
+
5
+ class Propshaft::Compiler::SourceMappingUrls < Propshaft::Compiler
6
+ SOURCE_MAPPING_PATTERN = %r{(//|/\*)# sourceMappingURL=(.+\.map)(\s*?\*\/)?\s*?\Z}
7
+
8
+ def compile(asset, input)
9
+ input.gsub(SOURCE_MAPPING_PATTERN) { source_mapping_url(asset.logical_path, asset_path($2, asset.logical_path), $1, $3) }
10
+ end
11
+
12
+ private
13
+ def asset_path(source_mapping_url, logical_path)
14
+ source_mapping_url.gsub!(/^(.+\/)?#{url_prefix}\//, "")
15
+
16
+ if logical_path.dirname.to_s == "."
17
+ source_mapping_url
18
+ else
19
+ logical_path.dirname.join(source_mapping_url).to_s
20
+ end
21
+ end
22
+
23
+ def source_mapping_url(logical_path, resolved_path, comment_start, comment_end)
24
+ if asset = load_path.find(resolved_path)
25
+ "#{comment_start}# sourceMappingURL=#{url_prefix}/#{asset.digested_path}#{comment_end}"
26
+ else
27
+ Propshaft.logger.warn "Removed sourceMappingURL comment for missing asset '#{resolved_path}' from #{logical_path}"
28
+ "#{comment_start}#{comment_end}"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Base compiler from which other compilers can inherit
4
+ class Propshaft::Compiler
5
+ attr_reader :assembly
6
+ delegate :config, :load_path, to: :assembly
7
+
8
+ def initialize(assembly)
9
+ @assembly = assembly
10
+ end
11
+
12
+ # Override this in a specific compiler
13
+ def compile(asset, input)
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def referenced_by(asset)
18
+ Set.new
19
+ end
20
+
21
+ private
22
+ def url_prefix
23
+ @url_prefix ||= File.join(config.relative_url_root.to_s, config.prefix.to_s).chomp("/")
24
+ end
25
+ end
@@ -23,11 +23,21 @@ class Propshaft::Compilers
23
23
  if relevant_registrations = registrations[asset.content_type.to_s]
24
24
  asset.content.dup.tap do |input|
25
25
  relevant_registrations.each do |compiler|
26
- input.replace compiler.new(assembly).compile(asset.logical_path, input)
26
+ input.replace compiler.new(assembly).compile(asset, input)
27
27
  end
28
28
  end
29
29
  else
30
30
  asset.content
31
31
  end
32
32
  end
33
+
34
+ def referenced_by(asset)
35
+ Set.new.tap do |references|
36
+ if relevant_registrations = registrations[asset.content_type.to_s]
37
+ relevant_registrations.each do |compiler|
38
+ references.merge compiler.new(assembly).referenced_by(asset)
39
+ end
40
+ end
41
+ end
42
+ end
33
43
  end
@@ -3,5 +3,28 @@ module Propshaft
3
3
  def compute_asset_path(path, options = {})
4
4
  Rails.application.assets.resolver.resolve(path) || raise(MissingAssetError.new(path))
5
5
  end
6
+
7
+ # Add an option to call `stylesheet_link_tag` with `:all` to include every css file found on the load path
8
+ # or `:app` to include css files found in `Rails.root("app/assets/**/*.css")`, which will exclude lib/ and plugins.
9
+ def stylesheet_link_tag(*sources, **options)
10
+ case sources.first
11
+ when :all
12
+ super(*all_stylesheets_paths , **options)
13
+ when :app
14
+ super(*app_stylesheets_paths , **options)
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ # Returns a sorted and unique array of logical paths for all stylesheets in the load path.
21
+ def all_stylesheets_paths
22
+ Rails.application.assets.load_path.asset_paths_by_type("css")
23
+ end
24
+
25
+ # Returns a sorted and unique array of logical paths for all stylesheets in app/assets/**/*.css.
26
+ def app_stylesheets_paths
27
+ Rails.application.assets.load_path.asset_paths_by_glob("#{Rails.root.join("app/assets")}/**/*.css")
28
+ end
6
29
  end
7
30
  end
@@ -1,23 +1,32 @@
1
1
  require "propshaft/asset"
2
2
 
3
3
  class Propshaft::LoadPath
4
- attr_reader :paths, :version
4
+ attr_reader :paths, :compilers, :version
5
5
 
6
- def initialize(paths = [], version: nil)
7
- @paths = dedup(paths)
8
- @version = version
6
+ def initialize(paths = [], compilers:, version: nil)
7
+ @paths, @compilers, @version = dedup(paths), compilers, version
9
8
  end
10
9
 
11
10
  def find(asset_name)
12
11
  assets_by_path[asset_name]
13
12
  end
14
13
 
15
- def assets(content_types: nil)
16
- if content_types
17
- assets_by_path.values.select { |asset| asset.content_type.in?(content_types) }
18
- else
19
- assets_by_path.values
20
- end
14
+ def find_referenced_by(asset)
15
+ compilers.referenced_by(asset).delete(self)
16
+ end
17
+
18
+ def assets
19
+ assets_by_path.values
20
+ end
21
+
22
+ def asset_paths_by_type(content_type)
23
+ (@cached_asset_paths_by_type ||= Hash.new)[content_type] ||=
24
+ extract_logical_paths_from(assets.select { |a| a.content_type == Mime::EXTENSION_LOOKUP[content_type] })
25
+ end
26
+
27
+ def asset_paths_by_glob(glob)
28
+ (@cached_asset_paths_by_glob ||= Hash.new)[glob] ||=
29
+ extract_logical_paths_from(assets.select { |a| a.path.fnmatch?(glob) })
21
30
  end
22
31
 
23
32
  def manifest
@@ -28,16 +37,20 @@ class Propshaft::LoadPath
28
37
  end
29
38
  end
30
39
 
31
- # Returns a ActiveSupport::FileUpdateChecker object configured to clear the cache of the load_path
40
+ # Returns a file watcher object configured to clear the cache of the load_path
32
41
  # when the directories passed during its initialization have changes. This is used in development
33
42
  # and test to ensure the map caches are reset when javascript files are changed.
34
43
  def cache_sweeper
35
44
  @cache_sweeper ||= begin
36
45
  exts_to_watch = Mime::EXTENSION_LOOKUP.map(&:first)
37
46
  files_to_watch = Array(paths).collect { |dir| [ dir.to_s, exts_to_watch ] }.to_h
47
+ mutex = Mutex.new
38
48
 
39
49
  Rails.application.config.file_watcher.new([], files_to_watch) do
40
- clear_cache
50
+ mutex.synchronize do
51
+ clear_cache
52
+ seed_cache
53
+ end
41
54
  end
42
55
  end
43
56
  end
@@ -48,7 +61,7 @@ class Propshaft::LoadPath
48
61
  paths.each do |path|
49
62
  without_dotfiles(all_files_from_tree(path)).each do |file|
50
63
  logical_path = file.relative_path_from(path)
51
- mapped[logical_path.to_s] ||= Propshaft::Asset.new(file, logical_path: logical_path, version: version)
64
+ mapped[logical_path.to_s] ||= Propshaft::Asset.new(file, logical_path: logical_path, load_path: self)
52
65
  end if path.exist?
53
66
  end
54
67
  end
@@ -58,12 +71,22 @@ class Propshaft::LoadPath
58
71
  path.children.flat_map { |child| child.directory? ? all_files_from_tree(child) : child }
59
72
  end
60
73
 
74
+ def extract_logical_paths_from(assets)
75
+ assets.collect { |asset| asset.logical_path.to_s }.sort
76
+ end
77
+
61
78
  def without_dotfiles(files)
62
79
  files.reject { |file| file.basename.to_s.starts_with?(".") }
63
80
  end
64
81
 
65
82
  def clear_cache
66
83
  @cached_assets_by_path = nil
84
+ @cached_asset_paths_by_type = nil
85
+ @cached_asset_paths_by_glob = nil
86
+ end
87
+
88
+ def seed_cache
89
+ assets_by_path
67
90
  end
68
91
 
69
92
  def dedup(paths)
@@ -20,8 +20,8 @@ class Propshaft::Processor
20
20
  FileUtils.rm_r(output_path) if File.exist?(output_path)
21
21
  end
22
22
 
23
- def clean
24
- Propshaft::OutputPath.new(output_path, load_path.manifest).clean(2, 1.hour)
23
+ def clean(count)
24
+ Propshaft::OutputPath.new(output_path, load_path.manifest).clean(count, 1.hour)
25
25
  end
26
26
 
27
27
  private
@@ -0,0 +1,14 @@
1
+ class Propshaft::QuietAssets
2
+ def initialize(app)
3
+ @app = app
4
+ @assets_regex = %r(\A/{0,2}#{::Rails.application.config.assets.prefix})
5
+ end
6
+
7
+ def call(env)
8
+ if env['PATH_INFO'] =~ @assets_regex
9
+ ::Rails.logger.silence { @app.call(env) }
10
+ else
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
@@ -1,5 +1,6 @@
1
1
  require "rails"
2
2
  require "active_support/ordered_options"
3
+ require "propshaft/quiet_assets"
3
4
 
4
5
  module Propshaft
5
6
  class Railtie < ::Rails::Railtie
@@ -8,13 +9,15 @@ module Propshaft
8
9
  config.assets.excluded_paths = []
9
10
  config.assets.version = "1"
10
11
  config.assets.prefix = "/assets"
12
+ config.assets.quiet = false
11
13
  config.assets.compilers = [
12
- [ "text/css", Propshaft::Compilers::CssAssetUrls ],
13
- [ "text/css", Propshaft::Compilers::SourceMappingUrls ],
14
- [ "text/javascript", Propshaft::Compilers::SourceMappingUrls ]
14
+ [ "text/css", Propshaft::Compiler::CssAssetUrls ],
15
+ [ "text/css", Propshaft::Compiler::SourceMappingUrls ],
16
+ [ "text/javascript", Propshaft::Compiler::SourceMappingUrls ]
15
17
  ]
16
18
  config.assets.sweep_cache = Rails.env.development?
17
19
  config.assets.server = Rails.env.development? || Rails.env.test?
20
+ config.assets.relative_url_root = nil
18
21
 
19
22
  # Register propshaft initializer to copy the assets path in all the Rails Engines.
20
23
  # This makes possible for us to keep all `assets` config in this Railtie, but still
@@ -28,6 +31,7 @@ module Propshaft
28
31
  end
29
32
 
30
33
  config.after_initialize do |app|
34
+ config.assets.relative_url_root ||= app.config.relative_url_root
31
35
  config.assets.output_path ||=
32
36
  Pathname.new(File.join(app.config.paths["public"].first, app.config.assets.prefix))
33
37
 
@@ -54,6 +58,12 @@ module Propshaft
54
58
  Propshaft.logger = config.assets.logger || Rails.logger
55
59
  end
56
60
 
61
+ initializer :quiet_assets do |app|
62
+ if app.config.assets.quiet
63
+ app.middleware.insert_before ::Rails::Rack::Logger, Propshaft::QuietAssets
64
+ end
65
+ end
66
+
57
67
  rake_tasks do
58
68
  load "propshaft/railties/assets.rake"
59
69
  end
@@ -61,9 +71,7 @@ module Propshaft
61
71
  # Compatibility shiming (need to provide log warnings when used)
62
72
  config.assets.precompile = []
63
73
  config.assets.debug = nil
64
- config.assets.quiet = nil
65
74
  config.assets.compile = nil
66
- config.assets.version = nil
67
75
  config.assets.css_compressor = nil
68
76
  config.assets.js_compressor = nil
69
77
  end
@@ -2,6 +2,10 @@ namespace :assets do
2
2
  desc "Compile all the assets from config.assets.paths"
3
3
  task precompile: :environment do
4
4
  Rails.application.assets.processor.process
5
+ if Rails.env.development?
6
+ puts "Warning: You are precompiling assets in development. Rails will not " \
7
+ "serve any changed assets until you delete public#{Rails.application.config.assets.prefix}/.manifest.json"
8
+ end
5
9
  end
6
10
 
7
11
  desc "Remove config.assets.output_path"
@@ -10,8 +14,9 @@ namespace :assets do
10
14
  end
11
15
 
12
16
  desc "Removes old files in config.assets.output_path"
13
- task clean: :environment do
14
- Rails.application.assets.processor.clean
17
+ task :clean, [:count] => [:environment] do |_, args|
18
+ count = args.fetch(:count, 2)
19
+ Rails.application.assets.processor.clean(count.to_i)
15
20
  end
16
21
 
17
22
  desc "Print all the assets available in config.assets.paths"
@@ -20,7 +20,7 @@ module Propshaft::Resolver
20
20
 
21
21
  private
22
22
  def parsed_manifest
23
- @parsed_manifest ||= JSON.parse(manifest_path.read)
23
+ @parsed_manifest ||= JSON.parse(manifest_path.read, symbolize_names: false)
24
24
  end
25
25
  end
26
26
  end
@@ -1,4 +1,5 @@
1
1
  require "rack/utils"
2
+ require "rack/version"
2
3
 
3
4
  class Propshaft::Server
4
5
  def initialize(assembly)
@@ -11,19 +12,19 @@ class Propshaft::Server
11
12
  if (asset = @assembly.load_path.find(path)) && asset.fresh?(digest)
12
13
  compiled_content = @assembly.compilers.compile(asset)
13
14
 
14
- [
15
- 200,
15
+ [
16
+ 200,
16
17
  {
17
- "Content-Length" => compiled_content.length.to_s,
18
- "Content-Type" => asset.content_type.to_s,
19
- "Accept-Encoding" => "Vary",
20
- "ETag" => asset.digest,
21
- "Cache-Control" => "public, max-age=31536000, immutable"
18
+ Rack::CONTENT_LENGTH => compiled_content.length.to_s,
19
+ Rack::CONTENT_TYPE => asset.content_type.to_s,
20
+ VARY => "Accept-Encoding",
21
+ Rack::ETAG => asset.digest,
22
+ Rack::CACHE_CONTROL => "public, max-age=31536000, immutable"
22
23
  },
23
24
  [ compiled_content ]
24
25
  ]
25
26
  else
26
- [ 404, { "Content-Type" => "text/plain", "Content-Length" => "9" }, [ "Not found" ] ]
27
+ [ 404, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "9" }, [ "Not found" ] ]
27
28
  end
28
29
  end
29
30
 
@@ -39,4 +40,10 @@ class Propshaft::Server
39
40
 
40
41
  [ path, digest ]
41
42
  end
43
+
44
+ if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
45
+ VARY = "Vary"
46
+ else
47
+ VARY = "vary"
48
+ end
42
49
  end
@@ -1,3 +1,3 @@
1
1
  module Propshaft
2
- VERSION = "0.6.4"
2
+ VERSION = "0.9.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propshaft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-22 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -78,14 +78,16 @@ files:
78
78
  - lib/propshaft.rb
79
79
  - lib/propshaft/assembly.rb
80
80
  - lib/propshaft/asset.rb
81
+ - lib/propshaft/compiler.rb
82
+ - lib/propshaft/compiler/css_asset_urls.rb
83
+ - lib/propshaft/compiler/source_mapping_urls.rb
81
84
  - lib/propshaft/compilers.rb
82
- - lib/propshaft/compilers/css_asset_urls.rb
83
- - lib/propshaft/compilers/source_mapping_urls.rb
84
85
  - lib/propshaft/errors.rb
85
86
  - lib/propshaft/helper.rb
86
87
  - lib/propshaft/load_path.rb
87
88
  - lib/propshaft/output_path.rb
88
89
  - lib/propshaft/processor.rb
90
+ - lib/propshaft/quiet_assets.rb
89
91
  - lib/propshaft/railtie.rb
90
92
  - lib/propshaft/railties/assets.rake
91
93
  - lib/propshaft/resolver/dynamic.rb
@@ -112,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
114
  - !ruby/object:Gem::Version
113
115
  version: '0'
114
116
  requirements: []
115
- rubygems_version: 3.2.32
117
+ rubygems_version: 3.5.10
116
118
  signing_key:
117
119
  specification_version: 4
118
120
  summary: Deliver assets for Rails.
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Propshaft::Compilers::CssAssetUrls
4
- attr_reader :assembly
5
-
6
- ASSET_URL_PATTERN = /url\(\s*["']?(?!(?:\#|data|http))([^"'\s?#)]+)([#?][^"']+)?\s*["']?\)/
7
-
8
- def initialize(assembly)
9
- @assembly = assembly
10
- end
11
-
12
- def compile(logical_path, input)
13
- input.gsub(ASSET_URL_PATTERN) { asset_url resolve_path(logical_path.dirname, $1), logical_path, $1 }
14
- end
15
-
16
- private
17
- def resolve_path(directory, filename)
18
- if filename.start_with?("../")
19
- Pathname.new(directory + filename).relative_path_from("").to_s
20
- elsif filename.start_with?("/")
21
- filename.delete_prefix("/").to_s
22
- else
23
- (directory + filename.delete_prefix("./")).to_s
24
- end
25
- end
26
-
27
- def asset_url(resolved_path, logical_path, pattern)
28
- if asset = assembly.load_path.find(resolved_path)
29
- %[url("#{assembly.config.prefix}/#{asset.digested_path}")]
30
- else
31
- Propshaft.logger.warn "Unable to resolve '#{pattern}' for missing asset '#{resolved_path}' in #{logical_path}"
32
- %[url("#{pattern}")]
33
- end
34
- end
35
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Propshaft::Compilers::SourceMappingUrls
4
- attr_reader :assembly
5
-
6
- SOURCE_MAPPING_PATTERN = %r{^(//|/\*)# sourceMappingURL=(.+\.map)}
7
-
8
- def initialize(assembly)
9
- @assembly = assembly
10
- end
11
-
12
- def compile(logical_path, input)
13
- input.gsub(SOURCE_MAPPING_PATTERN) { source_mapping_url(asset_path($2, logical_path), $1) }
14
- end
15
-
16
- private
17
- def asset_path(source_mapping_url, logical_path)
18
- if logical_path.dirname.to_s == "."
19
- source_mapping_url
20
- else
21
- logical_path.dirname.join(source_mapping_url).to_s
22
- end
23
- end
24
-
25
- def source_mapping_url(resolved_path, comment)
26
- if asset = assembly.load_path.find(resolved_path)
27
- "#{comment}# sourceMappingURL=#{assembly.config.prefix}/#{asset.digested_path}"
28
- else
29
- Propshaft.logger.warn "Removed sourceMappingURL comment for missing asset '#{resolved_path}' from #{resolved_path}"
30
- nil
31
- end
32
- end
33
- end