Add absolute_file_name/2
Adds the predicate absolute_file_name/2.
It takes a local path and returns an absolute path. Works for both existing and non-existing files. If you pass an absolute path, it returns the same path.
?- use_module(library(os)).
true.
?- absolute_file_name("README.md", X).
X = "/home/aarroyoc/dev/ ...".
?- absolute_file_name("README.md", X);true.
X = "/home/aarroyoc/dev/ ..."
X = "/home/aarroyoc/dev/scryer-prolog/README.md"
; ...
?- absolute_file_name("README.m", X);true.
X = "/home/aarroyoc/dev/ ..."
X = "/home/aarroyoc/dev/scryer-prolog/README.m"
; ...
?- absolute_file_name("../README.m", X);true.
X = "/home/aarroyoc/dev/ ..."
X = "/home/aarroyoc/dev/scryer-prolog/../README.m"
; ...
?- absolute_file_name("/home/README.m", X);true.
X = "/home/README.m"
; ...
This version doesn't expand environment variables. E.g.
?- absolute_file_name("$HOME/logtalk", X), writeq(X), nl.
"/Users/pmoura/scryer-prolog/$HOME/logtalk"
X = "/Users/pmoura/scrye ...".
Do you think that you could add support for expanding environment variables? Is that something where Rust native libraries can do the actual work? Possibly with a absolute_file_name/3 that would take a list of options, including a boolean option for performing that expansion?
Intermingling this functionality with expansion of environment variables is not a good idea, please see https://github.com/infradig/trealla/issues/86#issuecomment-721979426 for arising issues.
@aarroyoc: Does path_canonical/2 from library(files) work for you?
https://github.com/mthom/scryer-prolog/blob/ca62e54652ace8374225e9f43f28aac508819255/src/lib/files.pl#L140
Intermingling this functionality with expansion of environment variables is not a good idea, please see infradig/trealla#86 (comment) for arising issues.
In that thread, you only criticize the idea without actually presenting any arguments. What's your suggestion then for expanding paths containing environment variables? The suggestion I made above makes it depending on a boolean option, a solution that's common to several Prolog systems (including Trealla). This solution works well in practice. Currently, for Logtalk, I'm using the ugly workaround listed at https://github.com/mthom/scryer-prolog/discussions/1041#discussioncomment-1483975 But, as I remarked there, this is core functionality that should be available either as a built-in predicate or as core library predicate.
@triska: for my use case I think path_canonical/2 should work because all the files that are going to use already exist. I didn't look at it because I didn't know that predicate existed TBH and I checked that SICStus, SWI and Trealla have absolute_file_name/2 (which will also work on non-existing files).
@triska: for my use case I think
path_canonical/2should work because all the files that are going to use already exist. I didn't look at it because I didn't know that predicate existed TBH and I checked that SICStus, SWI and Trealla haveabsolute_file_name/2(which will also work on non-existing files).
That's indeed a key distinction. Applications often need to expand paths for non-existing files. A simple example opening a stream for writing to a new file.
?- use_module(library(files)).
true.
?- path_canonical("/Users/pmoura/some_new_file", Path).
false.
I suggest to use the existing functionality if it suffices for your use case. In case you need to create for example "/Users/pmoura/some_new_file", simply specify that path (there is no reason for path_canonical/2 in this example).
In general, predicates relating to files and directories are a good fit for library(files).
In case environment variables are needed, I suggest getenv/2 from library(os), together with path_segments/2 from library(files).
I suggest to use the existing functionality if it suffices for your use case. In case you need to create for example
"/Users/pmoura/some_new_file", simply specify that path (there is no reason forpath_canonical/2in this example).
It doesn't suffice in general. That's why I'm using the workaround I linked in my previous reply.
In general, predicates relating to files and directories are a good fit for
library(files).
Sure.
In case environment variables are needed, I suggest
getenv/2fromlibrary(os), together withpath_segments/2fromlibrary(files).
https://github.com/mthom/scryer-prolog/discussions/1041#discussioncomment-1483975
Btw, the path_canonical/2 conflates expanding a path with checking if the expanded path exists. This should be separated functionality as these are orthogonal. Adding absolute_file_name/2-3 predicates fixes it as we already have file_exists/1 and directory_exists/1 predicates.