...
 
Commits (2)
......@@ -5,24 +5,27 @@ CXXFLAGS ?= -mcpu=native -ggdb
all: libparcel.a libparcel.so
libparcel.a: Package.o Repository.o
$(AR) rcs libparcel.a Package.o Repository.o
@printf "\tAR\tlibparcel.a\n"
@$(AR) rcs libparcel.a Package.o Repository.o
libparcel.so: Package.o Repository.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o libparcel.so.0 Package.o Repository.o
-ln -s libparcel.so.0 libparcel.so
@printf "\tLINK\tlibparcel.so\n"
@$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o libparcel.so.0 Package.o Repository.o
Package.o: Package.cc Package.hh
$(CXX) $(CXXFLAGS) -c -o Package.o Package.cc
@printf "\tCXX\tPackage.cc\n"
@$(CXX) $(CXXFLAGS) -c -o Package.o Package.cc
Repository.o: Repository.cc Repository.hh Package.hh
$(CXX) $(CXXFLAGS) -c -o Repository.o Repository.cc
@printf "\tCXX\tRepository.cc\n"
@$(CXX) $(CXXFLAGS) -c -o Repository.o Repository.cc
clean:
rm libparcel.a
rm libparcel.so*
rm Package.o
rm Repository.o
@-rm libparcel.a 2>/dev/null
@-rm libparcel.so* 2>/dev/null
@-rm Package.o 2>/dev/null
@-rm Repository.o 2>/dev/null
make -C test clean
check: libparcel.so
check: all
make -C test check
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <sstream>
......@@ -7,13 +6,7 @@
namespace Parcel {
bool operator<(const PackageVersion &left, const PackageVersion &right)
{
assert("NYI");
return false;
}
Package::Package(std::istream& from_pkginfo)
Package::Package(std::istream& from_pkginfo) : _done_deps(false), _done_ii(false), _done_prov(false), _done_replace(false)
{
// We can't blindly trust this input - we could be called from something
// other than the Repository ctor.
......@@ -54,15 +47,18 @@ Package::Package(std::istream& from_pkginfo)
case 'A':
_arch = raw_value;
break;
#define ATOM_CASE(CURRENT_TYPE) {\
std::istringstream atom_stream(raw_value);\
CURRENT_TYPE = {std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()};\
break;\
}
case 'D': ATOM_CASE(_dependencies)
case 'p': ATOM_CASE(_provides)
case 'r': ATOM_CASE(_replaces)
#undef ATOM_CASE
case 'D':
_raw_deps = raw_value;
break;
case 'i':
_raw_ii = raw_value;
break;
case 'p':
_raw_prov = raw_value;
break;
case 'r':
_raw_replace = raw_value;
break;
case 'm':
_maintainer = raw_value;
break;
......@@ -83,4 +79,47 @@ Package::Package(std::istream& from_pkginfo)
}
}
std::set<string>* Package::depends() {
if(!this->_done_deps) {
this->_done_deps = true;
std::istringstream atom_stream(_raw_deps);
this->_dependencies = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
return this->_dependencies;
}
std::set<string>* Package::install_if() {
if(!this->_done_ii) {
this->_done_ii = true;
std::istringstream atom_stream(_raw_ii);
this->_install_if = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
return this->_install_if;
}
std::set<string>* Package::provides() {
if(!this->_done_prov) {
this->_done_prov = true;
std::istringstream atom_stream(_raw_prov);
this->_provides = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
return this->_provides;
}
std::set<string>* Package::replaces() {
if(!this->_done_replace) {
this->_done_replace = true;
std::istringstream atom_stream(_raw_replace);
this->_replaces = new std::set<string>({std::istream_iterator<string>(atom_stream), std::istream_iterator<string>()});
}
return this->_replaces;
}
Package::~Package() {
if(this->_done_deps) delete this->_dependencies;
if(this->_done_ii) delete this->_install_if;
if(this->_done_prov) delete this->_provides;
if(this->_done_replace) delete this->_replaces;
}
}
#include <cassert>
#include <cstdint>
#include <iostream>
#include <set>
#include <string>
#include <tuple>
#include <vector>
......@@ -37,7 +39,10 @@ public:
return this->_revision;
}
friend bool operator<(const PackageVersion &left, const PackageVersion &right);
friend bool operator<(const PackageVersion &left, const PackageVersion &right) {
assert("NYI");
return false;
}
friend bool operator>(const PackageVersion &left, const PackageVersion &right) { return right < left; }
private:
string _version;
......@@ -53,14 +58,15 @@ public:
uint64_t size() { return _install_size; }
const string license() { return _license; }
const string arch() { return _arch; }
std::vector<string> depends() { return _dependencies; }
std::vector<string> install_if() { return _install_if; }
std::vector<string> provides() { return _provides; }
std::vector<string> replaces() { return _replaces; }
std::set<string>* depends();
std::set<string>* install_if();
std::set<string>* provides();
std::set<string>* replaces();
const string maintainer() { return _maintainer; }
uint64_t builddate() { return _built_at; }
const string commit() { return _commit_id; }
const string origin() { return _origin; }
~Package();
private:
string _name;
string _version;
......@@ -69,10 +75,18 @@ private:
uint64_t _install_size;
string _license;
string _arch;
std::vector<string> _dependencies;
std::vector<string> _install_if;
std::vector<string> _provides;
std::vector<string> _replaces;
string _raw_deps;
bool _done_deps;
std::set<string>* _dependencies;
string _raw_ii;
bool _done_ii;
std::set<string>* _install_if;
string _raw_prov;
bool _done_prov;
std::set<string>* _provides;
string _raw_replace;
bool _done_replace;
std::set<string>* _replaces;
uint64_t _replaces_priority;
string _maintainer;
uint64_t _built_at;
......
......@@ -65,4 +65,26 @@ Package* Repository::package(string name) {
});
}
vector<Package*> Repository::providers(string name) {
vector<Package*> provider_list;
std::copy_if(this->_packages.cbegin(), this->_packages.cend(), std::back_inserter(provider_list),
[name](Package* elem) {
// if the package name exactly matches, this is automatically a provider
if(elem->pkgname() == name) return true;
// no version specified, so find any version
std::set<string>* providers = elem->provides();
return std::any_of(providers->begin(), providers->end(), [name](string elem){
string::size_type equals;
if(elem == name) return true;
equals = elem.find("=");
if(equals != string::npos) return elem.substr(0, equals) == name;
return false;
});
});
return provider_list;
}
}
......@@ -14,16 +14,21 @@ public:
Repository(std::istream& from_index);
~Repository();
/*! All packages in this repository. */
/*! All packages in this repository */
std::vector<Package*> packages() { return _packages; }
/*! True if at least one Package is present in this repository with
* the specified name. */
* the specified name */
bool has_package(string name);
/*! Returns the newest version of the package specified by name. */
/*! The newest version of the package specified by `name` */
Package* package(string name);
/*! Number of packages in this repository */
unsigned long package_count() { return _packages.size(); }
/*! Names of every origin package in this repository */
std::vector<string> origins() { return std::vector<string>(_origins.begin(), _origins.end()); }
/*! Number of origin packages in this repository */
unsigned long origin_count() { return _origins.size(); }
/*! All packages that provide `name`. */
std::vector<Package*> providers(string name);
private:
std::vector<Package*> _packages;
std::unordered_set<string> _origins;
......
......@@ -3,17 +3,21 @@
all: packageversion repoquery repository
packageversion: packageversion.cc
$(CXX) $(CXXFLAGS) -o packageversion packageversion.cc -L.. -lparcel
@printf "\tCXX\tpackageversion\n"
@$(CXX) $(CXXFLAGS) -o packageversion packageversion.cc -L.. -lparcel
repoquery: repoquery.cc
$(CXX) $(CXXFLAGS) -o repoquery repoquery.cc -L.. -Wl,-rpath .. -lparcel
@printf "\tCXX\trepoquery\n"
@$(CXX) $(CXXFLAGS) -o repoquery repoquery.cc -L.. -Wl,-rpath .. -lparcel
repository: repository.cc
$(CXX) $(CXXFLAGS) -o repository repository.cc -L.. -Wl,-rpath .. -lparcel
@printf "\tCXX\trepository\n"
@$(CXX) $(CXXFLAGS) -o repository repository.cc -L.. -Wl,-rpath .. -lparcel
clean:
rm packageversion
rm repository
@-rm packageversion 2>/dev/null
@-rm repoquery 2>/dev/null
@-rm repository 2>/dev/null
check: all
./packageversion
......
......@@ -27,6 +27,11 @@ int main(int argc, char* argv[])
if(argc == 2) repo = make_repo_from_file("ActualSystemRepo");
else repo = make_repo_from_file(string(argv[2]));
if(!repo) {
std::cout << "Error opening repository" << std::endl;
return EXIT_FAILURE;
}
if((pkg = repo->package(string(argv[1]))) == nullptr) {
std::cout << "No package \"" << argv[1] << "\" found." << std::endl;
delete repo;
......@@ -41,8 +46,12 @@ int main(int argc, char* argv[])
std::cout << "\tWeb Site: " << pkg->url() << std::endl;
std::cout << "\tMaintained by: " << pkg->maintainer() << std::endl;
std::cout << "\tSize when installed: " << pkg->size() << " bytes" << std::endl;
std::cout << "\tDepends on:\n" << std::endl;
for(auto dep : pkg->depends()) std::cout << "\t\t" << dep << std::endl;
std::cout << "\tDepends on:" << std::endl;
for(auto dep : *pkg->depends()) {
std::cout << "\t\t" << dep << " ( ";
for(auto provider : repo->providers(dep)) std::cout << provider->pkgname() << " ";
std::cout << ")" << std::endl;
}
delete repo;
......