Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit 2a91659

Browse files
authored
Add gem config, main and loader class
1 parent acd24a4 commit 2a91659

19 files changed

+897
-1
lines changed

.env.development.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AUTORELOAD_ENABLED='true'

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.bundle/
2+
/log/*
3+
/tmp/*
4+
!/log/.keep
5+
!/tmp/.keep
6+
7+
# ruby version files
8+
.ruby-*
9+
10+
# rspec configs
11+
.rspec
12+
13+
# dotenv files
14+
.env
15+
.env.test
16+
17+
# Ignore rubymine files.
18+
.idea
19+
20+
.DS_Store
21+
.vimrc
22+
# vim ignores
23+
# swap
24+
[._]*.s[a-v][a-z]
25+
[._]*.sw[a-p]
26+
[._]s[a-v][a-z]
27+
[._]sw[a-p]
28+
# session
29+
Session.vim
30+
# temporary
31+
.netrwhist
32+
*~
33+
# auto-generated tag files
34+
tags
35+
36+
.byebug_history

.rspec.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
--color
2+
--require spec_helper

.rubocop.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
AllCops:
2+
TargetRubyVersion: 2.5.3
3+
DisplayCopNames: true
4+
Exclude:
5+
- '**/Gemfile'
6+
- '**/Rakefile'
7+
- '**/*.gemspec'
8+
9+
Documentation:
10+
Enabled: false
11+
12+
ClassLength:
13+
Max: 150
14+
15+
Metrics/AbcSize:
16+
Max: 20
17+
18+
Metrics/BlockLength:
19+
Exclude:
20+
- '**/spec/**/*.rb'
21+
22+
Metrics/LineLength:
23+
Max: 120
24+
25+
Metrics/PerceivedComplexity:
26+
Max: 10
27+
28+
Metrics/MethodLength:
29+
Max: 20
30+
31+
Metrics/CyclomaticComplexity:
32+
Max: 10
33+
34+
Style/RegexpLiteral:
35+
EnforcedStyle: percent_r
36+
37+
Rails/HasAndBelongsToMany:
38+
Enabled: false
39+
40+
Rails/InverseOf:
41+
Enabled: false
42+
43+
Naming/UncommunicativeMethodParamName:
44+
AllowedNames:
45+
- '_'
46+
47+
Style/MixinUsage:
48+
Exclude:
49+
- 'bin/*'

CONTRIBUTING.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## Contributing
2+
3+
While not required to contribute, we recommend [RBENV](https://github.com/rbenv/rbenv) to manage your rubies.
4+
5+
1. Read the [Contributor Code of Conduct](https://www.contributor-covenant.org/version/1/0/0/code-of-conduct.html)
6+
2. [Fork it](https://help.github.com/articles/about-forks/)
7+
3. Clone the project `git clone git@github.com:[YOUR GITHUB USERNAME]/ruby-code-autoreloader.git`
8+
4. `cd ruby-code-autoreloader`
9+
5. Create your feature branch `git checkout -b my-new-feature`
10+
6. Write tests for your changes (feature/bug)
11+
7. Write your (feature/bugfix)
12+
8. Install the dependencies `bundle install`
13+
9. Run the tests `bundle exec rspec`
14+
10. Commit your changes `git commit -am 'Added some feature'`
15+
11. Push to the branch `git push origin my-new-feature`
16+
12. Create new [Pull Request](https://help.github.com/articles/creating-a-pull-request/)
17+
18+
If we've missed something please open an [issue](https://github.com/resolving/ruby-code-autoreloader/issues/new)

Gemfile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
source 'https://rubygems.org'
2+
3+
ruby '2.5.3'
4+
5+
# Declare your gem's dependencies in ruby_code_autoreloading.gemspec.
6+
# Bundler will treat runtime dependencies like base dependencies, and
7+
# development dependencies will be added by default to the :development group.
8+
gemspec
9+
10+
# Declare any dependencies that are still in development here instead of in
11+
# your gemspec. These might include edge Rails or gems from your path or
12+
# Git. Remember to move these dependencies to your gemspec before releasing
13+
# your gem to rubygems.org.
14+
15+
# To use a debugger
16+
gem 'byebug', group: [:development, :test]
17+
18+
group :development, :test do
19+
gem 'rubocop', require: false
20+
gem 'rspec'
21+
end

Gemfile.lock

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
PATH
2+
remote: .
3+
specs:
4+
ruby-code-autoreloader (0.1.0)
5+
activesupport (>= 5.1.4)
6+
7+
GEM
8+
remote: https://rubygems.org/
9+
specs:
10+
activesupport (5.2.3)
11+
concurrent-ruby (~> 1.0, >= 1.0.2)
12+
i18n (>= 0.7, < 2)
13+
minitest (~> 5.1)
14+
tzinfo (~> 1.1)
15+
ast (2.4.0)
16+
byebug (11.0.1)
17+
concurrent-ruby (1.1.5)
18+
diff-lcs (1.3)
19+
i18n (1.6.0)
20+
concurrent-ruby (~> 1.0)
21+
jaro_winkler (1.5.2)
22+
minitest (5.11.3)
23+
parallel (1.17.0)
24+
parser (2.6.3.0)
25+
ast (~> 2.4.0)
26+
rainbow (3.0.0)
27+
rspec (3.8.0)
28+
rspec-core (~> 3.8.0)
29+
rspec-expectations (~> 3.8.0)
30+
rspec-mocks (~> 3.8.0)
31+
rspec-core (3.8.0)
32+
rspec-support (~> 3.8.0)
33+
rspec-expectations (3.8.3)
34+
diff-lcs (>= 1.2.0, < 2.0)
35+
rspec-support (~> 3.8.0)
36+
rspec-mocks (3.8.0)
37+
diff-lcs (>= 1.2.0, < 2.0)
38+
rspec-support (~> 3.8.0)
39+
rspec-support (3.8.0)
40+
rubocop (0.70.0)
41+
jaro_winkler (~> 1.5.1)
42+
parallel (~> 1.10)
43+
parser (>= 2.6)
44+
rainbow (>= 2.2.2, < 4.0)
45+
ruby-progressbar (~> 1.7)
46+
unicode-display_width (>= 1.4.0, < 1.7)
47+
ruby-progressbar (1.10.0)
48+
thread_safe (0.3.6)
49+
tzinfo (1.2.5)
50+
thread_safe (~> 0.1)
51+
unicode-display_width (1.6.0)
52+
53+
PLATFORMS
54+
ruby
55+
56+
DEPENDENCIES
57+
byebug
58+
rspec
59+
rubocop
60+
ruby-code-autoreloader!
61+
62+
RUBY VERSION
63+
ruby 2.5.3p105
64+
65+
BUNDLED WITH
66+
1.17.3

README.md

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,145 @@
1-
# ruby-code-autoreloader
1+
# RubyCodeAutoreloader
2+
A simple way to add code auto-reloading to not Rails app
3+
4+
## Index
5+
- [Usage](#usage)
6+
- [Installation](#installation)
7+
- [Configuration](#configuration)
8+
- [Naming convention](#naming-convention)
9+
- [How to use in an application](#how-to-use-in-an-application)
10+
- [Contributing](CONTRIBUTING.md)
11+
- [Maintainers](https://github.com/resolving/ruby-code-autoreloader/graphs/contributors)
12+
- [License](#license)
13+
14+
15+
## Usage
16+
17+
### Installation
18+
Add this line to your application's Gemfile:
19+
20+
```ruby
21+
gem 'ruby-code-autoreloader', resolving: 'ruby-code-autoreloader', tag: '0.1.0' # or ref: 'some md5'
22+
```
23+
24+
And then execute:
25+
```bash
26+
$ bundle install
27+
```
28+
29+
### Configuration
30+
31+
To set configuration use `RubyCodeAutoreloader.configure` with a hash of params.
32+
List of possible params:
33+
34+
| Name | Default value | Description |
35+
| --- | :---: | --- |
36+
| default_file_watcher | ActiveSupport::FileUpdateChecker | File watcher class that will be used for checking files updates |
37+
| autoreload_enabled | ENV['RACK_ENV'] == 'development' | The code reloading will works only if this param is `true`. Then all libs specified in `autoloadable_paths` will be loaded with `load` directive, e.g. `load 'lib_path/file.rb'`. If this param is `false`, then all libs specified in `autoloadable_paths` will be loaded as usual with `require`. Loading process uses the `ActiveSupport::Dependencies::Loadable.require_or_load` method |
38+
| autoloadable_paths | [] | This is an `Array` of paths from which will be loaded all ruby files `'*.rb'`. All files and Classes should be in the compliance with the [`Naming convention`](#naming-convention) described below. |
39+
| reload_only_on_change | TRUE | If this is `true`, then Reloader will check files in `autoloadable_paths` with initialized `file_watcher` and will reload the files if any of them was updated. If this is `false`, then files will be reloaded on each `RubyCodeAutoreloader.reload` method call, e.g. always |
40+
| logger | Logger.new(STDOUT) | Logger object |
41+
42+
Also you can add specific environment variable for changing reloader mode, for
43+
example `ENV['AUTORELOAD_ENABLED']='true'`, and use it in configure.
44+
45+
Example of initializer with configuration:
46+
```ruby
47+
# config/initializers/ruby_code_autoreloader.rb
48+
require 'ruby_code_autoreloader'
49+
50+
RubyCodeAutoreloader.configure(autoreload_enabled: (ENV['RACK_ENV'] == 'development' &&
51+
ENV['AUTORELOAD_ENABLED'] == 'true'),
52+
reload_only_on_change: false,
53+
autoloadable_paths: %w(app/endpoint_flux/middlewares/decorator
54+
app/endpoint_flux/middlewares/validator
55+
app/models
56+
app/endpoint_flux/decorators
57+
app/endpoint_flux/endpoints
58+
app/workers).freeze)
59+
```
60+
61+
#### Naming convention
62+
63+
`RubyCodeAutoreloader` will search for all ruby `"*.rb"` files inside directories that described in `autoloadable_paths`.
64+
The pattern for searching files is `Dir.glob("#{path}/**/*.rb")`, e.g. will be loaded all files from subdirectories too.
65+
Each file will be loaded by `load` or `require` directive, depends on `autoreload_enabled` mode. After each file loading,
66+
`RubyCodeAutoreloader` will accumulate loaded Classes/Modules inside module variable `@autoloaded_classes`, that will be
67+
used to remove constant before each `Reloading`.
68+
69+
And here we have a special `Naming convention`:
70+
the **_Classes/Modules_** that will be used for `Reloading` (e.g. will be added to `autoloaded_classes`), **should have**
71+
**the same last module names** as the **`files name`** too. **Otherwise** it will not be included for `Reloading` and
72+
**will be loaded only once** at the start.
73+
That's because it's hard to track what modules was loaded from the file as they might have their own `require` libs inside.
74+
75+
For example we have this file `app/endpoint_flux/endpoints/users/create.rb` in specified dir `app/endpoint_flux/endpoints`,
76+
then Class/Module defined inside should has the name `Create` as **the last module name**,
77+
e.g. like this `::SomeModule::Create` or `Users::Create` or `EndpointFlux::Users::Create` or just `Create`
78+
79+
### How to use in an application
80+
81+
Firstly you need to configure it with initializer, as described in [Configuration](#configuration).
82+
Then you need to call `RubyCodeAutoreloader.start` method after all initializers.
83+
Depends on the `autoreload_enabled` config param, `RubyCodeAutoreloader` will loads the ruby libs specified in
84+
`autoloadable_paths` by `load` or `require` directive.
85+
86+
Example of `environment.rb` with initializing the `RubyCodeAutoreloader` by `start` method:
87+
```ruby
88+
# config/environment.rb
89+
ENV['RACK_ENV'] ||= 'development'
90+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
91+
92+
if ENV['RACK_ENV'] == 'development' || ENV['RACK_ENV'] == 'test'
93+
require 'dotenv'
94+
Dotenv.load(".env.#{ENV['RACK_ENV']}", '.env')
95+
end
96+
97+
require 'bundler/setup'
98+
Bundler.require(:default, ENV['RACK_ENV'])
99+
100+
$LOAD_PATH.unshift File.expand_path('..', __dir__)
101+
$LOAD_PATH.unshift File.expand_path('../app', __dir__)
102+
103+
Dir.glob('config/initializers/*.rb').each { |file| require file }
104+
105+
require "config/environments/#{ENV['RACK_ENV']}.rb"
106+
107+
RubyCodeAutoreloader.start ### Run it only after all initializers
108+
```
109+
110+
Then you can just put `RubyCodeAutoreloader.reload` to the place where you want to check for updates before starting
111+
processing the query. In the example below this `call_endpoint_flux` in Sneakers worker will be called on each query
112+
to the service, and we call `RubyCodeAutoreloader.reload` before another methods. If `autoreload_enabled` is set
113+
to `false`, then reloading will be skipped.
114+
115+
Example of Sneakers worker with the `RubyCodeAutoreloader.reload` call inside:
116+
```ruby
117+
# app/workers/base_worker.rb
118+
119+
module BunnyPublisher
120+
module EndpointFlux
121+
class SneakersWorker
122+
def call_endpoint_flux(message, props)
123+
action = self.class.endpoint_action || props[:headers]['action']
124+
125+
RubyCodeAutoreloader.reload # calling it before processing the query
126+
127+
endpoint = endpoint_for("#{self.class.endpoint_namespace}/#{action}")
128+
129+
_, response = endpoint.perform(request_object(message))
130+
131+
response.body
132+
end
133+
end
134+
end
135+
end
136+
```
137+
138+
## [Contributing](CONTRIBUTING.md)
139+
140+
### [Maintainers](https://github.com/resolving/endpoint-flux/graphs/contributors)
141+
142+
143+
## License
144+
145+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

circle.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: 2
2+
jobs:
3+
build:
4+
docker:
5+
- image: circleci/ruby:2.5.1-node
6+
steps:
7+
- checkout
8+
- run: gem install bundle
9+
- run:
10+
name: Bundle Install
11+
command: bundle check || bundle install
12+
- run:
13+
name: Run Specs
14+
command: bundle exec rspec --format progress

0 commit comments

Comments
 (0)