[haiku-commits] BRANCH HaikuPM-github.package-management - src/bin/pkgman src/kits/package/solver headers/os/package/solver

  • From: HaikuPM-github.package-management <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 11 Apr 2013 17:45:34 +0200 (CEST)

added 4 changesets to branch 'refs/remotes/HaikuPM-github/package-management'
old head: 62f7022a8294bbd5407826c0bb8b071975ed90d5
new head: dd46d9816332a8936534aeeb26613c5269b75a6a
overview: https://github.com/haiku/HaikuPM/compare/62f7022...dd46d98

----------------------------------------------------------------------------

a78a254: LibsolvSolver: Fix the lazy re-/initialization
  
  * _Init() was a bit too enthusiastic, throwing really everything away.
    So, after calling it at the beginning of _AddRepositories() there
    wouldn't be any repositories anymore.
  * Rename _Init() to _InitPool() to make its purpose clearer.
  * Pull a _CleanupPool() out of _Cleanup() that only deletes the pool
    and anything depending on it.
  * RepositoryInfo::HasChanged(): Always consider changed when there's no
    libsolv repo yet.

fc57db4: BSolver/LibsolvSolver: Add FindPackages()
  
  Given a search string it finds all matching packages.

7898675: pkgman RepositoryBuilder: Add BRepositoryConfig constructor

dd46d98: pkgman: Add "search" command

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

9 files changed, 390 insertions(+), 11 deletions(-)
headers/os/package/solver/Solver.h        |  14 ++
src/bin/pkgman/Jamfile                    |   1 +
src/bin/pkgman/RepositoryBuilder.cpp      |  13 ++
src/bin/pkgman/RepositoryBuilder.h        |   2 +
src/bin/pkgman/command_search.cpp         | 247 ++++++++++++++++++++++++++
src/bin/pkgman/pkgman.cpp                 |   7 +-
src/bin/pkgman/pkgman.h                   |   3 +-
src/kits/package/solver/LibsolvSolver.cpp | 106 ++++++++++-
src/kits/package/solver/LibsolvSolver.h   |   8 +-

############################################################################

Commit:      a78a2540a820ca541177fce1d454d3aa7073715c
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu Apr 11 15:21:27 2013 UTC

LibsolvSolver: Fix the lazy re-/initialization

* _Init() was a bit too enthusiastic, throwing really everything away.
  So, after calling it at the beginning of _AddRepositories() there
  wouldn't be any repositories anymore.
* Rename _Init() to _InitPool() to make its purpose clearer.
* Pull a _CleanupPool() out of _Cleanup() that only deletes the pool
  and anything depending on it.
* RepositoryInfo::HasChanged(): Always consider changed when there's no
  libsolv repo yet.

----------------------------------------------------------------------------

diff --git a/src/kits/package/solver/LibsolvSolver.cpp 
b/src/kits/package/solver/LibsolvSolver.cpp
index af536af..2a2926f 100644
--- a/src/kits/package/solver/LibsolvSolver.cpp
+++ b/src/kits/package/solver/LibsolvSolver.cpp
@@ -62,7 +62,7 @@ struct LibsolvSolver::RepositoryInfo {
                :
                fRepository(repository),
                fSolvRepo(NULL),
-               fChangeCount(repository->ChangeCount() - 1)
+               fChangeCount(repository->ChangeCount())
        {
        }
 
@@ -83,7 +83,7 @@ struct LibsolvSolver::RepositoryInfo {
 
        bool HasChanged() const
        {
-               return fChangeCount != fRepository->ChangeCount();
+               return fChangeCount != fRepository->ChangeCount() || fSolvRepo 
== NULL;
        }
 
        void SetUnchanged()
@@ -162,6 +162,8 @@ LibsolvSolver::~LibsolvSolver()
 status_t
 LibsolvSolver::Init()
 {
+       _Cleanup();
+
        // We do all initialization lazily.
        return B_OK;
 }
@@ -370,9 +372,9 @@ LibsolvSolver::GetResult(BSolverResult& _result)
 
 
 status_t
-LibsolvSolver::_Init()
+LibsolvSolver::_InitPool()
 {
-       _Cleanup();
+       _CleanupPool();
 
        fPool = pool_create();
 
@@ -403,12 +405,28 @@ LibsolvSolver::_Init()
 void
 LibsolvSolver::_Cleanup()
 {
-       _CleanupSolver();
+       _CleanupPool();
 
-       fSolvablePackages.clear();
        fInstalledRepository = NULL;
        fRepositoryInfos.MakeEmpty();
 
+}
+
+
+void
+LibsolvSolver::_CleanupPool()
+{
+       // clean up solver data
+       _CleanupSolver();
+
+       // clean up our data structures that depend on/refer to libsolv pool 
data
+       fSolvablePackages.clear();
+
+       int32 repositoryCount = fRepositoryInfos.CountItems();
+       for (int32 i = 0; i < repositoryCount; i++)
+               fRepositoryInfos.ItemAt(i)->SetSolvRepo(NULL);
+
+       // delete the pool
        if (fPool != NULL) {
                pool_free(fPool);
                fPool = NULL;
@@ -449,7 +467,7 @@ LibsolvSolver::_AddRepositories()
                return B_OK;
 
        // something has changed -- re-create the pool
-       status_t error = _Init();
+       status_t error = _InitPool();
        if (error != B_OK)
                return error;
 
diff --git a/src/kits/package/solver/LibsolvSolver.h 
b/src/kits/package/solver/LibsolvSolver.h
index 81f99eb..5ae1602 100644
--- a/src/kits/package/solver/LibsolvSolver.h
+++ b/src/kits/package/solver/LibsolvSolver.h
@@ -55,8 +55,9 @@ private:
                        typedef std::map<Solvable*, BSolverPackage*> 
SolvableMap;
 
 private:
-                       status_t                        _Init();
+                       status_t                        _InitPool();
                        void                            _Cleanup();
+                       void                            _CleanupPool();
                        void                            _CleanupSolver();
 
                        bool                            
_HaveRepositoriesChanged() const;

############################################################################

Commit:      fc57db481fa36695457bc355ca9710c91d53ab1d
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu Apr 11 15:30:08 2013 UTC

BSolver/LibsolvSolver: Add FindPackages()

Given a search string it finds all matching packages.

----------------------------------------------------------------------------

diff --git a/headers/os/package/solver/Solver.h 
b/headers/os/package/solver/Solver.h
index 2f1160b..5403baa 100644
--- a/headers/os/package/solver/Solver.h
+++ b/headers/os/package/solver/Solver.h
@@ -6,12 +6,14 @@
 #define _PACKAGE__SOLVER_H_
 
 
+#include <ObjectList.h>
 #include <SupportDefs.h>
 
 
 namespace BPackageKit {
 
 
+class BSolverPackage;
 class BSolverPackageSpecifierList;
 class BSolverProblem;
 class BSolverRepository;
@@ -20,6 +22,14 @@ class BSolverResult;
 
 class BSolver {
 public:
+                       // FindPackages() flags
+                       enum {
+                               B_FIND_CASE_INSENSITIVE         = 0x01,
+                               B_FIND_IN_SUMMARY                       = 0x02,
+                               B_FIND_IN_DESCRIPTION           = 0x04
+                       };
+
+public:
        virtual                                         ~BSolver();
 
        static  status_t                        Create(BSolver*& _solver);
@@ -29,6 +39,10 @@ public:
        virtual status_t                        AddRepository(
                                                                        
BSolverRepository* repository) = 0;
 
+       virtual status_t                        FindPackages(const char* 
searchString,
+                                                                       uint32 
flags,
+                                                                       
BObjectList<BSolverPackage>& _packages) = 0;
+
        virtual status_t                        Install(
                                                                        const 
BSolverPackageSpecifierList&
                                                                                
packages) = 0;
diff --git a/src/kits/package/solver/LibsolvSolver.cpp 
b/src/kits/package/solver/LibsolvSolver.cpp
index 2a2926f..a1ab43c 100644
--- a/src/kits/package/solver/LibsolvSolver.cpp
+++ b/src/kits/package/solver/LibsolvSolver.cpp
@@ -57,6 +57,20 @@ struct LibsolvSolver::SolvQueue : Queue {
 };
 
 
+struct LibsolvSolver::SolvDataIterator : Dataiterator {
+       SolvDataIterator(Pool* pool, Repo* repo, Id solvableId, Id keyname,
+               const char* match, int flags)
+       {
+               dataiterator_init(this, pool, repo, solvableId, keyname, match, 
flags);
+       }
+
+       ~SolvDataIterator()
+       {
+               dataiterator_free(this);
+       }
+};
+
+
 struct LibsolvSolver::RepositoryInfo {
        RepositoryInfo(BSolverRepository* repository)
                :
@@ -198,6 +212,66 @@ LibsolvSolver::AddRepository(BSolverRepository* repository)
 
 
 status_t
+LibsolvSolver::FindPackages(const char* searchString, uint32 flags,
+       BObjectList<BSolverPackage>& _packages)
+{
+       // add repositories to pool
+       status_t error = _AddRepositories();
+       if (error != B_OK)
+               return error;
+
+       // create data iterator
+       int iteratorFlags = SEARCH_SUBSTRING;
+       if ((flags & B_FIND_CASE_INSENSITIVE) != 0)
+               iteratorFlags |= SEARCH_NOCASE;
+
+       SolvDataIterator iterator(fPool, 0, 0, 0, searchString, iteratorFlags);
+
+       // search package names
+       dataiterator_set_keyname(&iterator, SOLVABLE_NAME);
+       dataiterator_set_search(&iterator, 0, 0);
+
+       SolvQueue selection;
+       while (dataiterator_step(&iterator))
+               queue_push2(&selection, SOLVER_SOLVABLE, iterator.solvid);
+
+       // search package summaries
+       if ((flags & B_FIND_IN_SUMMARY) != 0) {
+               dataiterator_set_keyname(&iterator, SOLVABLE_SUMMARY);
+               dataiterator_set_search(&iterator, 0, 0);
+
+               while (dataiterator_step(&iterator))
+                       queue_push2(&selection, SOLVER_SOLVABLE, 
iterator.solvid);
+       }
+
+       // search package description
+       if ((flags & B_FIND_IN_DESCRIPTION) != 0) {
+               dataiterator_set_keyname(&iterator, SOLVABLE_DESCRIPTION);
+               dataiterator_set_search(&iterator, 0, 0);
+
+               while (dataiterator_step(&iterator))
+                       queue_push2(&selection, SOLVER_SOLVABLE, 
iterator.solvid);
+       }
+
+       // get solvables        
+       SolvQueue solvables;
+       selection_solvables(fPool, &selection, &solvables);
+
+       // get packages
+       for (int i = 0; i < solvables.count; i++) {
+               BSolverPackage* package = _GetPackage(solvables.elements[i]);
+               if (package == NULL)
+                       return B_ERROR;
+
+               if (!_packages.AddItem(package))
+                       return B_NO_MEMORY;
+       }
+
+       return B_OK;
+}
+
+
+status_t
 LibsolvSolver::Install(const BSolverPackageSpecifierList& packages)
 {
        if (packages.IsEmpty())
diff --git a/src/kits/package/solver/LibsolvSolver.h 
b/src/kits/package/solver/LibsolvSolver.h
index 5ae1602..eaecd8f 100644
--- a/src/kits/package/solver/LibsolvSolver.h
+++ b/src/kits/package/solver/LibsolvSolver.h
@@ -34,6 +34,10 @@ public:
 
        virtual status_t                        
AddRepository(BSolverRepository* repository);
 
+       virtual status_t                        FindPackages(const char* 
searchString,
+                                                                       uint32 
flags,
+                                                                       
BObjectList<BSolverPackage>& _packages);
+
        virtual status_t                        Install(
                                                                        const 
BSolverPackageSpecifierList&
                                                                                
packages);
@@ -46,6 +50,7 @@ public:
 
 private:
                        struct SolvQueue;
+                       struct SolvDataIterator;
                        struct RepositoryInfo;
                        struct Problem;
                        struct Solution;

############################################################################

Commit:      789867563ad6e4730b470bfe2b8b7314aa671756
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu Apr 11 15:32:17 2013 UTC

pkgman RepositoryBuilder: Add BRepositoryConfig constructor

----------------------------------------------------------------------------

diff --git a/src/bin/pkgman/RepositoryBuilder.cpp 
b/src/bin/pkgman/RepositoryBuilder.cpp
index a307533..1b7e0e9 100644
--- a/src/bin/pkgman/RepositoryBuilder.cpp
+++ b/src/bin/pkgman/RepositoryBuilder.cpp
@@ -34,6 +34,19 @@ RepositoryBuilder::RepositoryBuilder(BSolverRepository& 
repository,
 }
 
 
+RepositoryBuilder::RepositoryBuilder(BSolverRepository& repository,
+       const BRepositoryConfig& config)
+       :
+       fRepository(repository),
+       fErrorName(fRepository.Name()),
+       fPackagePaths(NULL)
+{
+       status_t error = fRepository.SetTo(config);
+       if (error != B_OK)
+               DIE(error, "failed to init %s repository", fErrorName.String());
+}
+
+
 RepositoryBuilder&
 RepositoryBuilder::SetPackagePathMap(PackagePathMap* packagePaths)
 {
diff --git a/src/bin/pkgman/RepositoryBuilder.h 
b/src/bin/pkgman/RepositoryBuilder.h
index 0b9e72a..d3c72ad 100644
--- a/src/bin/pkgman/RepositoryBuilder.h
+++ b/src/bin/pkgman/RepositoryBuilder.h
@@ -31,6 +31,8 @@ public:
                                                                
RepositoryBuilder(BSolverRepository& repository,
                                                                        const 
BString& name,
                                                                        const 
BString& errorName = BString());
+                                                               
RepositoryBuilder(BSolverRepository& repository,
+                                                                       const 
BRepositoryConfig& config);
 
                        RepositoryBuilder&      
SetPackagePathMap(PackagePathMap* packagePaths);
 

############################################################################

Commit:      dd46d9816332a8936534aeeb26613c5269b75a6a
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu Apr 11 15:33:23 2013 UTC

pkgman: Add "search" command

----------------------------------------------------------------------------

diff --git a/src/bin/pkgman/Jamfile b/src/bin/pkgman/Jamfile
index db1206a..de9b873 100644
--- a/src/bin/pkgman/Jamfile
+++ b/src/bin/pkgman/Jamfile
@@ -8,6 +8,7 @@ BinCommand pkgman :
        command_list_repos.cpp
        command_refresh.cpp
        command_resolve_dependencies.cpp
+       command_search.cpp
        DecisionProvider.cpp
        JobStateListener.cpp
        PackageInfoErrorListener.cpp
diff --git a/src/bin/pkgman/command_search.cpp 
b/src/bin/pkgman/command_search.cpp
new file mode 100644
index 0000000..069489e
--- /dev/null
+++ b/src/bin/pkgman/command_search.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <package/PackageRoster.h>
+#include <package/RepositoryConfig.h>
+
+#include <AutoDeleter.h>
+
+#include "pkgman.h"
+#include "RepositoryBuilder.h"
+
+
+// TODO: internationalization!
+// The printing code will need serious attention wrt. dealing with UTF-8 and,
+// even worse, full-width characters.
+
+
+using namespace BPackageKit;
+
+
+typedef std::map<BSolverPackage*, BString> PackagePathMap;
+
+
+static const char* kCommandUsage =
+       "Usage: %s search <search-string>\n"
+       "Searches for packages matching <search-string>.\n"
+       "\n"
+       "Options:\n"
+       "  -i, --installed-only\n"
+       "    Only find installed packages.\n"
+       "  -u, --uninstalled-only\n"
+       "    Only find not installed packages.\n"
+       "\n"
+;
+
+
+static void
+print_command_usage_and_exit(bool error)
+{
+    fprintf(error ? stderr : stdout, kCommandUsage, kProgramName);
+    exit(error ? 1 : 0);
+}
+
+
+static int
+get_terminal_width()
+{
+    int fd = fileno(stdout);
+    struct winsize windowSize;
+       if (isatty(fd) == 1 && ioctl(fd, TIOCGWINSZ, &windowSize) == 0)
+               return windowSize.ws_col;
+       
+    return INT_MAX;
+}
+
+
+int
+command_search(int argc, const char* const* argv)
+{
+       bool installedOnly = false;
+       bool uninstalledOnly = false;
+
+       while (true) {
+               static struct option sLongOptions[] = {
+                       { "help", no_argument, 0, 'h' },
+                       { "installed-only", no_argument, 0, 'i' },
+                       { "uninstalled-only", no_argument, 0, 'u' },
+                       { 0, 0, 0, 0 }
+               };
+
+               opterr = 0; // don't print errors
+               int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, 
NULL);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+                       case 'h':
+                               print_command_usage_and_exit(false);
+                               break;
+
+                       case 'i':
+                               installedOnly = true;
+                               uninstalledOnly = false;
+                               break;
+
+                       case 'u':
+                               uninstalledOnly = true;
+                               installedOnly = false;
+                               break;
+
+                       default:
+                               print_command_usage_and_exit(true);
+                               break;
+               }
+       }
+
+       // The remaining argument is the search string.
+       if (argc != optind + 1)
+               print_command_usage_and_exit(true);
+
+       const char* searchString = argv[optind++];
+
+       // create the solver
+       BSolver* solver;
+       status_t error = BSolver::Create(solver);
+       if (error != B_OK)
+               DIE(error, "failed to create solver");
+
+       // add repositories
+
+       // installed
+       BSolverRepository systemRepository;
+       BSolverRepository commonRepository;
+       BSolverRepository homeRepository;
+       if (!uninstalledOnly) {
+               RepositoryBuilder(systemRepository, "system")
+                       .AddPackages(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, 
"system")
+                       .AddToSolver(solver, false);
+               RepositoryBuilder(commonRepository, "common")
+                       .AddPackages(B_PACKAGE_INSTALLATION_LOCATION_COMMON, 
"common")
+                       .AddToSolver(solver, false);
+//             RepositoryBuilder(homeRepository, "home")
+//                     .AddPackages(B_PACKAGE_INSTALLATION_LOCATION_HOME, 
"home")
+//                     .AddToSolver(solver, false);
+       }
+
+       // not installed
+       BObjectList<BSolverRepository> uninstalledRepositories(10, true);
+
+       if (!installedOnly) {
+               BPackageRoster roster;
+               BStringList repositoryNames;
+               error = roster.GetRepositoryNames(repositoryNames);
+               if (error != B_OK)
+                       WARN(error, "failed to get repository names");
+
+               int32 repositoryNameCount = repositoryNames.CountStrings();
+               for (int32 i = 0; i < repositoryNameCount; i++) {
+                       const BString& name = repositoryNames.StringAt(i);
+                       BRepositoryConfig config;
+                       error = roster.GetRepositoryConfig(name, &config);
+                       if (error != B_OK) {
+                               WARN(error, "failed to get config for 
repository \"%s\". "
+                                       "Skipping.", name.String());
+                               continue;
+                       }
+
+                       BSolverRepository* repository = new(std::nothrow) 
BSolverRepository;
+                       if (repository == NULL
+                               || 
!uninstalledRepositories.AddItem(repository)) {
+                               DIE(B_NO_MEMORY, "out of memory");
+                       }
+
+                       RepositoryBuilder(*repository, config)
+                               .AddToSolver(solver, false);
+               }
+       }
+
+       // search
+       BObjectList<BSolverPackage> packages;
+       error = solver->FindPackages(searchString,
+               BSolver::B_FIND_CASE_INSENSITIVE | BSolver::B_FIND_IN_SUMMARY
+                       | BSolver::B_FIND_IN_DESCRIPTION, packages);
+       if (error != B_OK)
+               DIE(error, "searching packages failed");
+
+       if (packages.IsEmpty()) {
+               printf("No matching packages found.\n");
+               return 0;
+       }
+
+       // print table
+
+       // determine column widths
+       BString installedColumnTitle("Installed");
+       BString nameColumnTitle("Name");
+       BString descriptionColumnTitle("Description");
+
+       int installedColumnWidth = installedColumnTitle.Length();
+       int nameColumnWidth = nameColumnTitle.Length();
+       int descriptionColumnWidth = descriptionColumnTitle.Length();
+
+       int32 packageCount = packages.CountItems();
+       for (int32 i = 0; i < packageCount; i++) {
+               BSolverPackage* package = packages.ItemAt(i);
+               nameColumnWidth = std::max(nameColumnWidth,
+                       (int)package->Name().Length());
+               descriptionColumnWidth = std::max(descriptionColumnWidth,
+                       (int)package->Info().Summary().Length());
+       }
+
+       // print header
+       BString header;
+       header.SetToFormat("%-*s  %-*s  %s",
+               installedColumnWidth, installedColumnTitle.String(),
+               nameColumnWidth, nameColumnTitle.String(),
+               descriptionColumnTitle.String());
+       printf("%s\n", header.String());
+
+       int minLineWidth = header.Length();
+       int lineWidth = minLineWidth + descriptionColumnWidth
+               - descriptionColumnTitle.Length();
+       int terminalWidth = get_terminal_width();
+       if (lineWidth > terminalWidth) {
+               // truncate description
+               int actualLineWidth = std::max(minLineWidth, terminalWidth);
+               descriptionColumnWidth -= lineWidth - actualLineWidth;
+               lineWidth = actualLineWidth;
+       }
+
+       header.SetTo('-', lineWidth);
+       printf("%s\n", header.String());
+
+       // print packages
+       for (int32 i = 0; i < packageCount; i++) {
+               BSolverPackage* package = packages.ItemAt(i);
+
+               const char* installed = "";
+               if (package->Repository() == &systemRepository)
+                       installed = "system";
+               else if (package->Repository() == &commonRepository)
+                       installed = "common";
+               else if (package->Repository() == &homeRepository)
+                       installed = "home";
+
+               printf("%-*s  %-*s  %-*.*s\n",
+                       installedColumnWidth, installed,
+                       nameColumnWidth, package->Name().String(),
+                       descriptionColumnWidth, descriptionColumnWidth,
+                       package->Info().Summary().String());
+       }
+
+       return 0;
+}
diff --git a/src/bin/pkgman/pkgman.cpp b/src/bin/pkgman/pkgman.cpp
index 6942008..6611700 100644
--- a/src/bin/pkgman/pkgman.cpp
+++ b/src/bin/pkgman/pkgman.cpp
@@ -36,6 +36,9 @@ static const char* kUsage =
        "  resolve-dependencies <package> <repository> [ <priority> ] ...\n"
        "    Resolves all packages a given package depends on.\n"
        "\n"
+       "  search <search-string>\n"
+       "    Searches for packages matching <search-string>.\n"
+       "\n"
        "Common Options:\n"
        "  -h, --help   - Print this usage info.\n"
 ;
@@ -71,8 +74,8 @@ main(int argc, const char* const* argv)
        if (strcmp(command, "resolve-dependencies") == 0)
                return command_resolve_dependencies(argc - 1, argv + 1);
 
-//     if (strcmp(command, "search") == 0)
-//             return command_search(argc - 1, argv + 1);
+       if (strcmp(command, "search") == 0)
+               return command_search(argc - 1, argv + 1);
 
        if (strcmp(command, "help") == 0)
                print_usage_and_exit(false);
diff --git a/src/bin/pkgman/pkgman.h b/src/bin/pkgman/pkgman.h
index 9808903..c2a2fe9 100644
--- a/src/bin/pkgman/pkgman.h
+++ b/src/bin/pkgman/pkgman.h
@@ -35,10 +35,11 @@ do {                                                        
                                                                        \
 
 void   print_usage_and_exit(bool error);
 int            command_add_repo(int argc, const char* const* argv);
-int            command_resolve_dependencies(int argc, const char* const* 
argv);  
 int            command_drop_repo(int argc, const char* const* argv);
 int            command_list_repos(int argc, const char* const* argv);
 int            command_refresh(int argc, const char* const* argv);
+int            command_resolve_dependencies(int argc, const char* const* 
argv);  
+int            command_search(int argc, const char* const* argv);  
 
 
 #endif // PKGMAN_H


Other related posts: