diff options
-rw-r--r-- | bdep/new.cli | 32 | ||||
-rw-r--r-- | bdep/new.cxx | 122 | ||||
-rw-r--r-- | bdep/types.hxx | 1 |
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; } |