webpacker_uploader 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|