Guard, how to temporally track specific file? - ruby

I'm using Guard gem
At some time of development I need to track only a specific file or several files but not an entire project.
Is there some handy way to temporarily track a particular file?
I know it can be done by modifying guard file but I don't think it's a neat solution.

Actually you can just use focus: true in the it statement for instance:
In your Spec file.
it "needs to focus on this!", focus: true do
#test written here.
end
Then in spec/spec_helper you need to add the config option.
RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
end
Then Guard will automatically pick up test that is focused and run it only. Also the config.run_all_when_everything_filtered = true tells guard to run all of the tests when there is nothing filtered even though the name sounds misleading.
I find Ryan Bate's rails casts to be very helpful on Guard and Spork.

Perhaps groups will work for you?
# In your Guardfile
group :focus do
guard :ruby do
watch('file_to_focus_on.rb')
end
end
# Run it with
guard -g focus
I know you mentioned you don't want to modify the Guardfile, but adding a group would just need to be done once, not every time you switch from watching the project to a focused set and back.
Of course if the set of files you need to focus on changes, you'll need to change the args to watch (and maybe add more watchers), but I figure you'll have to specify them somewhere and this seems as good a place as any.
Alternately, if you really don't want to list the files to focus on in the Guardfile, you could have the :focus group read in a list of files from a separate file or an environment variable as suggested by David above. The Guardfile is just plain ruby (with access to the guard DSL), so it's easy to read a file or ENV variable.

If you use guard-rspec. You can do this.
Change your Guardfile rspec block so that is has something like this:
guard 'rspec', :cli => ENV['RSPEC_e'].nil? ? "": "-e #{ENV['RSPEC_e']}") do
# ... regular rspec-rails stuff goes here ...
end
Start Guard. And set RSPEC_e before. Like so...
RSPEC_e=here guard
Then whenever you change something only specs that have text "here" (set by RSPEC_e) in their description will be re-run.

You could permanently modify the guard file to check an environment variable of your choosing and behave differently if it is present. For example, access the variable ENV['FILE']. Then you can prepend your command for running guard with FILE=foo.rb whenever you want.

Related

What is a good schema for naming screenshots in selenium webdriver + capyabara

First pass: I name my screenshot "x".
Obviously that minimal setup only allows for 1 screenshot
I want to name the screenshots in a way that makes them unique and also reflect the usage.
I can make the filenname fairly unique with
output_directory = 'screenshots'
time = Time.new
page.save_screenshot("#{output_directory}/#{time}.png")
It's a bit ugly but I get
$ ls screenshots/
'019-04-13 07:07:50 -0400.png''
What would be good format to use that would meet the requirements of both unique and also descriptive. Could I include the scenario description somehow?
How could I end up with something like:
scenario_decsription_2019_04_19-08_55_20
The RSpec test definition methods and hooks (scenario, before, after, etc) all receive an optional parameter which is the test example itself. This allows you to get the description of the test, etc for use in naming your file
scenario "my test" do |example|
...
page.save_screenshot("#{example.full_description}.png")
end
Obviously you could transform the description in any way you want (convert spaces to underscores, etc).
Note: you may also want to look at Capybara.save_path which specifies what directory screenshots are stored in, if you don't want to prepend screenshots/ everywhere.
How about something like this?
scenario "#{scenario = 'user_clicks_the_dropdown'}" do
output_directory = 'screenshots'
time = Time.new
suffix = time.to_s(:db).gsub(/[\:\.\_\s]/,'_')
page.save_screenshot("#{output_directory}/#{scenario}_#{suffix}.png")
end

Ruby I/O Existence Issues

I have a decent amount of knowledge about Ruby code, but I do have an issue with my current project. I use Gosu to make 2D games (and once I figure out how, simple 3D games), so I need a resolution.
And this is where my question comes in, why does Ruby keep giving me an error when seeing if the settings file exists? I've been trying to get it working with the file not existing, which keeps giving me the error, "'initialize': No such file or directory # rb_sysopen - ./settings.set (Errno::ENOENT)" which has been annoying me for the last few days. The file gives no issues and actually works as intended when I leave the file created, but I want it to be where if the file gets deleted off of someone's computer, it rebuilds the file and creates a new one using default values.
Here's the area that it keeps crashing at:
settings = []
settings_file_existance = File.file?("settings.set")
if settings_file_existance == true
File.open("settings.set").readlines.each do |line|
settings.push line
end
else
settings_file = File.open("settings.set")
settings_file.write "800"
settings_file.write "\n"
settings_file.write "600"
settings_file.close
end
I have tried looking for fixes on this site, along with many others, but no one so far has been able to help.
You could try this:
settings = []
if File.file?("settings.set")
settings = File.read("settings.set").split("\n")
else
File.open("settings.set", "w") do |file|
file.write "800\n600"
end
end
As a side note, consider that the above code will set settings only if settings.set file exits, otherwise it will remain in an empty array (i.e. []).
If you wish to avoid that, just define settings with the default values, for example:
settings = [800, 600]
Now if settings.set file doesn't exist, then settings will be [800, 600], otherwise it will be overwritten with the values from settings.set.
To avoid writing 800 and 600 twice, you could use settings variable to get the values to be written in the new file, for example:
file.write(settings.join("\n"))
Putting it all together, your code would look like this:
settings = [800, 600]
if File.file?("settings.set")
settings = File.read("settings.set").split("\n")
else
File.open("settings.set", "w") do |file|
file.write(settings.join("\n"))
end
end

Chef Template - Timestamping

While implementing a templated config file using chef 11.x I'd like to insert the current date/time into the file whenever it is updated.
For example:
# Created By : core::time-settings
# On : <%= Time.now %>
Obviously this evaluates on each recipe run and constantly updates the target file even when the other attributes are OK - which is not desired.
Therefore is anyone aware of a solution? I'm not aware of any built-in logic within Chef to achieve this and I don't know of a built-in chef variable that I could evaluate within a ruby block that would only be true if the other attributes are out of compliance (as that would provide a potential workaround).
I know that I could run an execute type operation which only gets run after the template resource has been fired, and it expands a variable in the file to achieve this, but I don't like the concept or idea of doing that.
Thanks,
While I agree with Tensibai that what you expect is not what Chef is made for.
What I want to add (because some time ago I searched pretty long for that) is how to include the current time stamp in a file, once it was modified through Chef (somehow you have to circumvent that it always updates the time stamp).
The result can be found here, simplified, untested version:
time = Time.new.strftime("%Y%m%d%H%M%S")
template "/tmp/example.txt" do
source "/tmp/example.txt.erb" # the source is not in a cookbook, but on the disk of the node!
local true
variables(
:time => time
)
action :nothing
end
template "/tmp/example.txt.erb" do
variables(
variable1 => "test"
)
notifies :create, resources(:template => "/tmp/example.txt"), :immediately
end
Everytime, when the content of /tmp/example.txt.erb changes, it triggers /tmp/example.txt to be written - taking /tmp/example.txt.erb as template from the local disk instead of from the cookbook (because local true) and replacing the time variable with the current time.
So the only variable that has to be replaced when writing /tmp/example.txt is the time, thus the example.txt.erb template looks like this:
# my template
time: <%%= #time %>
other stuff here.. <%= #variable1 %>
That's the way chef works, it makes a diff between rendered template and actual file, as the timestamp is not the same it replace it.
Your alternate solution won't work either for the same reason, a placeholder will be different than the datetime of the replacements.
The best you can do is write a file aside named 'myfile-last-update' for exemple with a text inside describing the last update of it.
But last question: Why would you want to have the time inside the file as it's already present in the file attribute (ls -l should give you this information) ?

Is there a way to fold all multi-line Ruby comments in Vim?

I'm working on a Ruby gem and I would love to be able to hide all the documentation comments in the file because they are more for people using the library than reading or writing the code. I see the value in having the comments, but when I'm working on the code they are visually distracting to me.
In MacVim I can manually fold lines of code by selecting them and clicking Tools > Folding > Create Fold, but is there a way to automatically hide all comments using some sort of shortcut?
For example, the following code:
# Returns a 2D array for Rails select helper options.
# Also used internally for Formtastic support
#
# ==== Example
# # Create an Enum with some elements
# class Priority < ClassyEnum::Base
# end
#
# class Priority::Low < Priority; end
# class Priority::ReallyHigh < Priority; end
#
# Priority.select_options # => [["Low", "low"], ["Really High", "really_high"]]
def select_options
map {|e| [e.text, e.to_s] }
end
would be displayed as:
def select_options
map {|e| [e.text, e.to_s] }
end
You could try this method:
:set fdm=expr
:set fde=getline(v:lnum)=~'^\\s#'?1:getline(prevnonblank(v:lnum))=~'^\\s#'?1:getline(nextnonblank(v:lnum))=~'^\\s*#'?1:0
The problem is that this method would become the only folding option so that's probably a little bit extreme.
I guess you would like to play with vim’s foldmethod setting. Sorry for slightly vague answer, but I have no MacVim here so you are supposed to adjust directories/filenames in my suggestion yourself.
First of all, try :setlocal foldmethod=syntax in command mode to enable folding within your current file only. If it works, you have all the prerequisites installed (namely, the ruby.vim syntax file.) Try to add let ruby_fold=1 to your .vimrc file. The latter should enable folding over all ruby files (or, alternatively you may explicetely set folding to true for all filetypes supporting folding with set foldmethod=syntax.)
Now you are to find ruby.vim over your file system to tune it up. To give a hint, on Linux distros it’s located at /usr/share/vim/vim73/syntax/ruby.vim. My syntax file enables folding for all the stuff which “may” be folded (e. g. functions, methods, etc.) Copy the original file to your $HOME/.vim/syntax directory and adjust it according to your needs. Navigate through it (by searching for fold, for instance) and remove fold keyword where you don’t want the folding is applied. The names in syntax file are self-explanatory, so you would not be in trouble here.
Restart vim and enjoy your folding. Hope that helps.

Rails File I/O: What works in Ruby doesn't work in Rails?

So, I wrote a simple Ruby class, and put it in my rails /lib directory. This class has the following method:
def Image.make_specific_image(paths, newfilename)
puts "making specific image"
#new_image = File.open(newfilename, "w")
puts #new_image.inspect
##blank.each(">") do |line|
puts line + "~~~~~"
#new_image.puts line
if line =~ /<g/
paths.each do |p|
puts "adding a path"
puts p
#new_image.puts p
end
end
end
end
Which creates a new file, and copies a hardcoded string (##blank) to this file, adding custom content at a certain location (after a g tag is found).
If I run this code from ruby, everything is just peachy.
HOWEVER, if I run this code from rails, the file gets CREATED, but is then empty. I've inspected each line of the code: nothing I'm trying to write to the file is nil, but the file is empty nonetheless.
I'm really stumped here. Is it a permissions thing? If so, why on EARTH would Rails have the permissions necessary to MAKE a file, but then not WRITE to the file it made?
Does File I/O somehow work differently in rails?
Specifically, I have a model method that calls:
Image.make_specific_image(paths, creature.id.to_s + ".svg")
which succesfully makes a file of the type "47.svg" that is empty.
Have you tried calling close on the file after you're done writing it? (You could also use the block-based File.open syntax, which will automatically close once the block is complete). I'm guessing the problem is that the writes aren't getting flushed to disk.
So.
Apparently File I/0 DOES work in Rails...just very, very slowly. In Ruby, as soon as I go to look at the file, it's there, it works, everything is spiffy.
Before, after seeing blank files from Rails, I would get frustrated, then delete the file, and change some code and try again (so as not to be full of spam, since each file is genearted on creature creation, so I would soon end up with a lot of files like "47.svg" and "48.svg", etc.
....So. I took my lunch break, came back to see if I could tell if the permissions of the rails generated file were different from the ruby generated file...and noticed that the RAILS file is no longer blank.
Seems to take about five minutes for rails to finally write to the file, even AFTER it claims it's done processing that whole call. Ruby takes a few seconds. Not really sure WHY they are so different, but at least now I know it's not a permissions thing.
Edit: Actually, on some files take so long, others are instant...

Resources