react_on_rails 16.6.0.rc.0 → 16.6.0.rc.1
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/Gemfile.lock +1 -1
- data/lib/generators/react_on_rails/pro_generator.rb +89 -24
- data/lib/generators/react_on_rails/rsc_setup.rb +2 -2
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +1 -1
- data/lib/react_on_rails/configuration.rb +14 -50
- data/lib/react_on_rails/controller.rb +12 -6
- data/lib/react_on_rails/dev/server_manager.rb +4 -2
- data/lib/react_on_rails/doctor.rb +233 -32
- data/lib/react_on_rails/error.rb +2 -0
- data/lib/react_on_rails/helper.rb +46 -6
- data/lib/react_on_rails/packer_utils.rb +5 -1
- data/lib/react_on_rails/packs_generator.rb +3 -3
- data/lib/react_on_rails/pro_helper.rb +8 -12
- data/lib/react_on_rails/react_component/render_options.rb +0 -10
- data/lib/react_on_rails/system_checker.rb +42 -68
- data/lib/react_on_rails/utils.rb +0 -40
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +21 -1
- data/lib/react_on_rails/version_synchronizer.rb +106 -29
- data/lib/tasks/generate_packs.rake +2 -3
- data/sig/react_on_rails/configuration.rbs +0 -2
- data/sig/react_on_rails/controller.rbs +1 -2
- data/sig/react_on_rails/helper.rbs +6 -1
- 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: 5c525aa58afae47bf65f4118b11472b00b06649b2b3eba698fa6f7b82a6a6050
|
|
4
|
+
data.tar.gz: 2fe64e5d5ce2306b56408b26ffef471177ed33319732336f2f4d203b4917b742
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e580e7e342ed62b643a5d89a8b8b9f145a3edb2e51089c240575445824b1b7c5b8d82286e477a6a8457d54ed26d64fb4a05f6a42a9cbca229e3512bfdbeddc8
|
|
7
|
+
data.tar.gz: 95539a4061db5f32a57c0e0d0e4665ba2fea563de45686ff0fecc10d94ce28f5f043348d29af748acee96f078c9337fd805677f388c903b34b1562c90571c22d
|
data/Gemfile.lock
CHANGED
|
@@ -147,28 +147,25 @@ module ReactOnRails
|
|
|
147
147
|
|
|
148
148
|
base_gem_entry_found = true
|
|
149
149
|
|
|
150
|
+
declaration = consume_non_parenthesized_base_gem_declaration(
|
|
151
|
+
gemfile_lines,
|
|
152
|
+
line_index,
|
|
153
|
+
match.end(0)
|
|
154
|
+
)
|
|
155
|
+
|
|
150
156
|
unless pro_entry_added
|
|
151
157
|
indentation = match[1]
|
|
152
158
|
quote = match[2]
|
|
153
159
|
updated_lines << build_pro_gem_replacement_line(
|
|
154
160
|
indentation: indentation,
|
|
155
161
|
quote: quote,
|
|
156
|
-
suffix:
|
|
162
|
+
suffix: declaration[:trailing_suffix],
|
|
157
163
|
parenthesized_gem_call: match[0].include?("(")
|
|
158
164
|
)
|
|
159
165
|
pro_entry_added = true
|
|
160
166
|
end
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
line_index += 1
|
|
164
|
-
current_line = line
|
|
165
|
-
while line_index < gemfile_lines.length &&
|
|
166
|
-
line_continues_with_comma?(current_line) &&
|
|
167
|
-
gem_declaration_continues_on_next_line?(gemfile_lines[line_index])
|
|
168
|
-
next_line = gemfile_lines[line_index]
|
|
169
|
-
current_line = next_line unless comment_or_blank_line?(next_line)
|
|
170
|
-
line_index += 1
|
|
171
|
-
end
|
|
168
|
+
line_index = declaration[:next_index]
|
|
172
169
|
end
|
|
173
170
|
|
|
174
171
|
updated_content = updated_lines.join
|
|
@@ -476,17 +473,18 @@ module ReactOnRails
|
|
|
476
473
|
pending_multiline_static_import_specifier
|
|
477
474
|
) { |line_fragment| yield line_fragment }
|
|
478
475
|
in_multiline_template_literal = updated_template_literal_state
|
|
479
|
-
in_block_comment =
|
|
476
|
+
in_block_comment = unclosed_block_comment_starts?(rewritten_line)
|
|
480
477
|
rewritten_line
|
|
481
478
|
elsif line_contains_unescaped_backtick
|
|
482
479
|
rewritten_line, pending_multiline_module_call_depth, pending_multiline_static_import_specifier =
|
|
483
480
|
rewrite_line_before_template_literal_open(
|
|
484
481
|
line,
|
|
485
482
|
pending_multiline_module_call_depth,
|
|
486
|
-
pending_multiline_static_import_specifier
|
|
483
|
+
pending_multiline_static_import_specifier,
|
|
484
|
+
in_block_comment: in_block_comment
|
|
487
485
|
) { |line_fragment| yield line_fragment }
|
|
488
486
|
in_multiline_template_literal = updated_template_literal_state
|
|
489
|
-
in_block_comment =
|
|
487
|
+
in_block_comment = unclosed_block_comment_starts?(rewritten_line)
|
|
490
488
|
rewritten_line
|
|
491
489
|
else
|
|
492
490
|
in_multiline_template_literal = updated_template_literal_state
|
|
@@ -648,7 +646,7 @@ module ReactOnRails
|
|
|
648
646
|
|
|
649
647
|
rewritten_line = yield line_without_inline_templates
|
|
650
648
|
template_placeholders.each do |placeholder, template_literal|
|
|
651
|
-
rewritten_line = rewritten_line.sub(placeholder
|
|
649
|
+
rewritten_line = rewritten_line.sub(placeholder) { template_literal }
|
|
652
650
|
end
|
|
653
651
|
rewritten_line
|
|
654
652
|
end
|
|
@@ -742,8 +740,13 @@ module ReactOnRails
|
|
|
742
740
|
["#{template_literal_prefix}#{rewritten_fragment}", pending_depth, pending_multiline_static_import_specifier]
|
|
743
741
|
end
|
|
744
742
|
|
|
745
|
-
def rewrite_line_before_template_literal_open(
|
|
746
|
-
|
|
743
|
+
def rewrite_line_before_template_literal_open(
|
|
744
|
+
line,
|
|
745
|
+
pending_depth,
|
|
746
|
+
pending_multiline_static_import_specifier,
|
|
747
|
+
in_block_comment: false
|
|
748
|
+
)
|
|
749
|
+
opening_index = opening_backtick_index_for_multiline_start(line, in_block_comment: in_block_comment)
|
|
747
750
|
return [line, pending_depth, pending_multiline_static_import_specifier] unless opening_index&.positive?
|
|
748
751
|
|
|
749
752
|
line_prefix = line[0, opening_index]
|
|
@@ -757,17 +760,56 @@ module ReactOnRails
|
|
|
757
760
|
end
|
|
758
761
|
|
|
759
762
|
def first_unescaped_backtick_index(line)
|
|
763
|
+
unescaped_backtick_indexes(line, skip_comments: true).first
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
def opening_backtick_index_for_multiline_start(line, in_block_comment: false)
|
|
767
|
+
backtick_indexes = unescaped_backtick_indexes(line, in_block_comment: in_block_comment)
|
|
768
|
+
return nil if backtick_indexes.empty? || backtick_indexes.length.even?
|
|
769
|
+
|
|
770
|
+
backtick_indexes.last
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
774
|
+
def unescaped_backtick_indexes(line, in_block_comment: false, skip_comments: false)
|
|
760
775
|
quote_state = nil
|
|
776
|
+
backtick_indexes = []
|
|
777
|
+
|
|
778
|
+
scan_index = 0
|
|
779
|
+
while scan_index < line.length
|
|
780
|
+
if in_block_comment
|
|
781
|
+
closing_index = line.index("*/", scan_index)
|
|
782
|
+
break unless closing_index
|
|
783
|
+
|
|
784
|
+
in_block_comment = false
|
|
785
|
+
scan_index = closing_index + 2
|
|
786
|
+
next
|
|
787
|
+
end
|
|
761
788
|
|
|
762
|
-
|
|
763
|
-
quote_state = next_quote_state(quote_state, char, line,
|
|
764
|
-
|
|
765
|
-
|
|
789
|
+
char = line[scan_index]
|
|
790
|
+
quote_state = next_quote_state(quote_state, char, line, scan_index)
|
|
791
|
+
if quote_state
|
|
792
|
+
scan_index += 1
|
|
793
|
+
next
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
unless skip_comments
|
|
797
|
+
break if line[scan_index, 2] == "//"
|
|
798
|
+
|
|
799
|
+
if line[scan_index, 2] == "/*"
|
|
800
|
+
in_block_comment = true
|
|
801
|
+
scan_index += 2
|
|
802
|
+
next
|
|
803
|
+
end
|
|
804
|
+
end
|
|
766
805
|
|
|
767
|
-
|
|
806
|
+
backtick_indexes << scan_index if char == "`" && !character_escaped?(line, scan_index)
|
|
807
|
+
scan_index += 1
|
|
768
808
|
end
|
|
769
|
-
|
|
809
|
+
|
|
810
|
+
backtick_indexes
|
|
770
811
|
end
|
|
812
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
771
813
|
|
|
772
814
|
def next_quote_state(current_state, char, line, index)
|
|
773
815
|
if current_state
|
|
@@ -830,13 +872,36 @@ module ReactOnRails
|
|
|
830
872
|
end
|
|
831
873
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
832
874
|
|
|
875
|
+
def consume_non_parenthesized_base_gem_declaration(lines, start_index, match_end)
|
|
876
|
+
line_index = start_index
|
|
877
|
+
current_line = lines[line_index]
|
|
878
|
+
declaration_lines = [current_line]
|
|
879
|
+
line_index += 1
|
|
880
|
+
|
|
881
|
+
while line_index < lines.length &&
|
|
882
|
+
line_continues_with_comma?(current_line) &&
|
|
883
|
+
gem_declaration_continues_on_next_line?(lines[line_index])
|
|
884
|
+
next_line = lines[line_index]
|
|
885
|
+
declaration_lines << next_line
|
|
886
|
+
current_line = next_line unless comment_or_blank_line?(next_line)
|
|
887
|
+
line_index += 1
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
trailing_suffix = lines[start_index][match_end..].to_s + declaration_lines.drop(1).join
|
|
891
|
+
{ trailing_suffix: trailing_suffix, next_index: line_index }
|
|
892
|
+
end
|
|
893
|
+
|
|
833
894
|
def build_pro_gem_replacement_line(indentation:, quote:, suffix:, parenthesized_gem_call: false)
|
|
834
895
|
normalized_suffix = suffix || "\n"
|
|
835
896
|
normalized_suffix = "#{normalized_suffix}\n" unless normalized_suffix.end_with?("\n")
|
|
836
897
|
version_arg_pattern = /\A(?<prefix>\s*,(?:\s*#.*\n|\s++)*)["'][^"']*["'](?<trailing_comma>\s*,)?/
|
|
837
898
|
loop do
|
|
838
899
|
updated_suffix = normalized_suffix.sub(version_arg_pattern) do
|
|
839
|
-
Regexp.last_match[:trailing_comma]
|
|
900
|
+
if Regexp.last_match[:trailing_comma]
|
|
901
|
+
Regexp.last_match[:prefix].sub(/\n[ \t]*\z/, "")
|
|
902
|
+
else
|
|
903
|
+
""
|
|
904
|
+
end
|
|
840
905
|
end
|
|
841
906
|
break if updated_suffix == normalized_suffix
|
|
842
907
|
|
|
@@ -170,7 +170,7 @@ module ReactOnRails
|
|
|
170
170
|
⚠️ Procfile.dev not found. Skipping RSC bundle watcher addition.
|
|
171
171
|
|
|
172
172
|
You'll need to add the RSC bundle watcher to your process manager manually:
|
|
173
|
-
rsc-bundle: RSC_BUNDLE_ONLY=
|
|
173
|
+
rsc-bundle: RSC_BUNDLE_ONLY=true bin/shakapacker-watch --watch
|
|
174
174
|
MSG
|
|
175
175
|
return
|
|
176
176
|
end
|
|
@@ -185,7 +185,7 @@ module ReactOnRails
|
|
|
185
185
|
rsc_watcher_line = <<~PROCFILE
|
|
186
186
|
|
|
187
187
|
# React on Rails Pro - RSC bundle watcher
|
|
188
|
-
rsc-bundle: RSC_BUNDLE_ONLY=
|
|
188
|
+
rsc-bundle: RSC_BUNDLE_ONLY=true bin/shakapacker-watch --watch
|
|
189
189
|
PROCFILE
|
|
190
190
|
|
|
191
191
|
append_to_file("Procfile.dev", rsc_watcher_line)
|
|
@@ -94,51 +94,6 @@ module ReactOnRails
|
|
|
94
94
|
:server_bundle_output_path, :enforce_private_server_bundles,
|
|
95
95
|
:check_database_on_dev_start
|
|
96
96
|
|
|
97
|
-
# Class instance variable and mutex to track if deprecation warning has been shown
|
|
98
|
-
# Using mutex to ensure thread-safety in multi-threaded environments
|
|
99
|
-
@immediate_hydration_warned = false
|
|
100
|
-
@immediate_hydration_mutex = Mutex.new
|
|
101
|
-
|
|
102
|
-
class << self
|
|
103
|
-
attr_accessor :immediate_hydration_warned, :immediate_hydration_mutex
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Deprecated: immediate_hydration configuration has been removed
|
|
107
|
-
def immediate_hydration=(value)
|
|
108
|
-
warned = false
|
|
109
|
-
self.class.immediate_hydration_mutex.synchronize do
|
|
110
|
-
warned = self.class.immediate_hydration_warned
|
|
111
|
-
self.class.immediate_hydration_warned = true unless warned
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
return if warned
|
|
115
|
-
|
|
116
|
-
Rails.logger.warn <<~WARNING
|
|
117
|
-
[REACT ON RAILS] The 'config.immediate_hydration' configuration option is deprecated and no longer used.
|
|
118
|
-
Immediate hydration is now automatically enabled for React on Rails Pro users.
|
|
119
|
-
Please remove 'config.immediate_hydration = #{value}' from your config/initializers/react_on_rails.rb file.
|
|
120
|
-
See CHANGELOG.md for migration instructions.
|
|
121
|
-
WARNING
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def immediate_hydration
|
|
125
|
-
warned = false
|
|
126
|
-
self.class.immediate_hydration_mutex.synchronize do
|
|
127
|
-
warned = self.class.immediate_hydration_warned
|
|
128
|
-
self.class.immediate_hydration_warned = true unless warned
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
return nil if warned
|
|
132
|
-
|
|
133
|
-
Rails.logger.warn <<~WARNING
|
|
134
|
-
[REACT ON RAILS] The 'config.immediate_hydration' configuration option is deprecated and no longer used.
|
|
135
|
-
Immediate hydration is now automatically enabled for React on Rails Pro users.
|
|
136
|
-
Please remove any references to 'config.immediate_hydration' from your config/initializers/react_on_rails.rb file.
|
|
137
|
-
See CHANGELOG.md for migration instructions.
|
|
138
|
-
WARNING
|
|
139
|
-
nil
|
|
140
|
-
end
|
|
141
|
-
|
|
142
97
|
# rubocop:disable Metrics/AbcSize
|
|
143
98
|
def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
|
|
144
99
|
replay_console: nil, make_generated_server_bundle_the_entrypoint: nil,
|
|
@@ -257,12 +212,14 @@ module ReactOnRails
|
|
|
257
212
|
Rails.logger.warn("**WARNING** #{msg}")
|
|
258
213
|
self.generated_component_packs_loading_strategy = :sync
|
|
259
214
|
elsif generated_component_packs_loading_strategy == :async
|
|
260
|
-
raise ReactOnRails::Error, "**ERROR** #{msg}"
|
|
215
|
+
raise ReactOnRails::Error, "**ERROR** #{msg}\n\n#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
261
216
|
end
|
|
262
217
|
|
|
263
218
|
return if %i[async defer sync].include?(generated_component_packs_loading_strategy)
|
|
264
219
|
|
|
265
|
-
raise ReactOnRails::Error,
|
|
220
|
+
raise ReactOnRails::Error,
|
|
221
|
+
"generated_component_packs_loading_strategy must be either :async, :defer, or :sync. " \
|
|
222
|
+
"#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
266
223
|
end
|
|
267
224
|
|
|
268
225
|
def validate_enforce_private_server_bundles
|
|
@@ -272,7 +229,8 @@ module ReactOnRails
|
|
|
272
229
|
if server_bundle_output_path.nil?
|
|
273
230
|
raise ReactOnRails::Error, "enforce_private_server_bundles is set to true, but " \
|
|
274
231
|
"server_bundle_output_path is nil. Please set server_bundle_output_path " \
|
|
275
|
-
"to a directory outside of the public directory."
|
|
232
|
+
"to a directory outside of the public directory. " \
|
|
233
|
+
"#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
276
234
|
end
|
|
277
235
|
|
|
278
236
|
# Check if server_bundle_output_path is inside public directory
|
|
@@ -286,7 +244,8 @@ module ReactOnRails
|
|
|
286
244
|
|
|
287
245
|
raise ReactOnRails::Error, "enforce_private_server_bundles is set to true, but " \
|
|
288
246
|
"server_bundle_output_path (#{server_bundle_output_path}) is inside " \
|
|
289
|
-
"the public directory. Please set it to a directory outside of public."
|
|
247
|
+
"the public directory. Please set it to a directory outside of public. " \
|
|
248
|
+
"#{ReactOnRails::DOCTOR_RECOMMENDATION}"
|
|
290
249
|
end
|
|
291
250
|
|
|
292
251
|
# Auto-detect server_bundle_output_path from Shakapacker 9.0+ private_output_path
|
|
@@ -401,6 +360,8 @@ module ReactOnRails
|
|
|
401
360
|
that does not match the value for public_output_path specified in
|
|
402
361
|
shakapacker.yml = #{packer_public_output_path}. You should remove the configuration
|
|
403
362
|
value for "generated_assets_dir" from your config/initializers/react_on_rails.rb file.
|
|
363
|
+
|
|
364
|
+
#{ReactOnRails::DOCTOR_RECOMMENDATION}
|
|
404
365
|
MSG
|
|
405
366
|
raise ReactOnRails::Error, msg
|
|
406
367
|
end
|
|
@@ -465,7 +426,9 @@ module ReactOnRails
|
|
|
465
426
|
msg = <<~MSG
|
|
466
427
|
**ERROR** ReactOnRails: auto_load_bundle is set to true, yet components_subdirectory is not configured.\
|
|
467
428
|
Please set components_subdirectory to the desired directory. For more information, please see \
|
|
468
|
-
https://reactonrails.com/docs/core-concepts/auto-bundling
|
|
429
|
+
https://reactonrails.com/docs/core-concepts/auto-bundling/
|
|
430
|
+
|
|
431
|
+
#{ReactOnRails::DOCTOR_RECOMMENDATION}
|
|
469
432
|
MSG
|
|
470
433
|
|
|
471
434
|
raise ReactOnRails::Error, msg
|
|
@@ -482,6 +445,7 @@ module ReactOnRails
|
|
|
482
445
|
Alternatively, remove the config/react_on_rails.rb config.build_production_command and the
|
|
483
446
|
default bin/shakapacker script will be used for assets:precompile.
|
|
484
447
|
|
|
448
|
+
#{ReactOnRails::DOCTOR_RECOMMENDATION}
|
|
485
449
|
MSG
|
|
486
450
|
end
|
|
487
451
|
end
|
|
@@ -9,16 +9,22 @@ module ReactOnRails
|
|
|
9
9
|
# JavaScript code.
|
|
10
10
|
# props: Named parameter props which is a Ruby Hash or JSON string which contains the properties
|
|
11
11
|
# to pass to the redux store.
|
|
12
|
-
# immediate_hydration: React on Rails Pro (licensed) feature. When nil (default), Pro users get
|
|
13
|
-
# immediate hydration, non-Pro users don't. Can be explicitly overridden.
|
|
14
12
|
#
|
|
15
13
|
# Be sure to include view helper `redux_store_hydration_data` at the end of your layout or view
|
|
16
14
|
# or else there will be no client side hydration of your stores.
|
|
17
|
-
def redux_store(store_name, props: {},
|
|
18
|
-
|
|
15
|
+
def redux_store(store_name, props: {}, **rest)
|
|
16
|
+
immediate_hydration_present = rest.key?(:immediate_hydration)
|
|
17
|
+
unknown_keys = rest.keys - [:immediate_hydration]
|
|
18
|
+
if unknown_keys.any?
|
|
19
|
+
plural = unknown_keys.one? ? "" : "s"
|
|
20
|
+
unknown_options = unknown_keys.map { |key| ":#{key}" }.join(", ")
|
|
21
|
+
raise ArgumentError, "unknown keyword#{plural}: #{unknown_options}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ReactOnRails::Helper.warn_removed_immediate_hydration_option("redux_store") if immediate_hydration_present
|
|
25
|
+
|
|
19
26
|
redux_store_data = { store_name: store_name,
|
|
20
|
-
props: props
|
|
21
|
-
immediate_hydration: immediate_hydration }
|
|
27
|
+
props: props }
|
|
22
28
|
@registered_stores_defer_render ||= []
|
|
23
29
|
@registered_stores_defer_render << redux_store_data
|
|
24
30
|
end
|
|
@@ -290,7 +290,7 @@ module ReactOnRails
|
|
|
290
290
|
|
|
291
291
|
env = { "RAILS_ENV" => "test" }
|
|
292
292
|
if resolved_mode == "client-only"
|
|
293
|
-
env["CLIENT_BUNDLE_ONLY"] = "
|
|
293
|
+
env["CLIENT_BUNDLE_ONLY"] = "true"
|
|
294
294
|
puts Rainbow("🧪 Starting test watch (client-only mode)...").cyan
|
|
295
295
|
puts Rainbow(" Reusing server bundle from existing watcher if available.").cyan
|
|
296
296
|
else
|
|
@@ -320,7 +320,9 @@ module ReactOnRails
|
|
|
320
320
|
def shakapacker_watch_process_running?
|
|
321
321
|
# Detect existing shakapacker watcher processes (from either bin/dev or bin/dev static).
|
|
322
322
|
# If one is already running, client-only test watch avoids duplicate server-bundle rebuilds.
|
|
323
|
-
|
|
323
|
+
# Also detect legacy =yes convention during transition
|
|
324
|
+
server_only_watchers = find_process_pids("SERVER_BUNDLE_ONLY=true bin/shakapacker --watch")
|
|
325
|
+
server_only_watchers |= find_process_pids("SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch")
|
|
324
326
|
if server_only_watchers.any?
|
|
325
327
|
return true if shared_private_output_paths?
|
|
326
328
|
|