Ruby deleting directories - ruby

I'm trying to delete a non-empty directory in Ruby and no matter which way I go about it it refuses to work.
I have tried using FileUtils, system calls, recursively going into the given directory and deleting everything, but always seem to end up with (temporary?) files such as
.__afsECFC
.__afs73B9
Anyone know why this is happening and how I can go around it?

require 'fileutils'
FileUtils.rm_rf('directorypath/name')
Doesn't this work?

Safe method: FileUtils.remove_dir(somedir)

Realised my error, some of the files hadn't been closed.
I earlier in my program I was using
File.open(filename).read
which I swapped for a
f = File.open(filename, "r")
while line = f.gets
puts line
end
f.close
And now
FileUtils.rm_rf(dirname)
works flawlessly

I guess the best way to remove a directory with all your content "without using an aditional lib" is using a simple recursive method:
def remove_dir(path)
if File.directory?(path)
Dir.foreach(path) do |file|
if ((file.to_s != ".") and (file.to_s != ".."))
remove_dir("#{path}/#{file}")
end
end
Dir.delete(path)
else
File.delete(path)
end
end
remove_dir(path)

The built-in pathname gem really improves the ergonomics of working with paths, and it has an #rmtree method that can achieve exactly this:
require "pathname"
path = Pathname.new("~/path/to/folder").expand_path
path.rmtree

Related

Test all subclasses on file update

I am learning unit testing with PHP and am following the TDD session on tutsplus: http://net.tutsplus.com/sessions/test-driven-php/
I have set up a ruby watchr script to run the PHPUnit unit tests every time a file is modified using Susan Buck's script: https://gist.github.com/susanBuck/4335092
I would like to change the ruby script so that in addition to testing a file when it is updated it will test all files that inherit from it. I name my files to indicate inheritance (and to group files) as Parent.php, Parent.Child.php, and Parent.Child.GrandChild.php, etc so the watchr script could just search by name. I just have no idea how to do that.
I would like to change:
watch("Classes/(.*).php") do |match|
run_test %{Tests/#{match[1]}_test.php}
end
to something like:
watch("Classes/(.*).php") do |match|
files = get all classes that inherit from {match[1]} /\b{match[1]}\.(.*)\.php/i
files.each do |file|
run_test %{Tests/{file}_test.php}
end
end
How do I do the search for file names in the directory? Or, is there an easier/better way to accomplish this?
Thanks
EDIT
This is what I ended up with:
watch("#{Library}/(.*/)?(.*).php") do |match|
file_moded(match[1], match[2])
end
def file_moded(path, file)
subclasses = Dir["#{Library}/#{path}#{file}*.php"]
p subclasses
subclasses.each do |file|
test_file = Tests + file.tap{|s| s.slice!(".php")}.tap{|s| s.slice!("#{Library}")} + TestFileEnd
run_test test_file
end
end
Where Library, Tests, and TestFileEnd are values defined at the top of the file. It was also changed so that it will detect changes in subfolders to the application library and load the appropriate test file.
I'm not entirely certain, but i think this will work:
watch("Classes/(.*).php") do |match|
subclasses = Dir["Classes/#{match[1]}*.php"]
filenames = subclasses.map do |file|
file.match(/Classes\/(.*)\.php/)[1]
end
filenames.each do |file|
run_test "Tests/#{file}_test.php"
end
end
It's probably not the cleaneast way, but it should work.
The first line saves all the relative paths to files in the Classes directory beginning with the changed filename in subclasses.
in the map block I use a regex to only get the filename, without any folder names or the .php extensions.
Hope this helps you

Is there a better way to ensure ruby's LOAD_PATH doesn't get messed up?

I'm trying to avoid ever adding a redundant path to ruby's LOAD_PATH. It's not a remarkably complicated task, I'm just wondering if there is a cleaner method then what I've come up with.
This is my current solution as it stands now:
def add_loadpath(new_path)
included = $LOAD_PATH.inject(false) do |acc,path|
acc || new_path == File.expand_path(path)
end
$LOAD_PATH.unshift new_path unless included
end
Then instead of doing the usual $LOAD_PATH.unshift SOME_PATH you'd call
add_loadpath SOME_PATH
This is to avoid problems when the load path includes two paths that point to the same folder but are not the same string. For example foo/../bar and bar
I believe all paths in $LOAD_PATH are already expanded, so File.expand_path(path) is pointless. Your code can be refactored to this:
def add_loadpath(new_path)
File.expand_path(new_path)
.tap{|new_path| $LOAD_PATH.unshift(new_path) unless $LOAD_PATH.include?(new_path)}
end
or
def add_loadpath(new_path)
$LOAD_PATH.unshift(File.expand_path(new_path)).uniq!
end

Can't delete Dir/Files after using File.open block

When trying to delete a directory (+ contents) and after reading the files inside, FileUtils.rm_rf(path) will not delete all the folders, although it does delete all the files and some of the folders.
After some experimentation it seems to be related to a File.open block. (I actually do a regex match inside the block, but I'm just using a puts here to keep things clear)
File.open(file).each do |line|
puts line
end
From what I've read, the above should automatically close the file but when using this, FileUtils fails to complete its task.
However, if I use the following code, FileUtils works as desired.
open_file = File.open(file)
open_file.each do |line|
puts line
end
open_file.close
It's no big deal to use the code in the second example, but I do prefer the cleanliness of the first.
Is there any reason why that first example breaks FileUtils?
P.S. I'm new to both Ruby and Stack Overflow....Hi. My system is Ubuntu 11.04 (64bit), running RVM with Ruby 1.9.2-p180
You should use something like this:
File.open(file) do |f|
f.each{|line| puts line}
end
In your example the block is supplied to the each method and the version of open without a block is executed returning an IO object on which the each method is called.

Is it possible to recursively require all files in a directory in Ruby?

I am working on an API that needs to load all of the .rb files in its current directory and all subdirectories. Currently, I am entering a new require statement for each file that I add but I would like to make it where I only have to place the file in one of the subdirectories and have it automatically added.
Is there a standard command to do this?
In this case its loading all the files under the lib directory:
Dir["#{File.dirname(__FILE__)}/lib/**/*.rb"].each { |f| load(f) }
require "find"
Find.find(folder) do |file|
next if File.extname(file) != ".rb"
puts "loading #{file}"
load(file)
end
This will recursively load each .rb file.
like Miguel Fonseca said, but in ruby >= 2 you can do :
Dir[File.expand_path "lib/**/*.rb"].each{|f| require_relative(f)}
I use the gem require_all all the time, and it gets the job done with the following pattern in your requires:
require 'require_all'
require_all './lib/exceptions/'
def rLoad(dir)
Dir.entries(dir).each {|f|
next if f=='.' or f=='..'
if File.directory?(f)
rInclude(f)
else
load(f) if File.fnmatch('*.rb', f)
end
}
end
This should recursively load all .rb files in the directory specified by dir. For example, rLoad Dir.pwd would work on the current working directory.
Be careful doing this, though. This does a depth-first search and if there are any conflicting definitions in your Ruby scripts, they may be resolved in some non-obvious manner (alphabetical by folder/file name I believe).
You should have a look at this gem. It is quite small so you can actually re-use the code instead of installing the whole gem.

How do I move a file with Ruby?

I want to move a file with Ruby. How do I do that?
You can use FileUtils to do this.
#!/usr/bin/env ruby
require 'fileutils'
FileUtils.mv('/tmp/your_file', '/opt/new/location/your_file')
Remember; if you are moving across partitions, "mv" will copy the file to new destination and unlink the source path.
An old question, i'm surprised no one answered this simple solution. You don't need fileutils or a systemcall, just rename the file to the new location.
File.rename source_path, target_path
Happy coding
FileUtils.move
require 'fileutils'
FileUtils.move 'stuff.rb', '/notexist/lib/ruby'
Use the module 'fileutils' and use FileUtils.mv:
http://www.ruby-doc.org/stdlib-2.0/libdoc/fileutils/rdoc/FileUtils.html#method-c-mv
here is a template .
src_dir = "/full_path/to_some/ex_file.txt"
dst_dir = "/full_path/target_dir"
#Use the method below to do the moving
move_src_to_target_dir(src_dir, dst_dir)
def archive_src_to_dst_dir(src_dir, dst_dir)
if File.exist ? (src_dir)
puts "about to move this file: #{src_dir}"
FileUtils.mv(src_dir, dst_dir)
else
puts "can not find source file to move"
end
end
you can move your file like this
Rails.root.join('foo','bar')

Resources