From 9664d2849ee30d63cd10ce5b258f1433a650b488 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 21 Jul 2021 21:31:18 +0300 Subject: Add support for automatic creation of configurations for build-time dependencies --- bdep/init.cxx | 119 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 40 deletions(-) (limited to 'bdep/init.cxx') diff --git a/bdep/init.cxx b/bdep/init.cxx index 2dbc1bb..a8d0658 100644 --- a/bdep/init.cxx +++ b/bdep/init.cxx @@ -94,7 +94,9 @@ namespace bdep const configurations& cfgs, const package_locations& pkgs, const strings& pkg_args, - bool sync) + bool sync, + bool create_host_config, + bool create_build2_config) { // Return true if a package is initialized in the specified configuration. // @@ -208,55 +210,90 @@ namespace bdep "--type", "dir", prj); - transaction t (db.begin ()); - - // Reload the configuration object that could have been changed during - // verification. This is required for skipping the already initialized - // packages. - // - db.reload (*c); + vector> created_cfgs; - for (const package_location& p: pkgs) + try { - if (initialized (p, c)) + transaction t (db.begin ()); + + // Reload the configuration object that could have been changed during + // verification. This is required for skipping the already initialized + // packages. + // + db.reload (*c); + + for (const package_location& p: pkgs) { - if (verb) - info << "package " << p.name << " is already initialized"; + if (initialized (p, c)) + { + if (verb) + info << "package " << p.name << " is already initialized"; + + continue; + } + + // If we are initializing multiple packages or there will be no sync, + // print their names. + // + if (verb && (pkgs.size () > 1 || !sync)) + text << "initializing package " << p.name; - continue; + c->packages.push_back (package_state {p.name}); } - // If we are initializing multiple packages or there will be no sync, - // print their names. + // Should we sync then commit the database or commit and then sync? + // Either way we can end up with an inconsistent state. Note, however, + // that the state in the build configuration can in most cases be + // corrected with a retry (e.g., "upgrade" the package to the fixed + // version, etc) while if we think (from the database state) that the + // package has already been initialized, then there will be no way to + // retry anything (though it could probably be corrected with a sync + // or, failed that, deinit/init). + // + // However, there is a drawback to doing it this way: if we trigger an + // implicit sync (e.g., via a hook) of something that uses the same + // database, we will get the "database is used by another process" + // error. This can be worked around by disabling the implicit sync + // (BDEP_SYNC=0). + // + // Note: semantically equivalent to the first form of the sync + // command. // - if (verb && (pkgs.size () > 1 || !sync)) - text << "initializing package " << p.name; + if (sync) + cmd_sync (o, + prj, + c, + pkg_args, + false /* implicit */, + true /* fetch */, + true /* yes */, + false /* name_cfg */, + create_host_config, + create_build2_config, + &t, + &created_cfgs); - c->packages.push_back (package_state {p.name}); + db.update (c); + t.commit (); } + catch (const failed&) + { + if (!created_cfgs.empty ()) + { + transaction t (db.begin ()); - // Should we sync then commit the database or commit and then sync? - // Either way we can end up with an inconsistent state. Note, however, - // that the state in the build configuration can in most cases be - // corrected with a retry (e.g., "upgrade" the package to the fixed - // version, etc) while if we think (from the database state) that the - // package has already been initialized, then there will be no way to - // retry anything (though it could probably be corrected with a sync or, - // failed that, deinit/init). - // - // However, there is a drawback to doing it this way: if we trigger an - // implicit sync (e.g., via a hook) of something that uses the same - // database, we will get the "database is used by another process" - // error. This can be worked around by disabling the implicit sync - // (BDEP_SYNC=0). - // - // Note: semantically equivalent to the first form of the sync command. - // - if (sync) - cmd_sync (o, prj, c, pkg_args, false /* implicit */); + for (const auto& c: created_cfgs) + cmd_config_add (prj, + t, + c.first /* path */, + c.second /* name */, + c.second /* type */); - db.update (c); - t.commit (); + t.commit (); + } + + throw; + } } } @@ -372,7 +409,9 @@ namespace bdep cfgs, pp.packages, scan_arguments (args) /* pkg_args */, - !o.no_sync ()); + !o.no_sync (), + o.create_host_config (), + o.create_build2_config ()); return 0; } -- cgit v1.1