aboutsummaryrefslogtreecommitdiff
path: root/bdep/status.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-03-15 15:24:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-03-15 15:24:48 +0200
commit4f6abb0576e810b37d56ad3cafc67fac84682ec2 (patch)
treea8dbf336cea736b99a7ece1cb1e32b985e9f7934 /bdep/status.cxx
parentb44b4088f48a27bff88f8f010b8cd42303cbdad0 (diff)
Implement status command
Diffstat (limited to 'bdep/status.cxx')
-rw-r--r--bdep/status.cxx147
1 files changed, 147 insertions, 0 deletions
diff --git a/bdep/status.cxx b/bdep/status.cxx
new file mode 100644
index 0000000..ade5381
--- /dev/null
+++ b/bdep/status.cxx
@@ -0,0 +1,147 @@
+// file : bdep/status.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <bdep/status.hxx>
+
+#include <bdep/project.hxx>
+#include <bdep/project-odb.hxx>
+#include <bdep/database.hxx>
+#include <bdep/diagnostics.hxx>
+
+#include <bdep/fetch.hxx>
+
+using namespace std;
+
+namespace bdep
+{
+ static void
+ cmd_status (const cmd_status_options& o,
+ const dir_path& prj,
+ const dir_path& cfg,
+ const cstrings& pkgs,
+ bool fetch)
+ {
+ // Shallow fetch the project to make sure we show latest iterations and
+ // pick up any new repositories.
+ //
+ // We do it in a separate command for the same reason as in sync.
+ //
+ if (fetch)
+ run_bpkg (o,
+ "fetch",
+ "-d", cfg,
+ "--shallow",
+ "dir:" + prj.string ());
+
+ run_bpkg (o,
+ "status",
+ "-d", cfg,
+ (o.immediate () ? "--immediate" :
+ o.recursive () ? "--recursive" :
+ nullptr),
+ pkgs);
+ }
+
+ static void
+ cmd_status (const cmd_status_options& o,
+ const dir_path& prj,
+ const shared_ptr<configuration>& c,
+ const package_locations& ps,
+ bool fetch)
+ {
+ assert (!c->packages.empty ());
+
+ // If no packages were explicitly specified, then we print the status for
+ // all that have been initialized in the configuration.
+ //
+ cstrings pkgs;
+
+ if (ps.empty ())
+ {
+ for (const package_state& p: c->packages)
+ pkgs.push_back (p.name.c_str ());
+ }
+ else
+ {
+ for (const package_location& p: ps)
+ pkgs.push_back (p.name.c_str ());
+ }
+
+ cmd_status (o, prj, c->path, pkgs, fetch);
+ }
+
+ int
+ cmd_status (const cmd_status_options& o, cli::scanner& args)
+ {
+ tracer trace ("status");
+
+ if (o.immediate () && o.recursive ())
+ fail << "both --immediate|-i and --recursive|-r specified";
+
+ // We have two pretty different modes: project status and dependency
+ // status (have arguments).
+ //
+ cstrings pkgs;
+ for (; args.more (); pkgs.push_back (args.next ())) ;
+
+ // For the project status the same story as in sync.
+ //
+ project_packages pp (
+ find_project_packages (o,
+ !pkgs.empty () /* 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.
+ //
+ if (!pp.packages.empty ())
+ verify_project_packages (pp, cfgs);
+
+ // Print status in each configuration skipping empty ones.
+ //
+ bool first (true);
+ for (const shared_ptr<configuration>& c: cfgs)
+ {
+ if (c->packages.empty ())
+ {
+ if (verb)
+ info << "skipping empty configuration " << *c;
+
+ continue;
+ }
+
+ // If we are printing multiple configurations, separate them with a
+ // blank line and print the configuration name/directory.
+ //
+ if (verb && cfgs.size () > 1)
+ {
+ text << (first ? "" : "\n")
+ << "status in configuration " << *c;
+
+ first = false;
+ }
+
+ bool fetch (o.fetch () || o.fetch_full ());
+
+ if (fetch)
+ cmd_fetch (o, prj, c, o.fetch_full ());
+
+ // Don't re-fetch if we just fetched.
+ //
+ if (pkgs.empty ())
+ cmd_status (o, prj, c, pp.packages, !fetch);
+ else
+ cmd_status (o, prj, c->path, pkgs, !fetch);
+ }
+
+ return 0;
+ }
+}