summaryrefslogtreecommitdiff
path: root/apt-private
diff options
context:
space:
mode:
authorSam Bingner <sam@bingner.com>2019-12-30 16:31:01 -1000
committerSam Bingner <sam@bingner.com>2019-12-30 23:10:02 -1000
commitbfe83a62a27bbe8ee960749ff78735a91624f05a (patch)
treef3b15533444d7313d6118ad2deb4007e05844f05 /apt-private
parent343cbbac912d9de5c72388bfc4c3bbbcb81506df (diff)
Add support for JSON output
Diffstat (limited to 'apt-private')
-rw-r--r--apt-private/CMakeLists.txt4
-rw-r--r--apt-private/private-output.mm (renamed from apt-private/private-output.cc)163
2 files changed, 161 insertions, 6 deletions
diff --git a/apt-private/CMakeLists.txt b/apt-private/CMakeLists.txt
index 88a8f97fe..4a6ea51b8 100644
--- a/apt-private/CMakeLists.txt
+++ b/apt-private/CMakeLists.txt
@@ -5,14 +5,14 @@ set(MINOR 0)
# Definition of the C++ files used to build the library - note that this
# is expanded at CMake time, so you have to rerun cmake if you add or remove
# a file (you can just run cmake . in the build directory)
-file(GLOB_RECURSE library "*.cc")
+file(GLOB_RECURSE library "*.cc" "*.mm")
file(GLOB_RECURSE headers "*.h")
# Create a library using the C++ files
add_library(apt-private SHARED ${library})
# Link the library and set the SONAME
-target_link_libraries(apt-private PUBLIC apt-pkg)
+target_link_libraries(apt-private PUBLIC apt-pkg "-framework Foundation")
set_target_properties(apt-private PROPERTIES VERSION ${MAJOR}.${MINOR})
set_target_properties(apt-private PROPERTIES SOVERSION ${MAJOR})
set_target_properties(apt-private PROPERTIES CXX_VISIBILITY_PRESET hidden)
diff --git a/apt-private/private-output.cc b/apt-private/private-output.mm
index eb9a34abe..2cf3dc656 100644
--- a/apt-private/private-output.cc
+++ b/apt-private/private-output.mm
@@ -1,6 +1,8 @@
// Include files /*{{{*/
#include <config.h>
+#include <Foundation/Foundation.h>
+
#include <apt-pkg/cachefile.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/depcache.h>
@@ -443,15 +445,150 @@ static void ShowBrokenPackage(ostream &out, pkgCacheFile * const Cache, pkgCache
}
}
}
+
+static NSMutableDictionary * BrokenPackage(ostream &out, pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg, bool const Now)
+{
+ if (Now == true)
+ {
+ if ((*Cache)[Pkg].NowBroken() == false)
+ return nil;
+ }
+ else
+ {
+ if ((*Cache)[Pkg].InstBroken() == false)
+ return nil;
+ }
+
+ NSMutableDictionary *packages = [NSMutableDictionary dictionary];
+
+ // Array of depends for package
+ NSMutableArray *deps = [NSMutableArray array];
+
+ // Print out each package and the failed dependencies
+ packages[@(Pkg.FullName(true).c_str())] = deps;
+
+ pkgCache::VerIterator Ver;
+
+ if (Now == true)
+ Ver = Pkg.CurrentVer();
+ else
+ Ver = (*Cache)[Pkg].InstVerIter(*Cache);
+
+ if (Ver.end() == true)
+ {
+ return packages;
+ }
+
+ for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
+ {
+ // Compute a single dependency element (glob or)
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End); // advances D
+
+ if ((*Cache)->IsImportantDep(End) == false)
+ continue;
+
+ if (Now == true)
+ {
+ if (((*Cache)[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
+ continue;
+ }
+ else
+ {
+ if (((*Cache)[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
+ continue;
+ }
+
+ // Array of depends that can satisfy this depend
+ NSMutableArray *possibleDepends = [NSMutableArray array];
+ [deps addObject:possibleDepends];
+
+ while (1)
+ {
+
+ NSMutableDictionary *dependency = [NSMutableDictionary dictionary];
+ dependency[@"Type"] = @(End.DepType());
+ dependency[@"Package"] = @(Start.TargetPkg().FullName(true).c_str());
+
+ // Show a quick summary of the version requirements
+ if (Start.TargetVer() != 0) {
+ dependency[@"VersionSummary"] = [NSString stringWithFormat:@"%s %s", Start.CompType(), Start.TargetVer()];
+ dependency[@"CompType"] = @(Start.CompType());
+ dependency[@"TargetVer"] = @(Start.TargetVer());
+ }
+
+ /* Show a summary of the target package if possible. In the case
+ of virtual packages we show nothing */
+ pkgCache::PkgIterator Targ = Start.TargetPkg();
+ if (Targ->ProvidesList == 0)
+ {
+ pkgCache::VerIterator Ver = (*Cache)[Targ].InstVerIter(*Cache);
+ if (Now == true)
+ Ver = Targ.CurrentVer();
+
+ if (Ver.end() == false)
+ {
+ dependency[@"VerStr"] = @(Ver.VerStr());
+ if (Now == true)
+ dependency[@"Reason"] = [NSString stringWithFormat:@"%s is installed",Ver.VerStr()];
+ else
+ dependency[@"Reason"] = [NSString stringWithFormat:@"%s is to be installed",Ver.VerStr()];
+ }
+ else
+ {
+ if ((*Cache)[Targ].CandidateVerIter(*Cache).end() == true)
+ {
+ if (Targ->ProvidesList == 0)
+ dependency[@"Reason"] = @"it is not installable";
+ else
+ dependency[@"Reason"] = @"it is a virtual package";
+ }
+ else {
+ if (Now)
+ dependency[@"Reason"] = @"it is not installed";
+ else
+ dependency[@"Reason"] = @"it is not going to be installed";
+ }
+ }
+ }
+
+ [possibleDepends addObject:dependency];
+ if (Start == End)
+ break;
+ ++Start;
+ }
+ }
+ return packages;
+}
+
void ShowBroken(ostream &out, CacheFile &Cache, bool const Now)
{
if (Cache->BrokenCount() == 0)
return;
out << _("The following packages have unmet dependencies:") << endl;
+
+ bool useJSON = _config->FindB("APT::Format::JSON", false);
+
SortedPackageUniverse Universe(Cache);
- for (auto const &Pkg: Universe)
- ShowBrokenPackage(out, &Cache, Pkg, Now);
+
+ if (useJSON){
+ NSMutableDictionary *packages = [NSMutableDictionary dictionary];
+ for (auto const &Pkg: Universe){
+ NSMutableDictionary *package = BrokenPackage(out, &Cache, Pkg, Now);
+ [packages addEntriesFromDictionary:package];
+ }
+
+ NSData *data = [NSJSONSerialization dataWithJSONObject:@{@"brokenPackages": packages} options:NSJSONWritingPrettyPrinted error:nil];
+ NSFileHandle *stdout = [NSFileHandle fileHandleWithStandardOutput];
+ [stdout writeData:data];
+
+ cout << endl << flush;
+ } else {
+ for (auto const &Pkg: Universe)
+ ShowBrokenPackage(out, &Cache, Pkg, Now);
+ }
}
void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
{
@@ -459,9 +596,27 @@ void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
return;
out << _("The following packages have unmet dependencies:") << endl;
+
+ bool useJSON = _config->FindB("APT::Format::JSON", false);
+
APT::PackageUniverse Universe(Cache);
- for (auto const &Pkg: Universe)
- ShowBrokenPackage(out, &Cache, Pkg, Now);
+
+ if (useJSON){
+ NSMutableDictionary *packages = [NSMutableDictionary dictionary];
+ for (auto const &Pkg: Universe){
+ NSMutableDictionary *package = BrokenPackage(out, &Cache, Pkg, Now);
+ [packages addEntriesFromDictionary:package];
+ }
+
+ NSData *data = [NSJSONSerialization dataWithJSONObject:@{@"brokenPackages": packages} options:NSJSONWritingPrettyPrinted error:nil];
+ NSFileHandle *stdout = [NSFileHandle fileHandleWithStandardOutput];
+ [stdout writeData:data];
+
+ cout << endl << flush;
+ } else {
+ for (auto const &Pkg: Universe)
+ ShowBrokenPackage(out, &Cache, Pkg, Now);
+ }
}
/*}}}*/
// ShowNew - Show packages to newly install /*{{{*/