| @@ -234,6 +234,8 @@ struct cli_catalog { | |||
| "The Git ref to from which the source distribution should be created", | |||
| {"git-ref"}}; | |||
| string_flag description{cmd, "description", "A description of the package", {"desc"}}; | |||
| int run() { | |||
| auto ident = dds::package_id::parse(pkg_id.Get()); | |||
| @@ -244,7 +246,7 @@ struct cli_catalog { | |||
| // deps.push_back({dep_id.name, dep_id.version}); | |||
| } | |||
| dds::package_info info{ident, std::move(deps), {}}; | |||
| dds::package_info info{ident, std::move(deps), description.Get(), {}}; | |||
| if (git_url) { | |||
| if (!git_ref) { | |||
| @@ -30,6 +30,7 @@ void migrate_repodb_1(sqlite3::database& db) { | |||
| git_ref TEXT, | |||
| lm_name TEXT, | |||
| lm_namespace TEXT, | |||
| description TEXT NOT NULL, | |||
| UNIQUE(name, version), | |||
| CONSTRAINT has_source_info CHECK( | |||
| ( | |||
| @@ -132,14 +133,16 @@ void catalog::_store_pkg(const package_info& pkg, const git_remote_listing& git) | |||
| git_url, | |||
| git_ref, | |||
| lm_name, | |||
| lm_namespace | |||
| lm_namespace, | |||
| description | |||
| ) VALUES ( | |||
| ?1, | |||
| ?2, | |||
| ?3, | |||
| ?4, | |||
| CASE WHEN ?5 = '' THEN NULL ELSE ?5 END, | |||
| CASE WHEN ?6 = '' THEN NULL ELSE ?6 END | |||
| CASE WHEN ?6 = '' THEN NULL ELSE ?6 END, | |||
| ?7 | |||
| ) | |||
| )"_sql, | |||
| std::forward_as_tuple( // | |||
| @@ -148,7 +151,8 @@ void catalog::_store_pkg(const package_info& pkg, const git_remote_listing& git) | |||
| git.url, | |||
| git.ref, | |||
| lm_usage.name, | |||
| lm_usage.namespace_)); | |||
| lm_usage.namespace_, | |||
| pkg.description)); | |||
| } | |||
| void catalog::store(const package_info& pkg) { | |||
| @@ -191,7 +195,8 @@ std::optional<package_info> catalog::get(const package_id& pk_id) const noexcept | |||
| git_url, | |||
| git_ref, | |||
| lm_name, | |||
| lm_namespace | |||
| lm_namespace, | |||
| description | |||
| FROM dds_cat_pkgs | |||
| WHERE name = ? AND version = ? | |||
| )"_sql); | |||
| @@ -203,11 +208,13 @@ std::optional<package_info> catalog::get(const package_id& pk_id) const noexcept | |||
| std::optional<std::string>, | |||
| std::optional<std::string>, | |||
| std::optional<std::string>, | |||
| std::optional<std::string>>(st); | |||
| std::optional<std::string>, | |||
| std::string>(st); | |||
| if (!opt_tup) { | |||
| return std::nullopt; | |||
| } | |||
| const auto& [pkg_id, name, version, git_url, git_ref, lm_name, lm_namespace] = *opt_tup; | |||
| const auto& [pkg_id, name, version, git_url, git_ref, lm_name, lm_namespace, description] | |||
| = *opt_tup; | |||
| assert(pk_id.name == name); | |||
| assert(pk_id.version == semver::version::parse(version)); | |||
| assert(git_url); | |||
| @@ -218,6 +225,7 @@ std::optional<package_info> catalog::get(const package_id& pk_id) const noexcept | |||
| return package_info{ | |||
| pk_id, | |||
| std::move(deps), | |||
| std::move(description), | |||
| git_remote_listing{ | |||
| *git_url, | |||
| *git_ref, | |||
| @@ -317,7 +325,7 @@ void catalog::import_json_str(std::string_view content) { | |||
| pkg_name, | |||
| version_)); | |||
| package_info info{{pkg_name, version}, {}, {}}; | |||
| package_info info{{pkg_name, version}, {}, {}, {}}; | |||
| for (const auto& [dep_name, dep_version] : deps.items()) { | |||
| check_json(dep_version.is_string(), | |||
| fmt::format("/packages/{}/{}/depends/{} must be a string", | |||
| @@ -348,6 +356,12 @@ void catalog::import_json_str(std::string_view content) { | |||
| version_); | |||
| } | |||
| auto desc_ = pkg_info["description"]; | |||
| if (!desc_.is_null()) { | |||
| check_json(desc_.is_string(), "`description` must be a string"); | |||
| info.description = desc_; | |||
| } | |||
| store(info); | |||
| } | |||
| } | |||
| @@ -10,6 +10,7 @@ | |||
| #include <neo/sqlite3/statement_cache.hpp> | |||
| #include <neo/sqlite3/transaction.hpp> | |||
| #include <string> | |||
| #include <variant> | |||
| #include <vector> | |||
| @@ -18,6 +19,7 @@ namespace dds { | |||
| struct package_info { | |||
| package_id ident; | |||
| std::vector<dependency> deps; | |||
| std::string description; | |||
| std::variant<git_remote_listing> remote; | |||
| }; | |||
| @@ -18,6 +18,7 @@ TEST_CASE_METHOD(catalog_test_case, "Store a simple package") { | |||
| db.store(dds::package_info{ | |||
| dds::package_id("foo", semver::version::parse("1.2.3")), | |||
| {}, | |||
| "example", | |||
| dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | |||
| }); | |||
| @@ -36,6 +37,7 @@ TEST_CASE_METHOD(catalog_test_case, "Store a simple package") { | |||
| CHECK_NOTHROW(db.store(dds::package_info{ | |||
| dds::package_id("foo", semver::version::parse("1.2.3")), | |||
| {}, | |||
| "example", | |||
| dds::git_remote_listing{"http://example.com", "develop", std::nullopt}, | |||
| })); | |||
| // The previous pkg_id is still a valid lookup key | |||
| @@ -51,6 +53,7 @@ TEST_CASE_METHOD(catalog_test_case, "Package requirements") { | |||
| {"bar", {semver::version::parse("1.2.3"), semver::version::parse("1.4.0")}}, | |||
| {"baz", {semver::version::parse("5.3.0"), semver::version::parse("6.0.0")}}, | |||
| }, | |||
| "example", | |||
| dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | |||
| }); | |||
| auto pkgs = db.by_name("foo"); | |||
| @@ -81,6 +81,9 @@ def main(argv: Sequence[str]) -> int: | |||
| assert False, 'impossible' | |||
| cat_path = paths.BUILD_DIR / 'catalog.db' | |||
| if cat_path.is_file(): | |||
| cat_path.unlink() | |||
| ci_repo_dir = paths.BUILD_DIR / '_ci-repo' | |||
| if ci_repo_dir.exists(): | |||
| shutil.rmtree(ci_repo_dir) | |||
| @@ -101,6 +104,10 @@ def main(argv: Sequence[str]) -> int: | |||
| ]) | |||
| print('Main build PASSED!') | |||
| # Delete the catalog database, since there may be schema changes since the | |||
| # bootstrap executable was built | |||
| cat_path.unlink() | |||
| proc.check_run([ | |||
| paths.CUR_BUILT_DDS, | |||
| 'catalog', | |||
| @@ -1,6 +1,7 @@ | |||
| import json | |||
| from typing import NamedTuple, Tuple, List, Sequence, Union, Optional, Mapping | |||
| import sys | |||
| import textwrap | |||
| class Git(NamedTuple): | |||
| @@ -23,9 +24,12 @@ class Version(NamedTuple): | |||
| version: str | |||
| remote: RemoteInfo | |||
| depends: Mapping[str, str] = {} | |||
| description: str = '(No description provided)' | |||
| def to_dict(self) -> dict: | |||
| ret = {} | |||
| ret: dict = { | |||
| 'description': self.description, | |||
| } | |||
| ret['depends'] = {} | |||
| if isinstance(self.remote, Git): | |||
| ret['git'] = self.remote.to_dict() | |||
| @@ -42,10 +46,12 @@ def many_versions(name: str, | |||
| *, | |||
| tag_fmt: str = '{}', | |||
| git_url: str, | |||
| auto_lib: str = None) -> Package: | |||
| auto_lib: str = None, | |||
| description='(No description was provided)') -> Package: | |||
| return Package(name, [ | |||
| Version( | |||
| ver, | |||
| description='\n'.join(textwrap.wrap(description)), | |||
| remote=Git( | |||
| url=git_url, ref=tag_fmt.format(ver), auto_lib=auto_lib)) | |||
| for ver in versions | |||
| @@ -63,6 +69,8 @@ packages = [ | |||
| ), | |||
| git_url='https://github.com/ericniebler/range-v3.git', | |||
| auto_lib='Niebler/range-v3', | |||
| description= | |||
| 'Range library for C++14/17/20, basis for C++20\'s std::ranges', | |||
| ), | |||
| many_versions( | |||
| 'nlohmann-json', | |||
| @@ -85,10 +93,12 @@ packages = [ | |||
| ), | |||
| git_url='https://github.com/vector-of-bool/json.git', | |||
| tag_fmt='dds/{}', | |||
| description='JSON for Modern C++', | |||
| ), | |||
| Package('ms-wil', [ | |||
| Version( | |||
| '2019.11.10', | |||
| description='The Windows Implementation Library', | |||
| remote=Git('https://github.com/vector-of-bool/wil.git', | |||
| 'dds/2019.11.10')) | |||
| ]), | |||
| @@ -99,17 +109,22 @@ packages = [ | |||
| '0.2.0', | |||
| '0.2.1', | |||
| ), | |||
| description='A modern and low-level C++ SQLite API', | |||
| git_url='https://github.com/vector-of-bool/neo-sqlite3.git', | |||
| ), | |||
| Package('neo-fun', [ | |||
| Version( | |||
| '0.1.0', | |||
| description='Some library fundamentals that you might find useful', | |||
| remote=Git('https://github.com/vector-of-bool/neo-fun.git', | |||
| '0.1.0')) | |||
| ]), | |||
| Package('semver', [ | |||
| Version( | |||
| '0.2.1', | |||
| description= | |||
| 'A C++ library that implements Semantic Versioning parsing, emitting, ' | |||
| 'types, ordering, and operations. See https://semver.org/', | |||
| remote=Git('https://github.com/vector-of-bool/semver.git', | |||
| '0.2.1')) | |||
| ]), | |||
| @@ -119,6 +134,8 @@ packages = [ | |||
| '0.1.2', | |||
| '0.2.0', | |||
| ), | |||
| description= | |||
| 'A C++ implementation of the Pubgrub version solving algorithm', | |||
| git_url='https://github.com/vector-of-bool/pubgrub.git', | |||
| ), | |||
| many_versions( | |||
| @@ -147,6 +164,7 @@ packages = [ | |||
| git_url='https://github.com/gabime/spdlog.git', | |||
| tag_fmt='v{}', | |||
| auto_lib='spdlog/spdlog', | |||
| description='Fast C++ logging library', | |||
| ), | |||
| many_versions( | |||
| 'fmt', | |||
| @@ -178,6 +196,7 @@ packages = [ | |||
| ), | |||
| git_url='https://github.com/fmtlib/fmt.git', | |||
| auto_lib='fmt/fmt', | |||
| description='A modern formatting library : https://fmt.dev/', | |||
| ), | |||
| ] | |||