aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-05-13 08:30:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-05-13 12:52:17 +0200
commit9721773b915adf0bf7fcfb2bf8550787588e0aa2 (patch)
tree4a54c7c223e7d35a298fd4b9521ed6bce5d6c107
parent5f4d347767003b6b5870b97869897835c2cd40a4 (diff)
Add --package mode to new command for creating packages in existing projects
-rw-r--r--bdep/new.cli32
-rw-r--r--bdep/new.cxx122
-rw-r--r--bdep/types.hxx1
3 files changed, 111 insertions, 44 deletions
diff --git a/bdep/new.cli b/bdep/new.cli
index 27a982d..b0e7662 100644
--- a/bdep/new.cli
+++ b/bdep/new.cli
@@ -17,6 +17,7 @@ namespace bdep
<lang> <lang-opt>
<vcs> <vcs-opt>
<cfg-name> <cfg-dir>
+ <prj-spec> <prj-dir>
<cfg-args> <option> <module> <cfg-var>",
"\h|SYNOPSIS|
@@ -24,20 +25,23 @@ namespace bdep
\c{\b{bdep new} [<options>] [\b{--no-init}] <spec> <name>\n
\b{bdep new} [<options>] \b{--config-add|-A} <cfg-dir> [\b{@}<cfg-name>] <spec> <name>\n
\b{bdep new} [<options>] \b{--config-create|-C} <cfg-dir> [\b{@}<cfg-name>] <spec> <name>\n
- \ \ \ \ \ \ \ \ \ [<cfg-args>]}
+ \ \ \ \ \ \ \ \ \ [<cfg-args>]\n
+ \b{bdep new} [<options>] \b{--package} [<prj-spec>] <spec> <name>}
\c{<spec> \ \ \ \ = [<type>] [<lang>] [<vcs>]\n
<type> \ \ \ \ = \b{--type}|\b{-t} (\b{exe}|\b{lib}|\b{bare})[\b{,}<type-opt>...]\n
<lang> \ \ \ \ = \b{--lang}|\b{-l} (\b{c}|\b{c++})[\b{,}<lang-opt>...]\n
<vcs> \ \ \ \ \ = \b{--vcs}|\b{-s} \ (\b{git}|\b{none})[\b{,}<vcs-opt>...]\n
+ <prj-spec> = \b{--directory}|\b{-d} <prj-dir>\n
<cfg-args> = (<option> | <module> | <cfg-var>)...}
\h|DESCRIPTION|
- The \cb{new} command creates and initializes a new \cb{build2} project.
- All three forms first create according to <spec> a new \cb{build2}
- project called <name> in the <name> subdirectory of the current working
- directory (unless overridden with \c{\b{--output-dir}|\b{-o}}).
+ The \cb{new} command creates and initializes a new project (the first
+ three forms) or a new package in an already existing project (the last
+ form). All four forms first create according to <spec> a new \cb{build2}
+ project/package called <name> in the <name> subdirectory of the current
+ working directory (unless overridden with \c{\b{--output-dir}|\b{-o}}).
The first form then, unless the \cb{--no-init} option is specified,
initializes an empty project database as if by executing the
@@ -47,6 +51,11 @@ namespace bdep
the \l{bdep-init(1)} command with the \cb{--config-add} or
\cb{--config-create} option, respectively.
+ The last form adds the new package to the \cb{packages.manifest} file
+ creating it if necessary. If no project directory is explicitly specified
+ with \c{\b{--directory}|\b{-d}}, then the current working directory is
+ assumed.
+
The project parameters such as type (executable, library, etc), language,
and version control system can be customized as described next. Some of
these parameters also support parameter-specific options (such as the
@@ -168,6 +177,12 @@ namespace bdep
"Don't initialize an empty build configuration set."
}
+ bool --package
+ {
+ "Create a package inside an already existing project rather than a
+ new project."
+ }
+
dir_path --config-add|-A
{
"<dir>",
@@ -209,5 +224,12 @@ namespace bdep
"<dir>",
"Create the project in the specified directory."
}
+
+ dir_path --directory|-d
+ {
+ "<dir>",
+ "Assume project is in the specified directory rather than in the current
+ working directory."
+ }
};
}
diff --git a/bdep/new.cxx b/bdep/new.cxx
index 6eb1bd2..46f874b 100644
--- a/bdep/new.cxx
+++ b/bdep/new.cxx
@@ -27,12 +27,19 @@ namespace bdep
bool ca (o.config_add_specified ());
bool cc (o.config_create_specified ());
- if (o.no_init ())
+ if (o.package () && o.no_init ())
+ fail << "both --no-init and --package specified";
+
+ if (const char* n = (o.no_init () ? "--no-init" :
+ o.package () ? "--package" : nullptr))
{
- if (ca) fail << "both --no-init and --config-add specified";
- if (cc) fail << "both --no-init and --config-create specified";
+ if (ca) fail << "both " << n << " and --config-add specified";
+ if (cc) fail << "both " << n << " and --config-create specified";
}
+ if (o.directory_specified () && !o.package ())
+ fail << "--directory|-d only valid with --package";
+
if (const char* n = cmd_config_validate_add (o))
{
if (!ca && !cc)
@@ -97,25 +104,51 @@ namespace bdep
else
s = n;
- dir_path prj (o.output_dir_specified () ? o.output_dir () : dir_path (n));
- prj.complete ();
- prj.normalize ();
+ dir_path out; // Project/package output directory.
+ dir_path prj; // Project.
+ optional<dir_path> pkg; // Package relative to its project root.
+
+ if (o.package ())
+ {
+ if (o.directory_specified ())
+ (prj = o.directory ()).complete ().normalize ();
+ else
+ prj = path::current_directory ();
+
+ out = o.output_dir_specified () ? o.output_dir () : prj / dir_path (n);
+ out.complete ().normalize ();
+
+ if (!out.sub (prj))
+ fail << "package directory " << out << " is not a subdirectory of "
+ << "project directory " << prj;
+
+ pkg = out.leaf (prj);
+ }
+ else
+ {
+ out = o.output_dir_specified () ? o.output_dir () : dir_path (n);
+ out.complete ().normalize ();
+ prj = out;
+ }
// If the directory already exists, make sure it is empty. Otherwise
// create it.
//
- if (!exists (prj))
- mk (prj);
- else if (!empty (prj))
- fail << "directory " << prj << " already exists";
+ if (!exists (out))
+ mk (out);
+ else if (!empty (out))
+ fail << "directory " << out << " already exists";
// Initialize the version control system. Do it before writing anything
// ourselves in case it fails.
//
- switch (v)
+ if (!pkg)
{
- case vcs::git: run ("git", "init", "-q", prj); break;
- case vcs::none: break;
+ switch (v)
+ {
+ case vcs::git: run ("git", "init", "-q", out); break;
+ case vcs::none: break;
+ }
}
path f; // File currently being written.
@@ -125,7 +158,7 @@ namespace bdep
// manifest
//
- os.open (f = prj / "manifest");
+ os.open (f = out / "manifest");
os << ": 1" << endl
<< "name: " << n << endl
<< "version: 0.1.0-a.0.z" << endl
@@ -140,23 +173,36 @@ namespace bdep
// repositories.manifest
//
- os.open (f = prj / "repositories.manifest");
- os << ": 1" << endl
- << "summary: " << n << " project repository" << endl
- << endl
- << "#:" << endl
- << "#role: prerequisite" << endl
- << "#location: https://pkg.cppget.org/1/stable" << endl
- << "#trust: ..." << endl
- << endl
- << "#:" << endl
- << "#role: prerequisite" << endl
- << "#location: https://git.build2.org/hello/libhello.git" << endl;
- os.close ();
+ if (!pkg)
+ {
+ os.open (f = out / "repositories.manifest");
+ os << ": 1" << endl
+ << "summary: " << n << " project repository" << endl
+ << endl
+ << "#:" << endl
+ << "#role: prerequisite" << endl
+ << "#location: https://pkg.cppget.org/1/stable" << endl
+ << "#trust: ..." << endl
+ << endl
+ << "#:" << endl
+ << "#role: prerequisite" << endl
+ << "#location: https://git.build2.org/hello/libhello.git" << endl;
+ os.close ();
+ }
+ // packages.manifest
+ //
+ else
+ {
+ bool e (exists (f = prj / "packages.manifest"));
+ os.open (f, fdopen_mode::create | fdopen_mode::append);
+ os << (e ? ":" : ": 1") << endl
+ << "location: " << pkg->posix_representation () << endl;
+ os.close ();
+ }
// build/
//
- dir_path bd (dir_path (prj) /= "build");
+ dir_path bd (dir_path (out) /= "build");
mk (bd);
// build/bootstrap.build
@@ -226,7 +272,7 @@ namespace bdep
// buildfile
//
- os.open (f = prj / "buildfile");
+ os.open (f = out / "buildfile");
os << "./: {*/ -build/} file{manifest}" << endl;
if (tests && t == type::lib) // Have tests/ subproject.
os << endl
@@ -243,7 +289,7 @@ namespace bdep
{
// Use POSIX directory separators here.
//
- os.open (f = prj / ".gitignore");
+ os.open (f = out / ".gitignore");
os << bdep_dir.string () << '/' << endl
<< endl
<< "# Compiler/linker output." << endl
@@ -270,7 +316,7 @@ namespace bdep
// <name>/ (source subdirectory).
//
- dir_path sd (dir_path (prj) /= n);
+ dir_path sd (dir_path (out) /= n);
if (t != type::bare)
mk (sd);
@@ -685,7 +731,7 @@ namespace bdep
if (!tests)
break;
- dir_path td (dir_path (prj) /= "tests");
+ dir_path td (dir_path (out) /= "tests");
mk (td);
// tests/build/
@@ -908,19 +954,17 @@ namespace bdep
}
if (verb)
- text << "created new " << t << " project " << n << " in " << prj;
+ text << "created new " << t << ' ' << (pkg ? "package" : "project")
+ << ' ' << n << " in " << out;
- // --no-init
+ // --no-init | --package
//
- if (o.no_init ())
+ if (o.no_init () || o.package ())
return 0;
// Create .bdep/.
//
- {
- dir_path d (prj / bdep_dir);
- mk (prj / bdep_dir);
- }
+ mk (prj / bdep_dir);
// Everything else requires a database.
//
diff --git a/bdep/types.hxx b/bdep/types.hxx
index e31ab4b..0c412d3 100644
--- a/bdep/types.hxx
+++ b/bdep/types.hxx
@@ -102,6 +102,7 @@ namespace bdep
using butl::fdpipe;
using butl::ifdstream;
using butl::ofdstream;
+ using butl::fdopen_mode;
using butl::fdstream_mode;
}