Beginnings of the PackageKit dependency solver
Not functional (or tested) yet. The libsolv setup for a somewhat simplified installation case should be more or less complete, though. The solution conversion to to-be-created Haiku data structures and the handling of problems is still missing, though.
This commit is contained in:
parent
10efbe6c5e
commit
479ca8169c
43
headers/os/package/solver/Solver.h
Normal file
43
headers/os/package/solver/Solver.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__SOLVER_H_
|
||||
#define _PACKAGE__SOLVER_H_
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
class BSolverPackageSpecifierList;
|
||||
class BSolverRepository;
|
||||
|
||||
|
||||
class BSolver {
|
||||
public:
|
||||
BSolver();
|
||||
~BSolver();
|
||||
|
||||
status_t Init();
|
||||
|
||||
status_t AddRepository(BSolverRepository* repository);
|
||||
|
||||
status_t Install(
|
||||
const BSolverPackageSpecifierList&
|
||||
packages);
|
||||
|
||||
private:
|
||||
class Implementation;
|
||||
|
||||
private:
|
||||
Implementation* fImplementation;
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__SOLVER_H_
|
47
headers/os/package/solver/SolverPackageSpecifier.h
Normal file
47
headers/os/package/solver/SolverPackageSpecifier.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
|
||||
#define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
|
||||
|
||||
|
||||
#include <package/PackageResolvableExpression.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
class BSolverRepository;
|
||||
|
||||
|
||||
class BSolverPackageSpecifier {
|
||||
public:
|
||||
BSolverPackageSpecifier();
|
||||
BSolverPackageSpecifier(
|
||||
const BPackageResolvableExpression&
|
||||
expression);
|
||||
BSolverPackageSpecifier(
|
||||
BSolverRepository* repository,
|
||||
const BPackageResolvableExpression&
|
||||
expression);
|
||||
BSolverPackageSpecifier(
|
||||
const BSolverPackageSpecifier& other);
|
||||
~BSolverPackageSpecifier();
|
||||
|
||||
BSolverRepository* Repository() const;
|
||||
const BPackageResolvableExpression& Expression() const;
|
||||
|
||||
BSolverPackageSpecifier& operator=(
|
||||
const BSolverPackageSpecifier& other);
|
||||
|
||||
private:
|
||||
BSolverRepository* fRepository;
|
||||
BPackageResolvableExpression fExpression;
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
|
46
headers/os/package/solver/SolverPackageSpecifierList.h
Normal file
46
headers/os/package/solver/SolverPackageSpecifierList.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
|
||||
#define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
class BSolverPackageSpecifier;
|
||||
|
||||
|
||||
class BSolverPackageSpecifierList {
|
||||
public:
|
||||
BSolverPackageSpecifierList();
|
||||
BSolverPackageSpecifierList(
|
||||
const BSolverPackageSpecifierList& other);
|
||||
~BSolverPackageSpecifierList();
|
||||
|
||||
bool IsEmpty() const;
|
||||
int32 CountSpecifiers() const;
|
||||
const BSolverPackageSpecifier* SpecifierAt(int32 index) const;
|
||||
|
||||
bool AppendSpecifier(
|
||||
const BSolverPackageSpecifier& specifier);
|
||||
|
||||
BSolverPackageSpecifierList& operator=(
|
||||
const BSolverPackageSpecifierList& other);
|
||||
|
||||
private:
|
||||
class Vector;
|
||||
|
||||
private:
|
||||
Vector* fSpecifiers;
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
|
69
headers/os/package/solver/SolverRepository.h
Normal file
69
headers/os/package/solver/SolverRepository.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__SOLVER_REPOSITORY_H_
|
||||
#define _PACKAGE__SOLVER_REPOSITORY_H_
|
||||
|
||||
|
||||
#include <package/PackageDefs.h>
|
||||
#include <package/PackageInfoSet.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
class BPackageInfo;
|
||||
class BRepositoryConfig;
|
||||
|
||||
|
||||
class BSolverRepository {
|
||||
public:
|
||||
enum BAllInstallationLocations {
|
||||
B_ALL_INSTALLATION_LOCATIONS
|
||||
};
|
||||
|
||||
typedef BPackageInfoSet::Iterator Iterator;
|
||||
|
||||
public:
|
||||
BSolverRepository();
|
||||
BSolverRepository(const BString& name);
|
||||
BSolverRepository(
|
||||
BPackageInstallationLocation location);
|
||||
BSolverRepository(BAllInstallationLocations);
|
||||
BSolverRepository(
|
||||
const BRepositoryConfig& config);
|
||||
~BSolverRepository();
|
||||
|
||||
status_t SetTo(const BString& name);
|
||||
status_t SetTo(BPackageInstallationLocation location);
|
||||
status_t SetTo(BAllInstallationLocations);
|
||||
status_t SetTo(const BRepositoryConfig& config);
|
||||
void Unset();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
bool IsInstalled() const;
|
||||
|
||||
BString Name() const;
|
||||
uint8 Priority() const;
|
||||
|
||||
status_t AddPackage(const BPackageInfo& info);
|
||||
status_t AddPackages(
|
||||
BPackageInstallationLocation location);
|
||||
|
||||
Iterator GetIterator() const;
|
||||
|
||||
private:
|
||||
BString fName;
|
||||
uint8 fPriority;
|
||||
bool fIsInstalled;
|
||||
BPackageInfoSet fPackages;
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__SOLVER_REPOSITORY_H_
|
@ -74,3 +74,5 @@ SharedLibrary libpackage.so
|
||||
:
|
||||
libshared.a be z $(TARGET_LIBSTDC++)
|
||||
;
|
||||
|
||||
HaikuSubInclude solver ;
|
||||
|
23
src/kits/package/solver/Jamfile
Normal file
23
src/kits/package/solver/Jamfile
Normal file
@ -0,0 +1,23 @@
|
||||
SubDir HAIKU_TOP src kits package solver ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
# TODO: Add properly to BuildFeatures and remove here!
|
||||
HAIKU_LIBSOLV_INSTALL_DIR ?= /Transfer/ports/libsolv-install/boot/common ;
|
||||
HAIKU_LIBSOLV_HEADERS ?= $(HAIKU_LIBSOLV_INSTALL_DIR)/include ;
|
||||
HAIKU_LIBSOLV_LIBS ?= $(HAIKU_LIBSOLV_INSTALL_DIR)/lib/libsolv.so
|
||||
$(HAIKU_LIBSOLV_INSTALL_DIR)/lib/libsolvext.so ;
|
||||
|
||||
SubDirSysHdrs $(HAIKU_LIBSOLV_HEADERS) ;
|
||||
SubDirHdrs $(HAIKU_LIBSOLV_HEADERS)/solv ;
|
||||
|
||||
|
||||
SharedLibrary libpackage_solver.so
|
||||
:
|
||||
Solver.cpp
|
||||
SolverPackageSpecifier.cpp
|
||||
SolverPackageSpecifierList.cpp
|
||||
SolverRepository.cpp
|
||||
:
|
||||
package $(HAIKU_LIBSOLV_LIBS) be $(TARGET_LIBSTDC++)
|
||||
;
|
356
src/kits/package/solver/Solver.cpp
Normal file
356
src/kits/package/solver/Solver.cpp
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/solver/Solver.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <solv/pool.h>
|
||||
#include <solv/poolarch.h>
|
||||
#include <solv/repo.h>
|
||||
#include <solv/repo_haiku.h>
|
||||
#include <solv/selection.h>
|
||||
#include <solv/solver.h>
|
||||
|
||||
#include <package/RepositoryCache.h>
|
||||
#include <package/solver/SolverPackageSpecifier.h>
|
||||
#include <package/solver/SolverPackageSpecifierList.h>
|
||||
#include <package/solver/SolverRepository.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
|
||||
|
||||
// TODO: libsolv doesn't have any helpful out-of-memory handling. It just just
|
||||
// abort()s. Obviously that isn't good behavior for a library.
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
// #pragma mark - BSolver::Implementation
|
||||
|
||||
|
||||
class BSolver::Implementation {
|
||||
public:
|
||||
Implementation();
|
||||
~Implementation();
|
||||
|
||||
status_t Init();
|
||||
|
||||
status_t AddRepository(BSolverRepository* repository);
|
||||
|
||||
status_t Install(
|
||||
const BSolverPackageSpecifierList&
|
||||
packages);
|
||||
|
||||
private:
|
||||
struct SolvQueue;
|
||||
struct RepositoryInfo;
|
||||
|
||||
typedef BObjectList<RepositoryInfo> RepositoryInfoList;
|
||||
|
||||
private:
|
||||
status_t _AddRepositories();
|
||||
RepositoryInfo* _GetRepositoryInfo(
|
||||
BSolverRepository* repository) const;
|
||||
|
||||
private:
|
||||
Pool* fPool;
|
||||
RepositoryInfoList fRepositoryInfos;
|
||||
RepositoryInfo* fInstalledRepository;
|
||||
};
|
||||
|
||||
|
||||
struct BSolver::Implementation::SolvQueue : Queue {
|
||||
SolvQueue()
|
||||
{
|
||||
queue_init(this);
|
||||
}
|
||||
|
||||
~SolvQueue()
|
||||
{
|
||||
queue_free(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct BSolver::Implementation::RepositoryInfo {
|
||||
RepositoryInfo(BSolverRepository* repository)
|
||||
:
|
||||
fRepository(repository),
|
||||
fSolvRepo(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
BSolverRepository* Repository() const
|
||||
{
|
||||
return fRepository;
|
||||
}
|
||||
|
||||
Repo* SolvRepo()
|
||||
{
|
||||
return fSolvRepo;
|
||||
}
|
||||
|
||||
void SetSolvRepo(Repo* repo)
|
||||
{
|
||||
fSolvRepo = repo;
|
||||
}
|
||||
|
||||
private:
|
||||
BSolverRepository* fRepository;
|
||||
Repo* fSolvRepo;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - BSolver
|
||||
|
||||
|
||||
BSolver::BSolver()
|
||||
:
|
||||
fImplementation(new(std::nothrow) Implementation)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolver::~BSolver()
|
||||
{
|
||||
delete fImplementation;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::Init()
|
||||
{
|
||||
return fImplementation != NULL ? fImplementation->Init() : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::AddRepository(BSolverRepository* repository)
|
||||
{
|
||||
return fImplementation != NULL
|
||||
? fImplementation->AddRepository(repository) : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::Install(const BSolverPackageSpecifierList& packages)
|
||||
{
|
||||
return fImplementation != NULL
|
||||
? fImplementation->Install(packages) : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BSolver::Implementation
|
||||
|
||||
|
||||
BSolver::Implementation::Implementation()
|
||||
:
|
||||
fPool(NULL),
|
||||
fRepositoryInfos(),
|
||||
fInstalledRepository(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolver::Implementation::~Implementation()
|
||||
{
|
||||
if (fPool != NULL)
|
||||
pool_free(fPool);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::Implementation::Init()
|
||||
{
|
||||
// already initialized?
|
||||
if (fPool != NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
fPool = pool_create();
|
||||
|
||||
// Set the system architecture. We use what uname() returns unless we're on
|
||||
// x86 gcc2.
|
||||
{
|
||||
const char* arch;
|
||||
#ifdef __HAIKU_ARCH_X86
|
||||
#if (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2
|
||||
arch = "x86_gcc2";
|
||||
#else
|
||||
arch = "x86";
|
||||
#endif
|
||||
#else
|
||||
struct utsname info;
|
||||
if (uname(&info) != 0)
|
||||
return errno;
|
||||
arch = info.machine;
|
||||
#endif
|
||||
|
||||
pool_setarchpolicy(fPool, arch);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::Implementation::AddRepository(BSolverRepository* repository)
|
||||
{
|
||||
if (repository == NULL || repository->InitCheck() != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// If the repository represents installed packages, check, if we already
|
||||
// have such a repository.
|
||||
if (repository->IsInstalled() && fInstalledRepository != NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// add the repository info
|
||||
RepositoryInfo* info = new(std::nothrow) RepositoryInfo(repository);
|
||||
if (info == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (!fRepositoryInfos.AddItem(info)) {
|
||||
delete info;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (repository->IsInstalled())
|
||||
fInstalledRepository = info;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::Implementation::Install(const BSolverPackageSpecifierList& packages)
|
||||
{
|
||||
if (packages.IsEmpty())
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: Clean up first?
|
||||
|
||||
// add repositories to pool
|
||||
status_t error = _AddRepositories();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// prepare pool for solving
|
||||
pool_createwhatprovides(fPool);
|
||||
|
||||
// add the packages to install to the job queue
|
||||
SolvQueue jobs;
|
||||
|
||||
int32 packageCount = packages.CountSpecifiers();
|
||||
for (int32 i = 0; i < packageCount; i++) {
|
||||
const BSolverPackageSpecifier& specifier = *packages.SpecifierAt(i);
|
||||
|
||||
// find matching packages
|
||||
SolvQueue matchingPackages;
|
||||
|
||||
int flags = SELECTION_NAME | SELECTION_PROVIDES | SELECTION_GLOB
|
||||
| SELECTION_CANON | SELECTION_DOTARCH | SELECTION_REL;
|
||||
// TODO: All flags needed/useful?
|
||||
/*int matchFlags =*/ selection_make(fPool, &matchingPackages,
|
||||
specifier.Expression().Name(), flags);
|
||||
// TODO: Don't just match the name, but also the version, if given!
|
||||
if (matchingPackages.count == 0)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
// restrict to the matching repository
|
||||
if (BSolverRepository* repository = specifier.Repository()) {
|
||||
RepositoryInfo* repositoryInfo = _GetRepositoryInfo(repository);
|
||||
if (repositoryInfo == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
SolvQueue repoFilter;
|
||||
queue_push2(&repoFilter,
|
||||
SOLVER_SOLVABLE_REPO/* | SOLVER_SETREPO | SOLVER_SETVENDOR*/,
|
||||
repositoryInfo->SolvRepo()->repoid);
|
||||
|
||||
selection_filter(fPool, &matchingPackages, &repoFilter);
|
||||
|
||||
if (matchingPackages.count == 0)
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (int j = 0; j < matchingPackages.count; j++)
|
||||
queue_push(&jobs, matchingPackages.elements[j]);
|
||||
}
|
||||
|
||||
// add solver mode to job queue elements
|
||||
int solverMode = SOLVER_INSTALL;
|
||||
for (int i = 0; i < jobs.count; i += 2) {
|
||||
jobs.elements[i] |= solverMode;
|
||||
// if (cleandeps)
|
||||
// jobs.elements[i] |= SOLVER_CLEANDEPS;
|
||||
// if (forcebest)
|
||||
// jobs.elements[i] |= SOLVER_FORCEBEST;
|
||||
}
|
||||
|
||||
// create the solver and solve
|
||||
Solver* solver = solver_create(fPool);
|
||||
solver_set_flag(solver, SOLVER_FLAG_SPLITPROVIDES, 1);
|
||||
solver_set_flag(solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
|
||||
|
||||
int problemCount = solver_solve(solver, &jobs);
|
||||
solver_free(solver);
|
||||
|
||||
// TODO: Problem support!
|
||||
return problemCount == 0 ? B_OK : B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolver::Implementation::_AddRepositories()
|
||||
{
|
||||
if (fInstalledRepository == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
int32 repositoryCount = fRepositoryInfos.CountItems();
|
||||
for (int32 i = 0; i < repositoryCount; i++) {
|
||||
RepositoryInfo* repositoryInfo = fRepositoryInfos.ItemAt(i);
|
||||
BSolverRepository* repository = repositoryInfo->Repository();
|
||||
Repo* repo = repo_create(fPool, repository->Name());
|
||||
repositoryInfo->SetSolvRepo(repo);
|
||||
|
||||
repo->priority = 256 - repository->Priority();
|
||||
repo->appdata = (void*)repositoryInfo;
|
||||
|
||||
BRepositoryCache::Iterator it = repository->GetIterator();
|
||||
while (const BPackageInfo* packageInfo = it.Next()) {
|
||||
repo_add_haiku_package_info(repo, *packageInfo,
|
||||
REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE);
|
||||
}
|
||||
|
||||
repo_internalize(repo);
|
||||
|
||||
if (repository->IsInstalled())
|
||||
pool_set_installed(fPool, repo);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
BSolver::Implementation::RepositoryInfo*
|
||||
BSolver::Implementation::_GetRepositoryInfo(BSolverRepository* repository) const
|
||||
{
|
||||
int32 repositoryCount = fRepositoryInfos.CountItems();
|
||||
for (int32 i = 0; i < repositoryCount; i++) {
|
||||
RepositoryInfo* repositoryInfo = fRepositoryInfos.ItemAt(i);
|
||||
if (repository == repositoryInfo->Repository())
|
||||
return repositoryInfo;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
79
src/kits/package/solver/SolverPackageSpecifier.cpp
Normal file
79
src/kits/package/solver/SolverPackageSpecifier.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/solver/SolverPackageSpecifier.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
BSolverPackageSpecifier::BSolverPackageSpecifier()
|
||||
:
|
||||
fRepository(NULL),
|
||||
fExpression()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifier::BSolverPackageSpecifier(
|
||||
const BPackageResolvableExpression& expression)
|
||||
:
|
||||
fRepository(NULL),
|
||||
fExpression(expression)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifier::BSolverPackageSpecifier(BSolverRepository* repository,
|
||||
const BPackageResolvableExpression& expression)
|
||||
:
|
||||
fRepository(repository),
|
||||
fExpression(expression)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifier::BSolverPackageSpecifier(
|
||||
const BSolverPackageSpecifier& other)
|
||||
:
|
||||
fRepository(other.fRepository),
|
||||
fExpression(other.fExpression)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifier::~BSolverPackageSpecifier()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository*
|
||||
BSolverPackageSpecifier::Repository() const
|
||||
{
|
||||
return fRepository;
|
||||
}
|
||||
|
||||
|
||||
const BPackageResolvableExpression&
|
||||
BSolverPackageSpecifier::Expression() const
|
||||
{
|
||||
return fExpression;
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifier&
|
||||
BSolverPackageSpecifier::operator=(const BSolverPackageSpecifier& other)
|
||||
{
|
||||
fRepository = other.fRepository;
|
||||
fExpression = other.fExpression;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
125
src/kits/package/solver/SolverPackageSpecifierList.cpp
Normal file
125
src/kits/package/solver/SolverPackageSpecifierList.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/solver/SolverPackageSpecifierList.h>
|
||||
|
||||
#include <new>
|
||||
#include <vector>
|
||||
|
||||
#include <package/solver/SolverPackageSpecifier.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
class BSolverPackageSpecifierList::Vector
|
||||
: public std::vector<BSolverPackageSpecifier> {
|
||||
public:
|
||||
Vector()
|
||||
:
|
||||
std::vector<BSolverPackageSpecifier>()
|
||||
{
|
||||
}
|
||||
|
||||
Vector(const std::vector<BSolverPackageSpecifier>& other)
|
||||
:
|
||||
std::vector<BSolverPackageSpecifier>(other)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BSolverPackageSpecifierList::BSolverPackageSpecifierList()
|
||||
:
|
||||
fSpecifiers(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifierList::BSolverPackageSpecifierList(
|
||||
const BSolverPackageSpecifierList& other)
|
||||
:
|
||||
fSpecifiers(NULL)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifierList::~BSolverPackageSpecifierList()
|
||||
{
|
||||
delete fSpecifiers;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BSolverPackageSpecifierList::IsEmpty() const
|
||||
{
|
||||
return fSpecifiers == NULL || fSpecifiers->empty();
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BSolverPackageSpecifierList::CountSpecifiers() const
|
||||
{
|
||||
return fSpecifiers != NULL ? fSpecifiers->size() : 0;
|
||||
}
|
||||
|
||||
|
||||
const BSolverPackageSpecifier*
|
||||
BSolverPackageSpecifierList::SpecifierAt(int32 index) const
|
||||
{
|
||||
if (fSpecifiers == NULL || index < 0
|
||||
|| (size_t)index >= fSpecifiers->size()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &(*fSpecifiers)[index];
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BSolverPackageSpecifierList::AppendSpecifier(
|
||||
const BSolverPackageSpecifier& specifier)
|
||||
{
|
||||
try {
|
||||
if (fSpecifiers == NULL) {
|
||||
fSpecifiers = new(std::nothrow) Vector;
|
||||
if (fSpecifiers == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
fSpecifiers->push_back(specifier);
|
||||
return true;
|
||||
} catch (std::bad_alloc&) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BSolverPackageSpecifierList&
|
||||
BSolverPackageSpecifierList::operator=(const BSolverPackageSpecifierList& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
delete fSpecifiers;
|
||||
fSpecifiers = NULL;
|
||||
|
||||
if (other.fSpecifiers == NULL)
|
||||
return *this;
|
||||
|
||||
try {
|
||||
fSpecifiers = new(std::nothrow) Vector(*other.fSpecifiers);
|
||||
} catch (std::bad_alloc&) {
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
235
src/kits/package/solver/SolverRepository.cpp
Normal file
235
src/kits/package/solver/SolverRepository.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/solver/SolverRepository.h>
|
||||
|
||||
#include <package/PackageDefs.h>
|
||||
#include <package/PackageRoster.h>
|
||||
#include <package/RepositoryCache.h>
|
||||
#include <package/RepositoryConfig.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
BSolverRepository::BSolverRepository()
|
||||
:
|
||||
fName(),
|
||||
fPriority(0),
|
||||
fIsInstalled(false),
|
||||
fPackages()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository::BSolverRepository(const BString& name)
|
||||
:
|
||||
fName(),
|
||||
fPriority(0),
|
||||
fIsInstalled(false),
|
||||
fPackages()
|
||||
{
|
||||
SetTo(name);
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository::BSolverRepository(BPackageInstallationLocation location)
|
||||
:
|
||||
fName(),
|
||||
fPriority(0),
|
||||
fIsInstalled(false),
|
||||
fPackages()
|
||||
{
|
||||
SetTo(location);
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository::BSolverRepository(BAllInstallationLocations)
|
||||
:
|
||||
fName(),
|
||||
fPriority(0),
|
||||
fIsInstalled(false),
|
||||
fPackages()
|
||||
{
|
||||
SetTo(B_ALL_INSTALLATION_LOCATIONS);
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository::BSolverRepository(const BRepositoryConfig& config)
|
||||
:
|
||||
fName(),
|
||||
fPriority(0),
|
||||
fIsInstalled(false),
|
||||
fPackages()
|
||||
{
|
||||
SetTo(config);
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository::~BSolverRepository()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::SetTo(const BString& name)
|
||||
{
|
||||
Unset();
|
||||
|
||||
fName = name;
|
||||
return fName.IsEmpty() ? B_BAD_VALUE : B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::SetTo(BPackageInstallationLocation location)
|
||||
{
|
||||
Unset();
|
||||
|
||||
fName = "Installed";
|
||||
|
||||
status_t error = AddPackages(location);
|
||||
if (error != B_OK) {
|
||||
Unset();
|
||||
return error;
|
||||
}
|
||||
|
||||
fIsInstalled = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::SetTo(BAllInstallationLocations)
|
||||
{
|
||||
status_t error = SetTo(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
error = AddPackages(B_PACKAGE_INSTALLATION_LOCATION_COMMON);
|
||||
if (error != B_OK) {
|
||||
Unset();
|
||||
return error;
|
||||
}
|
||||
|
||||
error = AddPackages(B_PACKAGE_INSTALLATION_LOCATION_HOME);
|
||||
if (error != B_OK) {
|
||||
Unset();
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::SetTo(const BRepositoryConfig& config)
|
||||
{
|
||||
Unset();
|
||||
|
||||
if (config.InitCheck() != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
fName = config.Name();
|
||||
fPriority = config.Priority();
|
||||
|
||||
BPackageRoster roster;
|
||||
BRepositoryCache cache;
|
||||
status_t error = roster.GetRepositoryCache(config.Name(), &cache);
|
||||
if (error != B_OK) {
|
||||
Unset();
|
||||
return error;
|
||||
}
|
||||
|
||||
BRepositoryCache::Iterator it = cache.GetIterator();
|
||||
while (const BPackageInfo* packageInfo = it.Next()) {
|
||||
error = AddPackage(*packageInfo);
|
||||
if (error != B_OK) {
|
||||
Unset();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BSolverRepository::Unset()
|
||||
{
|
||||
fName = BString();
|
||||
fPriority = 0;
|
||||
fIsInstalled = false;
|
||||
fPackages.MakeEmpty();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::InitCheck()
|
||||
{
|
||||
return fName.IsEmpty() ? B_NO_INIT : B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BSolverRepository::IsInstalled() const
|
||||
{
|
||||
return fIsInstalled;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
BSolverRepository::Name() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
BSolverRepository::Priority() const
|
||||
{
|
||||
return fPriority;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::AddPackage(const BPackageInfo& info)
|
||||
{
|
||||
return fPackages.AddInfo(info);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BSolverRepository::AddPackages(BPackageInstallationLocation location)
|
||||
{
|
||||
BPackageRoster roster;
|
||||
BPackageInfoSet packageInfos;
|
||||
status_t error = roster.GetActivePackages(location, packageInfos);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
BRepositoryCache::Iterator it = packageInfos.GetIterator();
|
||||
while (const BPackageInfo* packageInfo = it.Next()) {
|
||||
error = fPackages.AddInfo(*packageInfo);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
BSolverRepository::Iterator
|
||||
BSolverRepository::GetIterator() const
|
||||
{
|
||||
return fPackages.GetIterator();
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
Loading…
Reference in New Issue
Block a user