diff options
author | 2010-08-24 20:30:01 +0100 | |
---|---|---|
committer | 2010-08-26 11:36:11 +0100 | |
commit | d41dee1b4366dc685eaa2c435b01be03aef9929b (patch) | |
tree | 497cd2a6f67f2f3403db38d1285bd1775f4bee71 /paludis/repositories/gemcutter | |
parent | 4fcfd14b89dcce88d0182ab89019f1b7d8fa70bf (diff) | |
download | paludis-d41dee1b4366dc685eaa2c435b01be03aef9929b.tar.gz paludis-d41dee1b4366dc685eaa2c435b01be03aef9929b.tar.xz |
Add GemcutterRepository
Diffstat (limited to 'paludis/repositories/gemcutter')
18 files changed, 1664 insertions, 0 deletions
diff --git a/paludis/repositories/gemcutter/Makefile.am b/paludis/repositories/gemcutter/Makefile.am new file mode 100644 index 000000000..5c2fe6e30 --- /dev/null +++ b/paludis/repositories/gemcutter/Makefile.am @@ -0,0 +1,36 @@ +include $(top_srcdir)/misc/common-makefile.am + +SUBDIRS = . + +AM_CXXFLAGS = -I$(top_srcdir) -I$(top_builddir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@ +DEFS= \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DDATADIR=\"$(datadir)\" \ + -DLIBDIR=\"$(libdir)\" + +noinst_LTLIBRARIES = libpaludisgemcutterrepository.la + +noinst_HEADERS = \ + gemcutter_id.hh gemcutter_id-fwd.hh \ + gemcutter_repository.hh gemcutter_repository-fwd.hh \ + gemcutter_repository_store.hh \ + json_common.hh json_common-fwd.hh \ + json_things_handle.hh json_things_handle-fwd.hh + +libpaludisgemcutterrepository_la_SOURCES = \ + gemcutter_id.cc \ + gemcutter_repository.cc \ + gemcutter_repository_store.cc \ + json_common.cc \ + json_things_handle.cc \ + registration.cc \ + $(noinst_HEADERS) + +lib_LTLIBRARIES = libpaludisgemcutterrepositoryjsonthings_@PALUDIS_PC_SLOT@.la + +libpaludisgemcutterrepositoryjsonthings_@PALUDIS_PC_SLOT@_la_SOURCES = json_things.cc json_things.hh +libpaludisgemcutterrepositoryjsonthings_@PALUDIS_PC_SLOT@_la_CXXFLAGS = $(AM_CXXFLAGS) @JANSSONDEPS_CFLAGS@ +libpaludisgemcutterrepositoryjsonthings_@PALUDIS_PC_SLOT@_la_LIBADD = @JANSSONDEPS_LIBS@ +libpaludisgemcutterrepositoryjsonthings_@PALUDIS_PC_SLOT@_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0 + diff --git a/paludis/repositories/gemcutter/gemcutter_id-fwd.hh b/paludis/repositories/gemcutter/gemcutter_id-fwd.hh new file mode 100644 index 000000000..afb2a7c48 --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_id-fwd.hh @@ -0,0 +1,32 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_ID_FWD_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_ID_FWD_HH 1 + +namespace paludis +{ + namespace gemcutter_repository + { + class GemcutterID; + class GemcutterIDParams; + } +} + +#endif diff --git a/paludis/repositories/gemcutter/gemcutter_id.cc b/paludis/repositories/gemcutter/gemcutter_id.cc new file mode 100644 index 000000000..613e42a31 --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_id.cc @@ -0,0 +1,289 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/gemcutter/gemcutter_id.hh> +#include <paludis/repositories/gemcutter/gemcutter_repository.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/simple_visitor_cast.hh> +#include <paludis/util/set.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/wrapped_forward_iterator.hh> +#include <paludis/util/make_null_shared_ptr.hh> +#include <paludis/util/singleton-impl.hh> +#include <paludis/name.hh> +#include <paludis/version_spec.hh> +#include <paludis/metadata_key.hh> +#include <paludis/literal_metadata_key.hh> +#include <paludis/action.hh> +#include <paludis/unchoices_key.hh> +#include <paludis/user_dep_spec.hh> + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +namespace paludis +{ + template <> + struct Imp<GemcutterID> + { + const Environment * const env; + const QualifiedPackageName name; + const VersionSpec version; + const GemcutterRepository * const repo; + + Imp(const GemcutterIDParams & e) : + env(e.environment()), + name(CategoryNamePart("gem"), PackageNamePart(e.info().name())), + version(e.info().version(), { }), + repo(e.repository()) + { + } + }; +} + +GemcutterID::GemcutterID(const GemcutterIDParams & entry) : + Pimp<GemcutterID>(entry), + _imp(Pimp<GemcutterID>::_imp) +{ +} + +GemcutterID::~GemcutterID() +{ +} + +void +GemcutterID::need_keys_added() const +{ +} + +void +GemcutterID::need_masks_added() const +{ +} + +const std::string +GemcutterID::canonical_form(const PackageIDCanonicalForm f) const +{ + switch (f) + { + case idcf_full: + return stringify(_imp->name) + "-" + stringify(_imp->version) + + "::" + stringify(_imp->repo->name()); + + case idcf_no_version: + return stringify(_imp->name) + "::" + stringify(_imp->repo->name()); + + case idcf_version: + return stringify(_imp->version); + + case idcf_no_name: + return stringify(_imp->version) + "::" + stringify(_imp->repo->name()); + + case last_idcf: + break; + } + + throw InternalError(PALUDIS_HERE, "Bad PackageIDCanonicalForm"); +} + +PackageDepSpec +GemcutterID::uniquely_identifying_spec() const +{ + return parse_user_package_dep_spec("=" + stringify(name()) + "-" + stringify(version()) + + + "::" + stringify(repository()->name()), + _imp->env, { }); +} + +const QualifiedPackageName +GemcutterID::name() const +{ + return _imp->name; +} + +const VersionSpec +GemcutterID::version() const +{ + return _imp->version; +} + +const std::shared_ptr<const Repository> +GemcutterID::repository() const +{ + return _imp->repo->shared_from_this(); +} + +bool +GemcutterID::supports_action(const SupportsActionTestBase &) const +{ + return false; +} + +void +GemcutterID::perform_action(Action & a) const +{ + throw ActionFailedError("Unsupported action: " + a.simple_name()); +} + +std::shared_ptr<const Set<std::string> > +GemcutterID::breaks_portage() const +{ + return std::make_shared<Set<std::string>>(); +} + +bool +GemcutterID::arbitrary_less_than_comparison(const PackageID &) const +{ + return false; +} + +std::size_t +GemcutterID::extra_hash_value() const +{ + return 0; +} + +const std::shared_ptr<const MetadataCollectionKey<PackageIDSequence> > +GemcutterID::contains_key() const +{ + return std::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >(); +} + +const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const PackageID> > > +GemcutterID::contained_in_key() const +{ + return std::shared_ptr<const MetadataValueKey<std::shared_ptr<const PackageID> > >(); +} + +const std::shared_ptr<const MetadataValueKey<FSPath> > +GemcutterID::fs_location_key() const +{ + return std::shared_ptr<const MetadataValueKey<FSPath> >(); +} + +const std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > +GemcutterID::behaviours_key() const +{ + return make_null_shared_ptr(); +} + +const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const PackageID> > > +GemcutterID::virtual_for_key() const +{ + return std::shared_ptr<const MetadataValueKey<std::shared_ptr<const PackageID> > >(); +} + +const std::shared_ptr<const MetadataCollectionKey<KeywordNameSet> > +GemcutterID::keywords_key() const +{ + return std::shared_ptr<const MetadataCollectionKey<KeywordNameSet> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> > +GemcutterID::provide_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > +GemcutterID::dependencies_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > +GemcutterID::build_dependencies_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > +GemcutterID::run_dependencies_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > +GemcutterID::post_dependencies_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > +GemcutterID::suggested_dependencies_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >(); +} + +const std::shared_ptr<const MetadataValueKey<std::string> > +GemcutterID::short_description_key() const +{ + return make_null_shared_ptr(); +} + +const std::shared_ptr<const MetadataValueKey<std::string> > +GemcutterID::long_description_key() const +{ + return std::shared_ptr<const MetadataValueKey<std::string> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> > +GemcutterID::fetches_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >(); +} + +const std::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > +GemcutterID::homepage_key() const +{ + return std::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >(); +} + +const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const Contents> > > +GemcutterID::contents_key() const +{ + return std::shared_ptr<const MetadataValueKey<std::shared_ptr<const Contents> > >(); +} + +const std::shared_ptr<const MetadataTimeKey> +GemcutterID::installed_time_key() const +{ + return std::shared_ptr<const MetadataTimeKey>(); +} + +const std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > +GemcutterID::from_repositories_key() const +{ + return make_null_shared_ptr(); +} + +const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const Choices> > > +GemcutterID::choices_key() const +{ + return make_null_shared_ptr(); +} + +const std::shared_ptr<const MetadataValueKey<SlotName> > +GemcutterID::slot_key() const +{ + return make_null_shared_ptr(); +} + +template class Pimp<GemcutterID>; + diff --git a/paludis/repositories/gemcutter/gemcutter_id.hh b/paludis/repositories/gemcutter/gemcutter_id.hh new file mode 100644 index 000000000..a0b7afd6c --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_id.hh @@ -0,0 +1,115 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_ID_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_ID_HH 1 + +#include <paludis/repositories/gemcutter/gemcutter_id-fwd.hh> +#include <paludis/repositories/gemcutter/gemcutter_repository-fwd.hh> +#include <paludis/repositories/gemcutter/json_common.hh> +#include <paludis/util/named_value.hh> +#include <paludis/package_id.hh> +#include <paludis/name.hh> + +namespace paludis +{ + namespace n + { + typedef Name<struct environment_name> environment; + typedef Name<struct info_name> info; + typedef Name<struct repository_name> repository; + } + + namespace gemcutter_repository + { + struct GemcutterIDParams + { + NamedValue<n::environment, const Environment *> environment; + NamedValue<n::info, GemJSONInfo> info; + NamedValue<n::repository, const GemcutterRepository *> repository; + }; + + class PALUDIS_VISIBLE GemcutterID : + public PackageID, + private Pimp<GemcutterID> + { + private: + Pimp<GemcutterID>::ImpPtr & _imp; + + protected: + void need_keys_added() const; + void need_masks_added() const; + + public: + GemcutterID(const GemcutterIDParams &); + ~GemcutterID(); + + const std::string canonical_form(const PackageIDCanonicalForm) const; + const QualifiedPackageName name() const; + const VersionSpec version() const; + const std::shared_ptr<const Repository> repository() const; + virtual PackageDepSpec uniquely_identifying_spec() const; + + const std::shared_ptr<const MetadataValueKey<SlotName> > slot_key() const; + const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const PackageID> > > + virtual_for_key() const; + const std::shared_ptr<const MetadataCollectionKey<KeywordNameSet> > keywords_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> > provide_key() const; + const std::shared_ptr<const MetadataCollectionKey<PackageIDSequence> > contains_key() const; + const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const PackageID> > > + contained_in_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > + dependencies_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > + build_dependencies_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > + run_dependencies_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > + post_dependencies_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > + suggested_dependencies_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> > fetches_key() const; + const std::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > homepage_key() const; + const std::shared_ptr<const MetadataValueKey<std::string> > short_description_key() const; + const std::shared_ptr<const MetadataValueKey<std::string> > long_description_key() const; + const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const Contents> > > + contents_key() const; + const std::shared_ptr<const MetadataTimeKey> installed_time_key() const; + const std::shared_ptr<const MetadataValueKey<FSPath> > fs_location_key() const; + const std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > behaviours_key() const; + const std::shared_ptr<const MetadataCollectionKey<Set<std::string> > > from_repositories_key() const; + const std::shared_ptr<const MetadataValueKey<std::shared_ptr<const Choices> > > choices_key() const; + + bool supports_action(const SupportsActionTestBase &) const + PALUDIS_ATTRIBUTE((warn_unused_result)); + void perform_action(Action &) const PALUDIS_ATTRIBUTE((noreturn)); + + std::shared_ptr<const Set<std::string> > breaks_portage() const + PALUDIS_ATTRIBUTE((warn_unused_result)); + + bool arbitrary_less_than_comparison(const PackageID &) const + PALUDIS_ATTRIBUTE((warn_unused_result)); + std::size_t extra_hash_value() const + PALUDIS_ATTRIBUTE((warn_unused_result)); + }; + + } +} + +#endif diff --git a/paludis/repositories/gemcutter/gemcutter_repository-fwd.hh b/paludis/repositories/gemcutter/gemcutter_repository-fwd.hh new file mode 100644 index 000000000..e2135295f --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_repository-fwd.hh @@ -0,0 +1,31 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_REPOSITORY_FWD_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_REPOSITORY_FWD_HH 1 + +namespace paludis +{ + namespace gemcutter_repository + { + class GemcutterRepository; + } +} + +#endif diff --git a/paludis/repositories/gemcutter/gemcutter_repository.cc b/paludis/repositories/gemcutter/gemcutter_repository.cc new file mode 100644 index 000000000..934ff56bd --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_repository.cc @@ -0,0 +1,327 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/gemcutter/gemcutter_repository.hh> +#include <paludis/repositories/gemcutter/gemcutter_repository_store.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/active_object_ptr.hh> +#include <paludis/util/deferred_construction_ptr.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/tokeniser.hh> +#include <paludis/util/make_named_values.hh> +#include <paludis/util/simple_visitor_cast.hh> +#include <paludis/util/simple_parser.hh> +#include <paludis/util/safe_ifstream.hh> +#include <paludis/util/safe_ofstream.hh> +#include <paludis/util/make_null_shared_ptr.hh> +#include <paludis/util/fs_stat.hh> +#include <paludis/literal_metadata_key.hh> +#include <paludis/action.hh> +#include <paludis/syncer.hh> +#include <paludis/hook.hh> +#include <paludis/package_id.hh> +#include <paludis/output_manager.hh> +#include <paludis/environment.hh> +#include <list> + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +namespace +{ + std::shared_ptr<GemcutterRepositoryStore> + make_store(const GemcutterRepository * const repo, const GemcutterRepositoryParams & p) + { + return std::make_shared<GemcutterRepositoryStore>(p.environment(), repo, p.location()); + } +} + +namespace paludis +{ + template <> + struct Imp<GemcutterRepository> + { + const GemcutterRepositoryParams params; + + const std::shared_ptr<LiteralMetadataValueKey<std::string> > format_key; + const std::shared_ptr<LiteralMetadataValueKey<FSPath> > location_key; + + const ActiveObjectPtr<DeferredConstructionPtr<std::shared_ptr<GemcutterRepositoryStore> > > store; + + Imp(const GemcutterRepository * const repo, const GemcutterRepositoryParams & p) : + params(p), + format_key(std::make_shared<LiteralMetadataValueKey<std::string> >("format", "format", mkt_significant, "gemcutter")), + location_key(std::make_shared<LiteralMetadataValueKey<FSPath> >("location", "location", mkt_significant, params.location())), + store(DeferredConstructionPtr<std::shared_ptr<GemcutterRepositoryStore> > (std::bind(&make_store, repo, std::cref(params)))) + { + } + }; +} + +GemcutterRepositoryConfigurationError::GemcutterRepositoryConfigurationError(const std::string & s) throw () : + ConfigurationError("GemcutterRepository configuration error: " + s) +{ +} + +GemcutterRepository::GemcutterRepository(const GemcutterRepositoryParams & p) : + Pimp<GemcutterRepository>(this, p), + Repository( + p.environment(), + p.name(), + make_named_values<RepositoryCapabilities>( + n::destination_interface() = static_cast<RepositoryDestinationInterface *>(0), + n::environment_variable_interface() = static_cast<RepositoryEnvironmentVariableInterface *>(0), + n::make_virtuals_interface() = static_cast<RepositoryMakeVirtualsInterface *>(0), + n::manifest_interface() = static_cast<RepositoryManifestInterface *>(0), + n::provides_interface() = static_cast<RepositoryProvidesInterface *>(0), + n::virtuals_interface() = static_cast<RepositoryVirtualsInterface *>(0) + )), + _imp(Pimp<GemcutterRepository>::_imp) +{ + _add_metadata_keys(); +} + +GemcutterRepository::~GemcutterRepository() +{ +} + +bool +GemcutterRepository::can_be_favourite_repository() const +{ + return false; +} + +const bool +GemcutterRepository::is_unimportant() const +{ + return false; +} + +void +GemcutterRepository::_add_metadata_keys() +{ + clear_metadata_keys(); + add_metadata_key(_imp->format_key); + add_metadata_key(_imp->location_key); +} + +void +GemcutterRepository::need_keys_added() const +{ +} + +const std::shared_ptr<const MetadataValueKey<std::string> > +GemcutterRepository::format_key() const +{ + return _imp->format_key; +} + +const std::shared_ptr<const MetadataValueKey<FSPath> > +GemcutterRepository::location_key() const +{ + return _imp->location_key; +} + +const std::shared_ptr<const MetadataValueKey<FSPath> > +GemcutterRepository::installed_root_key() const +{ + return make_null_shared_ptr(); +} + +void +GemcutterRepository::invalidate() +{ + _imp.reset(new Imp<GemcutterRepository>(this, _imp->params)); + _add_metadata_keys(); +} + +void +GemcutterRepository::invalidate_masks() +{ +} + +bool +GemcutterRepository::has_category_named(const CategoryNamePart & c) const +{ + return _imp->store->has_category_named(c); +} + +bool +GemcutterRepository::has_package_named(const QualifiedPackageName & q) const +{ + return _imp->store->has_package_named(q); +} + +std::shared_ptr<const CategoryNamePartSet> +GemcutterRepository::category_names() const +{ + return _imp->store->category_names(); +} + +std::shared_ptr<const CategoryNamePartSet> +GemcutterRepository::unimportant_category_names() const +{ + return _imp->store->unimportant_category_names(); +} + +std::shared_ptr<const CategoryNamePartSet> +GemcutterRepository::category_names_containing_package(const PackageNamePart & p) const +{ + return Repository::category_names_containing_package(p); +} + +std::shared_ptr<const QualifiedPackageNameSet> +GemcutterRepository::package_names(const CategoryNamePart & c) const +{ + return _imp->store->package_names(c); +} + +std::shared_ptr<const PackageIDSequence> +GemcutterRepository::package_ids(const QualifiedPackageName & p) const +{ + return _imp->store->package_ids(p); +} + +namespace +{ + struct SupportsActionQuery + { + bool visit(const SupportsActionTest<InstallAction> &) const + { + return true; + } + + bool visit(const SupportsActionTest<FetchAction> &) const + { + return true; + } + + bool visit(const SupportsActionTest<PretendFetchAction> &) const + { + return false; + } + + bool visit(const SupportsActionTest<ConfigAction> &) const + { + return false; + } + + bool visit(const SupportsActionTest<PretendAction> &) const + { + return false; + } + + bool visit(const SupportsActionTest<InfoAction> &) const + { + return false; + } + + bool visit(const SupportsActionTest<UninstallAction> &) const + { + return false; + } + }; +} + +bool +GemcutterRepository::some_ids_might_support_action(const SupportsActionTestBase & a) const +{ + SupportsActionQuery q; + return a.accept_returning<bool>(q); +} + +bool +GemcutterRepository::some_ids_might_not_be_masked() const +{ + return true; +} + +bool +GemcutterRepository::sync(const std::shared_ptr<OutputManager> &) const +{ + return false; +} + +std::shared_ptr<Repository> +GemcutterRepository::repository_factory_create( + Environment * const env, + const std::function<std::string (const std::string &)> & f) +{ + Context context("When making repository repository from repo_file '" + f("repo_file") + "':"); + + std::string name_str(f("name")); + if (name_str.empty()) + name_str = "gemcutter"; + + std::string location_str(f("location")); + if (location_str.empty()) + throw GemcutterRepositoryConfigurationError("Key 'location' not specified or empty"); + + return std::make_shared<GemcutterRepository>( + make_named_values<GemcutterRepositoryParams>( + n::environment() = env, + n::location() = FSPath(location_str), + n::name() = RepositoryName(name_str) + )); +} + +RepositoryName +GemcutterRepository::repository_factory_name( + const Environment * const, + const std::function<std::string (const std::string &)> & f) +{ + if (f("name").empty()) + return RepositoryName("gemcutter"); + else + return RepositoryName(f("name")); +} + +std::shared_ptr<const RepositoryNameSet> +GemcutterRepository::repository_factory_dependencies( + const Environment * const, + const std::function<std::string (const std::string &)> &) +{ + return std::make_shared<RepositoryNameSet>(); +} + +void +GemcutterRepository::populate_sets() const +{ +} + +HookResult +GemcutterRepository::perform_hook(const Hook &, const std::shared_ptr<OutputManager> &) +{ + return make_named_values<HookResult>(n::max_exit_status() = 0, n::output() = ""); +} + +const std::shared_ptr<const MetadataValueKey<std::string> > +GemcutterRepository::accept_keywords_key() const +{ + return make_null_shared_ptr(); +} + +const std::shared_ptr<const MetadataValueKey<std::string> > +GemcutterRepository::sync_host_key() const +{ + return make_null_shared_ptr(); +} + +template class Pimp<gemcutter_repository::GemcutterRepository>; + diff --git a/paludis/repositories/gemcutter/gemcutter_repository.hh b/paludis/repositories/gemcutter/gemcutter_repository.hh new file mode 100644 index 000000000..ffecd7e66 --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_repository.hh @@ -0,0 +1,127 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_REPOSITORY_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_REPOSITORY_HH 1 + +#include <paludis/repositories/gemcutter/gemcutter_repository-fwd.hh> +#include <paludis/repository.hh> +#include <paludis/util/pimp.hh> +#include <paludis/util/attributes.hh> +#include <paludis/util/fs_path.hh> + +namespace paludis +{ + namespace n + { + typedef Name<struct environment_name> environment; + typedef Name<struct location_name> location; + typedef Name<struct name_name> name; + } + + namespace gemcutter_repository + { + class PALUDIS_VISIBLE GemcutterRepositoryConfigurationError : + public ConfigurationError + { + public: + GemcutterRepositoryConfigurationError(const std::string &) throw (); + }; + + struct GemcutterRepositoryParams + { + NamedValue<n::environment, Environment *> environment; + NamedValue<n::location, FSPath> location; + NamedValue<n::name, RepositoryName> name; + }; + + class PALUDIS_VISIBLE GemcutterRepository : + private Pimp<GemcutterRepository>, + public Repository, + public std::enable_shared_from_this<GemcutterRepository> + { + private: + Pimp<GemcutterRepository>::ImpPtr & _imp; + + void _add_metadata_keys(); + + protected: + virtual void need_keys_added() const; + + public: + GemcutterRepository(const GemcutterRepositoryParams &); + ~GemcutterRepository(); + + virtual bool can_be_favourite_repository() const; + + virtual const bool is_unimportant() const; + + virtual const std::shared_ptr<const MetadataValueKey<std::string> > format_key() const; + virtual const std::shared_ptr<const MetadataValueKey<FSPath> > location_key() const; + virtual const std::shared_ptr<const MetadataValueKey<FSPath> > installed_root_key() const; + virtual const std::shared_ptr<const MetadataValueKey<std::string> > accept_keywords_key() const; + virtual const std::shared_ptr<const MetadataValueKey<std::string> > sync_host_key() const; + + virtual bool has_category_named(const CategoryNamePart & c) const; + virtual bool has_package_named(const QualifiedPackageName & q) const; + virtual std::shared_ptr<const CategoryNamePartSet> category_names() const; + virtual std::shared_ptr<const CategoryNamePartSet> unimportant_category_names() const; + virtual std::shared_ptr<const CategoryNamePartSet> category_names_containing_package(const PackageNamePart & p) const; + virtual std::shared_ptr<const QualifiedPackageNameSet> package_names(const CategoryNamePart & c) const; + virtual std::shared_ptr<const PackageIDSequence> package_ids(const QualifiedPackageName & p) const; + + virtual bool some_ids_might_support_action(const SupportsActionTestBase &) const; + virtual bool some_ids_might_not_be_masked() const; + virtual void invalidate(); + virtual void invalidate_masks(); + + virtual bool sync(const std::shared_ptr<OutputManager> &) const; + + ///\name RepositoryFactory functions + ///\{ + + static RepositoryName repository_factory_name( + const Environment * const env, + const std::function<std::string (const std::string &)> &); + + static std::shared_ptr<Repository> repository_factory_create( + Environment * const env, + const std::function<std::string (const std::string &)> &); + + static std::shared_ptr<const RepositoryNameSet> repository_factory_dependencies( + const Environment * const env, + const std::function<std::string (const std::string &)> &); + + ///\} + + ///\name Set methods + ///\{ + + virtual void populate_sets() const; + + ///\} + + virtual HookResult perform_hook(const Hook & hook, const std::shared_ptr<OutputManager> &); + }; + } + + extern template class Pimp<gemcutter_repository::GemcutterRepository>; +} + +#endif diff --git a/paludis/repositories/gemcutter/gemcutter_repository_store.cc b/paludis/repositories/gemcutter/gemcutter_repository_store.cc new file mode 100644 index 000000000..4a54282af --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_repository_store.cc @@ -0,0 +1,195 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/gemcutter/gemcutter_repository_store.hh> +#include <paludis/repositories/gemcutter/gemcutter_repository.hh> +#include <paludis/repositories/gemcutter/gemcutter_id.hh> +#include <paludis/repositories/gemcutter/json_things_handle.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/set.hh> +#include <paludis/util/sequence.hh> +#include <paludis/util/hashes.hh> +#include <paludis/util/is_file_with_extension.hh> +#include <paludis/util/log.hh> +#include <paludis/util/make_named_values.hh> +#include <paludis/util/fs_stat.hh> +#include <paludis/name.hh> +#include <paludis/version_spec.hh> +#include <paludis/literal_metadata_key.hh> +#include <paludis/environment.hh> +#include <paludis/package_database.hh> +#include <functional> +#include <unordered_map> +#include <algorithm> +#include <set> + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +typedef std::unordered_map<CategoryNamePart, + std::shared_ptr<QualifiedPackageNameSet>, + Hash<CategoryNamePart> > PackageNames; + +typedef std::unordered_map<QualifiedPackageName, + std::shared_ptr<PackageIDSequence>, + Hash<QualifiedPackageName> > IDs; + +namespace paludis +{ + template <> + struct Imp<GemcutterRepositoryStore> + { + const Environment * const env; + const GemcutterRepository * const repo; + const FSPath location; + std::shared_ptr<CategoryNamePartSet> categories; + PackageNames package_names; + IDs ids; + + Imp(const Environment * const e, const GemcutterRepository * const r, const FSPath & l) : + env(e), + repo(r), + location(l), + categories(std::make_shared<CategoryNamePartSet>()) + { + } + }; +} + +GemcutterRepositoryStore::GemcutterRepositoryStore( + const Environment * const env, + const GemcutterRepository * const repo, + const FSPath & location) : + Pimp<GemcutterRepositoryStore>(env, repo, location) +{ + _populate(); +} + +GemcutterRepositoryStore::~GemcutterRepositoryStore() +{ +} + +void +GemcutterRepositoryStore::_populate() +{ + Context context("When populating ::" + stringify(_imp->repo->name()) + ":"); + + FSPath all_gems(_imp->location / "all-gems.json"); + if (! all_gems.stat().exists()) + { + Log::get_instance()->message("gemcutter_repository.no_all_gems_file", ll_warning, lc_context) + << "File '" << all_gems << "' does not exist, and it should, unless you have just created " + << "the ::" << stringify(_imp->repo->name()) << " repository and not yet synced it"; + return; + } + + try + { + JSONThingsHandle::get_instance()->parse_all_gems( + all_gems, + std::bind(&GemcutterRepositoryStore::_populate_one, this, std::placeholders::_1)); + } + catch (const Exception & e) + { + Log::get_instance()->message("gemcutter_repository.not_available", ll_warning, lc_context) + << "Not loading '" << all_gems << "' for ::" << stringify(_imp->repo->name()) << " due to " + << "exception '" << e.message() << "' (" << e.what() << ")"; + + _imp->categories->clear(); + _imp->package_names.clear(); + _imp->ids.clear(); + + return; + } +} + +void +GemcutterRepositoryStore::_populate_one(const GemJSONInfo & info) +{ + Context context("When populating ::" + stringify(_imp->repo->name()) + " " + + stringify(info.name()) + " " + stringify(info.version()) + ":"); + + const std::shared_ptr<GemcutterID> id(std::make_shared<GemcutterID>(make_named_values<GemcutterIDParams>( + n::environment() = _imp->env, + n::info() = info, + n::repository() = _imp->repo + ))); + + _imp->categories->insert(id->name().category()); + + PackageNames::iterator p(_imp->package_names.find(id->name().category())); + if (_imp->package_names.end() == p) + p = _imp->package_names.insert(std::make_pair(id->name().category(), + std::make_shared<QualifiedPackageNameSet>())).first; + p->second->insert(id->name()); + + IDs::iterator i(_imp->ids.find(id->name())); + if (_imp->ids.end() == i) + i = _imp->ids.insert(std::make_pair(id->name(), std::make_shared<PackageIDSequence>())).first; + i->second->push_back(id); +} + +bool +GemcutterRepositoryStore::has_category_named(const CategoryNamePart & c) const +{ + return _imp->categories->end() != _imp->categories->find(c); +} + +bool +GemcutterRepositoryStore::has_package_named(const QualifiedPackageName & q) const +{ + return _imp->ids.end() != _imp->ids.find(q); +} + +std::shared_ptr<const CategoryNamePartSet> +GemcutterRepositoryStore::category_names() const +{ + return _imp->categories; +} + +std::shared_ptr<const CategoryNamePartSet> +GemcutterRepositoryStore::unimportant_category_names() const +{ + std::shared_ptr<CategoryNamePartSet> result(std::make_shared<CategoryNamePartSet>()); + return result; +} + +std::shared_ptr<const QualifiedPackageNameSet> +GemcutterRepositoryStore::package_names(const CategoryNamePart & c) const +{ + auto p(_imp->package_names.find(c)); + if (_imp->package_names.end() == p) + return std::make_shared<QualifiedPackageNameSet>(); + else + return p->second; +} + +std::shared_ptr<const PackageIDSequence> +GemcutterRepositoryStore::package_ids(const QualifiedPackageName & p) const +{ + auto i(_imp->ids.find(p)); + if (_imp->ids.end() == i) + return std::make_shared<PackageIDSequence>(); + else + return i->second; +} + +template class Pimp<gemcutter_repository::GemcutterRepositoryStore>; + diff --git a/paludis/repositories/gemcutter/gemcutter_repository_store.hh b/paludis/repositories/gemcutter/gemcutter_repository_store.hh new file mode 100644 index 000000000..c175ce8fd --- /dev/null +++ b/paludis/repositories/gemcutter/gemcutter_repository_store.hh @@ -0,0 +1,75 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_REPOSITORY_STORE_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_GEMCUTTER_REPOSITORY_STORE_HH 1 + +#include <paludis/repositories/gemcutter/gemcutter_repository-fwd.hh> +#include <paludis/repositories/gemcutter/json_things_handle-fwd.hh> +#include <paludis/repositories/gemcutter/json_things.hh> +#include <paludis/util/pimp.hh> +#include <paludis/util/fs_path-fwd.hh> +#include <paludis/name-fwd.hh> +#include <paludis/package_id-fwd.hh> +#include <paludis/environment-fwd.hh> +#include <memory> + +namespace paludis +{ + namespace gemcutter_repository + { + class PALUDIS_VISIBLE GemcutterRepositoryStore : + private Pimp<GemcutterRepositoryStore> + { + private: + void _populate(); + void _populate_one(const GemJSONInfo &); + + public: + GemcutterRepositoryStore( + const Environment * const, + const GemcutterRepository * const, + const FSPath &); + + ~GemcutterRepositoryStore(); + + bool has_category_named(const CategoryNamePart &) const + PALUDIS_ATTRIBUTE((warn_unused_result)); + + bool has_package_named(const QualifiedPackageName & q) const + PALUDIS_ATTRIBUTE((warn_unused_result)); + + std::shared_ptr<const CategoryNamePartSet> category_names() const + PALUDIS_ATTRIBUTE((warn_unused_result)); + + std::shared_ptr<const CategoryNamePartSet> unimportant_category_names() const + PALUDIS_ATTRIBUTE((warn_unused_result)); + + std::shared_ptr<const QualifiedPackageNameSet> package_names( + const CategoryNamePart & c) const PALUDIS_ATTRIBUTE((warn_unused_result)); + + std::shared_ptr<const PackageIDSequence> package_ids( + const QualifiedPackageName & p) const PALUDIS_ATTRIBUTE((warn_unused_result)); + }; + } + + extern template class Pimp<gemcutter_repository::GemcutterRepositoryStore>; +} + +#endif diff --git a/paludis/repositories/gemcutter/json_common-fwd.hh b/paludis/repositories/gemcutter/json_common-fwd.hh new file mode 100644 index 000000000..ab2ae0414 --- /dev/null +++ b/paludis/repositories/gemcutter/json_common-fwd.hh @@ -0,0 +1,36 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_COMMON_FWD_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_COMMON_FWD_HH 1 + +#include <functional> + +namespace paludis +{ + namespace gemcutter_repository + { + class JSONError; + class GemJSONInfo; + + typedef std::function<void (const GemJSONInfo &)> ParsedOneGemCallback; + } +} + +#endif diff --git a/paludis/repositories/gemcutter/json_common.cc b/paludis/repositories/gemcutter/json_common.cc new file mode 100644 index 000000000..35b4d1e41 --- /dev/null +++ b/paludis/repositories/gemcutter/json_common.cc @@ -0,0 +1,29 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/gemcutter/json_common.hh> + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +JSONError::JSONError(const std::string & s) throw () : + Exception(s) +{ +} + diff --git a/paludis/repositories/gemcutter/json_common.hh b/paludis/repositories/gemcutter/json_common.hh new file mode 100644 index 000000000..196a4e055 --- /dev/null +++ b/paludis/repositories/gemcutter/json_common.hh @@ -0,0 +1,52 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_COMMON_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_COMMON_HH 1 + +#include <paludis/repositories/gemcutter/json_common-fwd.hh> +#include <paludis/util/exception.hh> +#include <paludis/util/named_value.hh> + +namespace paludis +{ + namespace n + { + typedef Name<struct name_name> name; + typedef Name<struct version_name> version; + } + + namespace gemcutter_repository + { + struct GemJSONInfo + { + NamedValue<n::name, std::string> name; + NamedValue<n::version, std::string> version; + }; + + class PALUDIS_VISIBLE JSONError : + public Exception + { + public: + JSONError(const std::string &) throw (); + }; + } +} + +#endif diff --git a/paludis/repositories/gemcutter/json_things.cc b/paludis/repositories/gemcutter/json_things.cc new file mode 100644 index 000000000..b525dab86 --- /dev/null +++ b/paludis/repositories/gemcutter/json_things.cc @@ -0,0 +1,74 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/gemcutter/json_things.hh> +#include <paludis/repositories/gemcutter/json_common.hh> +#include <paludis/util/fs_path.hh> +#include <paludis/util/make_named_values.hh> +#include <paludis/util/stringify.hh> + +#include <jansson.h> + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +extern "C" +void +gemcutter_json_things_parse_all_gems( + const FSPath & path, + const ParsedOneGemCallback & parsed_one_gem) +{ + json_error_t error; + json_t * root(json_load_file(stringify(path).c_str(), &error)); + + if (! root) + throw JSONError("Couldn't load '" + stringify(path) + "': jansson said: " + error.text); + + if (! json_is_array(root)) + throw JSONError("Root is not an array"); + + for (int i(0), i_end(json_array_size(root)) ; + i != i_end ; ++i) + { + std::string name, version; + + json_t * entry(json_array_get(root, i)); + if ((! entry) || (! json_is_object(entry))) + throw JSONError("Entry is not an object"); + + json_t * name_id(json_object_get(entry, "name")); + if ((! name_id) || (! json_is_string(name_id))) + throw JSONError("Entry name is not a string"); + name = std::string(json_string_value(name_id)); + + json_t * version_id(json_object_get(entry, "version")); + if ((! version_id) || (! json_is_string(version_id))) + throw JSONError("Entry version is not a string"); + version = std::string(json_string_value(version_id)); + + GemJSONInfo info(make_named_values<GemJSONInfo>( + n::name() = name, + n::version() = version + )); + parsed_one_gem(info); + } + + json_decref(root); +} + diff --git a/paludis/repositories/gemcutter/json_things.hh b/paludis/repositories/gemcutter/json_things.hh new file mode 100644 index 000000000..20c4f68f9 --- /dev/null +++ b/paludis/repositories/gemcutter/json_things.hh @@ -0,0 +1,34 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_THINGS_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_THINGS_HH 1 + +#include <paludis/repositories/gemcutter/json_common-fwd.hh> +#include <paludis/util/attributes.hh> +#include <paludis/util/fs_path-fwd.hh> +#include <paludis/util/named_value.hh> +#include <paludis/util/exception.hh> +#include <functional> + +extern "C" void gemcutter_json_things_parse_all_gems( + const paludis::FSPath &, + const paludis::gemcutter_repository::ParsedOneGemCallback &) PALUDIS_VISIBLE; + +#endif diff --git a/paludis/repositories/gemcutter/json_things_handle-fwd.hh b/paludis/repositories/gemcutter/json_things_handle-fwd.hh new file mode 100644 index 000000000..671fd4c47 --- /dev/null +++ b/paludis/repositories/gemcutter/json_things_handle-fwd.hh @@ -0,0 +1,31 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_THINGS_HANDLE_FWD_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_THINGS_HANDLE_FWD_HH 1 + +namespace paludis +{ + namespace gemcutter_repository + { + struct JSONThingsHandle; + } +} + +#endif diff --git a/paludis/repositories/gemcutter/json_things_handle.cc b/paludis/repositories/gemcutter/json_things_handle.cc new file mode 100644 index 000000000..f6d48bd10 --- /dev/null +++ b/paludis/repositories/gemcutter/json_things_handle.cc @@ -0,0 +1,63 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repositories/gemcutter/json_things_handle.hh> +#include <paludis/util/singleton-impl.hh> +#include <paludis/util/exception.hh> + +#include <paludis/about.hh> + +#include <string.h> +#include <dlfcn.h> +#include <stdint.h> + +#include "config.h" + +#define STUPID_CAST(type, val) reinterpret_cast<type>(reinterpret_cast<uintptr_t>(val)) + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +JSONThingsHandle::JSONThingsHandle() : + handle(0), + parse_all_gems_function(0) +{ + handle = ::dlopen(("libpaludisgemcutterrepositoryjsonthings_" + stringify(PALUDIS_PC_SLOT) + ".so").c_str(), RTLD_NOW | RTLD_GLOBAL); + if (! handle) + throw NotAvailableError("JSON not available because dlopen said " + stringify(::dlerror())); + + parse_all_gems_function = STUPID_CAST(ParseAllGemsFunction, ::dlsym(handle, "gemcutter_json_things_parse_all_gems")); + if (! parse_all_gems_function) + throw NotAvailableError("JSON not available because dlsym said " + stringify(::dlerror())); +} + +JSONThingsHandle::~JSONThingsHandle() +{ + if (handle) + ::dlclose(handle); +} + +void +JSONThingsHandle::parse_all_gems(const FSPath & p, const ParsedOneGemCallback & c) const +{ + parse_all_gems_function(p, c); +} + +template class Singleton<JSONThingsHandle>; + diff --git a/paludis/repositories/gemcutter/json_things_handle.hh b/paludis/repositories/gemcutter/json_things_handle.hh new file mode 100644 index 000000000..9a45b57fa --- /dev/null +++ b/paludis/repositories/gemcutter/json_things_handle.hh @@ -0,0 +1,56 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_THINGS_HANDLE_HH +#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_GEMCUTTER_JSON_THINGS_HANDLE_HH 1 + +#include <paludis/repositories/gemcutter/json_things_handle-fwd.hh> +#include <paludis/repositories/gemcutter/json_things.hh> +#include <paludis/util/singleton.hh> +#include <paludis/util/named_value.hh> +#include <paludis/util/fs_path-fwd.hh> +#include <string> + +namespace paludis +{ + namespace gemcutter_repository + { + class JSONThingsHandle : + public Singleton<JSONThingsHandle> + { + friend class Singleton<JSONThingsHandle>; + + private: + void * handle; + + typedef void (* ParseAllGemsFunction)(const FSPath &, const ParsedOneGemCallback &); + ParseAllGemsFunction parse_all_gems_function; + + JSONThingsHandle(); + ~JSONThingsHandle(); + + public: + void parse_all_gems(const FSPath &, const ParsedOneGemCallback &) const; + }; + } + + extern template class Singleton<gemcutter_repository::JSONThingsHandle>; +} + +#endif diff --git a/paludis/repositories/gemcutter/registration.cc b/paludis/repositories/gemcutter/registration.cc new file mode 100644 index 000000000..597300215 --- /dev/null +++ b/paludis/repositories/gemcutter/registration.cc @@ -0,0 +1,62 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/repository_factory.hh> +#include <paludis/repositories/gemcutter/gemcutter_repository.hh> +#include <paludis/util/set.hh> +#include <paludis/util/destringify.hh> +#include "config.h" + +using namespace paludis; +using namespace paludis::gemcutter_repository; + +namespace +{ + int generic_importance(const Environment * const, const std::function<std::string (const std::string &)> & f) + { + if (! f("importance").empty()) + return destringify<int>(f("importance")); + else + return 1; + } +} + +namespace paludis +{ + namespace repository_groups + { + REPOSITORY_GROUPS_DECLS; + } + + template <> + void register_repositories<repository_groups::gemcutter>(const repository_groups::gemcutter * const, + RepositoryFactory * const factory) + { + std::shared_ptr<Set<std::string> > repository_formats(std::make_shared<Set<std::string>>()); + repository_formats->insert("gemcutter"); + + factory->add_repository_format(repository_formats, + &GemcutterRepository::repository_factory_name, + &generic_importance, + &GemcutterRepository::repository_factory_create, + &GemcutterRepository::repository_factory_dependencies + ); + } +} + |