1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// file : bpkg/cfg-info.cxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#include <bpkg/cfg-info.hxx>
#include <set>
#include <iostream> // cout
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
#include <bpkg/database.hxx>
#include <bpkg/diagnostics.hxx>
using namespace std;
namespace bpkg
{
int
cfg_info (const cfg_info_options& o, cli::scanner&)
{
tracer trace ("cfg_info");
dir_path c (o.directory ());
l4 ([&]{trace << "configuration: " << c;});
if (o.recursive () && !o.link () && !o.backlink ())
fail << "--recursive requires --link or --backlink";
try
{
cout.exceptions (ostream::badbit | ostream::failbit);
// Return false if the configuration information has already been
// printed and print the information and return true otherwise.
//
auto print = [first = true,
printed = set<dir_path> {}]
(const dir_path& path,
const uuid& uid,
const string& type,
const optional<string>& name) mutable
{
if (!printed.insert (path).second)
return false;
if (!first)
cout << endl;
else
first = false;
cout << "path: " << path << endl
<< "uuid: " << uid << endl
<< "type: " << type << endl
<< "name: " << (name ? *name : "") << endl;
return true;
};
using query = odb::query<configuration>;
query q (false);
if (o.link ())
q = q || query::expl;
if (o.backlink () || o.dangling ())
q = q || (!query::expl && query::id != 0);
// Make the output consistent across runs.
//
q = q + "ORDER BY" + query::id;
auto print_db = [&o, &q, &print] (database& db,
bool links,
const auto& print_db)
{
if (!print (db.config, db.uuid, db.type, db.name))
return;
if (links)
{
for (auto& c: db.query<configuration> (q))
{
const dir_path& d (c.make_effective_path (db.config));
auto print_link = [&o, &db, &c, &print_db] ()
{
database& ldb (db.attach (c.path));
db.verify_link (c, ldb);
// While at it, also verify the backlink.
//
if (c.expl)
db.backlink (ldb);
print_db (ldb, o.recursive (), print_db);
};
if (c.expl)
{
if (o.link ())
print_link ();
}
else if (exists (d))
{
if (o.backlink ())
print_link ();
}
else if (o.dangling ())
print (d, c.uuid, c.type, c.name);
}
}
};
database db (c, trace, false /* pre_attach */);
transaction t (db);
print_db (db, o.link () || o.backlink () || o.dangling (), print_db);
t.commit ();
}
catch (const io_error&)
{
fail << "unable to write to stdout";
}
return 0;
}
}
|