forked from shakacode/shakapacker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler.rb
117 lines (93 loc) · 2.75 KB
/
compiler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
require "open3"
require "fileutils"
require_relative "compiler_strategy"
class Shakapacker::Compiler
# Additional environment variables that the compiler is being run with
# Shakapacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
cattr_accessor(:env) { {} }
delegate :config, :logger, :strategy, to: :instance
delegate :fresh?, :stale?, :after_compile_hook, to: :strategy
def initialize(instance)
@instance = instance
end
def compile
unless stale?
logger.debug "Everything's up-to-date. Nothing to do"
return true
end
if compiling?
wait_for_compilation_to_complete
true
else
acquire_ipc_lock do
run_webpack.tap do |success|
after_compile_hook
end
end
end
end
private
attr_reader :instance
def acquire_ipc_lock
open_lock_file do |lf|
lf.flock(File::LOCK_EX)
yield if block_given?
end
end
def locked?
open_lock_file do |lf|
lf.flock(File::LOCK_EX | File::LOCK_NB) != 0
end
end
alias compiling? locked?
def wait_for_compilation_to_complete
logger.info "Waiting for the compilation to complete..."
acquire_ipc_lock
end
def open_lock_file
create_lock_file_dir unless File.exist?(lock_file_path)
File.open(lock_file_path, File::CREAT) do |lf|
return yield lf
end
end
def create_lock_file_dir
dirname = File.dirname(lock_file_path)
FileUtils.mkdir_p(dirname)
end
def lock_file_path
config.root_path.join("tmp/shakapacker.lock")
end
def optional_ruby_runner
first_line = File.readlines(bin_shakapacker_path).first.chomp
/ruby/.match?(first_line) ? RbConfig.ruby : ""
end
def run_webpack
logger.info "Compiling..."
stdout, stderr, status = Open3.capture3(
webpack_env,
"#{optional_ruby_runner} '#{bin_shakapacker_path}'",
chdir: File.expand_path(config.root_path)
)
if status.success?
logger.info "Compiled all packs in #{config.public_output_path}"
logger.warn "#{stderr}" unless stderr.empty?
if config.webpack_compile_output?
logger.info stdout
end
else
non_empty_streams = [stdout, stderr].delete_if(&:empty?)
logger.error "\nCOMPILATION FAILED:\nEXIT STATUS: #{status}\nOUTPUTS:\n#{non_empty_streams.join("\n\n")}"
end
status.success?
end
def webpack_env
return env unless defined?(ActionController::Base)
env.merge(
"SHAKAPACKER_ASSET_HOST" => instance.config.asset_host,
"SHAKAPACKER_CONFIG" => instance.config.config_path.to_s
)
end
def bin_shakapacker_path
config.root_path.join("bin/shakapacker")
end
end