aboutsummaryrefslogtreecommitdiff
path: root/bpkg/utility.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/utility.cxx')
-rw-r--r--bpkg/utility.cxx120
1 files changed, 105 insertions, 15 deletions
diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx
index 39dea81..d084b76 100644
--- a/bpkg/utility.cxx
+++ b/bpkg/utility.cxx
@@ -3,8 +3,8 @@
#include <bpkg/utility.hxx>
-#include <libbutl/prompt.mxx>
-#include <libbutl/fdstream.mxx>
+#include <libbutl/prompt.hxx>
+#include <libbutl/fdstream.hxx>
#include <bpkg/diagnostics.hxx>
#include <bpkg/common-options.hxx>
@@ -26,24 +26,48 @@ namespace bpkg
const dir_path certs_dir (dir_path (bpkg_dir) /= "certs");
const dir_path repos_dir (dir_path (bpkg_dir) /= "repos");
+ // Standard and alternative build file/directory naming schemes.
+ //
+ // build:
+ //
+ const dir_path std_build_dir ("build");
+ const dir_path std_config_dir (dir_path (std_build_dir) /= "config");
+ const path std_bootstrap_file (dir_path (std_build_dir) /= "bootstrap.build");
+ const path std_root_file (dir_path (std_build_dir) /= "root.build");
+ const string std_build_ext ("build");
+
+ // build2:
+ //
+ const dir_path alt_build_dir ("build2");
+ const dir_path alt_config_dir (dir_path (alt_build_dir) /= "config");
+ const path alt_bootstrap_file (dir_path (alt_build_dir) /= "bootstrap.build2");
+ const path alt_root_file (dir_path (alt_build_dir) /= "root.build2");
+ const string alt_build_ext ("build2");
+
const dir_path current_dir (".");
- map<dir_path, dir_path> temp_dir;
+ const target_triplet host_triplet (BPKG_HOST_TRIPLET);
+
+ map<dir_path, dir_path> tmp_dirs;
+
+ bool keep_tmp;
auto_rmfile
tmp_file (const dir_path& cfg, const string& p)
{
- auto i (temp_dir.find (cfg));
- assert (i != temp_dir.end ());
- return auto_rmfile (i->second / path::traits_type::temp_name (p));
+ auto i (tmp_dirs.find (cfg));
+ assert (i != tmp_dirs.end ());
+ return auto_rmfile (i->second / path::traits_type::temp_name (p),
+ !keep_tmp);
}
auto_rmdir
tmp_dir (const dir_path& cfg, const string& p)
{
- auto i (temp_dir.find (cfg));
- assert (i != temp_dir.end ());
- return auto_rmdir (i->second / dir_path (path::traits_type::temp_name (p)));
+ auto i (tmp_dirs.find (cfg));
+ assert (i != tmp_dirs.end ());
+ return auto_rmdir (i->second / dir_path (path::traits_type::temp_name (p)),
+ !keep_tmp);
}
void
@@ -64,13 +88,13 @@ namespace bpkg
mk (d); // We shouldn't need mk_p().
- temp_dir[cfg] = move (d);
+ tmp_dirs[cfg] = move (d);
}
void
clean_tmp (bool ignore_error)
{
- for (const auto& d: temp_dir)
+ for (const auto& d: tmp_dirs)
{
const dir_path& td (d.second);
@@ -83,7 +107,7 @@ namespace bpkg
}
}
- temp_dir.clear ();
+ tmp_dirs.clear ();
}
path&
@@ -91,7 +115,8 @@ namespace bpkg
{
try
{
- f.complete ().normalize ();
+ if (!f.complete ().normalized ())
+ f.normalize ();
}
catch (const invalid_path& e)
{
@@ -110,7 +135,8 @@ namespace bpkg
{
try
{
- d.complete ().normalize ();
+ if (!d.complete ().normalized ())
+ d.normalize ();
}
catch (const invalid_path& e)
{
@@ -137,7 +163,8 @@ namespace bpkg
}
}
- bool stderr_term;
+ optional<const char*> stderr_term = nullopt;
+ bool stderr_term_color = false;
bool
yn_prompt (const string& p, char d)
@@ -286,6 +313,30 @@ namespace bpkg
return true;
}
+ bool
+ mv (const path& from, const path& to, bool ie)
+ {
+ if (verb >= 3)
+ text << "mv " << from << ' ' << to;
+
+ try
+ {
+ mvfile (from, to,
+ cpflags::overwrite_content | cpflags::overwrite_permissions);
+ }
+ catch (const system_error& e)
+ {
+ error << "unable to move file " << from << " to " << to << ": " << e;
+
+ if (ie)
+ return false;
+
+ throw failed ();
+ }
+
+ return true;
+ }
+
dir_path
change_wd (const dir_path& d)
{
@@ -341,4 +392,43 @@ namespace bpkg
? co.build ().string ().c_str ()
: BPKG_EXE_PREFIX "b" BPKG_EXE_SUFFIX;
}
+
+ process_path
+ search_b (const common_options& co)
+ {
+ const char* b (name_b (co));
+
+ try
+ {
+ // Use our executable directory as a fallback search since normally the
+ // entire toolchain is installed into one directory. This way, for
+ // example, if we installed into /opt/build2 and run bpkg with absolute
+ // path (and without PATH), then bpkg will be able to find "its" b.
+ //
+ return process::path_search (b, true /* init */, exec_dir);
+ }
+ catch (const process_error& e)
+ {
+ fail << "unable to execute " << b << ": " << e << endf;
+ }
+ }
+
+ void
+ dump_stderr (auto_fd&& fd)
+ {
+ ifdstream is (move (fd), fdstream_mode::skip, ifdstream::badbit);
+
+ // We could probably write something like this, instead:
+ //
+ // *diag_stream << is.rdbuf () << flush;
+ //
+ // However, it would never throw and we could potentially miss the reading
+ // failure, unless we decide to additionally mess with the diagnostics
+ // stream exception mask.
+ //
+ for (string l; !eof (getline (is, l)); )
+ *diag_stream << l << endl;
+
+ is.close ();
+ }
}