aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/functions-filesystem.cxx51
-rw-r--r--tests/function/filesystem/testscript48
-rw-r--r--tests/function/path/testscript2
3 files changed, 99 insertions, 2 deletions
diff --git a/libbuild2/functions-filesystem.cxx b/libbuild2/functions-filesystem.cxx
index 665a0f3..340c2bc 100644
--- a/libbuild2/functions-filesystem.cxx
+++ b/libbuild2/functions-filesystem.cxx
@@ -5,6 +5,7 @@
#include <libbuild2/function.hxx>
#include <libbuild2/variable.hxx>
+#include <libbuild2/filesystem.hxx>
using namespace std;
using namespace butl;
@@ -95,14 +96,60 @@ namespace build2
return r;
}
+ static bool
+ file_exists (path&& f)
+ {
+ if (f.relative () && path_traits::thread_current_directory () != nullptr)
+ f.complete ();
+
+ return exists (f);
+ }
+
+ static bool
+ directory_exists (dir_path&& d)
+ {
+ if (d.relative () && path_traits::thread_current_directory () != nullptr)
+ d.complete ();
+
+ return exists (d);
+ }
+
void
filesystem_functions (function_map& m)
{
- // @@ Maybe we should have the ability to mark the whole family as not
- // pure?
+ // NOTE: anything that depends on relative path must handle the
+ // thread-specific curren directory override explicitly.
function_family f (m, "filesystem");
+ // $file_exists(<path>)
+ //
+ // Return true if a filesystem entry at the specified path exists and is a
+ // regular file (or is a symlink to a regular file) and false otherwise.
+ //
+ // Note that this function is not pure.
+ //
+ {
+ auto e (f.insert ("file_exists", false));
+
+ e += [](path f) {return file_exists (move (f));};
+ e += [](names ns) {return file_exists (convert<path> (move (ns)));};
+ }
+
+ // $directory_exists(<path>)
+ //
+ // Return true if a filesystem entry at the specified path exists and is a
+ // directory (or is a symlink to a directory) and false otherwise.
+ //
+ // Note that this function is not pure.
+ //
+ {
+ auto e (f.insert ("directory_exists", false));
+
+ e += [](path f) {return directory_exists (path_cast<dir_path> (move (f)));};
+ e += [](names ns) {return directory_exists (convert<dir_path> (move (ns)));};
+ }
+
// $path_search(<pattern>[, <start-dir>])
//
// Return filesystem paths that match the shell-like wildcard pattern. If
diff --git a/tests/function/filesystem/testscript b/tests/function/filesystem/testscript
index cf93b8b..c7c08f1 100644
--- a/tests/function/filesystem/testscript
+++ b/tests/function/filesystem/testscript
@@ -73,3 +73,51 @@
EOE
}
}
+
+: file_exists
+:
+{
+ : file
+ :
+ touch f;
+ $* <'print $file_exists(f)' >'true'
+
+ : symlink
+ :
+ touch f && ln -s f s;
+ $* <'print $file_exists([path] s)' >'true'
+
+ : directory
+ :
+ mkdir d;
+ $* <'print $file_exists([dir_path] d)' >'false'
+
+ : testscript
+ :
+ touch f;
+ echo $file_exists(f) >'true'
+}
+
+: directory_exists
+:
+{
+ : directory
+ :
+ mkdir d;
+ $* <'print $directory_exists(d)' >'true'
+
+ : symlink
+ :
+ mkdir d && ln -s d s;
+ $* <'print $directory_exists([dir_path] d)' >'true'
+
+ : file
+ :
+ touch f;
+ $* <'print $directory_exists([path] f)' >'false'
+
+ : testscript
+ :
+ mkdir d;
+ echo $directory_exists(d) >'true'
+}
diff --git a/tests/function/path/testscript b/tests/function/path/testscript
index d49e9e5..6321b3d 100644
--- a/tests/function/path/testscript
+++ b/tests/function/path/testscript
@@ -210,6 +210,8 @@ s = ($posix ? '/' : '\')
$* <'print $complete([path] a)' >"$~$(s)a" : path
$* <'print $complete([dir_path] a)' >"$~$(s)a$(s)" : dir-path
$* <'print $path.complete(a)' >"$~$(s)a" : untyped
+
+ echo $path.complete(a) > "$~$(s)a" : testscript
}
: canonicalize