From 8717405eb2869115a5abe4b146fa5e73421467d4 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 22 May 2018 07:27:18 +0200 Subject: Implement config-move subcommand --- bdep/config.cli | 29 +++++++++---- bdep/config.cxx | 127 +++++++++++++++++++++++++++++++++++++++++++++++-------- bdep/project.cxx | 4 +- bdep/project.hxx | 3 +- 4 files changed, 134 insertions(+), 29 deletions(-) diff --git a/bdep/config.cli b/bdep/config.cli index 02e02ed..8248510 100644 --- a/bdep/config.cli +++ b/bdep/config.cli @@ -21,8 +21,9 @@ namespace bdep \c{\b{bdep config add} \ \ \ [] [] [\b{@}] \n \b{bdep config create} [] [] [\b{@}] []\n \b{bdep config list} \ \ [] [] [...]\n - \b{bdep config remove} [] [] ... | \b{--all}|\b{-a}\n + \b{bdep config move} \ \ [] [] \n \b{bdep config rename} [] [] \n + \b{bdep config remove} [] [] ... | \b{--all}|\b{-a}\n \b{bdep config set} \ \ \ [] [] ... | \b{--all}|\b{-a}\n \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\b{--}[\b{no-}]\b{default}]\n \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\b{--}[\b{no-}]\b{forward}]\n @@ -99,13 +100,14 @@ namespace bdep configurations. Note that the output is written to \cb{STDOUT}, not \cb{STDERR}.| - \li|\cb{remove} + \li|\cb{move} - The \cb{remove} subcommand removes one or more build configurations - from the project's build configuration set. Note that only - configurations that have no initialized packages can be removed. See - \l{bdep-projects-configs(1)} for various ways to specify build - configurations.| + The \cb{move} subcommand assigns the specified build configuration a + new directory. It is normally used after moving/renaming the + configuration directory. Note that an explicit \l{bdep-sync(1)} + command is required for this change to take effect. See + \l{bdep-projects-configs(1)} for various ways to specify a build + configuration.| \li|\cb{rename} @@ -113,6 +115,14 @@ namespace bdep new name. See \l{bdep-projects-configs(1)} for various ways to specify a build configuration.| + \li|\cb{remove} + + The \cb{remove} subcommand removes one or more build configurations + from the project's build configuration set. Note that only + configurations that have no initialized packages can be removed. See + \l{bdep-projects-configs(1)} for various ways to specify build + configurations.| + \li|\cb{set} The \cb{set} subcommand modifies various properties of one or more @@ -123,15 +133,16 @@ namespace bdep The properties that can be modified include the default (\c{\b{--}[\b{no-}]\b{default}}), forward (\c{\b{--}[\b{no-}]\b{forward}}), and auto-synchronization - (\c{\b{--}[\b{no-}]\b{auto-sync}}) flags. Note that changing any of + (\c{\b{--}[\b{no-}]\b{auto-sync}}) flags. Note that changing any of these flags requires an explicit \l{bdep-sync(1)} command to take effect. ||" bool add; bool create; bool list; - bool remove; + bool move; bool rename; + bool remove; bool set; }; diff --git a/bdep/config.cxx b/bdep/config.cxx index aa10d78..d0b641e 100644 --- a/bdep/config.cxx +++ b/bdep/config.cxx @@ -213,7 +213,7 @@ namespace bdep << "in project " << prj; if (db.query_value (query::path == path.string ()) != 0) - fail << "configuration with path " << path << " already exists " + fail << "configuration with directory " << path << " already exists " << "in project " << prj; // Hm, what could that be? @@ -414,13 +414,42 @@ namespace bdep } static int - cmd_config_remove (const cmd_config_options& o, cli::scanner&) + cmd_config_move (cmd_config_options& o, cli::scanner& args) { - tracer trace ("config_remove"); + tracer trace ("config_move"); + + if (!args.more ()) + fail << "configuration directory argument expected"; dir_path prj (find_project (o)); + + // Similar story to config-add. + // + dir_path path; + optional rel_path; + { + const char* a (args.next ()); + try + { + path = dir_path (a); + + if (!exists (path)) + fail << "configuration directory " << path << " does not exist"; + + path.complete (); + path.normalize (); + } + catch (const invalid_path& e) + { + fail << "invalid configuration directory '" << a << "'"; + } + + try {rel_path = path.relative (prj);} catch (const invalid_path&) {} + } + database db (open (prj, trace)); + session ses; transaction t (db.begin ()); configurations cfgs ( @@ -430,26 +459,40 @@ namespace bdep false /* fallback_default */, false /* validate */)); - for (const shared_ptr& c: cfgs) - { - if (!c->packages.empty ()) - fail << "configuration " << *c << " contains initialized packages" << - info << "use deinit command to deinitialize packages" << - info << "use status command to list initialized packages"; + if (cfgs.size () > 1) + fail << "multiple configurations specified for config move"; - db.erase (c); + const shared_ptr& c (cfgs.front ()); + + // Check if there is already a configuration with this path. + // + using query = bdep::query; + + if (auto p = db.query_one (query::path == path.string ())) + { + // Note that this also covers the case where p == c. + // + fail << "configuration " << *p << " already uses directory " << path; } + // Save the old path for diagnostics. + // + c->path.swap (path); + c->relative_path = move (rel_path); + + db.update (c); t.commit (); if (verb) { - for (const shared_ptr& c: cfgs) - { - diag_record dr (text); - dr << "removed configuration "; - print_configuration (dr, c, false /* flags */); - } + // Restore the original path so that we can use print_configuration(). + // + path.swap (c->path); + + diag_record dr (text); + dr << "moved configuration "; + print_configuration (dr, c, false /* flags */); + dr << " to " << path; } return 0; @@ -504,7 +547,6 @@ namespace bdep const shared_ptr& c (cfgs.front ()); - // Check if this name is already taken. // using query = bdep::query; @@ -542,6 +584,53 @@ namespace bdep } static int + cmd_config_remove (const cmd_config_options& o, cli::scanner&) + { + tracer trace ("config_remove"); + + dir_path prj (find_project (o)); + database db (open (prj, trace)); + + transaction t (db.begin ()); + + configurations cfgs ( + find_configurations (o, + prj, + t, + false /* fallback_default */, + false /* validate */)); + + for (const shared_ptr& c: cfgs) + { + if (!c->packages.empty ()) + { + bool e (exists (c->path)); + + fail << "configuration " << *c << " contains initialized packages" << + info << "use deinit " << (e ? "" : "--force ") << "command to " + << "deinitialize packages" << + info << "use status command to list initialized packages"; + } + + db.erase (c); + } + + t.commit (); + + if (verb) + { + for (const shared_ptr& c: cfgs) + { + diag_record dr (text); + dr << "removed configuration "; + print_configuration (dr, c, false /* flags */); + } + } + + return 0; + } + + static int cmd_config_set (const cmd_config_options& o, cli::scanner&) { tracer trace ("config_set"); @@ -559,6 +648,7 @@ namespace bdep dir_path prj (find_project (o)); database db (open (prj, trace)); + session ses; transaction t (db.begin ()); configurations cfgs ( @@ -650,8 +740,9 @@ namespace bdep if (c.add ()) return cmd_config_add (o, scan); if (c.create ()) return cmd_config_create (o, scan); if (c.list ()) return cmd_config_list (o, scan); - if (c.remove ()) return cmd_config_remove (o, scan); + if (c.move ()) return cmd_config_move (o, scan); if (c.rename ()) return cmd_config_rename (o, scan); + if (c.remove ()) return cmd_config_remove (o, scan); if (c.set ()) return cmd_config_set (o, scan); assert (false); // Unhandled (new) subcommand. diff --git a/bdep/project.cxx b/bdep/project.cxx index 0d8686f..e553a1d 100644 --- a/bdep/project.cxx +++ b/bdep/project.cxx @@ -116,7 +116,9 @@ namespace bdep for (const shared_ptr& c: r) { if (!exists (c->path)) - fail << "configuration directory " << c->path << " no longer exists"; + fail << "configuration directory " << c->path << " no longer exists" << + info << "use config move command if it has been moved/renamed" << + info << "use config remove commands if it has been removed"; } } diff --git a/bdep/project.hxx b/bdep/project.hxx index 2fc4fec..652c2e8 100644 --- a/bdep/project.hxx +++ b/bdep/project.hxx @@ -70,7 +70,8 @@ namespace bdep // project and its configurations as a bundle (note that the dir: // repository path in the configuration will have to be adjust as well). // Since it is not always possible to derive a relative path, it is - // optional. + // optional. This is still a (maybe) @@ TODO; see find_configurations() + // for the place where we could possibly do this. // optional_uint64_t id; optional_string name; -- cgit v1.1