aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-09-03 18:24:08 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-09-04 12:40:57 +0300
commit7bb44980ced46506c10bad333f526b7bc62ea1db (patch)
tree207a14ee727f7237e8fc2b08e47f4de8a97e0b99
parentbd02eaa1298271ecf8365aa869e93fdcb04fdeb1 (diff)
Add support for multiple temporary directories
-rw-r--r--bpkg/auth.cxx2
-rw-r--r--bpkg/bpkg.cxx50
-rw-r--r--bpkg/cfg-create.cxx5
-rw-r--r--bpkg/pkg-checkout.cxx13
-rw-r--r--bpkg/rep-fetch.cxx5
-rw-r--r--bpkg/rep-info.cxx17
-rw-r--r--bpkg/rep-remove.cxx11
-rw-r--r--bpkg/utility.cxx35
-rw-r--r--bpkg/utility.hxx18
9 files changed, 97 insertions, 59 deletions
diff --git a/bpkg/auth.cxx b/bpkg/auth.cxx
index 8698445..08f6b11 100644
--- a/bpkg/auth.cxx
+++ b/bpkg/auth.cxx
@@ -713,7 +713,7 @@ namespace bpkg
try
{
- rm = tmp_file ("cert");
+ rm = tmp_file (conf != nullptr ? *conf : empty_dir_path, "cert");
f = rm.path;
ofdstream ofs (f);
diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx
index 04aa798..49f4055 100644
--- a/bpkg/bpkg.cxx
+++ b/bpkg/bpkg.cxx
@@ -535,37 +535,37 @@ try
// pkg-* commands
//
-#define PKG_COMMAND(CMD, SEP) COMMAND_IMPL(pkg_, "pkg-", CMD, SEP, true)
+#define PKG_COMMAND(CMD, SEP, TMP) COMMAND_IMPL(pkg_, "pkg-", CMD, SEP, TMP)
// These commands need the '--' separator to be kept in args.
//
- PKG_COMMAND (build, true);
- PKG_COMMAND (clean, true);
- PKG_COMMAND (configure, true);
- PKG_COMMAND (install, true);
- PKG_COMMAND (test, true);
- PKG_COMMAND (uninstall, true);
- PKG_COMMAND (update, true);
-
- PKG_COMMAND (checkout, false);
- PKG_COMMAND (disfigure, false);
- PKG_COMMAND (drop, false);
- PKG_COMMAND (fetch, false);
- PKG_COMMAND (purge, false);
- PKG_COMMAND (status, false);
- PKG_COMMAND (unpack, false);
- PKG_COMMAND (verify, false);
+ PKG_COMMAND (build, true, false);
+ PKG_COMMAND (clean, true, true);
+ PKG_COMMAND (configure, true, true);
+ PKG_COMMAND (install, true, true);
+ PKG_COMMAND (test, true, true);
+ PKG_COMMAND (uninstall, true, true);
+ PKG_COMMAND (update, true, true);
+
+ PKG_COMMAND (checkout, false, true);
+ PKG_COMMAND (disfigure, false, true);
+ PKG_COMMAND (drop, false, true);
+ PKG_COMMAND (fetch, false, true);
+ PKG_COMMAND (purge, false, true);
+ PKG_COMMAND (status, false, true);
+ PKG_COMMAND (unpack, false, true);
+ PKG_COMMAND (verify, false, true);
// rep-* commands
//
-#define REP_COMMAND(CMD) COMMAND_IMPL(rep_, "rep-", CMD, false, true)
-
- REP_COMMAND (add);
- REP_COMMAND (create);
- REP_COMMAND (fetch);
- REP_COMMAND (info);
- REP_COMMAND (list);
- REP_COMMAND (remove);
+#define REP_COMMAND(CMD, TMP) COMMAND_IMPL(rep_, "rep-", CMD, false, TMP)
+
+ REP_COMMAND (add, true);
+ REP_COMMAND (create, true);
+ REP_COMMAND (fetch, true);
+ REP_COMMAND (info, false);
+ REP_COMMAND (list, true);
+ REP_COMMAND (remove, true);
assert (false);
fail << "unhandled command";
diff --git a/bpkg/cfg-create.cxx b/bpkg/cfg-create.cxx
index 8101dc0..29de01c 100644
--- a/bpkg/cfg-create.cxx
+++ b/bpkg/cfg-create.cxx
@@ -165,10 +165,9 @@ namespace bpkg
}
}
- // Initialize tmp directory, unless it is already initialized.
+ // Initialize tmp directory.
//
- if (temp_dir.empty ())
- init_tmp (c);
+ init_tmp (c);
// Create the database.
//
diff --git a/bpkg/pkg-checkout.cxx b/bpkg/pkg-checkout.cxx
index d8c6819..49fc89f 100644
--- a/bpkg/pkg-checkout.cxx
+++ b/bpkg/pkg-checkout.cxx
@@ -191,6 +191,15 @@ namespace bpkg
dir_path sd (repository_state (rl));
dir_path rd (rdb.config_orig / repos_dir / sd);
+ // Use the temporary directory from the repository information source
+ // configuration, so that we can always move the repository into and out
+ // of it (note that if they appear on different filesystems that won't
+ // be possible).
+ //
+ auto ti (temp_dir.find (rdb.config_orig));
+ assert (ti != temp_dir.end ());
+ const dir_path& tdir (ti->second);
+
// Try to reuse the cached repository (moved to the temporary directory
// with some fragment checked out and fixed up).
//
@@ -214,7 +223,7 @@ namespace bpkg
// The repository temporary directory.
//
- auto_rmdir rmt (temp_dir / sd);
+ auto_rmdir rmt (tdir / sd);
// Move the repository to the temporary directory.
//
@@ -248,7 +257,7 @@ namespace bpkg
// The temporary out of source directory that is required for the dist
// meta-operation.
//
- auto_rmdir rmo (temp_dir / dir_path (n.string ()));
+ auto_rmdir rmo (tdir / dir_path (n.string ()));
const dir_path& od (rmo.path);
if (exists (od))
diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx
index 7e0d3da..c000f05 100644
--- a/bpkg/rep-fetch.cxx
+++ b/bpkg/rep-fetch.cxx
@@ -408,9 +408,12 @@ namespace bpkg
assert (conf == nullptr || !conf->empty ());
+ auto i (temp_dir.find (conf != nullptr ? *conf : empty_dir_path));
+ assert (i != temp_dir.end ());
+
dir_path sd (repository_state (rl));
- auto_rmdir rm (temp_dir / sd);
+ auto_rmdir rm (i->second / sd);
const dir_path& td (rm.path);
if (exists (td))
diff --git a/bpkg/rep-info.cxx b/bpkg/rep-info.cxx
index c935114..4e3315b 100644
--- a/bpkg/rep-info.cxx
+++ b/bpkg/rep-info.cxx
@@ -49,9 +49,24 @@ namespace bpkg
// unknown manifest entries unless we are dumping them.
//
dir_path d (o.directory ());
+
+ const dir_path* conf (o.directory_specified () && d.empty ()
+ ? nullptr
+ : &d);
+
+ // If --directory|-d is not specified and the current working directory is
+ // a configuration directory, then initialize the temporary directory
+ // inside it, so that we can always move a version control-based
+ // repository into and out of it (see pkg_checkout() for details).
+ //
+ if (conf != nullptr && conf->empty ())
+ conf = exists (bpkg_dir) ? &current_dir : nullptr;
+
+ init_tmp (conf != nullptr ? *conf : empty_dir_path);
+
rep_fetch_data rfd (
rep_fetch (o,
- o.directory_specified () && d.empty () ? nullptr : &d,
+ conf,
rl,
!o.manifest () /* ignore_unknow */,
o.deep () /* expand_values */));
diff --git a/bpkg/rep-remove.cxx b/bpkg/rep-remove.cxx
index 266d70c..5dab94b 100644
--- a/bpkg/rep-remove.cxx
+++ b/bpkg/rep-remove.cxx
@@ -129,9 +129,12 @@ namespace bpkg
// the chances for the operation to succeed.
//
static void
- rmdir (const dir_path& d)
+ rmdir (const dir_path& cfg, const dir_path& d)
{
- dir_path td (temp_dir / d.leaf ());
+ auto i (temp_dir.find (cfg));
+ assert (i != temp_dir.end ());
+
+ dir_path td (i->second / d.leaf ());
if (exists (td))
rm_r (td);
@@ -210,7 +213,7 @@ namespace bpkg
}
if (rm)
- rmdir (sd);
+ rmdir (db.config_orig, sd);
}
}
}
@@ -336,7 +339,7 @@ namespace bpkg
for (const dir_entry& de: dir_iterator (rd, false /* ignore_dangling */))
{
if (de.ltype () == entry_type::directory)
- rmdir (rd / path_cast<dir_path> (de.path ()));
+ rmdir (db.config_orig, rd / path_cast<dir_path> (de.path ()));
}
}
catch (const system_error& e)
diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx
index b179f63..39dea81 100644
--- a/bpkg/utility.cxx
+++ b/bpkg/utility.cxx
@@ -28,20 +28,22 @@ namespace bpkg
const dir_path current_dir (".");
- dir_path temp_dir;
+ map<dir_path, dir_path> temp_dir;
auto_rmfile
- tmp_file (const string& p)
+ tmp_file (const dir_path& cfg, const string& p)
{
- assert (!temp_dir.empty ());
- return auto_rmfile (temp_dir / path::traits_type::temp_name (p));
+ auto i (temp_dir.find (cfg));
+ assert (i != temp_dir.end ());
+ return auto_rmfile (i->second / path::traits_type::temp_name (p));
}
auto_rmdir
- tmp_dir (const string& p)
+ tmp_dir (const dir_path& cfg, const string& p)
{
- assert (!temp_dir.empty ());
- return auto_rmdir (temp_dir / dir_path (path::traits_type::temp_name (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)));
}
void
@@ -62,21 +64,26 @@ namespace bpkg
mk (d); // We shouldn't need mk_p().
- temp_dir = move (d);
+ temp_dir[cfg] = move (d);
}
void
clean_tmp (bool ignore_error)
{
- if (!temp_dir.empty () && exists (temp_dir))
+ for (const auto& d: temp_dir)
{
- rm_r (temp_dir,
- true /* dir_itself */,
- 3,
- ignore_error ? rm_error_mode::ignore : rm_error_mode::fail);
+ const dir_path& td (d.second);
- temp_dir.clear ();
+ if (exists (td))
+ {
+ rm_r (td,
+ true /* dir_itself */,
+ 3,
+ ignore_error ? rm_error_mode::ignore : rm_error_mode::fail);
+ }
}
+
+ temp_dir.clear ();
}
path&
diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx
index ce6120f..dabffbe 100644
--- a/bpkg/utility.hxx
+++ b/bpkg/utility.hxx
@@ -4,6 +4,7 @@
#ifndef BPKG_UTILITY_HXX
#define BPKG_UTILITY_HXX
+#include <map>
#include <memory> // make_shared()
#include <string> // to_string()
#include <cstring> // strcmp(), strchr()
@@ -83,19 +84,20 @@ namespace bpkg
// Temporary directory facility.
//
- // This is normally .bpkg/tmp/ but can also be some system-wide directory
- // (e.g., /tmp/bpkg-XXX/) if there is no bpkg configuration. This directory
- // is automatically created and cleaned up for most commands in main() so
- // you don't need to call init_tmp() explicitly except for certain special
- // commands (like cfg-create).
+ // An entry normally maps <cfg-dir> to <cfg-dir>/.bpkg/tmp/ but can also map
+ // an empty directory to some system-wide directory (e.g., /tmp/bpkg-XXX/)
+ // if there is no bpkg configuration. The temporary directory for the
+ // current configuration is automatically created and cleaned up for most
+ // commands in main(), so you don't need to call init_tmp() explicitly
+ // except for certain special commands (like cfg-create).
//
- extern dir_path temp_dir;
+ extern std::map<dir_path, dir_path> temp_dir;
auto_rmfile
- tmp_file (const string& prefix);
+ tmp_file (const dir_path& cfg, const string& prefix);
auto_rmdir
- tmp_dir (const string& prefix);
+ tmp_dir (const dir_path& cfg, const string& prefix);
void
init_tmp (const dir_path& cfg);