From 8ab23ad062f53ed32107f19d7e855c07992eb517 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 13 Feb 2020 12:27:19 +0200 Subject: Add --type|-t,source sub-option for customizing source subdirectory For example: $ bdep new -l c++ -t lib,source=libhello/io libhello-io --- bdep/new.cli | 31 ++++++++++++++++++---- bdep/new.cxx | 73 +++++++++++++++++++++++++++++++++++++++++++--------- tests/new.testscript | 12 +++++++++ 3 files changed, 99 insertions(+), 17 deletions(-) diff --git a/bdep/new.cli b/bdep/new.cli index 9340f85..93d8aaf 100644 --- a/bdep/new.cli +++ b/bdep/new.cli @@ -72,8 +72,8 @@ namespace bdep $ bdep new -t empty hello $ cd hello - $ bdep new --package -l c++ -t lib libhello - $ bdep new --package -l c++ -t exe hello + $ bdep new --package -l c++ -t lib libhello + $ bdep new --package -l c++ -t exe hello $ bdep init -C @gcc cc config.cxx=g++ \ @@ -83,8 +83,8 @@ namespace bdep The \cb{--subdirectory} form operates \i{as-if} by first creating according to a temporary project called and then copying - its source subdirectory (\c{\i{name}\b{/}\i{name}\b{/}}) over to the - current working directory (unless overridden with + its source subdirectory (\c{\i{name}\b{/}\i{name}\b{/}} by default) over + to the current working directory (unless overridden with \c{\b{--output-dir}|\b{-o}}). If no project/package directory is explicitly specified with \c{\b{--directory}|\b{-d}}, then the current working directory is assumed. For example: @@ -94,7 +94,7 @@ namespace bdep $ cd hello $ bdep new --subdirectory -l c++ -t lib libhello - $ bdep new --subdirectory -l c++ -t exe hello + $ bdep new --subdirectory -l c++ -t exe hello $ bdep init -C @gcc cc config.cxx=g++ \ @@ -107,6 +107,17 @@ namespace bdep used as the project/package/subdirectory name. See \l{bpkg#package-name Package Name} for details on project/package names. + The source subdirectory can be customized with the \cb{source} project + type sub-option (see below for details). For example: + + \ + $ bdep new -l c++ -t lib,source=libhello/io libhello-io + \ + + After executing this command the \cb{libhello-io} project will contain + the \cb{libhello/io/} source subdirectory instead of the default + \cb{libhello-io/}. + The output directory may already contain existing files provided they don't clash with the files to be created. The \cb{new} command also recognizes certain well-known files and tries to use the extracted @@ -222,6 +233,10 @@ namespace bdep Don't add support for installing.| + \li|\n\ \ \ \c{\b{source=}\i{dir}} + + Alternative source subdirectory relative to project/package root.| + \li|\n\ \ \ \c{\b{license=}\i{name}}| \li|\ \ \ \cb{no-readme}| @@ -253,6 +268,10 @@ namespace bdep Don't add support for generating the version header.| + \li|\n\ \ \ \c{\b{source=}\i{dir}} + + Alternative source subdirectory relative to project/package root.| + \li|\n\ \ \ \c{\b{license=}\i{name}}| \li|\ \ \ \cb{no-readme}| @@ -369,6 +388,7 @@ namespace bdep bool no-tests; bool unit-tests; bool no-install; + dir_path "source"; string license = "proprietary"; bool no-readme; bool alt-naming; @@ -380,6 +400,7 @@ namespace bdep bool unit-tests; bool no-install; bool no-version; + dir_path "source"; string license = "proprietary"; bool no-readme; bool alt-naming; diff --git a/bdep/new.cxx b/bdep/new.cxx index 3e7f295..4c1146e 100644 --- a/bdep/new.cxx +++ b/bdep/new.cxx @@ -380,6 +380,26 @@ namespace bdep const string build_ext (altn ? "build2" : "build"); const path buildfile_file (altn ? "build2file" : "buildfile"); + // User-supplied source subdirectory (--type,source). + // + // Should we derive the C++ namespace from this (e.g., foo::bar from + // libfoo/bar) and allow its customization (e.g., --type,namespace)? That + // was the initial impulse but doing this will complicate things quite a + // bit. In particular, we will have to handle varying indentation levels. + // On the other hand, our goal is not to produce a project that requires + // an absolute minimum of changes but rather a project that is easy to + // tweak. And changing the namespace is straightforward (unlike changing + // the source subdirectory, which appears in quite a few places). So let's + // keep it simple for now. + // + const dir_path* source (t == type::exe ? (t.exe_opt.source_specified () + ? &t.exe_opt.source () + : nullptr) : + t == type::lib ? (t.lib_opt.source_specified () + ? &t.lib_opt.source () + : nullptr) : + nullptr); + // Validate vcs options. // vcs vc (o.vcs ()); @@ -396,13 +416,21 @@ namespace bdep if (!o.output_dir_specified ()) { // Reduce this case (for the logic that follows) to as-if the current - // working directory was specified as the output directory. + // working directory was specified as the output directory. Unless we + // are in the subdirectory mode and the source sub-option was + // specified (see the relevant code below for the whole picture). // - o.output_dir (path::current_directory ()); - o.output_dir_specified (true); + if (o.subdirectory () && source != nullptr) + a = source->leaf ().string (); + else + { + o.output_dir (path::current_directory ()); + o.output_dir_specified (true); + } } - a = o.output_dir ().leaf ().string (); + if (a.empty ()) + a = o.output_dir ().leaf ().string (); } // If the project type is not empty then the project name is also a package @@ -481,15 +509,15 @@ namespace bdep } } - dir_path prj; // Project. + dir_path prj; // Project root directory. dir_path out; // Project/package/subdirectory output directory. - optional pkg; // Package relative to its project root. + optional pkg; // Package directory relative to its project root. optional sub; // Source subdirectory relative to its // project/package root. { // Figure the final output and tentative project directories. // - if (o.package () || o.subdirectory ()) + if (o.package ()) { if (o.directory_specified ()) prj = normalize (o.directory (), "project"); @@ -499,6 +527,26 @@ namespace bdep out = o.output_dir_specified () ? o.output_dir () : prj / dir_path (n); normalize (out, "output"); } + else if (o.subdirectory ()) + { + // In the subdirectory mode --output-dir|-o is the source subdirectory + // so for this mode we have two ways of specifying the same thing (but + // see also the output directory fallback above for a special case). + // + if (o.output_dir_specified () && source != nullptr) + fail << "both --output-dir|-o and --type|-t,source specified"; + + if (o.directory_specified ()) + prj = normalize (o.directory (), "project"); + else + prj = current_directory (); + + out = o.output_dir_specified () + ? o.output_dir () + : prj / (source != nullptr ? *source : dir_path (n)); + + normalize (out, "output"); + } else { out = o.output_dir_specified () ? o.output_dir () : dir_path (n); @@ -684,7 +732,7 @@ namespace bdep // Source directory relative to package root. // - const dir_path& d (sub ? *sub : dir_path (b)); + const dir_path& d (sub ? *sub : source != nullptr ? *source : dir_path (b)); // Check if certain things already exist. // @@ -728,7 +776,7 @@ namespace bdep if (license_e->empty () && !license_o) fail << "unable to guess project license from " << f << - info << "use license --type|-t sub-option to specify explicitly"; + info << "use --type|-t,license sub-option to specify explicitly"; } } @@ -748,7 +796,8 @@ namespace bdep if (readme_e) { if (!readme) - fail << "no-readme sub-option specified but README already exists"; + fail << "--type|-t,no-readme sub-option specified but README " + << "already exists"; } if (license_e) @@ -1196,10 +1245,10 @@ namespace bdep if (t == type::bare) break; // Done - // / (source subdirectory). + // / (source subdirectory, can be overriden). // const dir_path& sd (sub ? out : out / d); - mk (sd); + mk_p (sd); switch (t) { diff --git a/tests/new.testscript b/tests/new.testscript index d8858b3..4fefe56 100644 --- a/tests/new.testscript +++ b/tests/new.testscript @@ -173,6 +173,18 @@ status += -d prj EOE } + : lib-alt-source + : + { + $* -l c++ -t lib,source=libprj/foo libprj-foo 2>>/"EOE" &libprj-foo/***; + created new library project libprj-foo in $~/libprj-foo/ + EOE + + $build libprj-foo/ $config_cxx 2>>~%EOE% + %(version\.in|c\+\+|ar|ld) .+%{7} + EOE + } + # C versions of the above. # : exe-c -- cgit v1.1