hot_reloader 0.5.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2bf9cabe1a8e3383c6fcdaaa3530f249a5df5742918831bc414aa30ae9b251f
4
- data.tar.gz: c4e1a3e0ddbc2332b16be27c4758d015e602b3cb9c4ddad70f257144c7004440
3
+ metadata.gz: 282ee5c0dc94f37d38e97f5ca54134c341c9566729fcdb82cb9be2352a6c62f1
4
+ data.tar.gz: 583954d5950e4c954b6dc668c5f7726b92b986026bfc180efd1aee6bff7377b9
5
5
  SHA512:
6
- metadata.gz: c8d4d1580458d66f0a03fdeb252f57074776d6dd07dd6711f805e537ff87267f8c3b24cc289e44d62657a8308e41e56e6233f0e5e7600516684490412dd0432a
7
- data.tar.gz: d2708191113c9441b7a8a769463ce5c6bd1967323703440d654de2e84e54625e289b2ffc920d52506b9045d16bdb7ca6171fe8f3f99aa79c9b614309b5f58975
6
+ metadata.gz: e69cf88b8edef12b7a22c39dd4a7163818097c4f9244047a637c5b771b0ef339783f5c579905fe5c4a61733a2cf6d7c619eaa7178b7952055c90bab7a4e35b5b
7
+ data.tar.gz: aa6f7ba74d2965fbecd221261581dc7d0fe56f213cadc31a3118c9e8b999bb963e184b1a6bcf535bfb34f47bbeef2d7b70cf096ee43ac891e18816f3ffd35d67
data/README.md CHANGED
@@ -20,22 +20,28 @@ Add to your Gemfile
20
20
 
21
21
  Following is a example for use hot_reloader with [Roda](https://github.com/jeremyevans/roda):
22
22
 
23
- `config.ru` which used to start rack based web server with `command rackup -o 0.0.0.0 -p 9393`
23
+ ### Add loader initialize code into `config/environment.rb`
24
+
25
+ For simple use case, you just need pass paths to `HotReloader.eager_load` or `HotReloader.will_listen`.
24
26
 
25
27
  ```rb
26
- # config.ru
28
+ # config/environment.rb
27
29
 
28
- require_relative './config/environment'
30
+ require 'bundler'
31
+ Bundler.require(:default, ENV.fetch('RACK_ENV', "development"))
32
+ require_relative 'application'
29
33
 
30
- if ENV['RACK_ENV'] == 'production'
31
- run App.freeze.app
34
+ paths = ["#{__dir__}/../app", "#{__dir__}/../app/models"]
35
+
36
+ if ENV['RACK_ENV'] == 'development'
37
+ HotReloader.will_listen(*paths)
32
38
  else
33
- run ->(env) { App.call(env) }
39
+ HotReloader.eager_load(*paths)
34
40
  end
35
41
  ```
36
42
 
37
- Add loader initialize code into `config/environment.rb`
38
-
43
+ For more advanced case(e.g. you need setup zeitwerk loader instance yourself), you
44
+ can pass this instance to HotReloader methods too.
39
45
 
40
46
  ```rb
41
47
  # config/environment.rb
@@ -47,41 +53,88 @@ require_relative 'application'
47
53
  loader = Zeitwerk::Loader.new
48
54
  loader.push_dir("#{__dir__}/../app")
49
55
  loader.push_dir("#{__dir__}/../app/models")
50
- loader.inflector.inflect "ar" => "AR"
51
56
 
52
- if ENV['RACK_ENV'] == 'production'
53
- HotReloader.eager_load(loader)
54
- else
57
+ if ENV['RACK_ENV'] == 'development'
55
58
  HotReloader.will_listen(loader)
59
+ else
60
+ HotReloader.eager_load(loader)
56
61
  end
57
62
  ```
58
63
 
59
- Or use more simple form (if you don't need setup Zeitwerk loader youself)
64
+ When you change root directories files(app/*.rb or app/models/*.rb for above case),
65
+ all monitored files will be reload.
60
66
 
67
+ it is possible to trigger reload from any `.rb` files, even this file not follow constant
68
+ lookup name convention, and this file folder not add to root directories use `push_dir` method.
69
+
70
+ Following is a example.
61
71
 
62
72
  ```rb
63
- # config/environment.rb
73
+ # app/app.rb
64
74
 
65
- require 'bundler'
66
- Bundler.require(:default, ENV.fetch('RACK_ENV', "development"))
75
+ class App < Roda
76
+ plugin :hash_routes
77
+
78
+ Dir["routes/**/*.rb"].each do |route_file|
79
+ load route_file
80
+ end
81
+ end
82
+ ```
67
83
 
68
- paths = ["#{__dir__}/../app", "#{__dir__}/../app/models"]
84
+ ```rb
85
+ # routes/blog.rb
69
86
 
70
- if ENV['RACK_ENV'] == 'production'
71
- HotReloader.eager_load(*paths)
87
+ class App
88
+ hash_routes.on "blog" do |r|
89
+ "blog"
90
+ end
91
+ end
92
+ ```
93
+
94
+ `routes/blog.rb` is not follow constant lookup name convention, so, `routes/` folder can't be
95
+ add to root directories use push_dir method, but you can always trigger with `loader.reload`
96
+ if `routes/blog.rb` was changed, then when `app/app.rb` reloaded, it will load the
97
+ newest code in `routes/blog.rb` from the Dir each loop.
98
+
99
+ For achieve this, you only need pass listened folders to will_listen method as secondary arg.
100
+
101
+ ```rb
102
+ loader = Zeitwerk::Loader.new
103
+ loader.push_dir("#{__dir__}/../app")
104
+
105
+ listened_folders = ["#{__dir__}/../routes"]
106
+
107
+ if ENV['RACK_ENV'] == 'development'
108
+ HotReloader.will_listen(loader, listened_folders)
72
109
  else
73
- HotReloader.will_listen(*paths)
110
+ HotReloader.eager_load(loader)
74
111
  end
112
+ ```
75
113
 
76
- require_relative 'application'
114
+ ### Add other app files
115
+
116
+ `config.ru` which used to start rack based web server with `command rackup -o 0.0.0.0 -p 9393`
117
+
118
+ ```rb
119
+ # config.ru
120
+
121
+ require_relative './config/environment'
122
+
123
+ if ENV['RACK_ENV'] == 'development'
124
+ run ->(env) { App.call(env) }
125
+ else
126
+ run App.freeze.app
127
+ end
77
128
  ```
78
129
 
79
- Write whatever application initialize code which need add into application.rb
130
+ Write whatever application needed initialize code into config/application.rb
80
131
 
81
132
  ```rb
82
133
  # config/application.rb
83
134
 
84
- DB = Sequel.connect(ENV.fetch("DATABASE_URL"), timeout: 10000)
135
+ DB = Sequel.connect(ENV.fetch("#{ENV.fetch('RACK_ENV', "development").upcase}_DATABASE_URL"), timeout: 10000)
136
+ Sequel::Model.plugin :timestamps
137
+ Sequel.extension :symbol_aref
85
138
  ```
86
139
 
87
140
  Add roda code into app/app.rb
@@ -115,7 +168,9 @@ Directory structure is like this:
115
168
  └── Gemfile.lock
116
169
  ```
117
170
 
118
- Change code in app.rb, **all constant get removed from memory, and app.rb evaluated again**!
171
+ After change code in app.rb, **all constant get removed from memory, and app.rb evaluated again**!
172
+
173
+ For a more rich WIP sample project, please check my another project [marketbet_crawler](https://github.com/zw963/marketbet_crawler).
119
174
 
120
175
  ## Support
121
176
 
@@ -124,8 +179,9 @@ Change code in app.rb, **all constant get removed from memory, and app.rb evalua
124
179
 
125
180
  ## Dependency
126
181
 
127
- zeitwerk https://github.com/fxn/zeitwerk
128
- listen https://github.com/guard/listen
182
+ [zeitwerk](https://github.com/fxn/zeitwerk) https://github.com/fxn/zeitwerk
183
+
184
+ [listen](https://github.com/guard/listen) https://github.com/guard/listen
129
185
 
130
186
  ## Contributing
131
187
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class HotReloader
4
- VERSION = '0.5.0'
4
+ VERSION = '0.8.1'
5
5
  end
data/lib/hot_reloader.rb CHANGED
@@ -10,31 +10,46 @@ class HotReloader
10
10
  #
11
11
  # @param [*String, Array<String>] folders Folders which should be monitor, can be multi-args or array.
12
12
  # or only one Zeitwerk::Loader object can be provided.
13
- # @param [#call] logger logger or any object should response call.
14
- # @param [Array<String>] ignore Glob patterns or Pathname object which should be excluded.
13
+ # @param [#call] logger logger object, e.g. Logger.new($stdout).
14
+ # @param [Array<String>, Array<Pathname>] ignore File names, Glob patterns or Pathname object which should be excluded for zeitwerk.
15
+ # @param [Integer] wait_for_delay Set the delay (in seconds) before call loader.reload when changes exist.
16
+ # @param [Array<Regexp>] listen_ignore The regexp pattern which don't want listen on.
17
+ # @yield [] ruby code will be run after Zeitwerk loader get reloaded.
15
18
  # @return nil
16
- def will_listen(*folders, logger: method(:puts), ignore: [])
19
+ def will_listen(*folders, logger: Logger.new(IO::NULL), ignore: [], wait_for_delay: nil, listen_ignore: [])
17
20
  folders = folders.flatten
18
21
 
19
22
  if folders.first.is_a? Zeitwerk::Loader
20
- loader = folders.first
23
+ loader, *listened_folders = folders
21
24
  folders = loader.root_dirs.keys
25
+ # `folders' will add to zeitwerk root directories and listened.
26
+ # `reloadable_folder' listened only, it can be reload dynamically.
27
+ # but not constant lookup use name convention.
22
28
  else
23
29
  loader = Zeitwerk::Loader.new
24
30
 
25
- raise 'you must set the root folders from which you want to load watched files.' if folders&.empty?
31
+ raise 'you must set the root directories from which you want to load watched files.' if folders&.empty?
26
32
  raise 'ignore: only accept an array of glob patterns string or Pathname objects.' unless ignore.is_a? Array
27
33
 
28
34
  folders.each {|folder| loader.push_dir(folder) }
35
+ listened_folders = []
29
36
  end
30
37
 
31
38
  loader.enable_reloading if loader.respond_to? :enable_reloading
32
39
  loader.logger = logger
33
-
34
40
  loader.ignore(ignore) unless ignore.empty?
35
-
36
41
  loader.setup
37
- Listen.to(*folders, wait_for_delay: 1) { loader.reload }.start
42
+
43
+ Listen.logger = logger
44
+
45
+ listen_options = {ignore: [/\A\.?#/]}
46
+ listen_options.merge!({wait_for_delay: wait_for_delay}) if wait_for_delay
47
+ listen_options[:ignore].concat listen_ignore if listen_ignore
48
+
49
+ Listen.to(*(folders + listened_folders), listen_options) do
50
+ loader.reload
51
+ yield if block_given?
52
+ end.start
38
53
  end
39
54
 
40
55
  # Enable autoload ruby file based on default Zeitwerk rule.
@@ -42,9 +57,10 @@ class HotReloader
42
57
  #
43
58
  # @param [*String, Array<String>] folders folders which should be autoload, can be multi-args or array.
44
59
  # or only one Zeitwerk::Loader object can be provided.
45
- # @param [#call] logger logger or any object should response call.
60
+ # @param [#call] logger logger object, e.g. Logger.new($stdout)
61
+ # @param [Array<String>, Array<Pathname>] ignore File names, Glob patterns or Pathname object which should be excluded for zeitwerk.
46
62
  # @return nil
47
- def eager_load(*folders, logger: method(:puts))
63
+ def eager_load(*folders, logger: Logger.new(IO::NULL), ignore: [])
48
64
  folders = folders.flatten
49
65
 
50
66
  if folders.first.is_a? Zeitwerk::Loader
@@ -52,12 +68,15 @@ class HotReloader
52
68
  folders = loader.root_dirs.keys
53
69
  else
54
70
  loader = Zeitwerk::Loader.new
55
- raise 'you must set the root folders from which you want to load watched files.' if folders&.empty?
71
+
72
+ raise 'you must set the root directories from which you want to load watched files.' if folders&.empty?
73
+ raise 'ignore: only accept an array of glob patterns string or Pathname objects.' unless ignore.is_a? Array
56
74
 
57
75
  folders.each {|folder| loader.push_dir(folder) }
58
76
  end
59
77
 
60
78
  loader.logger = logger
79
+ loader.ignore(ignore) unless ignore.empty?
61
80
 
62
81
  loader.setup
63
82
  loader.eager_load
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot_reloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Billy.Zheng(zw963)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-08 00:00:00.000000000 Z
11
+ date: 2021-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk