rails_live_reload 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +84 -0
- data/Rakefile +3 -0
- data/lib/rails_live_reload/checker.rb +36 -0
- data/lib/rails_live_reload/client.rb +35 -0
- data/lib/rails_live_reload/command.rb +21 -0
- data/lib/rails_live_reload/engine.rb +26 -0
- data/lib/rails_live_reload/instrument/metrics_collector.rb +29 -0
- data/lib/rails_live_reload/rails/middleware.rb +54 -0
- data/lib/rails_live_reload/thread/current_request.rb +23 -0
- data/lib/rails_live_reload/version.rb +3 -0
- data/lib/rails_live_reload/watcher.rb +38 -0
- data/lib/rails_live_reload.rb +41 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a12bfdd549b010582467b39ea3f897cd1576b6e85f9595893482cc6d9738a8bf
|
4
|
+
data.tar.gz: 0e1340b8b309f291c4e0eeae134ba70409c26bd483316c512670c815e056f738
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 64ccc99a6ae7c6e858bc6b623aa38b2f52000b2aa4131e01e2f54438dd186913a625a8e6bc9a45ae80e72012d25ce4be3a701f5bd1df59eb8585ccccbd0ac8d1
|
7
|
+
data.tar.gz: dff2d37006b4316bcd4d5dcfd2fd97f5f116c300fe1fb2313082abe226b6f5443f883477338bc08ca19da795a4ef61c96849b20e4be3981903ebecf704956818
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Rails Live Reload
|
2
|
+
|
3
|
+
This is the simplest and probably the most robust way to add a support for a live reload to your Rails app.
|
4
|
+
|
5
|
+
Just add the gem and thats all - congratulation, now you have a live reload.
|
6
|
+
|
7
|
+
Works with:
|
8
|
+
|
9
|
+
- views (EBR/HAML/SLIM) (reloading page only if you editing views which were rendered)
|
10
|
+
- partials
|
11
|
+
- CSS/JS
|
12
|
+
- helpers, locales (if you configure)
|
13
|
+
- on a "crash" page, so once you made a fix page it will be reloaded
|
14
|
+
|
15
|
+
Page is reloaded with `window.location.reload()` so it's the most robust way to reload the page because of CSS/JS/etc.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
Just add this gem to the Gemfile (in development environment) and start the `rails s`.
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
group :development do
|
27
|
+
gem "rails_live_reload"
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
```bash
|
33
|
+
$ bundle
|
34
|
+
```
|
35
|
+
|
36
|
+
## Configuration
|
37
|
+
|
38
|
+
Default configuration `config/initializers/rails_live_reload.rb`:
|
39
|
+
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
RailsLiveReload.setup do |config|
|
43
|
+
config.url = "/rails/live/reload"
|
44
|
+
config.timeout = 100
|
45
|
+
|
46
|
+
# Watched folders & files
|
47
|
+
config.watch %r{app/views/.+\.(erb|haml|slim)$}
|
48
|
+
config.watch %r{(app|vendor)/(assets|javascript)/\w+/(.+\.(css|js|html|png|jpg|ts|jsx)).*}, reload: :always
|
49
|
+
|
50
|
+
# More examples:
|
51
|
+
# config.watch %r{app/helpers/.+\.rb}, reload: :always
|
52
|
+
# config.watch %r{config/locales/.+\.yml}, reload: :always
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
## How it works
|
57
|
+
|
58
|
+
There are 3 main pieces how it works:
|
59
|
+
|
60
|
+
1) listener for file changes using `listen` gem
|
61
|
+
2) collector of rendered views (see rails instrumentation)
|
62
|
+
3) middleware which is responding to setInterval JS calls
|
63
|
+
|
64
|
+
## Contributing
|
65
|
+
|
66
|
+
You are welcome to contribute. See list of `TODO's` below.
|
67
|
+
|
68
|
+
## TODO
|
69
|
+
|
70
|
+
- reload CSS without reloading the whole page?
|
71
|
+
- smarter reload if there is a change in helper (check methods from rendered views?)
|
72
|
+
- generator for initializer
|
73
|
+
- check how it works with webpacker/importmaps/etc
|
74
|
+
- maybe complex rules, e.g. if "user.rb" file is changed - automatically reload all "users" views
|
75
|
+
- check with older Rails versions
|
76
|
+
- tests or specs
|
77
|
+
- CI (github actions)
|
78
|
+
|
79
|
+
## License
|
80
|
+
|
81
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
82
|
+
|
83
|
+
[<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
|
84
|
+
/>](https://www.railsjazz.com/?utm_source=github&utm_medium=bottom&utm_campaign=rails_live_reload)
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
class Checker
|
3
|
+
|
4
|
+
def self.scan(dt, rendered_files)
|
5
|
+
temp = []
|
6
|
+
|
7
|
+
# all changed files
|
8
|
+
RailsLiveReload.files.each do |file, fdt|
|
9
|
+
temp << file if fdt && fdt > dt
|
10
|
+
end
|
11
|
+
|
12
|
+
# ::Rails.logger.info "Changed: #{temp}"
|
13
|
+
|
14
|
+
result = []
|
15
|
+
|
16
|
+
temp.each do |file|
|
17
|
+
# ::Rails.logger.info "Checking: #{file}"
|
18
|
+
RailsLiveReload.patterns.each do |pattern, rule|
|
19
|
+
#puts "pattern = #{pattern} & rule = #{rule}"
|
20
|
+
# 1. CSS, JS, yaml, helper .rb
|
21
|
+
# 2. checking if rendered file
|
22
|
+
rule_1 = file.match(pattern) && rule == :always
|
23
|
+
rule_2 = file.match(pattern) && rendered_files.include?(file)
|
24
|
+
|
25
|
+
if rule_1 || rule_2
|
26
|
+
result << file
|
27
|
+
break
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
class Client
|
3
|
+
|
4
|
+
def Client.js_code
|
5
|
+
%Q{
|
6
|
+
<script>
|
7
|
+
const files = #{CurrentRequest.current.data.to_a.to_json};
|
8
|
+
setInterval(
|
9
|
+
() => {
|
10
|
+
const formData = new FormData();
|
11
|
+
formData.append('dt', #{Time.now.to_i})
|
12
|
+
formData.append('files', JSON.stringify(files))
|
13
|
+
|
14
|
+
fetch(
|
15
|
+
"#{RailsLiveReload.url}",
|
16
|
+
{
|
17
|
+
method: "post",
|
18
|
+
headers: { 'Accept': 'application/json', },
|
19
|
+
body: formData
|
20
|
+
}
|
21
|
+
)
|
22
|
+
.then(response => response.json())
|
23
|
+
.then(data => {
|
24
|
+
if(data['command'] === 'RELOAD') {
|
25
|
+
window.location.reload()
|
26
|
+
}
|
27
|
+
})
|
28
|
+
}, #{RailsLiveReload.timeout}
|
29
|
+
)
|
30
|
+
</script>
|
31
|
+
}.html_safe
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
class Command
|
3
|
+
attr_reader :dt, :files
|
4
|
+
|
5
|
+
def initialize(params)
|
6
|
+
@dt = params["dt"].to_i
|
7
|
+
@files = JSON.parse(params["files"])
|
8
|
+
end
|
9
|
+
|
10
|
+
def command
|
11
|
+
changes = RailsLiveReload::Checker.scan(dt, files)
|
12
|
+
|
13
|
+
if changes.size == 0
|
14
|
+
{ command: "NO_CHANGES" }
|
15
|
+
else
|
16
|
+
{ command: "RELOAD" }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
class Railtie < ::Rails::Engine
|
3
|
+
|
4
|
+
initializer "rails_live_reload.middleware" do |app|
|
5
|
+
if ::Rails::VERSION::MAJOR.to_i >= 5
|
6
|
+
app.middleware.insert_after ActionDispatch::Executor, RailsLiveReload::Rails::Middleware
|
7
|
+
else
|
8
|
+
begin
|
9
|
+
app.middleware.insert_after ActionDispatch::Static, RailsLiveReload::Rails::Middleware
|
10
|
+
rescue
|
11
|
+
app.middleware.insert_after Rack::SendFile, RailsLiveReload::Rails::Middleware
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
RailsLiveReload::Watcher.init
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer :configure_metrics, after: :initialize_logger do
|
19
|
+
ActiveSupport::Notifications.subscribe(
|
20
|
+
/\.action_view/,
|
21
|
+
RailsLiveReload::Instrument::MetricsCollector.new
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
module Instrument
|
3
|
+
class MetricsCollector
|
4
|
+
def call(event_name, started, finished, event_id, payload)
|
5
|
+
CurrentRequest.current.data.add(payload[:identifier])
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# render_template.action_view
|
12
|
+
# {
|
13
|
+
# identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb",
|
14
|
+
# layout: "layouts/application"
|
15
|
+
# }
|
16
|
+
# render_partial.action_view
|
17
|
+
# {
|
18
|
+
# identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
|
19
|
+
# }
|
20
|
+
# render_collection.action_view
|
21
|
+
# {
|
22
|
+
# identifier: "/Users/adam/projects/notifications/app/views/posts/_post.html.erb",
|
23
|
+
# count: 3,
|
24
|
+
# cache_hits: 0
|
25
|
+
# }
|
26
|
+
# render_layout.action_view
|
27
|
+
# {
|
28
|
+
# identifier: "/Users/adam/projects/notifications/app/views/layouts/application.html.erb"
|
29
|
+
# }
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
module Rails
|
3
|
+
class Middleware
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
dup.call!(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call!(env)
|
13
|
+
request = Rack::Request.new(env)
|
14
|
+
|
15
|
+
if env["REQUEST_PATH"] == RailsLiveReload.url
|
16
|
+
rails_live_response(request)
|
17
|
+
else
|
18
|
+
@status, @headers, @response = @app.call(env)
|
19
|
+
|
20
|
+
if html? && @response.respond_to?(:[]) && (@status == 500 || (@status.to_s =~ /20./ && request.get?))
|
21
|
+
new_response = make_new_response(@response[0])
|
22
|
+
@headers['Content-Length'] = new_response.bytesize.to_s
|
23
|
+
@response = [new_response]
|
24
|
+
end
|
25
|
+
|
26
|
+
[@status, @headers, @response]
|
27
|
+
end
|
28
|
+
rescue Exception => ex
|
29
|
+
puts ex.message
|
30
|
+
puts ex.backtrace.take(10)
|
31
|
+
raise ex
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def rails_live_response(request)
|
37
|
+
[
|
38
|
+
200,
|
39
|
+
{ 'Content-Type' => 'application/json' },
|
40
|
+
[ RailsLiveReload::Command.new(request.params).command.to_json ]
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
def make_new_response(body)
|
45
|
+
body.sub("</head>", "</head>#{RailsLiveReload::Client.js_code}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def html?
|
49
|
+
@headers["Content-Type"].include?("text/html")
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
class CurrentRequest
|
3
|
+
attr_accessor :data, :record
|
4
|
+
attr_reader :request_id
|
5
|
+
|
6
|
+
def CurrentRequest.init
|
7
|
+
Thread.current[:rc_current_request] ||= CurrentRequest.new(SecureRandom.hex(16))
|
8
|
+
end
|
9
|
+
|
10
|
+
def CurrentRequest.current
|
11
|
+
CurrentRequest.init
|
12
|
+
end
|
13
|
+
|
14
|
+
def CurrentRequest.cleanup
|
15
|
+
Thread.current[:rc_current_request] = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(request_id)
|
19
|
+
@request_id = request_id
|
20
|
+
@data = Set.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RailsLiveReload
|
2
|
+
class Watcher
|
3
|
+
attr_reader :root
|
4
|
+
|
5
|
+
def Watcher.init
|
6
|
+
watcher = new
|
7
|
+
RailsLiveReload.watcher = watcher
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@root = ::Rails.application.root
|
12
|
+
puts "Watching: #{root}"
|
13
|
+
RailsLiveReload.patterns.each do |pattern, rule|
|
14
|
+
puts " #{pattern} => #{rule}"
|
15
|
+
end
|
16
|
+
self.build_tree
|
17
|
+
self.start_listener
|
18
|
+
end
|
19
|
+
|
20
|
+
def start_listener
|
21
|
+
Thread.new do
|
22
|
+
listener = Listen.to(root) do |modified, added, removed|
|
23
|
+
all = modified + added + removed
|
24
|
+
all.each do |file|
|
25
|
+
RailsLiveReload.files[file] = File.mtime(file).to_i rescue nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
listener.start
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_tree
|
33
|
+
Dir.glob(File.join(root, '**', '*')).select{|file| File.file?(file)}.each do |file|
|
34
|
+
RailsLiveReload.files[file] = File.mtime(file).to_i rescue nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "listen"
|
2
|
+
require "rails_live_reload/version"
|
3
|
+
require "rails_live_reload/client"
|
4
|
+
require "rails_live_reload/watcher"
|
5
|
+
require "rails_live_reload/rails/middleware"
|
6
|
+
require "rails_live_reload/instrument/metrics_collector"
|
7
|
+
require "rails_live_reload/thread/current_request"
|
8
|
+
require "rails_live_reload/checker"
|
9
|
+
require "rails_live_reload/command"
|
10
|
+
require "rails_live_reload/engine"
|
11
|
+
|
12
|
+
module RailsLiveReload
|
13
|
+
mattr_accessor :files
|
14
|
+
@@files = {}
|
15
|
+
|
16
|
+
mattr_accessor :watcher
|
17
|
+
@@watcher = nil
|
18
|
+
|
19
|
+
mattr_accessor :url
|
20
|
+
@@url = "/rails/live/reload"
|
21
|
+
|
22
|
+
mattr_accessor :patterns
|
23
|
+
@@patterns = {}
|
24
|
+
|
25
|
+
mattr_accessor :timeout
|
26
|
+
@@timeout = 100
|
27
|
+
|
28
|
+
def self.setup
|
29
|
+
yield(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.watch(pattern, reload: :on_change)
|
33
|
+
RailsLiveReload.patterns[pattern] = reload
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# default watch settings
|
38
|
+
RailsLiveReload.setup do |config|
|
39
|
+
config.watch %r{app/views/.+\.(erb|haml|slim)$}
|
40
|
+
config.watch %r{(app|vendor)/(assets|javascript)/\w+/(.+\.(css|js|html|png|jpg|ts|jsx)).*}, reload: :always
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_live_reload
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Igor Kasyanchuk
|
8
|
+
- Liubomyr Manastyretskyi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2022-05-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: listen
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: puma
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: pry-nav
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: sprockets-rails
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: wrapped_print
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
description: Ruby on Rails Live Reload with just a single line of code - just add
|
113
|
+
the gem to Gemfile.
|
114
|
+
email:
|
115
|
+
- igorkasyanchuk@gmail.com
|
116
|
+
- manastyretskyi@gmail.com
|
117
|
+
executables: []
|
118
|
+
extensions: []
|
119
|
+
extra_rdoc_files: []
|
120
|
+
files:
|
121
|
+
- MIT-LICENSE
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- lib/rails_live_reload.rb
|
125
|
+
- lib/rails_live_reload/checker.rb
|
126
|
+
- lib/rails_live_reload/client.rb
|
127
|
+
- lib/rails_live_reload/command.rb
|
128
|
+
- lib/rails_live_reload/engine.rb
|
129
|
+
- lib/rails_live_reload/instrument/metrics_collector.rb
|
130
|
+
- lib/rails_live_reload/rails/middleware.rb
|
131
|
+
- lib/rails_live_reload/thread/current_request.rb
|
132
|
+
- lib/rails_live_reload/version.rb
|
133
|
+
- lib/rails_live_reload/watcher.rb
|
134
|
+
homepage: https://github.com/railsjazz/rails_live_reload
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubygems_version: 3.3.3
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Ruby on Rails Live Reload
|
157
|
+
test_files: []
|