propshaft 0.4.2 → 0.6.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: f19afc9fd39d03a8c6b7f61648fbb580a4c9ff8f4bf21d88abb8a802229ca90e
4
- data.tar.gz: ce49361ff29ab1abe61b933d94bc35d13d6a1527b8f40e38ac0abbcf501f97ff
3
+ metadata.gz: f7f4103bd65db2fdda3e1e8817f9d14951c48c2e823794c6167b90363931f48d
4
+ data.tar.gz: dd2503eb87c35fbf647618c2d840f05705583dfabcaac41ae68624923d92736f
5
5
  SHA512:
6
- metadata.gz: '05899de72dc909ea7f71eabf3cce43a1125ead5ee4cdee7485fbc0b328595e7a602489227204a7a4f482f1a86f91a3acdfa17fbe65e3ad5a8516ec5582e3b4e5'
7
- data.tar.gz: 6f270d85b2b2aedc3e3fa8145c4ebe7837c569a9ffabed578cb357071264563ed4d0b9caf6cf40e5b05a5a72bb5e1d07b72b9d3f5729c43fc533a541d12d5f62
6
+ metadata.gz: 5d0a9695812b4fa23ada2001d8f6f8adcc6d4cd8d724fe433fc08aeef48262e3b24e9de5a48ebde7b1d2aafee0ee5d58216ed9b252bdd7ba9fc10b0e87334250
7
+ data.tar.gz: 905a4681b68df4fa2020fc7a17e7b3fb50e6b67b9b332a903cbf2752aca3c6d83e03c5d198fa680e06299d1743a1ec0787e88f4f43ca2498dd94e46e73d09b63
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Propshaft
2
2
 
3
- Propshaft is an asset pipeline library for Rails. It's built for an era where bundling assets to save on HTTP connections is no longer urgent, where JavaScript and CSS are either compiled by dedicated Node.js bundlers or served directly to the browsers, and where increases in bandwidth have made the need for minification less pressing. These factors allow for a dramatically simpler and faster asset pipeline compared to previous options, like Sprockets.
3
+ Propshaft is an asset pipeline library for Rails. It's built for an era where bundling assets to save on HTTP connections is no longer urgent, where JavaScript and CSS are either compiled by dedicated Node.js bundlers or served directly to the browsers, and where increases in bandwidth have made the need for minification less pressing. These factors allow for a dramatically simpler and faster asset pipeline compared to previous options, like [Sprockets](https://github.com/rails/sprockets-rails).
4
4
 
5
5
  So that's what Propshaft doesn't do. Here's what it does provide:
6
6
 
@@ -12,12 +12,13 @@ So that's what Propshaft doesn't do. Here's what it does provide:
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` (pending the merge of [rails/rails#43261](https://github.com/rails/rails/pull/43261)).
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.
20
+
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.
21
22
 
22
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`).
23
24
 
@@ -31,7 +32,7 @@ If you need to put multiple files that refer to each other through Propshaft, li
31
32
 
32
33
  ## Migrating from Sprockets
33
34
 
34
- Propshaft does a lot less than Sprockets, by design, so it might well be a fair bit of work to migrate if it's even desirable. This is particularly true if you rely on Sprockets to provide any form of transpiling, like CoffeeScript or Sass, or if you rely on any gems that do. You'll need to either stop transpiling or use a Node-based transpiler, like those in `jsbundling-rails` and `cssbundling-rails`.
35
+ Propshaft does a lot less than Sprockets, by design, so it might well be a fair bit of work to migrate if it's even desirable. This is particularly true if you rely on Sprockets to provide any form of transpiling, like CoffeeScript or Sass, or if you rely on any gems that do. You'll need to either stop transpiling or use a Node-based transpiler, like those in [`jsbundling-rails`](https://github.com/rails/jsbundling-rails) and [`cssbundling-rails`](https://github.com/rails/cssbundling-rails).
35
36
 
36
37
  On the other hand, if you're already bundling JavaScript and CSS through a Node-based setup, then Propshaft is going to slot in easily. Since you don't need another tool to bundle or transpile. Just to digest and serve.
37
38
 
@@ -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
@@ -44,9 +44,11 @@ class Propshaft::Assembly
44
44
  end
45
45
  end
46
46
 
47
- def reveal
48
- load_path.assets.each do |asset|
49
- Propshaft.logger.info asset.logical_path
47
+ def reveal(path_type = :logical_path)
48
+ path_type = path_type.presence_in(%i[ logical_path path ]) || raise(ArgumentError, "Unknown path_type: #{path_type}")
49
+
50
+ load_path.assets.collect do |asset|
51
+ asset.send(path_type)
50
52
  end
51
53
  end
52
54
 
@@ -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
@@ -42,6 +42,6 @@ class Propshaft::Asset
42
42
 
43
43
  private
44
44
  def already_digested?
45
- logical_path.to_s =~ /-([0-9a-f]{7,128})\.digested/
45
+ logical_path.to_s =~ /-([0-9a-zA-Z]{7,128})\.digested/
46
46
  end
47
47
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require "propshaft/errors"
3
2
 
4
3
  class Propshaft::Compilers::CssAssetUrls
5
4
  attr_reader :assembly
@@ -1,5 +1,7 @@
1
- module Propshaft::Helper
2
- def compute_asset_path(path, options = {})
3
- Rails.application.assets.resolver.resolve(path)
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
@@ -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 = Array(paths).collect { |path| Pathname.new(path) }
6
+ def initialize(paths = [], version: nil)
7
+ @paths = Array(paths).collect { |path| Pathname.new(path) }
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,6 +58,10 @@ 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
@@ -1,18 +1,31 @@
1
1
  require "rails"
2
- require "rails/railtie"
3
2
  require "active_support/ordered_options"
4
3
 
5
4
  module Propshaft
6
5
  class Railtie < ::Rails::Railtie
7
6
  config.assets = ActiveSupport::OrderedOptions.new
8
- config.assets.paths = []
9
- config.assets.prefix = "/assets"
10
- config.assets.compilers = [
7
+ config.assets.paths = []
8
+ config.assets.excluded_paths = []
9
+ config.assets.version = "1"
10
+ config.assets.prefix = "/assets"
11
+ config.assets.compilers = [
11
12
  [ "text/css", Propshaft::Compilers::CssAssetUrls ],
12
13
  [ "text/css", Propshaft::Compilers::SourceMappingUrls ],
13
14
  [ "text/javascript", Propshaft::Compilers::SourceMappingUrls ]
14
15
  ]
15
16
  config.assets.sweep_cache = Rails.env.development?
17
+ config.assets.server = Rails.env.development? || Rails.env.test?
18
+
19
+ # Register propshaft initializer to copy the assets path in all the Rails Engines.
20
+ # This makes possible for us to keep all `assets` config in this Railtie, but still
21
+ # allow engines to automatically register their own paths.
22
+ Rails::Engine.initializer "propshaft.append_assets_path", group: :all do |app|
23
+ app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories)
24
+ app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
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))
28
+ end
16
29
 
17
30
  config.after_initialize do |app|
18
31
  config.assets.output_path ||=
@@ -20,8 +33,10 @@ module Propshaft
20
33
 
21
34
  app.assets = Propshaft::Assembly.new(app.config.assets)
22
35
 
23
- app.routes.prepend do
24
- mount app.assets.server => app.assets.config.prefix
36
+ if config.assets.server
37
+ app.routes.prepend do
38
+ mount app.assets.server => app.assets.config.prefix
39
+ end
25
40
  end
26
41
 
27
42
  ActiveSupport.on_load(:action_view) do
@@ -35,12 +50,6 @@ module Propshaft
35
50
  end
36
51
  end
37
52
 
38
- initializer "propshaft.append_assets_path" do |app|
39
- app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories)
40
- app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
41
- app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
42
- end
43
-
44
53
  initializer "propshaft.logger" do
45
54
  Propshaft.logger = config.assets.logger || Rails.logger
46
55
  end
@@ -16,6 +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
19
+ puts Rails.application.assets.reveal(:logical_path).join("\n")
20
+ end
21
+
22
+ namespace :reveal do
23
+ desc "Print the full path of assets available in config.assets.paths"
24
+ task full: :environment do
25
+ puts Rails.application.assets.reveal(:path).join("\n")
26
+ end
20
27
  end
21
28
  end
@@ -9,8 +9,6 @@ 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
- else
13
- raise Propshaft::MissingAssetError.new(logical_path)
14
12
  end
15
13
  end
16
14
  end
@@ -9,8 +9,6 @@ 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
- else
13
- raise Propshaft::MissingAssetError.new(logical_path)
14
12
  end
15
13
  end
16
14
 
@@ -34,7 +34,7 @@ class Propshaft::Server
34
34
  private
35
35
  def extract_path_and_digest(env)
36
36
  full_path = Rack::Utils.unescape(env["PATH_INFO"].to_s.sub(/^\//, ""))
37
- digest = full_path[/-([0-9a-f]{7,128})\.(?!digested)[^.]+\z/, 1]
37
+ digest = full_path[/-([0-9a-zA-Z]{7,128})\.(?!digested)[^.]+\z/, 1]
38
38
  path = digest ? full_path.sub("-#{digest}", "") : full_path
39
39
 
40
40
  [ path, digest ]
@@ -1,3 +1,3 @@
1
1
  module Propshaft
2
- VERSION = "0.4.2"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/propshaft.rb CHANGED
@@ -7,5 +7,6 @@ module Propshaft
7
7
  end
8
8
 
9
9
  require "propshaft/assembly"
10
+ require "propshaft/errors"
10
11
  require "propshaft/helper"
11
12
  require "propshaft/railtie"
metadata CHANGED
@@ -1,43 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propshaft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-03 00:00:00.000000000 Z
11
+ date: 2022-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: actionpack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 7.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.0.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: activesupport
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
18
32
  - !ruby/object:Gem::Version
19
- version: 7.0.0.alpha2
33
+ version: 7.0.0
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - ">="
25
39
  - !ruby/object:Gem::Version
26
- version: 7.0.0.alpha2
40
+ version: 7.0.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: railties
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: 7.0.0.alpha2
47
+ version: 7.0.0
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: 7.0.0.alpha2
54
+ version: 7.0.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rack
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,7 +66,7 @@ dependencies:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
- description:
69
+ description:
56
70
  email: dhh@hey.com
57
71
  executables: []
58
72
  extensions: []
@@ -83,7 +97,7 @@ licenses:
83
97
  - MIT
84
98
  metadata:
85
99
  rubygems_mfa_required: 'true'
86
- post_install_message:
100
+ post_install_message:
87
101
  rdoc_options: []
88
102
  require_paths:
89
103
  - lib
@@ -99,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
113
  version: '0'
100
114
  requirements: []
101
115
  rubygems_version: 3.2.32
102
- signing_key:
116
+ signing_key:
103
117
  specification_version: 4
104
118
  summary: Deliver assets for Rails.
105
119
  test_files: []