issue with file path - ruby

What I like to achive is to track the file changes in two directories by using the watchr.
my file structure is the following:
/PluginDir
/classes
Wrapper.php
/Tests
/classes
WrapperTest.php
autotest_watchr.rb
The contents of the autotest_watchr.rb is the following:
watch("../../classes/(.*).php") do |match|
run_test %{#{match[1]}Test.php}
end
watch(".*Test.php") do |match|
run_test match[0]
end
def run_test(file)
clear_console()
unless File.exists?(file)
puts "#{file} does not exists"
return
end
puts "Running #{file}"
results = `phpunit #{file}`
puts results
if results.match(/OK/)
notify "#{file}", "Tests Passed Successfuly", 4500
elsif results.match(/FAILURES\!/)
notify_failed file, results
end
end
def notify_failed cmd, results
failed_examples = results.scan(/([0-9]+\))\s+(.*)/)
notify "#{cmd}", failed_examples[0], 6000
end
def notify title, msg, show_time
systemMsg = "notifu.exe /p \"#{title}\" /m \"#{msg}\" /d #{show_time}"
systemMsg.gsub('“', "'")
system systemMsg
end
def clear_console
system "cls"
end
then from folder /PluginDir/Tests/classes/ I execute the following command from cmd:
watchr autotest_watchr.rb
In this case, the script starts normaly the execution, and when ever I made a modification in my Test files, the console is updated, but when I create a modification in the /PluginDir/classes/*.php files I do not get any update in my console.
Why?
NOTE: In first watch("../../classes/...... I have try also the match[0] just in case the regex variable is not correct, but still the script not works

In your first search string "../../classes/(.*).php" I think that the "." character is actually a place holder for any single character.
For your usage you probably need to escape it with backslashes, so it would be:
'\.\./\.\./classes/(.*)\.php'

Related

Ruby paths with backslash on Mac

Venturing into Ruby lands (learning Ruby). I like it, fun programming language.
Anyhow, I'm trying to build a simple program to delete suffixes from a folder, where user provides the path to the folder in the Mac terminal.
The scenario goes like this:
User runs my program
The program ask user to enter the folder path
User drags and drop the folder into the Mac terminal
Program receives path such as "/Users/zhang/Desktop/test\ folder"
Program goes and renames all files in that folder with suffix such as "image_mdpi.png" to "image.png"
I'm encountering a problem though.
Right now, I'm trying to list the contents of the directory using:
Dir.entries(#directoryPath)
However, it seems Dir.entries doesn't like backslashes '\' in the path. If I use Dir.entries() for a path with backslash, I get an exception saying folder or file doesn't exist.
So my next thought would be to use :
Pathname.new(rawPath)
To let Ruby create a proper path. Unfortunately, even Pathname.new() doesn't like backslash either. My terminal is spitting out
#directoryPath is not dir
This is my source code so far:
# ------------------------------------------------------------------------------
# Renamer.rb
# ------------------------------------------------------------------------------
#
# Program to strip out Android suffixes like _xhdpi, _hpdi, _mdpi and _ldpi
# but only for Mac at the moment.
#
# --------------------------------------------------
# Usage:
# --------------------------------------------------
# 1. User enters a the path to the drawable folder to clean
# 2. program outputs list of files and folder it detects to clean
# 3. program ask user to confirm cleaning
require "Pathname"
#directoryPath = ''
#isCorrectPath = false
# --------------------------------------------------
# Method definitions
# --------------------------------------------------
def ask_for_directory_path
puts "What is the path to the drawable folder you need cleaning?:"
rawPath = gets.chomp.strip
path = Pathname.new("#{rawPath}")
puts "Stored dir path = '#{path}'"
if path.directory?
puts "#directoryPath is dir"
else
puts "#directoryPath is not dir"
end
#directoryPath = path.to_path
end
def confirm_input_correct
print "\n\nIs this correct? [y/N]: "
#isCorrectPath = gets.chomp.strip
end
def reconfirm_input_correct
print "please enter 'y' or 'N': "
#isCorrectPath = gets.strip
end
def output_folder_path
puts "The folder '#{#directoryPath}' contains the following files and folders:"
# Dir.entries doesn't like \
# #directoryPath = #directoryPath.gsub("\\", "")
puts "cleaned path is '#{#directoryPath}'"
begin
puts Dir.entries(#directoryPath)
rescue
puts "\n\nLooks like the path is incorrect:"
puts #directoryPath
end
end
def clean_directory
puts "Cleaning directory now..."
end
puts "Hello, welcome to Renamer commander.\n\n"
ask_for_directory_path
output_folder_path
confirm_input_correct
while #isCorrectPath != 'y' && #isCorrectPath != 'N' do
reconfirm_input_correct
end
if #isCorrectPath == 'y'
clean_directory
else
ask_for_directory_path
end
I went through this learning resource for Ruby two three days ago:
http://rubylearning.com/satishtalim/tutorial.html
I'm also using these resource to figure out what I'm doing wrong:
http://ruby-doc.org/core-2.3.0/Dir.html
https://robm.me.uk/ruby/2014/01/18/pathname.html
Any ideas?
Edit
Well, the current work around(?) is to clean my raw string and delete any backslashes, using new method:
def cleanBackslash(originalString)
return originalString.gsub("\\", "")
end
Then
def ask_for_directory_path
puts "\nWhat is the path to the drawable folder you need cleaning?:"
rawPath = gets.chomp.strip
rawPath = cleanBackslash(rawPath)
...
end
Not the prettiest I guess.
A sample run of the program:
Zhang-computer:$ ruby Renamer.rb
Hello, welcome to Renamer commander.
What is the path to the drawable folder you need cleaning?:
/Users/zhang/Desktop/test\ folder
Stored dir path = '/Users/zhang/Desktop/test folder'
#directoryPath is dir
The folder '/Users/zhang/Desktop/test folder' contains the following files and folders:
cleaned path is '/Users/zhang/Desktop/test folder'
.
..
.DS_Store
file1.txt
file2.txt
file3.txt
Is this correct? [y/N]:
:]
I don't think the problem is with the backslash, but with the whitespace. You don't need to escape it:
Dir.pwd
# => "/home/lbrito/work/snippets/test folder"
Dir.entries(Dir.pwd)
# => ["..", "."]
Try calling Dir.entries without escaping the whitespace.
There is no backslash in the path. The backslash is an escape character displayed by the shell to prevent the space from being interpreted as a separator.
Just like Ruby displays strings containing double quotes by escaping those double quotes.
Okay, first of all, using gets.chomp.strip is probably not a good idea :P
The better and closer solution to what your normally see in a real bash program is to use the Readline library:
i.e.
require "Readline"
...
def ask_for_directory_path
rawPath = String.new
rawPath = Readline.readline("\nWhat is the path to the drawable folder you need cleaning?\n> ", true)
rawPath = rawPath.chomp.strip
rawPath = cleanBackslash(rawPath)
#directoryPath = Pathname.new(rawPath)
end
Using Readline lets you tab complete the folder path. I also needed to clean my backslash from the readline using my own defined:
def cleanBackslash(originalString)
return originalString.gsub("\\", "")
end
After that, the Dir.entries(#directorPath) is able to list all the files and folders in the path, whether the user typed it in manually or drag and drop the folder into the Mac terminal:
Zhang-iMac:Renamer zhang$ ruby Renamer.rb
Hello, welcome to Renamer commander.
What is the path to the drawable folder you need cleaning?
> /Users/zhang/Ruby\ Learning/Renamer/test_folder
The folder '/Users/zhang/Ruby Learning/Renamer/test_folder' contains the following files and folders:
.
..
.DS_Store
drawable
drawable-hdpi
drawable-mdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxhdpi
Is this correct? [y/N]: y
Cleaning directory now...
The program is not finish but I think that fixes my problem of the backslash getting in the way.
I don't know how real bash programs are made, but consider this my poor man's bash program lol.
Final program
Check it out:
I feel like a boss now! :D

Trying to change names of files using Dir and File.rename on Mac OS?

I'm following a tutorial and am trying to change the names of three files in a folder that's located under 'drive/users/myname/test'. I'm getting the error:
'chdir': No such file or directory - test'.
The starting path is already 'drive/users/myname', which is why I thought that I only had to enter 'test' for Dir.chdir.
How do I correctly input the paths on Mac OS?
Dir.chdir('test')
pic_names = Dir['test.{JPG,jpg}']
puts "What do you want to call this batch"
batch_name = gets.chomp
puts
print "Downloading #{pic_names.length} files: "
pic_number = 1
pic_names.each do |p|
print '.'
new_name = "batch_name#{pic_number}.jpg"
File.rename(name, new_name)
pic_number += 1
end
I think you have to provide the absolute path. So, your first line should be:
Dir.chdir("/drive/users/myname/test")
According to the documentation:
Dir.chdir("/var/spool/mail")
puts Dir.pwd
should output/var/spool/mail.
You can look at the documentation for more examples.
In:
File.rename(name, new_name)
name is never defined prior to its attempted use.
Perhaps p is supposed to be name, or name should be p?
With that assumption I'd write the loop something like:
pic_names.each_with_index do |name, pic_number|
print '.'
new_name = "#{ batch_name }#{ 1 + pic_number }.jpg"
File.rename(name, File.join(File.dirname(name), new_name))
end
File.join(File.dirname(name), new_name) is important. You have to refer to the same path in both the original and new filenames, otherwise the file will be moved to a new location, which would be wherever the current-working-directory points to. That's currently masked by your use of chdir at the start, but, without that, you'd wonder where your files went.

How to open and read files line-by-line from a directory?

I am trying to read file lines from a directory containing about 200 text files, however, I can't get Ruby to read them line-by-line. I did it before, using one text file, not reading them from a directory.
I can get the file names as strings, but I am struggling to open them and read each line.
Here are some of the methods I've tried.
Method 1:
def readdirectory
#filearray = []
Dir.foreach('mydirectory') do |i|
# puts i.class
#filearray.push(i)
#filearray.each do |s|
# #words =IO.readlines('s')
puts s
end#do
# puts #words
end#do
end#readdirectory
Method 2:
def tryread
Dir.foreach('mydir'){
|x| IO.readlines(x)
}
end#tryread
Method 3:
def tryread
Dir.foreach('mydir') do |s|
File.readlines(s).each do |line|
sentence =line.split
end#inner do
end #do
end#tryread
With every attempt to open the string passed by the loop function, I keep getting the error:
Permission denied - . (Errno::EACCES)
sudo ruby reader.rb or whatever your filename is.
Since permissions are process based you can not read files with elevated permissions if the process reading does not have them.
Only solutions are either to run the script with more permissions or call another process which is already running with higher permissions to read for you.
Thanks for all replies,I did a bit of trial and error and got it to work.This is the syntax I used
Dir.entries('lemmatised').each do |s|
if !File.directory?(s)
file = File.open("pathname/#{s}", 'r')
file.each_line do |line|
count+=1
#words<<line.split(/[^a-zA-Z]/)
end # inner do
puts #words
end #if
end #do
Try this one,
#it'll hold the lines
f = []
#here test directory contains all the files,
#write the path as per the your computer,
#mine's as you can see, below
#fetch filenames and keep in sorted order
a = Dir.entries("c:/Users/lordsangram/desktop/test")
#read the files, line by line
Dir.chdir("c:/Users/lordsangram/desktop/test")
#beginning for i = 1, to ignore first two elements of array a,
#which has no associated file names
2.upto(a.length-1) do |i|
File.readlines("#{a[i]}").each do |line|
f.push(line)
end
end
f.each do |l|
puts l
end
#the Tin Man -> you need to avoid processing "." and ".." which are listed in Dir.foreach and give the permission denied error. A simple if should fix all your apporoaches.
Dir.foreach(ARGV[0]) do |f|
if f != "." and f != ".."
# code to process file
# example
# File.open(ARGV[0] + "\\" + f) do |file|
# end
end
end

Reading file with Ruby returns strange output

I am trying to read in a JSON file with Ruby and the output is extremely strange. Here is the code that I am using:
require 'rubygems'
class ServiceCalls
def initialize ()
end
def getFile()
Dir.entries('./json').each do |mFile|
if mFile[0,1] != "."
self.sendServiceRequest(mFile)
end
end
end
def sendServiceRequest(mFile)
currentFile = File.new("./json/" + mFile, "r")
puts currentFile.read
currentFile.close
end
end
mServiceCalls = ServiceCalls.new
mServiceCalls.getFile
And here is the output:
Macintosh H??=A?v?P$66267945-2481-3907-B88A-1094AA9DAB6D??/??is32???????????????????????????????????vvz?????????????????????????????????????????????????????????????????????????????????????????????vvz?????????????????????????????????????????????????????????????????????????????????????????????vvz???????????????????????????????????????????????????????????s8m+88888888???????89????????99?????????9:??????????:;??????????;=??????????=>??????????>????????????#??????????#A??????????AC??????????CD??????????DE??????????EE??????????E6OXdknnkdXO6ic118?PNG
bookmark88?A[DT>??A?#
ApplicationsMAMPhtdocsServiceTestAutomationMDXservicecatalog-verizon.json$4T??
`?
U?????l??????
Macintosh H??=A?v?P$66267945-2481-3907-B88A-1094?is32???????????????????????????????????vvz?????????????????????????????????????????????????????????????????????????????????????????????vvz?????????????????????????????????????????????????????????????????????????????????????????????vvz???????????????????????????????????????????????????????????s8m+88888888???????89????????99?????????9:??????????:;??????????;=??????????=>??????????>????????????#??????????#A??????????AC??????????CD??????????DE??????????EE??????????E6OXdknnkdXO6ic118?PNG
UIEvolutions-MacBook-Pro-109:MDXServiceTesting Banderson$ ruby testmdxservices.rb
bookmark88?A?,P>??A?#
ApplicationsMAMPhtdocsServiceTestAutomationMDXservicecatalog-adaptation.json$4T??
`?
U?????l??????
Macintosh H??=A?v?P$66267945-2481-3907-B88A-1094AA9DAB6D??/?<icns<?TOC his32?s8mic118il32?l8mic1?ic07ic13#ic08#ic14^?ic09_ic1?is32???????????????????????????????????vvz?????????????????????????????????????????????????????????????????????????????????????????????vvz?????????????????????????????????????????????????????????????????????????????????????????????vvz???????????????????????????????????????????????????????????s8m+88888888???????89????????99?????????9:??????????:;??????????;=??????????=>??????????>????????????#??????????#A??????????AC??????????CD??????????DE??????????EE??????????E6OXdknnkdXO6ic118?PNG
IHDR szz?iCCPICC Profile(?T?k?P??e???:g >h?ndStC??kW??Z?6?!H??m\??$?~?ًo:?w?>?
كo{?a???"L?"???4M'S??????9'??^??qZ?/USO???????^C+?hM??J&G#Ӳy???lt?o߫?c՚?
? ??5?"?Y?i\?΁?'&??.?<?ER/?dE?oc?ግ#?f45#? ??B:K?#8?i??
??s??_???雭??m?N?|??9}p?????_?A??pX6?5~B?$?&???ti??e??Y)%$?bT?3li?
??????P???4?43Y???P??1???KF????ۑ??5>?)?#????r??y??????[?:V???ͦ#??wQ?HB??d(??B
a?cĪ?L"J??itTy?8?;(???Gx?_?^?[???????%׎??ŷ??Q???麲?ua??n?7???
Q???H^e?O?Q?u6?S??u
?2??%vX
???^?*l
O?????ޭˀq,>??S???%?L??d????B???1CZ??$M??9??P
'w????\/????]???.r#???E|!?3?>_?o?a?۾?d?1Z?ӑ???z???'?=??????~+??cjJ?tO%mN?????
|??-???bW?O+
o?
^?
I?H?.?;???S?]?i_s9?*p???.7U^??s.?3u?
Can someone please tell me what I am doing wrong? Do I need to specify what type of encoding I'm using? I have tried to read the file with gets, sysread, and another I can't remember.
I am not completely sure why but I believe it is the './json' path that is causing the issue. I tried the script on my Windows XP machine and got similar results.
However, when I rewrote the script to include File.dirname(__FILE__) instead of './' it worked. I also cleaned up some of the code.
class ServiceCalls
def get_file
dirname = File.join(File.dirname(__FILE__), 'json')
Dir.entries(dirname).each do |file|
unless file.start_with? '.'
File.open(File.join(dirname, file), 'r') {|f| puts f.read}
end
end
end
end
sc = ServiceCalls.new
sc.get_file
__FILE__ is the path of the current script. File.join uses system independent path separators. File.open, if you pass it a block, will actually close the file for you when it completes the block. String#start_with? is a cleaner way than using [0,1] to get the first element of a string.
try this:
Dir.entries('./json').each do |mFile|
next if ['.', '..'].include?(mFile)
self.sendServiceRequest(mFile)

Checking directory for file with certain extension

I am trying to check whether a directory entered through the command line contains files with a certain file extension. For example, if I have a folder "Folder1" with another folder in it "Folder 2" and Folder2 contains several files, "test.asm", "test.vm", "test.tst". I am taking either a directory or a file through the command line like this
ruby translator.rb Folder1/Folder2
or
ruby translator.rb Folder1/Folder2/test.vm
What I'm trying to do is error checking. I already have checks for whether the input is a folder and now I need to check whether the folder actually contains a .vm file.
What I've done so far is this:
require 'pathname'
pn = Pathname.new(ARGV[0])
if ARGV.size != 1
puts "Proper usage is: ruby vmtranslator.rb file_directory\file.vm \nOR \nruby vmtranslator.rb file_directory\ where file_directory has multiple vm files test".split("\n")
elsif !pn.exist? && !pn.directory?
puts "Something is wrong with the file"
puts "Either try another file or check the file extension"
elsif pn.directory? && pn.children(false).extname.include?('.vm')
puts "this should print if Folder1 is the folder, but not if Folder2 is.."
vm_file1 = File.open("OPEN FILES WITH .vm AS EXTENSION)
elsif pn.exist? || pn.file?
puts "this is right"
vm_file = File.open(ARGV[0], "r")
asm_file = File.new(ARGV[0].sub('.vm', '.asm'), "w")
end
So what that should do is check whether there is only 1 argument first, if so, then it checks if it's a file or directory else it outputs an error, then what I'm doing is checking if it's a directory. If so, I need to check if the directory actually contains .vm files. I tried pn.each_child {|f| f.extname == '.vm'} but that only checks the first value before it returns true. Is there any easier way to check the whole array before returning true, other than just setting some boolean?
Some of the code up there isn't done, I'm just asking if there is any way to check a directory for a file of a certain extension. I can't find anything with my searches so far.
str = ARGV[0]
proc = ->(f) { puts "doing something with #{f.path}" }
if Dir.exists?(str)
Dir.glob(File.join(str, File.join('**', '*.vm'))).each do |entry|
proc[File.open(entry)]
end
elsif File.exists?(str) && File.extname(str) == '.vm'
proc[File.open(str)]
else
puts "couldn't do anything with #{str}"
end
Dir["Folder1/Folder2/*.vm"].empty?
will return false if there are any .vm files in Folder1/Folder2.
require 'pathname'
def directory_has_vm_files?(path)
Dir.glob(path.join('*.vm')).size > 0
end
unless ARGV[0]
puts %{
Proper usage is:
ruby vmtranslator.rb file_directory or file.vm
OR
ruby vmtranslator.rb file_directory
where file_directory has multiple vm files
}
else
path = Pathname.new(ARGV[0])
if path.exist?
if path.file?
if File.extname(path) == '.vm'
puts "Valid VM file"
else
puts "Not a VM file"
end
else
if directory_has_vm_files?(path)
puts "Valid Directory - contains vm files"
else
puts "#{path} does not contain any VM file"
end
end
else
puts "Invalid path"
end
end

Resources