From 5dcbecfd8b83f516c067780214f06321f03d1cce Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 12 Mar 2018 11:17:21 +0200 Subject: Initial sync implementation --- bdep/bdep.cli | 7 +++- bdep/bdep.cxx | 4 ++- bdep/buildfile | 4 ++- bdep/init.cli | 2 +- bdep/init.cxx | 21 +++++++---- bdep/project.cxx | 20 ++++++----- bdep/project.hxx | 12 +++++-- bdep/sync.cli | 39 +++++++++++++++++++++ bdep/sync.cxx | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ bdep/sync.hxx | 25 +++++++++++++ doc/cli.sh | 2 +- 11 files changed, 218 insertions(+), 23 deletions(-) create mode 100644 bdep/sync.cli create mode 100644 bdep/sync.cxx create mode 100644 bdep/sync.hxx diff --git a/bdep/bdep.cli b/bdep/bdep.cli index 637803c..172eb48 100644 --- a/bdep/bdep.cli +++ b/bdep/bdep.cli @@ -66,7 +66,12 @@ namespace bdep bool init { - "\l{bdep-init(1)} \- @@ TODO" + "\l{bdep-init(1)} \- initialize project in configurations" + } + + bool sync + { + "\l{bdep-sync(1)} \- synchronize project and configurations" } }; diff --git a/bdep/bdep.cxx b/bdep/bdep.cxx index 77dcd71..39f08ad 100644 --- a/bdep/bdep.cxx +++ b/bdep/bdep.cxx @@ -24,6 +24,7 @@ #include #include +#include using namespace std; using namespace bdep; @@ -264,8 +265,9 @@ try } //COMMAND_IMPL (new_, new, "new"); - COMMAND_IMPL (init, init, "init"); COMMAND_IMPL (config, config, "config"); + COMMAND_IMPL (init, init, "init"); + COMMAND_IMPL (sync, sync, "sync"); assert (false); fail << "unhandled command"; diff --git a/bdep/buildfile b/bdep/buildfile index abbd774..5afe7c2 100644 --- a/bdep/buildfile +++ b/bdep/buildfile @@ -20,7 +20,8 @@ common-options \ project-options \ help-options \ config-options \ -init-options +init-options \ +sync-options exe{bdep}: {hxx ixx txx cxx}{** -{$options_topics} -*-odb -version} \ {hxx ixx cxx}{$options_topics} \ @@ -53,6 +54,7 @@ if $cli.configured cli.cxx{config-options}: cli{config} cli.cxx{init-options}: cli{init} + cli.cxx{sync-options}: cli{sync} # Option length must be the same to get commands/topics/options aligned. # diff --git a/bdep/init.cli b/bdep/init.cli index 6e50f10..77c84a4 100644 --- a/bdep/init.cli +++ b/bdep/init.cli @@ -6,7 +6,7 @@ include ; "\section=1" "\name=bdep-init" -"\summary=initialize project dependency management" +"\summary=initialize project in configurations" namespace bdep { diff --git a/bdep/init.cxx b/bdep/init.cxx index 1e864eb..a86079f 100644 --- a/bdep/init.cxx +++ b/bdep/init.cxx @@ -4,18 +4,20 @@ #include -#include #include #include #include #include +#include +#include + using namespace std; namespace bdep { int - cmd_init (const cmd_init_options& o, cli::scanner& args) + cmd_init (const cmd_init_options& o, cli::scanner&) { tracer trace ("init"); @@ -39,7 +41,7 @@ namespace bdep // Open the database creating it if necessary. // - database db (open (pp.project, trace, true /* create */)); + database db (open (prj, trace, true /* create */)); // --empty // @@ -117,6 +119,7 @@ namespace bdep // Initialize each package in each configuration skipping those that are // already initialized. Do each configuration in a separate transaction so // that our state reflects the bpkg configuration as closely as possible. + // Then synchronize each configuration. // for (const shared_ptr& c: cfgs) { @@ -127,7 +130,7 @@ namespace bdep // run_bpkg (o, "add", - "-d", c->path, + "-d", c->path, "--type", "dir", prj); @@ -140,8 +143,10 @@ namespace bdep return p.name == s.name; }) != c->packages.end ()) { - info << "package " << p.name << " is already initialized " - << "in configuration " << *c; + if (verb) + info << "package " << p.name << " is already initialized " + << "in configuration " << *c; + continue; } @@ -150,6 +155,10 @@ namespace bdep db.update (c); t.commit (); + + //@@ --no-sync for some reason? + // + cmd_sync (o, prj, c); } //@@ TODO: print project/package(s) being initialized. diff --git a/bdep/project.cxx b/bdep/project.cxx index d3e3f11..ebc466c 100644 --- a/bdep/project.cxx +++ b/bdep/project.cxx @@ -181,7 +181,9 @@ namespace bdep } project_packages - find_project_packages (const project_options& po, bool ignore_packages) + find_project_packages (const project_options& po, + bool ignore_packages, + bool load_packages) { project_packages r; @@ -268,14 +270,7 @@ namespace bdep return d; }; - if (r.packages.empty ()) - { - // Name is to be extracted later. - // - for (package_manifest& m: ms) - r.packages.push_back (package_location {"", location (m)}); - } - else + if (!r.packages.empty ()) { // It could be costly to normalize the location for each // comparison. We, however, do not expect more than a handful of @@ -296,6 +291,13 @@ namespace bdep } } } + else if (load_packages) + { + // Name is to be extracted later. + // + for (package_manifest& m: ms) + r.packages.push_back (package_location {"", location (m)}); + } } else { diff --git a/bdep/project.hxx b/bdep/project.hxx index 2d0d3f1..16716ef 100644 --- a/bdep/project.hxx +++ b/bdep/project.hxx @@ -142,8 +142,12 @@ namespace bdep // Given the project options (and CWD) locate the packages and their // project. The result is an absolute and normalized project directory and a - // vector of relative (to the project directory) package locations (which - // will be empty if ignore_packages is true). + // vector of relative (to the project directory) package locations. + // + // If ignore_packages is true then ignore packages in case the resulting + // vector will be empty. Otherwise, if load_packages is false, then don't + // load all the available packages from packages.manifest if none were + // found/specified. // // Note that if the package directory is the same as project, then the // package path will be empty (and not ./). @@ -163,7 +167,9 @@ namespace bdep }; project_packages - find_project_packages (const project_options&, bool ignore_packages = false); + find_project_packages (const project_options&, + bool ignore_packages = false, + bool load_packages = true); } #endif // BDEP_PROJECT_HXX diff --git a/bdep/sync.cli b/bdep/sync.cli new file mode 100644 index 0000000..27c62ff --- /dev/null +++ b/bdep/sync.cli @@ -0,0 +1,39 @@ +// file : bdep/sync.cli +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +include ; + +"\section=1" +"\name=bdep-sync" +"\summary=synchronize project and configurations" + +namespace bdep +{ + { + " + + + ", + + "\h|SYNOPSIS| + + \c{\b{bdep sync} [] [] []} + + \c{ = \b{--directory}|\b{-d} \n + = (\b{--directory}|\b{-d} )... | \n + = (\b{@} | \b{--config}|\b{-c} )... | \b{--all}|\b{-a}} + + \h|DESCRIPTION| + + The \cb{sync} command..." + } + + // Note that not all project/configuration options are valid for all + // subcommands. + // + class cmd_sync_options: project_options + { + //"\h|SYNC OPTIONS|" + }; +} diff --git a/bdep/sync.cxx b/bdep/sync.cxx new file mode 100644 index 0000000..e84fa0f --- /dev/null +++ b/bdep/sync.cxx @@ -0,0 +1,105 @@ +// file : bdep/sync.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include + +using namespace std; + +namespace bdep +{ + void + cmd_sync (const common_options& co, + const dir_path& prj, + const shared_ptr& c) + { + assert (!c->packages.empty ()); + + // Prepare the pkg-spec. + // + string spec; + for (const package_state& p: c->packages) + { + if (!spec.empty ()) + spec += ','; + + spec += p.name; + } + + spec += '@'; + spec += prj.string (); + + run_bpkg (co, + "build", + "-d", c->path, + //"--fetch-shallow", + "--configure-only", + //"--keep-out", + spec); + } + + int + cmd_sync (const cmd_sync_options& o, cli::scanner&) + { + tracer trace ("sync"); + + // We could be running from a package directory (or the user specified one + // with -d) that has not been init'ed in this configuration. We want to + // diagnose that since such a package will not be present in the bpkg + // configuration. But if we are running from the project, then we don't + // want to treat all the available packages as specified by the user (thus + // load_packages=false). + // + project_packages pp ( + find_project_packages (o, + false /* ignore_packages */, + false /* load_packages */)); + + const dir_path& prj (pp.project); + + database db (open (prj, trace)); + + transaction t (db.begin ()); + configurations cfgs (find_configurations (prj, t, o)); + t.commit (); + + // If specified, verify packages are present in each configuration. + // + for (const shared_ptr& c: cfgs) + { + for (const package_location& p: pp.packages) + { + if (find_if (c->packages.begin (), + c->packages.end (), + [&p] (const package_state& s) + { + return p.name == s.name; + }) == c->packages.end ()) + { + fail << "package " << p.name << " is not initialized " + << "in configuration " << *c; + } + } + } + + // Synchronize each configuration skipping empty ones. + // + for (const shared_ptr& c: cfgs) + { + if (c->packages.empty ()) + { + if (verb) + info << "skipping empty configuration " << *c; + + continue; + } + + cmd_sync (o, prj, c); + } + + return 0; + } +} diff --git a/bdep/sync.hxx b/bdep/sync.hxx new file mode 100644 index 0000000..e1fa7fb --- /dev/null +++ b/bdep/sync.hxx @@ -0,0 +1,25 @@ +// file : bdep/sync.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BDEP_SYNC_HXX +#define BDEP_SYNC_HXX + +#include +#include + +#include +#include + +namespace bdep +{ + void + cmd_sync (const common_options&, + const dir_path& prj, + const shared_ptr&); + + int + cmd_sync (const cmd_sync_options&, cli::scanner& args); +} + +#endif // BDEP_SYNC_HXX diff --git a/doc/cli.sh b/doc/cli.sh index 0cca076..08b6ff6 100755 --- a/doc/cli.sh +++ b/doc/cli.sh @@ -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" +pages="config help init sync" for p in $pages; do compile $p $o -- cgit v1.1