2 * Copyright (c) 2011-2013, Ingo Weinhold <ingo_weinhold@gmx.de>
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
8 #include <package/PackageInfo.h>
9 #include <package/PackageInfoSet.h>
10 #include <package/PackageRoster.h>
11 #include <package/PackageVersion.h>
12 #include <package/RepositoryCache.h>
13 #include <package/RepositoryConfig.h>
15 #include "repo_haiku.h"
17 using namespace BPackageKit;
18 using namespace BPackageKit::BHPKG;
20 static void add_dependency(Repo *repo, Offset &dependencies, const char *name,
21 const char *version, int flags, const char* compatVersion = NULL)
23 Pool *pool = repo->pool;
25 Id dependency = pool_str2id(pool, name, 1);
27 if (version && version[0] != '\0')
29 Id versionId = pool_str2id(pool, version, 1);
31 if (compatVersion && compatVersion[0] != '\0')
33 versionId = pool_rel2id(pool, versionId, pool_str2id(pool, compatVersion, 1),
37 dependency = pool_rel2id(pool, dependency, versionId, flags, 1);
40 dependencies = repo_addid_dep(repo, dependencies, dependency, 0);
43 static void add_dependency(Repo *repo, Offset &dependencies, const char *name,
44 const BPackageVersion &version, int flags)
46 add_dependency(repo, dependencies, name, version.ToString(),
50 static void add_resolvables(Repo *repo, Offset &dependencies,
51 const BObjectList<BPackageResolvable> &resolvables)
53 for (int32 i = 0; BPackageResolvable *resolvable = resolvables.ItemAt(i); i++)
55 add_dependency(repo, dependencies, resolvable->Name(),
56 resolvable->Version().ToString(), REL_EQ,
57 resolvable->CompatibleVersion().ToString());
61 static void add_resolvable_expressions(Repo *repo, Offset &dependencies,
62 const BObjectList<BPackageResolvableExpression> &expressions)
65 BPackageResolvableExpression *expression = expressions.ItemAt(i); i++)
67 // It is possible that no version is specified. In that case any version
69 if (expression->Version().InitCheck() != B_OK)
71 BPackageVersion version;
72 add_dependency(repo, dependencies, expression->Name(), NULL, 0);
77 switch (expression->Operator())
79 case B_PACKAGE_RESOLVABLE_OP_LESS:
82 case B_PACKAGE_RESOLVABLE_OP_LESS_EQUAL:
83 flags |= REL_LT | REL_EQ;
85 case B_PACKAGE_RESOLVABLE_OP_EQUAL:
88 case B_PACKAGE_RESOLVABLE_OP_NOT_EQUAL:
90 case B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL:
91 flags |= REL_GT | REL_EQ;
93 case B_PACKAGE_RESOLVABLE_OP_GREATER:
98 add_dependency(repo, dependencies, expression->Name(),
99 expression->Version(), flags);
103 static void add_replaces_list(Repo *repo, Offset &dependencies,
104 const BStringList &packageNames)
106 int32 count = packageNames.CountStrings();
107 for (int32 i = 0; i < count; i++)
109 const BString &packageName = packageNames.StringAt(i);
110 add_dependency(repo, dependencies, packageName, BPackageVersion(), 0);
114 static Id add_package_info_to_repo(Repo *repo, Repodata *repoData,
115 const BPackageInfo &packageInfo)
117 Pool *pool = repo->pool;
119 Id solvableId = repo_add_solvable(repo);
120 Solvable *solvable = pool_id2solvable(pool, solvableId);
121 // Prepend "pkg:" to package name, so "provides" don't match unless explicitly
122 // specified this way.
123 BString name("pkg:");
124 name << packageInfo.Name();
125 solvable->name = pool_str2id(pool, name, 1);
126 if (packageInfo.Architecture() == B_PACKAGE_ARCHITECTURE_ANY)
127 solvable->arch = ARCH_ANY;
128 else if (packageInfo.Architecture() == B_PACKAGE_ARCHITECTURE_SOURCE)
129 solvable->arch = ARCH_SRC;
131 solvable->arch = pool_str2id(pool,
132 BPackageInfo::kArchitectureNames[packageInfo.Architecture()], 1);
133 solvable->evr = pool_str2id(pool, packageInfo.Version().ToString(), 1);
134 solvable->vendor = pool_str2id(pool, packageInfo.Vendor(), 1);
135 repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_SUMMARY,
136 packageInfo.Summary());
137 repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_DESCRIPTION,
138 packageInfo.Description());
139 repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_PACKAGER,
140 packageInfo.Packager());
142 if (!packageInfo.Checksum().IsEmpty())
143 repodata_set_checksum(repoData, solvable - pool->solvables,
144 SOLVABLE_CHECKSUM, REPOKEY_TYPE_SHA256, packageInfo.Checksum());
146 solvable->provides = repo_addid_dep(repo, solvable->provides,
147 pool_rel2id(pool, solvable->name, solvable->evr, REL_EQ, 1), 0);
149 add_resolvables(repo, solvable->provides, packageInfo.ProvidesList());
150 add_resolvable_expressions(repo, solvable->requires,
151 packageInfo.RequiresList());
152 add_resolvable_expressions(repo, solvable->supplements,
153 packageInfo.SupplementsList());
154 add_resolvable_expressions(repo, solvable->conflicts,
155 packageInfo.ConflictsList());
156 add_resolvable_expressions(repo, solvable->enhances,
157 packageInfo.FreshensList());
158 add_replaces_list(repo, solvable->obsoletes, packageInfo.ReplacesList());
159 // TODO: Check whether freshens and replaces does indeed work as intended
162 // TODO: copyrights, licenses, URLs, source URLs
167 static void add_installed_packages(Repo *repo, Repodata *repoData,
168 BPackageInstallationLocation location)
170 BPackageRoster roster;
171 BPackageInfoSet packageInfos;
172 if (roster.GetActivePackages(location, packageInfos) == B_OK)
174 BRepositoryCache::Iterator it = packageInfos.GetIterator();
175 while (const BPackageInfo *packageInfo = it.Next())
176 add_package_info_to_repo(repo, repoData, *packageInfo);
180 int repo_add_haiku_installed_packages(Repo *repo, const char *rootdir,
183 Repodata *repoData = repo_add_repodata(repo, flags);
185 add_installed_packages(repo, repoData,
186 B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
187 add_installed_packages(repo, repoData, B_PACKAGE_INSTALLATION_LOCATION_HOME);
189 if (!(flags & REPO_NO_INTERNALIZE))
190 repodata_internalize(repoData);
195 Id repo_add_haiku_package(Repo *repo, const char *hpkgPath, int flags)
197 BPackageInfo packageInfo;
198 if (packageInfo.ReadFromPackageFile(hpkgPath) != B_OK)
201 return repo_add_haiku_package_info(repo, packageInfo, flags);
204 int repo_add_haiku_packages(Repo *repo, const char *repoName, int flags)
206 BPackageRoster roster;
207 BRepositoryCache cache;
208 if (roster.GetRepositoryCache(repoName, &cache) != B_OK)
211 Repodata *repoData = repo_add_repodata(repo, flags);
213 BRepositoryCache::Iterator it = cache.GetIterator();
214 while (const BPackageInfo *packageInfo = it.Next())
215 add_package_info_to_repo(repo, repoData, *packageInfo);
217 if (!(flags & REPO_NO_INTERNALIZE))
218 repodata_internalize(repoData);
223 Id repo_add_haiku_package_info(Repo *repo,
224 const BPackageKit::BPackageInfo &packageInfo, int flags)
226 if (packageInfo.InitCheck() != B_OK)
229 Repodata *repoData = repo_add_repodata(repo, flags);
231 Id id = add_package_info_to_repo(repo, repoData, packageInfo);
233 if (!(flags & REPO_NO_INTERNALIZE))
234 repodata_internalize(repoData);