webpacker_uploader 0.3.0 → 0.4.0
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/.rubocop.yml +197 -10
- data/.yardopts +8 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +43 -29
- data/README.md +6 -3
- data/Rakefile +5 -0
- data/lib/webpacker_uploader.rb +13 -3
- data/lib/webpacker_uploader/configuration.rb +22 -2
- data/lib/webpacker_uploader/instance.rb +32 -4
- data/lib/webpacker_uploader/manifest.rb +1 -1
- data/lib/webpacker_uploader/mime.rb +6 -0
- data/lib/webpacker_uploader/providers/aws.rb +44 -3
- data/lib/webpacker_uploader/version.rb +3 -1
- data/test/configuration_test.rb +87 -0
- data/test/manifest_test.rb +27 -0
- data/test/mime_test.rb +14 -0
- data/test/test_app/config/webpacker.yml +103 -0
- data/test/test_app/public/packs/manifest.json +33 -0
- data/test/test_helper.rb +35 -0
- data/test/webpacker_uploader_test.rb +32 -0
- data/webpacker_uploader.gemspec +5 -9
- metadata +52 -13
- data/.github/workflows/rubocop.yml +0 -35
- data/.github/workflows/ruby.yml +0 -39
- data/bin/console +0 -14
- data/bin/setup +0 -8
data/Rakefile
CHANGED
data/lib/webpacker_uploader.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/blank"
|
4
|
-
require "active_support/logger"
|
5
|
-
require "active_support/tagged_logging"
|
6
4
|
|
7
5
|
module WebpackerUploader
|
8
6
|
extend self
|
9
7
|
|
8
|
+
# @private
|
10
9
|
def instance=(instance)
|
11
10
|
@instance = instance
|
12
11
|
end
|
13
12
|
|
13
|
+
# @private
|
14
14
|
def instance
|
15
15
|
@instance ||= WebpackerUploader::Instance.new
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
# @!attribute [rw] config
|
19
|
+
# @see Instance#config
|
20
|
+
# @!scope class
|
21
|
+
# @!method configure
|
22
|
+
# @see Instance#configure
|
23
|
+
# @!scope class
|
24
|
+
# @!method upload!
|
25
|
+
# @return [void]
|
26
|
+
# @see Instance#upload!
|
27
|
+
# @!scope class
|
28
|
+
delegate :configure, :config, :upload!, to: :instance
|
19
29
|
end
|
20
30
|
|
21
31
|
require "webpacker_uploader/configuration"
|
@@ -1,13 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/logger"
|
4
|
+
require "active_support/tagged_logging"
|
5
|
+
|
6
|
+
# This is the class which holds the configuration options.
|
7
|
+
#
|
8
|
+
# Options are set and retrieved using `WebpackerUploader.config`
|
9
|
+
# and `WebpackerUploader.configure`.
|
3
10
|
class WebpackerUploader::Configuration
|
4
|
-
|
5
|
-
|
11
|
+
# @return [Array] the file extentions ignored by the uploader.
|
12
|
+
attr_accessor :ignored_extensions
|
13
|
+
|
14
|
+
# @return [ActiveSupport::Logger] the logger to use.
|
15
|
+
attr_accessor :logger
|
16
|
+
|
17
|
+
# @return [Boolean] whether or not to log operations.
|
18
|
+
attr_accessor :log_output
|
19
|
+
|
20
|
+
# @return [Pathname] the path to manifest.json, defaults to Webpacker public manifest path.
|
21
|
+
attr_reader :public_manifest_path
|
22
|
+
|
23
|
+
# @return [Pathname] the public root path, defaults to Webpacker public root path.
|
24
|
+
attr_reader :public_path
|
6
25
|
|
7
26
|
alias_method :log_output?, :log_output
|
8
27
|
|
9
28
|
def initialize
|
10
29
|
@ignored_extensions = []
|
30
|
+
@logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
|
11
31
|
@log_output = true
|
12
32
|
@public_manifest_path = ::Webpacker.config.public_manifest_path
|
13
33
|
@public_path = ::Webpacker.config.public_path
|
@@ -1,22 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class WebpackerUploader::Instance
|
4
|
-
cattr_accessor(:logger) { ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) }
|
5
|
-
|
6
4
|
attr_writer :config
|
7
5
|
|
6
|
+
# @private
|
8
7
|
def manifest
|
9
8
|
@manifest ||= WebpackerUploader::Manifest.new
|
10
9
|
end
|
11
10
|
|
11
|
+
# Returns the global WebpackerUploader::Configuration object.
|
12
|
+
# Use this to set and retrieve specific configuration options.
|
13
|
+
#
|
14
|
+
# @return [WebpackerUploader::Configuration]
|
15
|
+
#
|
16
|
+
# @example Disable log output
|
17
|
+
# WebpackerUploader.config.log_output = false
|
18
|
+
#
|
19
|
+
# @example Get the list of excluded file extension
|
20
|
+
# puts WebpackerUploader.config.ignored_extensions
|
21
|
+
#
|
22
|
+
# @see WebpackerUploader::Configuration
|
12
23
|
def config
|
13
24
|
@config ||= WebpackerUploader::Configuration.new
|
14
25
|
end
|
15
26
|
|
27
|
+
# Yields the global configuration to a block. Use this to
|
28
|
+
# configure the base gem features.
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# WebpackerUploader.configure do |config|
|
32
|
+
# config.ignored_extensions = [".png", ".jpg", ".webp"]
|
33
|
+
# config.log_output = false
|
34
|
+
# config.public_manifest_path = "path/to/manifest.json"
|
35
|
+
# config.public_path = "path/to/public/dir"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @see WebpackerUploader::Configuration
|
16
39
|
def configure
|
17
40
|
yield config
|
18
41
|
end
|
19
42
|
|
43
|
+
# Uploads assets using the supplied provider. Currently only AWS S3 is implemented.
|
44
|
+
#
|
45
|
+
# @return [void]
|
46
|
+
# @param provider [WebpackerUploader::Providers::Aws] A provider to use for file uploading.
|
47
|
+
# @param prefix [String] Used to prefix the remote file paths.
|
20
48
|
def upload!(provider, prefix: nil)
|
21
49
|
manifest.assets.each do |name, js_path|
|
22
50
|
path = js_path[1..-1]
|
@@ -31,11 +59,11 @@ class WebpackerUploader::Instance
|
|
31
59
|
file_path = config.public_path.join(path)
|
32
60
|
|
33
61
|
if name.end_with?(*config.ignored_extensions)
|
34
|
-
logger.info("Skipping #{file_path}") if config.log_output?
|
62
|
+
config.logger.info("Skipping #{file_path}") if config.log_output?
|
35
63
|
else
|
36
64
|
content_type = WebpackerUploader::Mime.mime_type(path)
|
37
65
|
|
38
|
-
logger.info("Processing #{file_path} as #{content_type}") if config.log_output?
|
66
|
+
config.logger.info("Processing #{file_path} as #{content_type}") if config.log_output?
|
39
67
|
|
40
68
|
provider.upload!(remote_path, file_path, content_type)
|
41
69
|
end
|
@@ -3,6 +3,12 @@
|
|
3
3
|
require "mime-types"
|
4
4
|
|
5
5
|
module WebpackerUploader::Mime
|
6
|
+
# Returns the mime type for the given file in the filesystem.
|
7
|
+
# If it's unable to detect the mime type, it returns +application/octet-stream+
|
8
|
+
# as a fallback.
|
9
|
+
#
|
10
|
+
# @param file_path [String] A file path in the local filesystem.
|
11
|
+
# @return [String] The file mime type.
|
6
12
|
def mime_type(file_path)
|
7
13
|
fallback = MIME::Types.type_for(file_path).first&.content_type || "application/octet-stream"
|
8
14
|
Rack::Mime.mime_type(File.extname(file_path), fallback)
|
@@ -3,18 +3,59 @@
|
|
3
3
|
require "aws-sdk-s3"
|
4
4
|
|
5
5
|
module WebpackerUploader
|
6
|
+
# Namespace for the upload providers.
|
6
7
|
module Providers
|
8
|
+
# AWS provider uploads files to AWS S3. It uses the +aws-sdk-s3+ gem.
|
7
9
|
class Aws
|
8
|
-
attr_reader :client
|
9
|
-
attr_reader :resource
|
10
|
-
attr_reader :bucket
|
10
|
+
attr_reader :client, :resource, :bucket # @private
|
11
11
|
|
12
|
+
# @param [Hash] options
|
13
|
+
# * :region (String) The S3 region name.
|
14
|
+
# * :bucket (String) The S3 bucket name.
|
15
|
+
# * :credentials (Hash) credential options for the AWS provider:
|
16
|
+
# * :profile_name (String) use a named profile configured in ~/.aws/credentials
|
17
|
+
# * :instance_profile (Boolean) use an instance profile from an EC2
|
18
|
+
# * :access_key_id (String) the AWS credentials access id.
|
19
|
+
# * :secret_access_key (String) the AWS credentials secret access key.
|
20
|
+
#
|
21
|
+
# @example Initialize the using a named profile:
|
22
|
+
#
|
23
|
+
# provider_options = {
|
24
|
+
# credentials: { profile_name: "staging" },
|
25
|
+
# region: "eu-central-1",
|
26
|
+
# bucket: "application-assets-20200929124523451600000001"
|
27
|
+
# }
|
28
|
+
# provider = WebpackerUploader::Providers::Aws.new(provider_options)
|
29
|
+
#
|
30
|
+
# @example Initialize using IAM keys
|
31
|
+
#
|
32
|
+
# provider_options = {
|
33
|
+
# credentials: { access_key_id: "KEY_ID", secret_access_key: "ACCESS_KEY" },
|
34
|
+
# region: "eu-central-1",
|
35
|
+
# bucket: "application-assets-20200929124523451600000001"
|
36
|
+
# }
|
37
|
+
# provider = WebpackerUploader::Providers::Aws.new(provider_options)
|
38
|
+
#
|
39
|
+
# @example Initialize using an EC2 instance profile
|
40
|
+
#
|
41
|
+
# provider_options = {
|
42
|
+
# credentials: { instance_profile: true },
|
43
|
+
# region: "eu-central-1",
|
44
|
+
# bucket: "application-assets-20200929124523451600000001"
|
45
|
+
# }
|
46
|
+
# provider = WebpackerUploader::Providers::Aws.new(provider_options)
|
12
47
|
def initialize(options)
|
13
48
|
@client = ::Aws::S3::Client.new(credentials: credentials(options[:credentials]), region: options[:region])
|
14
49
|
@resource = ::Aws::S3::Resource.new(client: @client)
|
15
50
|
@bucket = @resource.bucket(options[:bucket])
|
16
51
|
end
|
17
52
|
|
53
|
+
# Uploads a file to AWS S3.
|
54
|
+
#
|
55
|
+
# @param object_key [String] Is the remote path name for the S3 object.
|
56
|
+
# @param file [Pathname] Path of the local file.
|
57
|
+
# @param content_type [String] The content type that will be set to the S3 object.
|
58
|
+
# @return [void]
|
18
59
|
def upload!(object_key, file, content_type = "")
|
19
60
|
object = @bucket.object(object_key)
|
20
61
|
object.upload_file(file, content_type: content_type)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class ConfigurationTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@config = WebpackerUploader::Configuration.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
WebpackerUploader.reset!
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_default_config_options
|
15
|
+
assert_empty @config.ignored_extensions
|
16
|
+
|
17
|
+
assert_instance_of ActiveSupport::Logger, @config.logger
|
18
|
+
|
19
|
+
assert @config.log_output
|
20
|
+
assert @config.log_output?
|
21
|
+
|
22
|
+
public_manifest_path = Pathname.new(File.expand_path("test_app/public/packs/manifest.json", __dir__))
|
23
|
+
assert_equal public_manifest_path, @config.public_manifest_path
|
24
|
+
|
25
|
+
public_path = Pathname.new(File.expand_path("test_app/public/", __dir__))
|
26
|
+
assert_equal public_path, @config.public_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_changing_config_options
|
30
|
+
@config.ignored_extensions = [".css", ".js"]
|
31
|
+
assert_equal [".css", ".js"], @config.ignored_extensions
|
32
|
+
|
33
|
+
@config.logger = Logger.new(STDOUT)
|
34
|
+
assert_instance_of Logger, @config.logger
|
35
|
+
|
36
|
+
@config.log_output = false
|
37
|
+
refute @config.log_output
|
38
|
+
refute @config.log_output?
|
39
|
+
|
40
|
+
@config.public_manifest_path = "test_app/manifest.json"
|
41
|
+
assert_equal "test_app/manifest.json", @config.public_manifest_path.to_s
|
42
|
+
|
43
|
+
@config.public_path = "test_app"
|
44
|
+
assert_equal "test_app", @config.public_path.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_configure_block
|
48
|
+
WebpackerUploader.configure do |c|
|
49
|
+
c.ignored_extensions = [".js"]
|
50
|
+
c.logger = Logger.new(STDOUT)
|
51
|
+
c.log_output = false
|
52
|
+
c.public_manifest_path = "path/to/manifest.json"
|
53
|
+
c.public_path = "path/to/public/dir"
|
54
|
+
end
|
55
|
+
|
56
|
+
assert_equal [".js"], WebpackerUploader.config.ignored_extensions
|
57
|
+
assert_instance_of Logger, WebpackerUploader.config.logger
|
58
|
+
refute WebpackerUploader.config.log_output
|
59
|
+
refute WebpackerUploader.config.log_output?
|
60
|
+
assert_equal "path/to/manifest.json", WebpackerUploader.config.public_manifest_path.to_s
|
61
|
+
assert_equal "path/to/public/dir", WebpackerUploader.config.public_path.to_s
|
62
|
+
|
63
|
+
assert_raises(NoMethodError) do
|
64
|
+
WebpackerUploader.configure do |c|
|
65
|
+
c.unknown = true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_pathname_casting
|
71
|
+
WebpackerUploader.config do |c|
|
72
|
+
c.public_manifest_path = "path/to/manifest.json"
|
73
|
+
c.public_path = "path/to/public/dir"
|
74
|
+
end
|
75
|
+
|
76
|
+
assert_instance_of Pathname, WebpackerUploader.config.public_manifest_path
|
77
|
+
assert_instance_of Pathname, WebpackerUploader.config.public_path
|
78
|
+
|
79
|
+
WebpackerUploader.configure do |c|
|
80
|
+
c.public_manifest_path = Pathname.new("path/to/manifest.json")
|
81
|
+
c.public_path = Pathname.new("path/to/public/dir")
|
82
|
+
end
|
83
|
+
|
84
|
+
assert_instance_of Pathname, WebpackerUploader.config.public_manifest_path
|
85
|
+
assert_instance_of Pathname, WebpackerUploader.config.public_path
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class ManifestTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@manifest = ::WebpackerUploader::Manifest.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
WebpackerUploader.reset!
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_assets
|
15
|
+
assert_includes @manifest.assets, "application.css"
|
16
|
+
assert_includes @manifest.assets, "application.js"
|
17
|
+
assert_includes @manifest.assets, "application.png"
|
18
|
+
refute_includes @manifest.assets, "entrypoints"
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_missing_manifest
|
22
|
+
WebpackerUploader.config.public_manifest_path = "missing.json"
|
23
|
+
@empty_manifest = WebpackerUploader::Manifest.new
|
24
|
+
|
25
|
+
assert_empty @empty_manifest.assets
|
26
|
+
end
|
27
|
+
end
|
data/test/mime_test.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class MimeTest < Minitest::Test
|
6
|
+
def test_for_webp
|
7
|
+
# Rack < 3.x does not support this so we have a fallback mechanism in place
|
8
|
+
assert_equal "image/webp", WebpackerUploader::Mime.mime_type("image-dd6b1cd38bfa093df600.webp")
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_for_sourcemap
|
12
|
+
assert_equal "application/octet-stream", WebpackerUploader::Mime.mime_type("application-dd6b1cd38bfa093df600.css.map")
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Note: You must restart bin/webpack-dev-server for changes to take effect
|
2
|
+
|
3
|
+
default: &default
|
4
|
+
source_path: app/javascript
|
5
|
+
source_entry_path: packs
|
6
|
+
public_root_path: public
|
7
|
+
public_output_path: packs
|
8
|
+
cache_path: tmp/cache/webpacker
|
9
|
+
webpack_compile_output: false
|
10
|
+
|
11
|
+
# Additional paths webpack should lookup modules
|
12
|
+
# ['app/assets', 'engine/foo/app/assets']
|
13
|
+
additional_paths:
|
14
|
+
- app/assets
|
15
|
+
- /etc/yarn
|
16
|
+
|
17
|
+
# This configuration option is deprecated and is only here for testing, to
|
18
|
+
# ensure backwards-compatibility. Please use `additional_paths`.
|
19
|
+
resolved_paths:
|
20
|
+
- app/elm
|
21
|
+
|
22
|
+
# Reload manifest.json on all requests so we reload latest compiled packs
|
23
|
+
cache_manifest: false
|
24
|
+
|
25
|
+
# Extract and emit a css file
|
26
|
+
extract_css: false
|
27
|
+
|
28
|
+
static_assets_extensions:
|
29
|
+
- .jpg
|
30
|
+
- .jpeg
|
31
|
+
- .png
|
32
|
+
- .gif
|
33
|
+
- .tiff
|
34
|
+
- .ico
|
35
|
+
- .svg
|
36
|
+
|
37
|
+
extensions:
|
38
|
+
- .mjs
|
39
|
+
- .js
|
40
|
+
- .sass
|
41
|
+
- .scss
|
42
|
+
- .css
|
43
|
+
- .module.sass
|
44
|
+
- .module.scss
|
45
|
+
- .module.css
|
46
|
+
- .png
|
47
|
+
- .svg
|
48
|
+
- .gif
|
49
|
+
- .jpeg
|
50
|
+
- .jpg
|
51
|
+
- .elm
|
52
|
+
|
53
|
+
development:
|
54
|
+
<<: *default
|
55
|
+
compile: true
|
56
|
+
|
57
|
+
# Reference: https://webpack.js.org/configuration/dev-server/
|
58
|
+
dev_server:
|
59
|
+
https: false
|
60
|
+
host: localhost
|
61
|
+
port: 3035
|
62
|
+
public: localhost:3035
|
63
|
+
hmr: false
|
64
|
+
# Inline should be set to true if using HMR
|
65
|
+
inline: true
|
66
|
+
overlay: true
|
67
|
+
disable_host_check: true
|
68
|
+
use_local_ip: false
|
69
|
+
pretty: false
|
70
|
+
|
71
|
+
test:
|
72
|
+
<<: *default
|
73
|
+
compile: true
|
74
|
+
|
75
|
+
# Compile test packs to a separate directory
|
76
|
+
public_output_path: packs-test
|
77
|
+
|
78
|
+
production:
|
79
|
+
<<: *default
|
80
|
+
|
81
|
+
# Production depends on precompilation of packs prior to booting for performance.
|
82
|
+
compile: false
|
83
|
+
|
84
|
+
# Extract and emit a css file
|
85
|
+
extract_css: true
|
86
|
+
|
87
|
+
# Cache manifest.json for performance
|
88
|
+
cache_manifest: true
|
89
|
+
|
90
|
+
staging:
|
91
|
+
<<: *default
|
92
|
+
|
93
|
+
# Production depends on precompilation of packs prior to booting for performance.
|
94
|
+
compile: false
|
95
|
+
|
96
|
+
# Extract and emit a css file
|
97
|
+
extract_css: true
|
98
|
+
|
99
|
+
# Cache manifest.json for performance
|
100
|
+
cache_manifest: true
|
101
|
+
|
102
|
+
# Compile staging packs to a separate directory
|
103
|
+
public_output_path: packs-staging
|