diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2018-03-13 10:34:57 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2018-03-13 10:34:57 +0200 |
commit | 6be9c7746f92aa721782a4d0eaff5f901fc528cd (patch) | |
tree | ad072fd130d3bb64acee0be183698daa328e8966 | |
parent | 5dcbecfd8b83f516c067780214f06321f03d1cce (diff) |
Setup command line infrastructure for new command
-rw-r--r-- | bdep/bdep.cli | 9 | ||||
-rw-r--r-- | bdep/bdep.cxx | 13 | ||||
-rw-r--r-- | bdep/buildfile | 8 | ||||
-rw-r--r-- | bdep/common.cli | 1 | ||||
-rw-r--r-- | bdep/init.cli | 2 | ||||
-rw-r--r-- | bdep/new-parsers.cxx | 114 | ||||
-rw-r--r-- | bdep/new-parsers.hxx | 38 | ||||
-rw-r--r-- | bdep/new-types.hxx | 70 | ||||
-rw-r--r-- | bdep/new.cli | 125 | ||||
-rw-r--r-- | bdep/new.cxx | 25 | ||||
-rw-r--r-- | bdep/new.hxx | 19 | ||||
-rw-r--r-- | bdep/project.cli | 21 | ||||
-rwxr-xr-x | doc/cli.sh | 2 |
13 files changed, 427 insertions, 20 deletions
diff --git a/bdep/bdep.cli b/bdep/bdep.cli index 172eb48..12992d9 100644 --- a/bdep/bdep.cli +++ b/bdep/bdep.cli @@ -59,9 +59,9 @@ namespace bdep "" } - bool config + bool new { - "\l{bdep-config(1)} \- manage project's build configurations" + "\l{bdep-new(1)} \- create and initialize new project" } bool init @@ -73,6 +73,11 @@ namespace bdep { "\l{bdep-sync(1)} \- synchronize project and configurations" } + + bool config + { + "\l{bdep-config(1)} \- manage project's build configurations" + } }; // Make sure these don't conflict with command names above. diff --git a/bdep/bdep.cxx b/bdep/bdep.cxx index 39f08ad..ef4a6ec 100644 --- a/bdep/bdep.cxx +++ b/bdep/bdep.cxx @@ -22,9 +22,10 @@ // #include <bdep/help.hxx> -#include <bdep/config.hxx> +#include <bdep/new.hxx> #include <bdep/init.hxx> #include <bdep/sync.hxx> +#include <bdep/config.hxx> using namespace std; using namespace bdep; @@ -34,11 +35,11 @@ using namespace bdep; // Once this is done, use the "final" values of the common options to do // global initializations (verbosity level, etc). // -// If O is-a project_options, then also handle the @<cfg-name> arguments and -// place them into project_options::config_name. +// If O is-a configuration_name_options, then also handle the @<cfg-name> +// arguments and place them into configuration_name_options::config_name. // static inline bool -cfg_name (project_options* o, const char* a) +cfg_name (configuration_name_options* o, const char* a) { string n (a); @@ -264,10 +265,10 @@ try break; \ } - //COMMAND_IMPL (new_, new, "new"); - COMMAND_IMPL (config, config, "config"); + COMMAND_IMPL (new_, new, "new"); COMMAND_IMPL (init, init, "init"); COMMAND_IMPL (sync, sync, "sync"); + COMMAND_IMPL (config, config, "config"); assert (false); fail << "unhandled command"; diff --git a/bdep/buildfile b/bdep/buildfile index 5afe7c2..7559ed0 100644 --- a/bdep/buildfile +++ b/bdep/buildfile @@ -21,7 +21,8 @@ project-options \ help-options \ config-options \ init-options \ -sync-options +sync-options \ +new-options exe{bdep}: {hxx ixx txx cxx}{** -{$options_topics} -*-odb -version} \ {hxx ixx cxx}{$options_topics} \ @@ -55,6 +56,7 @@ if $cli.configured cli.cxx{config-options}: cli{config} cli.cxx{init-options}: cli{init} cli.cxx{sync-options}: cli{sync} + cli.cxx{new-options}: cli{new} # Option length must be the same to get commands/topics/options aligned. # @@ -67,9 +69,11 @@ if $cli.configured cli.cxx{common-options}: cli.options += --short-usage --long-usage # Both. cli.cxx{bdep-options}: cli.options += --short-usage - cli.options += --long-usage # All other pages -- long usage. + cli.cxx{new-options}: cli.options += \ +--cxx-prologue "#include <bdep/new-parsers.hxx>" + # Include the generated cli files into the distribution and don't remove # them when cleaning in src (so that clean results in a state identical to # distributed). diff --git a/bdep/common.cli b/bdep/common.cli index 80c01db..21b504d 100644 --- a/bdep/common.cli +++ b/bdep/common.cli @@ -3,6 +3,7 @@ // license : MIT; see accompanying LICENSE file include <bdep/types.hxx>; +include <bdep/options-types.hxx>; "\section=1" "\name=bdep-common-options" diff --git a/bdep/init.cli b/bdep/init.cli index 77c84a4..e4b7e2d 100644 --- a/bdep/init.cli +++ b/bdep/init.cli @@ -23,7 +23,7 @@ namespace bdep \c{\b{bdep init} [<options>] [<pkg-spec>] [<cfg-spec>] [<pkg-args>]\n \b{bdep init} [<options>] [<prj-spec>] \b{--empty|-E}\n \b{bdep init} [<options>] [<pkg-spec>] \b{--config-add|-A} <cfg-dir> [\b{@}<cfg-name>]\n - \b{bdep init} [<options>] [<pkg-spec>] \b{--config-create|-C} <cfg-dir> [\b{@}<cfg-name>] \\\n + \b{bdep init} [<options>] [<pkg-spec>] \b{--config-create|-C} <cfg-dir> [\b{@}<cfg-name>]\n \ \ \ \ \ \ \ \ \ \ [<cfg-args>]} \c{<prj-spec> = \b{--directory}|\b{-d} <prj-dir>\n diff --git a/bdep/new-parsers.cxx b/bdep/new-parsers.cxx new file mode 100644 index 0000000..d5b8e6e --- /dev/null +++ b/bdep/new-parsers.cxx @@ -0,0 +1,114 @@ +// file : bdep/new-parsers.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <bdep/new-parsers.hxx> + +#include <bdep/new-options.hxx> // bdep::cli namespace, cmd_new_*_options + +namespace bdep +{ + namespace cli + { + using type = cmd_new_type; + using lang = cmd_new_lang; + + // Parse comma-separated list of of options starting from the first comma + // at pos. + // + template <typename O> + static O + parse_options (const char* o, const string v, size_t pos) + { + // Use vector_scanner to parse the comma-separated list as options. + // + vector<string> os; + for (size_t i (pos), j; i != string::npos; ) + { + j = i + 1; + i = v.find (',', j); + os.push_back (string (v, j, i != string::npos ? i - j : i)); + } + + vector_scanner s (os); + + try + { + O r; + r.parse (s, + unknown_mode::fail /* unknown_option */, + unknown_mode::fail /* unknown_argument */); + return r; + } + catch (const unknown_option& e) + { + throw invalid_value (o, e.option ()); + } + catch (const unknown_argument& e) + { + throw invalid_value (o, e.argument ()); + } + } + + void parser<type>:: + parse (type& r, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (!s.more ()) + throw missing_value (o); + + string v (s.next ()); + size_t i (v.find (',')); + string l (v, 0, i); + + if (l == "exe") + { + r.type = type::exe; + r.exe_opt = parse_options<cmd_new_exe_options> (o, v, i); + } + else if (l == "lib") + { + r.type = type::lib; + r.lib_opt = parse_options<cmd_new_lib_options> (o, v, i); + } + else if (l == "bare") + { + r.type = type::bare; + r.bare_opt = parse_options<cmd_new_bare_options> (o, v, i); + } + else + throw invalid_value (o, l); + + xs = true; + } + + void parser<lang>:: + parse (lang& r, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (!s.more ()) + throw missing_value (o); + + string v (s.next ()); + size_t i (v.find (',')); + string l (v, 0, i); + + if (l == "c") + { + r.lang = lang::c; + r.c_opt = parse_options<cmd_new_c_options> (o, v, i); + } + else if (l == "c++") + { + r.lang = lang::cxx; + r.cxx_opt = parse_options<cmd_new_cxx_options> (o, v, i); + } + else + throw invalid_value (o, l); + + xs = true; + } + } +} diff --git a/bdep/new-parsers.hxx b/bdep/new-parsers.hxx new file mode 100644 index 0000000..c496314 --- /dev/null +++ b/bdep/new-parsers.hxx @@ -0,0 +1,38 @@ +// file : bdep/new-parsers.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +// CLI parsers, included into the generated source files. +// + +#ifndef BDEP_NEW_PARSERS_HXX +#define BDEP_NEW_PARSERS_HXX + +#include <bdep/new-types.hxx> + +namespace bdep +{ + namespace cli + { + class scanner; + + template <typename T> + struct parser; + + template <> + struct parser<cmd_new_type> + { + static void + parse (cmd_new_type&, bool&, scanner&); + }; + + template <> + struct parser<cmd_new_lang> + { + static void + parse (cmd_new_lang&, bool&, scanner&); + }; + } +} + +#endif // BDEP_NEW_PARSERS_HXX diff --git a/bdep/new-types.hxx b/bdep/new-types.hxx new file mode 100644 index 0000000..2612f62 --- /dev/null +++ b/bdep/new-types.hxx @@ -0,0 +1,70 @@ +// file : bdep/new-types.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BDEP_NEW_TYPES_HXX +#define BDEP_NEW_TYPES_HXX + +namespace bdep +{ + // We could have defined cmd_new_*_options in a separate .cli file, include + // that here, and so on. Or we can abuse templates and keep everything + // together. + + // --type + // + class cmd_new_exe_options; + class cmd_new_lib_options; + class cmd_new_bare_options; + + template <typename EXE = cmd_new_exe_options, + typename LIB = cmd_new_lib_options, + typename BARE = cmd_new_bare_options> + struct cmd_new_type_template + { + enum type_type {exe, lib, bare} type; + + operator type_type () const {return type;} + + union + { + EXE exe_opt; + LIB lib_opt; + BARE bare_opt; + }; + + // Default is bare with no options. + // + cmd_new_type_template (): type (bare) {bare_opt = BARE ();} + }; + + using cmd_new_type = cmd_new_type_template<>; + + // --lang + // + class cmd_new_c_options; + class cmd_new_cxx_options; + + template <typename C = cmd_new_c_options, + typename CXX = cmd_new_cxx_options> + struct cmd_new_lang_template + { + enum lang_type {c, cxx} lang; + + operator lang_type () const {return lang;} + + union + { + C c_opt; + CXX cxx_opt; + }; + + // Default is C++ with no options. + // + cmd_new_lang_template (): lang (cxx) {cxx_opt = CXX ();} + }; + + using cmd_new_lang = cmd_new_lang_template<>; +} + +#endif // BDEP_NEW_TYPES_HXX diff --git a/bdep/new.cli b/bdep/new.cli new file mode 100644 index 0000000..ddf61c0 --- /dev/null +++ b/bdep/new.cli @@ -0,0 +1,125 @@ +// file : bdep/new.cli +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +include <bdep/project.cli>; +include <bdep/new-types.hxx>; + +"\section=1" +"\name=bdep-new" +"\summary=create and initialize new project" + +namespace bdep +{ + { + "<options> <spec> <name> + <type> <type-opt> + <lang> <lang-opt> + <cfg-name> <cfg-dir> + <cfg-args> <cfg-var> <module>", + + "\h|SYNOPSIS| + + \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>]} + + \c{<spec> = [<type>] [<lang>]\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 + <cfg-args> = (<module> | <cfg-var>)...} + + \h|DESCRIPTION| + + The \cb{new} command... + + The first variant, unless the \cb{--no-init} is specified, initializes + an empty configuration set, as if by performing \cb{init --empty}. + + Recognized \cb{c++} language options: + + \dl| + + \li|\cb{cxx} + + Use the \cb{.cxx}, \cb{.hxx}, \cb{.ixx}, \cb{.txx}, and \cb{.mxx} + source file extensions (default).| + + \li|\cb{cpp} + + Use the \cb{.cpp}, \cb{.hpp}, \cb{.ipp}, \cb{.tpp}, and \cb{.mpp} + source file extensions.|| + " + } + + //--type options + // + class cmd_new_exe_options + { + }; + + class cmd_new_lib_options + { + }; + + class cmd_new_bare_options + { + }; + + // --lang options + // + class cmd_new_c_options + { + }; + + class cmd_new_cxx_options + { + bool cpp; + bool cxx; + }; + + class cmd_new_options: configuration_name_options + { + "\h|NEW OPTIONS|" + + bool --no-init + { + "Don't initialize an empty build configuration set." + } + + dir_path --config-add|-A + { + "<dir>", + "Add an existing build configuration <dir>." + } + + dir_path --config-create|-C + { + "<dir>", + "Create a new build configuration in <dir>." + } + + cmd_new_type --type|-t + { + "<type>[,<opt>...]", + "Specify project type and options. Valid values for <type> are \cb{exe} + (executable project) \cb{lib} (library project), and \cb{bare} (bare + project without any source code, default). Valid values for <opt> are + type-specific." + } + + cmd_new_lang --lang|-l + { + "<lang>[,<opt>...]", + "Specify language type and options. Valid values for <lang> are \cb{c}, + and \cb{c++} (default). Valid values for <opt> are language-specific." + } + + bool --no-git + { + "Don't initialize a \cb{git(1)} repository inside the project nor + generate any \cb{.gitignore} files." + } + }; +} diff --git a/bdep/new.cxx b/bdep/new.cxx new file mode 100644 index 0000000..f2975c8 --- /dev/null +++ b/bdep/new.cxx @@ -0,0 +1,25 @@ +// file : bdep/new.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <bdep/new.hxx> + +#include <bdep/diagnostics.hxx> + +using namespace std; + +namespace bdep +{ + using type = cmd_new_type; + using lang = cmd_new_lang; + + int + cmd_new (const cmd_new_options& o, cli::scanner& args) + { + tracer trace ("new"); + + //@@ TODO: validate options (cpp/cxx, -A/-C, etc). + + return 0; + } +} diff --git a/bdep/new.hxx b/bdep/new.hxx new file mode 100644 index 0000000..a9afbe8 --- /dev/null +++ b/bdep/new.hxx @@ -0,0 +1,19 @@ +// file : bdep/new.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BDEP_NEW_HXX +#define BDEP_NEW_HXX + +#include <bdep/types.hxx> +#include <bdep/utility.hxx> + +#include <bdep/new-options.hxx> + +namespace bdep +{ + int + cmd_new (const cmd_new_options&, cli::scanner& args); +} + +#endif // BDEP_NEW_HXX diff --git a/bdep/project.cli b/bdep/project.cli index cbf33a3..7680d99 100644 --- a/bdep/project.cli +++ b/bdep/project.cli @@ -8,10 +8,22 @@ include <bdep/common.cli>; namespace bdep { + // Common options for commands that accept @<cfg-name>. + // + class configuration_name_options: common_options + { + // Storage for configuration names specified as @<cfg-name>. + // + // Note that we leave it undocumented so that it's not mentioned in + // documentation. + // + strings --config-name; + }; + // Common options for commands that operate on project/packages (prj-spec // and pkg-spec) and configurations (cfg-spec). // - class project_options: common_options + class project_options: configuration_name_options { bool --all|-a { @@ -30,13 +42,6 @@ namespace bdep "Specify the build configuration to use as an id." }; - // Storage for configuration names specified as @<cfg-name>. - // - // Note that we leave it undocumented so that it's not mentioned in - // documentation. - // - strings --config-name; - dir_paths --directory|-d { "<dir>", @@ -56,7 +56,7 @@ o="--suppress-undocumented --output-prefix bdep- --class-doc bdep::common_option compile "common" $o --output-suffix "-options" --class-doc bdep::common_options=long compile "bdep" $o --output-prefix "" --class-doc bdep::commands=short --class-doc bdep::topics=short -pages="config help init sync" +pages="config help init sync new" for p in $pages; do compile $p $o |