propshaft 0.5.0 → 0.6.3
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.
- checksums.yaml +4 -4
- data/README.md +5 -6
- data/lib/propshaft/assembly.rb +3 -3
- data/lib/propshaft/asset.rb +4 -4
- data/lib/propshaft/compilers/css_asset_urls.rb +1 -2
- data/lib/propshaft/helper.rb +5 -3
- data/lib/propshaft/load_path.rb +18 -5
- data/lib/propshaft/railtie.rb +7 -3
- data/lib/propshaft/railties/assets.rake +2 -2
- data/lib/propshaft/resolver/dynamic.rb +6 -2
- data/lib/propshaft/resolver/static.rb +6 -2
- data/lib/propshaft/version.rb +1 -1
- data/lib/propshaft.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e186c6a8b298be03fa1f414751bf99e425614701c2283eafeafc49d14a10dd9
|
4
|
+
data.tar.gz: d447859d4a45ae4d7f62b54d71a9ce5c4d15d2151c98a3369cd33229587a1441
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 337241f55febf946b0b4e508012d3f8737882c8fc92665f84a6d407ec52a93acd9c11840f456897f8100294665ce4dac5ae6b70c79ca08b25479c6cf4689877e
|
7
|
+
data.tar.gz: e436e82a80404f84eb27e32e493d38bda181e80b08b8c0ca788a69354bd97eef51b2c73ddfff62ebeb6407ecf553b15a290bf5680d7e2fcd7150ede657675dcb
|
data/README.md
CHANGED
@@ -7,21 +7,20 @@ So that's what Propshaft doesn't do. Here's what it does provide:
|
|
7
7
|
1. **Configurable load path**: You can register directories from multiple places in your app and gems, and reference assets from all of these paths as though they were one.
|
8
8
|
1. **Digest stamping**: All assets in the load path will be copied (or compiled) in a precompilation step for production that also stamps all of them with a digest hash, so you can use long-expiry cache headers for better performance. The digested assets can be referred to through their logical path because the processing leaves a manifest file that provides a way to translate.
|
9
9
|
1. **Development server**: There's no need to precompile the assets in development. You can refer to them via the same asset_path helpers and they'll be served by a development server.
|
10
|
-
1. **Basic compilers**: Propshaft was explicitly not designed to provide full transpiler capabilities. You can get that better elsewhere. But it does offer a simple input->output compiler setup that by default is used to translate `asset
|
10
|
+
1. **Basic compilers**: Propshaft was explicitly not designed to provide full transpiler capabilities. You can get that better elsewhere. But it does offer a simple input->output compiler setup that by default is used to translate `url(asset)` function calls in CSS to `url(digested-asset)` instead and source mapping comments likewise.
|
11
11
|
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
15
|
-
With Rails 7+, you can start a new application with propshaft using `rails new myapp -a propshaft`.
|
16
|
-
|
15
|
+
With Rails 7+, you can start a new application with propshaft using `rails new myapp -a propshaft`. For existing applications, check the [upgrade guide](https://github.com/rails/propshaft/blob/main/UPGRADING.md) which contains step-by-step instructions.
|
17
16
|
|
18
17
|
## Usage
|
19
18
|
|
20
|
-
Propshaft makes all the assets from all the paths it's been configured with through `config.assets.paths` available for serving and will copy all of them into `public/assets` when precompiling. This is unlike Sprockets, which did not copy over assets that hadn't been explicitly included in one of the bundled assets.
|
19
|
+
Propshaft makes all the assets from all the paths it's been configured with through `config.assets.paths` available for serving and will copy all of them into `public/assets` when precompiling. This is unlike Sprockets, which did not copy over assets that hadn't been explicitly included in one of the bundled assets.
|
21
20
|
|
22
|
-
|
21
|
+
You can however exempt directories that have been added through the `config.assets.excluded_paths`. This is useful if you're for example using `app/assets/stylesheets` exclusively as a set of inputs to a compiler like Dart Sass for Rails, and you don't want these input files to be part of the load path. (Remember you need to add full paths, like `Rails.root.join("app/assets/stylesheets")`).
|
23
22
|
|
24
|
-
|
23
|
+
These assets can be referenced through their logical path using the normal helpers like `asset_path`, `image_tag`, `javascript_include_tag`, and all the other asset helper tags. These logical references are automatically converted into digest-aware paths in production when `assets:precompile` has been run (through a JSON mapping file found in `public/assets/.manifest.json`).
|
25
24
|
|
26
25
|
|
27
26
|
## Bypassing the digest step
|
data/lib/propshaft/assembly.rb
CHANGED
@@ -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)
|
18
|
+
@load_path ||= Propshaft::LoadPath.new(config.paths, version: config.version)
|
19
19
|
end
|
20
20
|
|
21
21
|
def resolver
|
@@ -47,8 +47,8 @@ class Propshaft::Assembly
|
|
47
47
|
def reveal(path_type = :logical_path)
|
48
48
|
path_type = path_type.presence_in(%i[ logical_path path ]) || raise(ArgumentError, "Unknown path_type: #{path_type}")
|
49
49
|
|
50
|
-
load_path.assets.
|
51
|
-
|
50
|
+
load_path.assets.collect do |asset|
|
51
|
+
asset.send(path_type)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
data/lib/propshaft/asset.rb
CHANGED
@@ -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
|
5
|
+
attr_reader :path, :logical_path, :version
|
6
6
|
|
7
|
-
def initialize(path, logical_path:)
|
8
|
-
@path, @logical_path = path, Pathname.new(logical_path)
|
7
|
+
def initialize(path, logical_path:, version: nil)
|
8
|
+
@path, @logical_path, @version = path, Pathname.new(logical_path), version
|
9
9
|
end
|
10
10
|
|
11
11
|
def content
|
@@ -21,7 +21,7 @@ class Propshaft::Asset
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def digest
|
24
|
-
@digest ||= Digest::SHA1.hexdigest(content)
|
24
|
+
@digest ||= Digest::SHA1.hexdigest("#{content}#{version}")
|
25
25
|
end
|
26
26
|
|
27
27
|
def digested_path
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "propshaft/errors"
|
3
2
|
|
4
3
|
class Propshaft::Compilers::CssAssetUrls
|
5
4
|
attr_reader :assembly
|
6
5
|
|
7
|
-
ASSET_URL_PATTERN = /url\(\s*["']?(?!(?:\#|data|http))([^"'\s)]+)
|
6
|
+
ASSET_URL_PATTERN = /url\(\s*["']?(?!(?:\#|data|http))([^"'\s?#)]+)([#?][^"']+)?\s*["']?\)/
|
8
7
|
|
9
8
|
def initialize(assembly)
|
10
9
|
@assembly = assembly
|
data/lib/propshaft/helper.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
module Propshaft
|
2
|
-
|
3
|
-
|
1
|
+
module Propshaft
|
2
|
+
module Helper
|
3
|
+
def compute_asset_path(path, options = {})
|
4
|
+
Rails.application.assets.resolver.resolve(path) || raise(MissingAssetError.new(path))
|
5
|
+
end
|
4
6
|
end
|
5
7
|
end
|
data/lib/propshaft/load_path.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require "propshaft/asset"
|
2
2
|
|
3
3
|
class Propshaft::LoadPath
|
4
|
-
attr_reader :paths
|
4
|
+
attr_reader :paths, :version
|
5
5
|
|
6
|
-
def initialize(paths = [])
|
7
|
-
@paths =
|
6
|
+
def initialize(paths = [], version: nil)
|
7
|
+
@paths = dedup(paths)
|
8
|
+
@version = version
|
8
9
|
end
|
9
10
|
|
10
11
|
def find(asset_name)
|
@@ -45,9 +46,9 @@ class Propshaft::LoadPath
|
|
45
46
|
def assets_by_path
|
46
47
|
@cached_assets_by_path ||= Hash.new.tap do |mapped|
|
47
48
|
paths.each do |path|
|
48
|
-
all_files_from_tree(path).each do |file|
|
49
|
+
without_dotfiles(all_files_from_tree(path)).each do |file|
|
49
50
|
logical_path = file.relative_path_from(path)
|
50
|
-
mapped[logical_path.to_s] ||= Propshaft::Asset.new(file, logical_path: logical_path)
|
51
|
+
mapped[logical_path.to_s] ||= Propshaft::Asset.new(file, logical_path: logical_path, version: version)
|
51
52
|
end if path.exist?
|
52
53
|
end
|
53
54
|
end
|
@@ -57,7 +58,19 @@ class Propshaft::LoadPath
|
|
57
58
|
path.children.flat_map { |child| child.directory? ? all_files_from_tree(child) : child }
|
58
59
|
end
|
59
60
|
|
61
|
+
def without_dotfiles(files)
|
62
|
+
files.reject { |file| file.basename.to_s.starts_with?(".") }
|
63
|
+
end
|
64
|
+
|
60
65
|
def clear_cache
|
61
66
|
@cached_assets_by_path = nil
|
62
67
|
end
|
68
|
+
|
69
|
+
def dedup(paths)
|
70
|
+
[].tap do |deduped|
|
71
|
+
Array(paths).map(&:to_s).sort.each do |path|
|
72
|
+
deduped << Pathname.new(path) if deduped.blank? || !path.start_with?(deduped.last.to_s)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
63
76
|
end
|
data/lib/propshaft/railtie.rb
CHANGED
@@ -4,9 +4,11 @@ require "active_support/ordered_options"
|
|
4
4
|
module Propshaft
|
5
5
|
class Railtie < ::Rails::Railtie
|
6
6
|
config.assets = ActiveSupport::OrderedOptions.new
|
7
|
-
config.assets.paths
|
8
|
-
config.assets.
|
9
|
-
config.assets.
|
7
|
+
config.assets.paths = []
|
8
|
+
config.assets.excluded_paths = []
|
9
|
+
config.assets.version = "1"
|
10
|
+
config.assets.prefix = "/assets"
|
11
|
+
config.assets.compilers = [
|
10
12
|
[ "text/css", Propshaft::Compilers::CssAssetUrls ],
|
11
13
|
[ "text/css", Propshaft::Compilers::SourceMappingUrls ],
|
12
14
|
[ "text/javascript", Propshaft::Compilers::SourceMappingUrls ]
|
@@ -21,6 +23,8 @@ module Propshaft
|
|
21
23
|
app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories)
|
22
24
|
app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
|
23
25
|
app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
|
26
|
+
|
27
|
+
app.config.assets.paths = app.config.assets.paths.without(Array(app.config.assets.excluded_paths).collect(&:to_s))
|
24
28
|
end
|
25
29
|
|
26
30
|
config.after_initialize do |app|
|
@@ -16,13 +16,13 @@ namespace :assets do
|
|
16
16
|
|
17
17
|
desc "Print all the assets available in config.assets.paths"
|
18
18
|
task reveal: :environment do
|
19
|
-
Rails.application.assets.reveal(:logical_path)
|
19
|
+
puts Rails.application.assets.reveal(:logical_path).join("\n")
|
20
20
|
end
|
21
21
|
|
22
22
|
namespace :reveal do
|
23
23
|
desc "Print the full path of assets available in config.assets.paths"
|
24
24
|
task full: :environment do
|
25
|
-
Rails.application.assets.reveal(:path)
|
25
|
+
puts Rails.application.assets.reveal(:path).join("\n")
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -9,8 +9,12 @@ module Propshaft::Resolver
|
|
9
9
|
def resolve(logical_path)
|
10
10
|
if asset = load_path.find(logical_path)
|
11
11
|
File.join prefix, asset.digested_path
|
12
|
-
|
13
|
-
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def read(logical_path)
|
16
|
+
if asset = load_path.find(logical_path)
|
17
|
+
asset.content
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
@@ -9,8 +9,12 @@ module Propshaft::Resolver
|
|
9
9
|
def resolve(logical_path)
|
10
10
|
if asset_path = parsed_manifest[logical_path]
|
11
11
|
File.join prefix, asset_path
|
12
|
-
|
13
|
-
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def read(logical_path)
|
16
|
+
if asset_path = parsed_manifest[logical_path]
|
17
|
+
manifest_path.dirname.join(asset_path).read
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
data/lib/propshaft/version.rb
CHANGED
data/lib/propshaft.rb
CHANGED
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.
|
4
|
+
version: 0.6.3
|
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-
|
11
|
+
date: 2022-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|