Hello, I have a tiny problem, in one implementation of my project, I need to get the full path of my program. How can I do that? I don’t found the way.
Depending on your exact need, I’d look into the __DIR__
pseudo constant or Dir.current.
Hmm this don’t solve my problem, the problem is after a Dir.cd, I need to retrieve my origin path of my software, and not where is my path after the Dir.cd command
Can I reset the path after a Dir.cd ?
Could you create a const that represents the root of your project that then wouldn’t be affected by changes in PWD? For example as you have /root/path/src/main.cr
:
module MyApp
ROOT = "#{__DIR__}/../" # => /root/path/
end
EDIT: Er that would be tied to whatever file system you compiled it on. Which is maybe fine?
Oh yes good idea.
Because I think I can’t use Process.run in a specific path without a Dir.cd before ?
Process.run
has a chdir
parameter which does a Dir.cd
to that path before executing the command.
Okay, I will do your first solution definitely. Thanks you very much for your help
Would it be better to make more use of relative paths? That way the program itself doesn’t need to be aware of the directory structure of the system its running on.
Uuuuh, it’s very annoying, your answer don’t solve my problem. Because my file for my module containing all of my default paths is located in some directories, my constant ROOT don’t return the good path…
I’m very annoying.
In this case I need to have the full path. Normally I use always relative path.
Look my implementation (where you have the “constant” DIR):
module ISM
module Option
class SoftwareSynchronize < ISM::CommandLineOption
def initialize
super( ISM::Default::Option::SoftwareSynchronize::ShortText,
ISM::Default::Option::SoftwareSynchronize::LongText,
ISM::Default::Option::SoftwareSynchronize::Description,
Array(ISM::CommandLineOption).new)
end
def start
synchronizationStartingTime = Time.monotonic
frameIndex = 0
reverseAnimation = false
print ISM::Default::Option::SoftwareSynchronize::SynchronizationTitle
text = ISM::Default::Option::SoftwareSynchronize::SynchronizationWaitingText
Dir.cd(ISM::Default::Path::SoftwaresDirectory)
#Pour chaque dépot, utiliser les branches selon la stabilité voulue (stable, testing ...etc)
Ism.ports.each do |port|
currentTime = Time.monotonic
if (currentTime - synchronizationStartingTime).milliseconds > 40
if frameIndex >= text.size
reverseAnimation = true
end
if frameIndex < 1
reverseAnimation = false
end
if reverseAnimation
print "\033[1D"
print " "
print "\033[1D"
frameIndex -= 1
end
if !reverseAnimation
print "#{text[frameIndex].colorize(:green)}"
frameIndex += 1
end
synchronizationStartingTime = Time.monotonic
end
if !Dir.exists?(port.name)
puts port.name
Dir.mkdir(port.name)
Dir.cd(port.name)
Process.run("git",args: ["init"])
Process.run("git",args: [ "remote",
"add",
"origin",
port.url])
else
Dir.cd(port.name)
end
Process.run("git",args: ["pull","origin","master"])
Dir.cd(__DIR__+ISM::Default::Path::SoftwaresDirectory)
end
print "#{ISM::Default::Option::SoftwareSynchronize::SynchronizationDoneText.colorize(:green)}\n"
puts "The database is synchronized"
end
end
end
end
Is it possible __DIR__
don’t return the good rooth path because I’m testing the program with the Crystal interpreter ?
Are you looking for Process - Crystal 1.2.2 ?
Won’t work in the interpreter, though.
I checked, if I build or not my program, it’s the same problem, __DIR__
don’t return the path of my program, just the path of the current running code…
Look:
zohran master ~ Documents Programmation ISM crystal Main.cr software -sy
ISM start to synchronizing: SystemBase-CrossToolchain
Unhandled exception: Error while changing directory: '/home/zohran/Documents/Programmation/ISM/ISM/Option/Software/SynchronizeSoftwares/': No such file or directory (File::NotFoundError)
from /usr/lib64/crystal/crystal/system/unix/dir.cr:52:7 in 'current='
from /usr/lib64/crystal/dir.cr:147:5 in 'cd'
from ISM/Option/Software/Synchronize/Synchronize.cr:66:21 in 'start'
from ISM/Option/Software/Software.cr:23:29 in 'start'
from ISM/CommandLine.cr:109:25 in 'checkEnteredArguments'
from ISM/CommandLine.cr:28:13 in 'start'
from Main.cr:70:1 in '__crystal_main'
from /usr/lib64/crystal/crystal/main.cr:110:5 in 'main_user_code'
from /usr/lib64/crystal/crystal/main.cr:96:7 in 'main'
from /usr/lib64/crystal/crystal/main.cr:119:3 in 'main'
from /lib64/libc.so.6 in '??'
from /lib64/libc.so.6 in '__libc_start_main'
from /home/zohran/.cache/crystal/crystal-run-Main.tmp in '_start'
from ???
Please define what you mean by “full path of my program”. There are multiple interpretations for that.
Okay, it’s simple. My program actually is located in /home/zohran/Documents/Programmation/ISM/, the full path, and I would like to get it.
But the problem, when my Main.cr is running, __DIR__
return the path of the running code, not the main root path of my project, in my previous post for example, it return /home/zohran/Documents/Programmation/ISM/ISM/Option/Software/SynchronizeSoftwares/, but this path is one of my code source file path, not the Main.cr path
I absolutely need the full path, because I use Dir.cd, and I can’t avoid this command because I need to run a git command
You can retrieve the path by traversing from __DIR__
upward - depending on how many nested directories there are between the current file’s directory and your target path.
For your example, that would be something like Path[__DIR__].parent.parent.parent
.
No worries finally, for my project I found the best way:
Just don’t use Dir.cd or FileUtils.cd, and use everytime chdir option of Process.run, because when the process is done, it restore the original path.
Definitely better, this can avoid a lot of problem after for my software
Thanks you very much