aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/cfg-create.cli31
-rw-r--r--bpkg/cfg-create.cxx88
2 files changed, 84 insertions, 35 deletions
diff --git a/bpkg/cfg-create.cli b/bpkg/cfg-create.cli
index bac601d..571c614 100644
--- a/bpkg/cfg-create.cli
+++ b/bpkg/cfg-create.cli
@@ -16,25 +16,28 @@ namespace bpkg
"\h|SYNOPSIS|
- \c{\b{bpkg cfg-create}|\b{create} [<options>] [<cfg-args>]}
+ \c{\b{bpkg cfg-create}|\b{create} [<options>] [<cfg-args>]\n
+ \b{bpkg cfg-create}|\b{create} [<options>] \b{--existing|-e}}
\c{<cfg-args> = (<module> | <cfg-var>)...}
\h|DESCRIPTION|
The \cb{cfg-create} command creates a new \cb{bpkg} configuration with
- the specified \cb{build2} modules and configuration variables. The
- \cb{bpkg} configuration itself is a build system configuration; see
- build system driver (\l{b(1)}) \cb{create} meta-operation for details.
+ the specified \cb{build2} modules and configuration variables (the first
+ form) or initializes one based on an existing build system configuration
+ (the second form). The \cb{bpkg} configuration itself is a build system
+ configuration; see build system driver (\l{b(1)}) \cb{create}
+ meta-operation for details.
- Unless the \cb{--wipe} option is specified, \cb{cfg-create} expects the
- configuration directory to be empty or to not exist (in which case it
- will be created).
+ Unless the \cb{--existing|-e} or \cb{--wipe} option is specified,
+ \cb{cfg-create} expects the configuration directory to be empty or to not
+ exist (in which case it will be created).
- By default, the resulting configuration loads the \cb{config}, \cb{test},
- \cb{dist}, and \cb{install} modules. However, additional modules and, if
- required, their configuration variables can be specified as the
- \cb{cfg-create} arguments. For example:
+ By default, the configuration created with the first form loads the
+ \cb{config}, \cb{test}, \cb{dist}, and \cb{install} modules. However,
+ additional modules and, if required, their configuration variables can be
+ specified as the \cb{cfg-create} arguments. For example:
\
bpkg create cxx config.cxx=clang++ config.install.root=/usr/local
@@ -63,6 +66,12 @@ namespace bpkg
directory."
}
+ bool --existing|-e
+ {
+ "Initialize a \cb{bpkg} configuration based on an existing build system
+ configuration."
+ }
+
bool --wipe
{
"Wipe the configuration directory clean before creating the new
diff --git a/bpkg/cfg-create.cxx b/bpkg/cfg-create.cxx
index d6f9cdc..14fb982 100644
--- a/bpkg/cfg-create.cxx
+++ b/bpkg/cfg-create.cxx
@@ -18,41 +18,58 @@ namespace bpkg
{
tracer trace ("cfg_create");
+ if (o.existing () && o.wipe ())
+ fail << "both --existing|-e and --wipe specified";
+
if (o.wipe () && !o.directory_specified ())
fail << "--wipe requires explicit --directory|-d";
dir_path c (o.directory ());
l4 ([&]{trace << "creating configuration in " << c;});
- // If the directory already exists, make sure it is empty. Otherwise
- // create it.
+ // Verify the existing directory is compatible with our mode.
//
if (exists (c))
{
- l5 ([&]{trace << "directory " << c << " exists";});
-
- if (!empty (c))
+ if (o.existing ())
{
- l5 ([&]{trace << "directory " << c << " not empty";});
-
- if (!o.wipe ())
- fail << "directory " << c << " is not empty" <<
- info << "use --wipe to clean it up but be careful";
-
- rm_r (c, false);
+ // Bail if the .bpkg/ directory already exists and is not empty.
+ //
+ // If you are wondering why don't we allow --wipe here, it's the
+ // existing packages that may be littering the configuration --
+ // cleaning those up will be messy.
+ //
+ dir_path d (c / bpkg_dir);
+
+ if (exists (d) && !empty (d))
+ fail << "directory " << d << " already exists";
+ }
+ else
+ {
+ // If the directory already exists, make sure it is empty.
+ //
+ if (!empty (c))
+ {
+ if (!o.wipe ())
+ fail << "directory " << c << " is not empty" <<
+ info << "use --wipe to clean it up but be careful";
+
+ rm_r (c, false);
+ }
}
}
else
{
- l5 ([&]{trace << "directory " << c << " does not exist";});
+ // Note that we allow non-existent directory even in the --existing mode
+ // in case the user wants to add the build system configuration later.
+ //
mk_p (c);
}
// Sort arguments into modules and configuration variables.
//
- string mods; // build2 create meta-operation parameters.
+ strings mods;
strings vars;
-
while (args.more ())
{
string a (args.next ());
@@ -63,8 +80,7 @@ namespace bpkg
}
else if (!a.empty ())
{
- mods += mods.empty () ? ", " : " ";
- mods += a;
+ mods.push_back (move (a));
}
else
fail << "empty string as argument";
@@ -72,12 +88,33 @@ namespace bpkg
// Create and configure.
//
- // Run quiet. Use path representation to get canonical trailing slash.
- //
- run_b (o,
- verb_b::quiet,
- vars,
- "create('" + c.representation () + "'" + mods + ")");
+ if (o.existing ())
+ {
+ if (!mods.empty ())
+ fail << "module '" << mods[0] << "' specified with --existing|-e";
+
+ if (!vars.empty ())
+ fail << "variable '" << vars[0] << "' specified with --existing|-e";
+ }
+ else
+ {
+ // Assemble the build2 create meta-operation parameters.
+ //
+ string params ("'" + c.representation () + "'");
+ if (!mods.empty ())
+ {
+ params += ',';
+ for (const string& m: mods)
+ {
+ params += ' ';
+ params += m;
+ }
+ }
+
+ // Run quiet. Use path representation to get canonical trailing slash.
+ //
+ run_b (o, verb_b::quiet, vars, "create(" + params + ")");
+ }
// Create .bpkg/ and its subdirectories.
//
@@ -125,7 +162,10 @@ namespace bpkg
if (verb && !o.no_result ())
{
c.complete ().normalize ();
- text << "created new configuration in " << c;
+ if (o.existing ())
+ text << "initialized existing configuration in " << c;
+ else
+ text << "created new configuration in " << c;
}
return 0;