📜 ⬆️ ⬇️

Setting up the Guard to automate Ruby on Rails development

Hello! In my opinion, every programmer should strive to automate and optimize everything that is moving and not yet. This article will explain how to automate a Ruby on Rails developer’s workflow using a gem Ruby called Guard. This article is primarily useful to Ruby developers, but may be useful to others.

image

What is the Guard?



Guard is a tool that allows you to automatically execute any commands when a file changes. For example, if you change the server settings file, Guard may automatically restart the server. Or you can set up an automatic compilation of LESS in CSS when saving a file. It all depends on how the Guard is configured by the developer.

At Guard there is a special file of settings Guardfile, which indicates which commands to run when changing which files. All settings can be specified by yourself, or you can use those written by the community Guard Plugins, in which the most frequently used settings are written in advance.
')

Installation and first launch


The best way to integrate Guard into a project is to add it to the Gemfile.

group :development do gem 'guard' end 

And then install it with the command

 $ bundle 

After that, you need to create a Guardfile command

 $ bundle exec guard init 

It is best to run Guard using the Bundler command.

 $ bundle exec guard 

image

Configuring Ruby on Rails Applications


After installation, consider using Guard for a standard RoR project. Suppose the RoR application is already created. Let the Guard automatically install all necessary gems when the gemfile changes.

1. Adding to the project


To do this, in the Gemfile we will add to the group to develop the guard-bundler gems.

 group :development do # And updates gems when needed gem 'guard-bundler', require: false end 

Set the heme

 $ bundle install 

And then we initialize the plugin with the command

 $ guard init bundler 

Pay attention to the Guardfile, located in the root of the project. Now there are lines

 guard :bundler do watch('Gemfile') end 

It says that Guard will monitor the Gemfile file and will execute the command previously recorded in the guard-bundler gem. In this case, this

 $ bundle install 


2. Check


Check it out! Enable Guard in the terminal command

 $ bundle exec guard 

Add some gems to the gemfile. For example, guard-rspec , which will automatically run tests for the Rspec.

 gem 'guard-rspec', require: false 

Let's open the terminal with the guard process and see that it automatically started the bundler there, as a result of which the guard-rspec was automatically installed. As you can see, such a setting Guard allows the developer to automate one of the frequently performed tasks.

3. Customization


Initialize the plugin for Rspec after installing it

 $ guard init rspec 

Now in the Guardfile there are new lines. Consider them:

 # Note: The cmd option is now required due to the increasing number of ways # rspec may be run, below are examples of the most common uses. # * bundler: 'bundle exec rspec' # * bundler binstubs: 'bin/rspec' # * spring: 'bin/rsspec' (This will use spring if running and you have # installed the spring binstubs per the docs) # * zeus: 'zeus rspec' (requires the server to be started separetly) # * 'just' rspec: 'rspec' guard :rspec, cmd: 'bundle exec rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch('config/routes.rb') { "spec/routing" } watch('app/controllers/application_controller.rb') { "spec/controllers" } watch('spec/rails_helper.rb') { "spec" } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" } # Turnip features and steps watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end 

These lines set up the automatic launch of the Rspec tests. Consider some of them. For example, the string

 ruby watch('spec/spec_helper.rb') { "spec” } 

says that Guard will monitor the spec / spec_helper.rb file (the path relative to the project root is the Guardfile file) and if it is changed it will start testing the entire spec folder. Block start

 ruby guard :rspec, cmd: 'bundle exec rspec' do 

says that for any rule all Rspec commands will be run with the parameters bundle exec rspec. That is, in the considered case, if you change ruby ​​spec / spec_helper.rb, the command will be run

 $ bundle exec rspec spec 

Line

 rubywatch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 

says that when changing any .rb file, the testing of the test associated with this file will be launched. That is, when you change app / models / user.rb, the command will automatically start.

 $ bundle exec spec spec/models/user_spec.rb 

Regular expressions are used to create and edit such actions. I recommend using the match command in the Ruby console for debugging, for example

 "app/views/units/index.html.slim".match(%r{^app/views/(.+)/(.*)\.(.*)\.(erb|haml|slim)$}) 


More examples!


For Guard written a large number of plugins for all occasions. Each developer should independently find the necessary for him and customize them for themselves. I will briefly describe those that are used by me at the moment. I myself have not yet found the ideal solutions, so I will be glad to any comments and suggestions!

In gemfile



 group :development, :test do # Integrates jasmine js testing gem 'jasmine-rails' # With guard gem 'guard-jasmine', git: "git://github.com/guard/guard-jasmine.git", branch: "jasmine-2" # Checks ruby code grammar gem 'rubocop', require: false # With rspec gem 'rubocop-rspec' # With guard gem 'guard-rubocop' end group :development do # Automagically launches tests for changed files gem 'guard' gem 'guard-rspec', require: false # And updates gems when needed gem 'guard-bundler', require: false # And auto starts rails server gem 'guard-rails' # And auto runs migrations gem 'guard-migrate' end 


In guardfile



 # More info at https://github.com/guard/guard#readme # https://github.com/guard/guard-bundler guard :bundler do watch('Gemfile') end # https://github.com/guard/guard-rspec guard :rspec, cmd: 'zeus rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } # Run the model specs related to the changed model watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } # Controller changes watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } watch('config/routes.rb') { "spec/controllers" } watch('app/controllers/application_controller.rb') { "spec/controllers" } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch('spec/rails_helper.rb') { "spec" } watch('spec/spec_helper.rb') { "spec" } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/acceptance/#{m[1]}" } watch(%r{^app/views/(.+)/(.*)\.(.*)\.(erb|haml|slim)$}) { |m| "spec/acceptance/#{m[1]}" } watch(%r{^app/views/(.+)/_.*\.(erb|haml|slim)$}) { |m| "spec/acceptance/#{m[1].partition('/').first}/#{m[1].partition('/').last}_spec.rb" } end # Checks any changed ruby file for code grammar # https://github.com/yujinakayama/guard-rubocop guard :rubocop, all_on_start: false, cli: ['--out', 'log/rubocop.log'] do watch(%r{^(.+)\.rb$}) { |m| "#{m[1]}.rb" } end # Restarts server on config changes # https://github.com/ranmocy/guard-rails guard :rails, zeus: true, daemon: true do watch('Gemfile.lock') watch(%r{^(config|lib)/.*}) end # Restarts all jasmine tests on any js change # https://github.com/guard/guard-jasmine guard :jasmine, all_on_start: false, server_mount: '/specs' do watch(%r{^app/(.+)\.(js\.coffee|js|coffee)}) { "spec/javascripts" } watch(%r{^spec/javascripts/(.+)\.(js\.coffee|js|coffee)}) { "spec/javascripts" } end # Runs migrations on migrate files changes # https://github.com/glanotte/guard-migrate guard :migrate do watch(%r{^db/migrate/(\d+).+\.rb}) watch('db/seeds.rb') end 

Little rubocop


image
Rubocop is a Ruby gem that allows you to check the .rb file for correct syntax. In this example, it is configured with Guard, so that every time a .rb file is modified, Rubocop checks it and displays the result in the console and in the log / rubocop.log file.

Rubocop has a huge amount of settings, thanks to which it can be adapted to any syntax requirements. You can even make it automatically adjust the code. To configure the gem, the .rubocop.yml file is used, for example, rubocop usually swears for lines greater than 90 characters, but thanks to the settings file, it can be made so that it points only to lines larger than 140.

To see all the settings, just run the command.

 $ rubocop --auto-gen-config 

which will create a file with all disabled settings. You can thus include one by one and get the final required .rubocop.yml file.

results


What is the final result? In this project, it is enough to run separate processes zeus and guard. Then the following happens:
  1. The server running via zeus Rails is automatically supported and restarted each time the main project settings files are changed.
  2. With each change in Gemfile, all gems are set.
  3. When changing any file with the test, this test is run.
  4. When changing any file controllers / models / libs / views, the associated test is started, if there is one
  5. Each modified ruby ​​file is checked for literacy using rubocop
  6. When changing any javascript / coffeescript file, all jasmine tests are run.
  7. When changing any migration file or seeds, all necessary migrations are run.

image

Thus, a sufficiently large number of processes could be automated. I would like to make it so that each project would only be enough to run guard and fully focus on the creative process.

An example of working with Guard


Now I will describe the current process of working with the Guard. Below are the recommendations that I gave the rest of the developers with whom I am currently working.
  1. Open a terminal and go to the project folder.
  2. Run zeus for accelerated tests / server
     $ zeus start 
  3. Launch Guard
     $ bundle exec guard 

    Now the Guard will automatically start and keep the enabled Rails server enabled via Zeus.
  4. Run all tests by pressing Enter in the terminal. After fixing all the tests you can work!

What you should pay attention: when changing test files, tests will be run automatically. That is, I recommend keeping the terminal window open at the same time as the IDE window (in Rubymine, for example, this can be done right in the sub window), where you can immediately see if the tests have fallen off with the changes made.

image

Thank!


Thank you for reading! I do not claim that I am an expert in the Guard, so I will be glad to any comments and suggestions.

Source: https://habr.com/ru/post/238667/


All Articles