hot_reloader 0.4.0 → 0.7.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: 653d3d0ea04c00516d19cbccfbc434c065dfbfc6bc0a2da9b4b6a48c21c9a8e4
4
- data.tar.gz: cfa179f1a802f6585ed42ae2a6dc5b3a3b89ce23cdedf33444a7750e6e8311b7
3
+ metadata.gz: 2662bca54aa2c3c8037bba0968b11b55ed697649fd4db820605db4a691d87e24
4
+ data.tar.gz: 7233061e421dfffb81445cdd11b2f23a9cfe8ad0b7f713a6c999a673790e5342
5
5
  SHA512:
6
- metadata.gz: 4a8b390f967df6eca1ed620508f2144e96dc89d52019232f108b2813dc22bb4f0af516220699af28347e95e96ec318170976d7cabf66150a9a3de033431b06b2
7
- data.tar.gz: 8408367dc5eadf1fc7278bd9ad40a10ae557c842b53f32df5faeb1726e6f80fbdc7ba73614fc9f74762238a2eceb34042be4fbbb983c6ffdd2cab48c5d6baebf
6
+ metadata.gz: 95f5e16fe369b17f8fd9ec71a8fb32cc285f94b6b18ad1cc4c6b9ef4088863cc4aab229beede4e18a0f49b3e715ddd095eb018f0540cb9c1ffb432ef2d46cba9
7
+ data.tar.gz: 91921b33d2ddb6218452dbcf5ab9069dbd44584fe390dd2c03d25eb28b587d6c6db01f67bb3a15ef1d459c5da8bcb1404eed1306fd44b2f8a8cd13df28fbcaae
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # HotReloader [![Build Status](https://travis-ci.org/zw963/hot_reloader.svg?branch=master)](https://travis-ci.org/zw963/hot_reloader) [![Gem Version](https://badge.fury.io/rb/hot_reloader.svg)](http://badge.fury.io/rb/hot_reloader)
1
+ # HotReloader [![Build Status](https://travis-ci.com/zw963/hot_reloader.svg?branch=master)](https://travis-ci.com/zw963/hot_reloader) [![Gem Version](https://badge.fury.io/rb/hot_reloader.svg)](http://badge.fury.io/rb/hot_reloader)
2
2
 
3
3
  A dead simple ruby code hot reloader wrap around [zeitwerk](https://github.com/fxn/zeitwerk) and [listen](https://github.com/guard/listen).
4
4
 
@@ -20,31 +20,138 @@ 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
+ ### 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`.
26
+
23
27
  ```rb
24
- # config.ru
28
+ # config/environment.rb
29
+
30
+ require 'bundler'
31
+ Bundler.require(:default, ENV.fetch('RACK_ENV', "development"))
32
+ require_relative 'application'
25
33
 
26
- require 'roda'
27
- require 'hot_reloader'
34
+ paths = ["#{__dir__}/../app", "#{__dir__}/../app/models"]
28
35
 
29
- if ENV['RACK_ENV'] == 'production'
30
- HotReloader.eager_load('path1', 'path2')
31
- run App
36
+ if ENV['RACK_ENV'] == 'development'
37
+ HotReloader.will_listen(*paths)
32
38
  else
33
- HotReloader.will_listen('path1', 'path2'')
34
- run ->(env) { App.call(env) }
39
+ HotReloader.eager_load(*paths)
35
40
  end
36
41
  ```
37
42
 
43
+ For more advanced case(e.g. you need setup zeitwerk loader instance yourself), you
44
+ can pass this instance to HotReloader methods too.
45
+
38
46
  ```rb
39
- # app.rb
47
+ # config/environment.rb
48
+
49
+ require 'bundler'
50
+ Bundler.require(:default, ENV.fetch('RACK_ENV', "development"))
51
+ require_relative 'application'
52
+
53
+ loader = Zeitwerk::Loader.new
54
+ loader.push_dir("#{__dir__}/../app")
55
+ loader.push_dir("#{__dir__}/../app/models")
56
+
57
+ if ENV['RACK_ENV'] == 'development'
58
+ HotReloader.will_listen(loader)
59
+ else
60
+ HotReloader.eager_load(loader)
61
+ end
62
+ ```
63
+
64
+ When you change root directories files(app/*.rb or app/models/*.rb for above case),
65
+ all monitored files will be reload.
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.
71
+
72
+ ```rb
73
+ # app/app.rb
40
74
 
41
75
  class App < Roda
42
- articles = []
76
+ plugin :hash_routes
77
+
78
+ Dir["routes/**/*.rb"].each do |route_file|
79
+ load route_file
80
+ end
81
+ end
82
+ ```
83
+
84
+ ```rb
85
+ # routes/blog.rb
86
+
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
+ ```
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)
109
+ else
110
+ HotReloader.eager_load(loader)
111
+ end
112
+ ```
113
+
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`
43
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
128
+ ```
129
+
130
+ Write whatever application needed initialize code into config/application.rb
131
+
132
+ ```rb
133
+ # config/application.rb
134
+
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
138
+ ```
139
+
140
+ Add roda code into app/app.rb
141
+
142
+ ```rb
143
+ # app/app.rb
144
+
145
+ class App < Roda
146
+ articles = ['programming ruby', 'programming rust']
44
147
  route do |r|
45
148
  r.post "articles" do
46
- articles << r.params["content"]
47
- "Count: #{articles.count}"
149
+ articles << r.params["content"]
150
+ "Count: #{articles.count}"
151
+ end
152
+
153
+ r.get "articles" do
154
+ articles.join(', ')
48
155
  end
49
156
  end
50
157
  end
@@ -53,13 +160,17 @@ end
53
160
  Directory structure is like this:
54
161
 
55
162
  ```
56
- ├── app.rb
163
+ ├── app/app.rb
164
+ ├── config/environment.rb
165
+ ├── config/application.rb
57
166
  ├── config.ru
58
167
  ├── Gemfile
59
168
  └── Gemfile.lock
60
169
  ```
61
170
 
62
- 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).
63
174
 
64
175
  ## Support
65
176
 
@@ -68,8 +179,9 @@ Change code in app.rb, **all constant get removed from memory, and app.rb evalua
68
179
 
69
180
  ## Dependency
70
181
 
71
- zeitwerk https://github.com/fxn/zeitwerk
72
- 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
73
185
 
74
186
  ## Contributing
75
187
 
data/lib/hot_reloader.rb CHANGED
@@ -9,40 +9,70 @@ class HotReloader
9
9
  # Should be used for development mode only.
10
10
  #
11
11
  # @param [*String, Array<String>] folders Folders which should be monitor, can be multi-args or array.
12
- # @param [#call] logger logger or any object should response call.
13
- # @param [Array<String>] ignore Glob patterns or Pathname object which should be excluded.
12
+ # or only one Zeitwerk::Loader object can be provided.
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.
14
17
  # @return nil
15
- def will_listen(*folders, logger: method(:puts), ignore: [])
16
- loader = Zeitwerk::Loader.new
18
+ def will_listen(*folders, logger: Logger.new(IO::NULL), ignore: [], wait_for_delay: nil, listen_ignore: [])
17
19
  folders = folders.flatten
18
20
 
19
- raise 'you must set the root folders from which you want to load watched files.' if folders&.empty?
20
- raise 'ignore: only accept an array of glob patterns string or Pathname objects.' unless ignore.is_a? Array
21
+ if folders.first.is_a? Zeitwerk::Loader
22
+ loader, *listened_folders = folders
23
+ folders = loader.root_dirs.keys
24
+ # `folders' will add to zeitwerk root directories and listened.
25
+ # `reloadable_folder' listened only, it can be reload dynamically.
26
+ # but not constant lookup use name convention.
27
+ else
28
+ loader = Zeitwerk::Loader.new
29
+
30
+ raise 'you must set the root directories from which you want to load watched files.' if folders&.empty?
31
+ raise 'ignore: only accept an array of glob patterns string or Pathname objects.' unless ignore.is_a? Array
32
+
33
+ folders.each {|folder| loader.push_dir(folder) }
34
+ listened_folders = []
35
+ end
21
36
 
22
- folders.each {|folder| loader.push_dir(folder) }
23
37
  loader.enable_reloading if loader.respond_to? :enable_reloading
24
38
  loader.logger = logger
25
-
26
39
  loader.ignore(ignore) unless ignore.empty?
27
-
28
40
  loader.setup
29
- Listen.to(*folders, wait_for_delay: 1) { loader.reload }.start
41
+
42
+ Listen.logger = logger
43
+
44
+ listen_options = {ignore: [/\A\.?#/]}
45
+ listen_options.merge!({wait_for_delay: wait_for_delay}) if wait_for_delay
46
+ listen_options[:ignore].concat listen_ignore if listen_ignore
47
+
48
+ Listen.to(*(folders + listened_folders), listen_options) { loader.reload }.start
30
49
  end
31
50
 
32
51
  # Enable autoload ruby file based on default Zeitwerk rule.
33
52
  # More rule see https://github.com/fxn/zeitwerk
34
53
  #
35
54
  # @param [*String, Array<String>] folders folders which should be autoload, can be multi-args or array.
36
- # @param [#call] logger logger or any object should response call.
55
+ # or only one Zeitwerk::Loader object can be provided.
56
+ # @param [#call] logger logger object, e.g. Logger.new($stdout)
57
+ # @param [Array<String>, Array<Pathname>] ignore File names, Glob patterns or Pathname object which should be excluded for zeitwerk.
37
58
  # @return nil
38
- def eager_load(*folders, logger: method(:puts))
39
- loader = Zeitwerk::Loader.new
59
+ def eager_load(*folders, logger: Logger.new(IO::NULL), ignore: [])
40
60
  folders = folders.flatten
41
61
 
42
- raise 'you must set the root folders from which you want to load watched files.' if folders&.empty?
62
+ if folders.first.is_a? Zeitwerk::Loader
63
+ loader = folders.first
64
+ folders = loader.root_dirs.keys
65
+ else
66
+ loader = Zeitwerk::Loader.new
67
+
68
+ raise 'you must set the root directories from which you want to load watched files.' if folders&.empty?
69
+ raise 'ignore: only accept an array of glob patterns string or Pathname objects.' unless ignore.is_a? Array
70
+
71
+ folders.each {|folder| loader.push_dir(folder) }
72
+ end
43
73
 
44
- folders.each {|folder| loader.push_dir(folder) }
45
74
  loader.logger = logger
75
+ loader.ignore(ignore) unless ignore.empty?
46
76
 
47
77
  loader.setup
48
78
  loader.eager_load
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class HotReloader
4
- VERSION = '0.4.0'
4
+ VERSION = '0.7.1'
5
5
  end
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.4.0
4
+ version: 0.7.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: 2020-06-23 00:00:00.000000000 Z
11
+ date: 2021-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  requirements: []
71
- rubygems_version: 3.0.3
71
+ rubygems_version: 3.2.3
72
72
  signing_key:
73
73
  specification_version: 4
74
74
  summary: A dead simple ruby code hot reloader wrap around zeitwerk and listen.