How in my code can I determine whether it’s being run with crystal run
vs when it’s a built executable?
i.e. in pseudo-code:
if CRYSTAL_RUN
do_something
else
do_something_else
end
How in my code can I determine whether it’s being run with crystal run
vs when it’s a built executable?
i.e. in pseudo-code:
if CRYSTAL_RUN
do_something
else
do_something_else
end
crystal run
also builds an executable, just like crystal build
. It just builds into a temporary file.
So you could potentially use that as an indicator, if PROGRAM_NAME
points to a temp file.
What do you want to achieve with this, though?
Not proud of this one, but
if (PROGRAM_NAME.starts_with? {{ `crystal env CRYSTAL_CACHE_DIR`.chomp.stringify }}) &&
(File.basename(PROGRAM_NAME).includes?("run")) &&
(PROGRAM_NAME.ends_with? ".tmp")
p "run"
else
p "build"
end
If run
is setting some kind of compile-time flag, it should be possible to detect it with a macro.
But I couldn’t find anything in the docs — Maybe there’s some undocumented flag that I just don’t know about.
The cache dir should be available directly as Crystal::CACHE_DIR
. You don’t need to shell out for that.
No. There’s nothing special about run
. It is semantically equivalent to build
into temp file + exec. The compiler doesn’t make any distinction about which command builds a program.
Another option is to look at the parent process. When using crystal run
, the parent is called crystal
.
For example, on a Linux system
# crystal_run.cr
ppid = File.read("/proc/#{Process.pid}/status").scan(/(?<=PPid:\t)\d+/)[0]
crystal_run = File.read("/proc/#{ppid}/comm") == "crystal\n"
p! crystal_run
$ crystal run crystal_run.cr
crystal_run # => true
$ crystal build crystal_run.cr && ./crystal_run
crystal_run # => false
I was having a problem using relative paths, they would work fine on my desktop but not in my VPS ( both Debian 12 ) so I used Path[PROGRAM_NAME].expand.dirname
to get the absolute path but of course that resulted in issues with crystal run
I had fudged a workaround like this:
program_path = Path[PROGRAM_NAME].expand.dirname
if program_path.includes?(".cache")
but I thought perhaps there was a proper way
Would Process.executable_path
be better for this?