| "The Git ref to from which the source distribution should be created", | "The Git ref to from which the source distribution should be created", | ||||
| {"git-ref"}}; | {"git-ref"}}; | ||||
| string_flag description{cmd, "description", "A description of the package", {"desc"}}; | |||||
| int run() { | int run() { | ||||
| auto ident = dds::package_id::parse(pkg_id.Get()); | auto ident = dds::package_id::parse(pkg_id.Get()); | ||||
| // deps.push_back({dep_id.name, dep_id.version}); | // 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_url) { | ||||
| if (!git_ref) { | if (!git_ref) { |
| git_ref TEXT, | git_ref TEXT, | ||||
| lm_name TEXT, | lm_name TEXT, | ||||
| lm_namespace TEXT, | lm_namespace TEXT, | ||||
| description TEXT NOT NULL, | |||||
| UNIQUE(name, version), | UNIQUE(name, version), | ||||
| CONSTRAINT has_source_info CHECK( | CONSTRAINT has_source_info CHECK( | ||||
| ( | ( | ||||
| git_url, | git_url, | ||||
| git_ref, | git_ref, | ||||
| lm_name, | lm_name, | ||||
| lm_namespace | |||||
| lm_namespace, | |||||
| description | |||||
| ) VALUES ( | ) VALUES ( | ||||
| ?1, | ?1, | ||||
| ?2, | ?2, | ||||
| ?3, | ?3, | ||||
| ?4, | ?4, | ||||
| CASE WHEN ?5 = '' THEN NULL ELSE ?5 END, | 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, | )"_sql, | ||||
| std::forward_as_tuple( // | std::forward_as_tuple( // | ||||
| git.url, | git.url, | ||||
| git.ref, | git.ref, | ||||
| lm_usage.name, | lm_usage.name, | ||||
| lm_usage.namespace_)); | |||||
| lm_usage.namespace_, | |||||
| pkg.description)); | |||||
| } | } | ||||
| void catalog::store(const package_info& pkg) { | void catalog::store(const package_info& pkg) { | ||||
| git_url, | git_url, | ||||
| git_ref, | git_ref, | ||||
| lm_name, | lm_name, | ||||
| lm_namespace | |||||
| lm_namespace, | |||||
| description | |||||
| FROM dds_cat_pkgs | FROM dds_cat_pkgs | ||||
| WHERE name = ? AND version = ? | WHERE name = ? AND version = ? | ||||
| )"_sql); | )"_sql); | ||||
| std::optional<std::string>, | std::optional<std::string>, | ||||
| std::optional<std::string>, | 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) { | if (!opt_tup) { | ||||
| return std::nullopt; | 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.name == name); | ||||
| assert(pk_id.version == semver::version::parse(version)); | assert(pk_id.version == semver::version::parse(version)); | ||||
| assert(git_url); | assert(git_url); | ||||
| return package_info{ | return package_info{ | ||||
| pk_id, | pk_id, | ||||
| std::move(deps), | std::move(deps), | ||||
| std::move(description), | |||||
| git_remote_listing{ | git_remote_listing{ | ||||
| *git_url, | *git_url, | ||||
| *git_ref, | *git_ref, | ||||
| pkg_name, | pkg_name, | ||||
| version_)); | version_)); | ||||
| package_info info{{pkg_name, version}, {}, {}}; | |||||
| package_info info{{pkg_name, version}, {}, {}, {}}; | |||||
| for (const auto& [dep_name, dep_version] : deps.items()) { | for (const auto& [dep_name, dep_version] : deps.items()) { | ||||
| check_json(dep_version.is_string(), | check_json(dep_version.is_string(), | ||||
| fmt::format("/packages/{}/{}/depends/{} must be a string", | fmt::format("/packages/{}/{}/depends/{} must be a string", | ||||
| version_); | 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); | store(info); | ||||
| } | } | ||||
| } | } |
| #include <neo/sqlite3/statement_cache.hpp> | #include <neo/sqlite3/statement_cache.hpp> | ||||
| #include <neo/sqlite3/transaction.hpp> | #include <neo/sqlite3/transaction.hpp> | ||||
| #include <string> | |||||
| #include <variant> | #include <variant> | ||||
| #include <vector> | #include <vector> | ||||
| struct package_info { | struct package_info { | ||||
| package_id ident; | package_id ident; | ||||
| std::vector<dependency> deps; | std::vector<dependency> deps; | ||||
| std::string description; | |||||
| std::variant<git_remote_listing> remote; | std::variant<git_remote_listing> remote; | ||||
| }; | }; |
| db.store(dds::package_info{ | db.store(dds::package_info{ | ||||
| dds::package_id("foo", semver::version::parse("1.2.3")), | dds::package_id("foo", semver::version::parse("1.2.3")), | ||||
| {}, | {}, | ||||
| "example", | |||||
| dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | ||||
| }); | }); | ||||
| CHECK_NOTHROW(db.store(dds::package_info{ | CHECK_NOTHROW(db.store(dds::package_info{ | ||||
| dds::package_id("foo", semver::version::parse("1.2.3")), | dds::package_id("foo", semver::version::parse("1.2.3")), | ||||
| {}, | {}, | ||||
| "example", | |||||
| dds::git_remote_listing{"http://example.com", "develop", std::nullopt}, | dds::git_remote_listing{"http://example.com", "develop", std::nullopt}, | ||||
| })); | })); | ||||
| // The previous pkg_id is still a valid lookup key | // The previous pkg_id is still a valid lookup key | ||||
| {"bar", {semver::version::parse("1.2.3"), semver::version::parse("1.4.0")}}, | {"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")}}, | {"baz", {semver::version::parse("5.3.0"), semver::version::parse("6.0.0")}}, | ||||
| }, | }, | ||||
| "example", | |||||
| dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | ||||
| }); | }); | ||||
| auto pkgs = db.by_name("foo"); | auto pkgs = db.by_name("foo"); |
| assert False, 'impossible' | assert False, 'impossible' | ||||
| cat_path = paths.BUILD_DIR / 'catalog.db' | cat_path = paths.BUILD_DIR / 'catalog.db' | ||||
| if cat_path.is_file(): | |||||
| cat_path.unlink() | |||||
| ci_repo_dir = paths.BUILD_DIR / '_ci-repo' | ci_repo_dir = paths.BUILD_DIR / '_ci-repo' | ||||
| if ci_repo_dir.exists(): | if ci_repo_dir.exists(): | ||||
| shutil.rmtree(ci_repo_dir) | shutil.rmtree(ci_repo_dir) | ||||
| ]) | ]) | ||||
| print('Main build PASSED!') | 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([ | proc.check_run([ | ||||
| paths.CUR_BUILT_DDS, | paths.CUR_BUILT_DDS, | ||||
| 'catalog', | 'catalog', |
| import json | import json | ||||
| from typing import NamedTuple, Tuple, List, Sequence, Union, Optional, Mapping | from typing import NamedTuple, Tuple, List, Sequence, Union, Optional, Mapping | ||||
| import sys | import sys | ||||
| import textwrap | |||||
| class Git(NamedTuple): | class Git(NamedTuple): | ||||
| version: str | version: str | ||||
| remote: RemoteInfo | remote: RemoteInfo | ||||
| depends: Mapping[str, str] = {} | depends: Mapping[str, str] = {} | ||||
| description: str = '(No description provided)' | |||||
| def to_dict(self) -> dict: | def to_dict(self) -> dict: | ||||
| ret = {} | |||||
| ret: dict = { | |||||
| 'description': self.description, | |||||
| } | |||||
| ret['depends'] = {} | ret['depends'] = {} | ||||
| if isinstance(self.remote, Git): | if isinstance(self.remote, Git): | ||||
| ret['git'] = self.remote.to_dict() | ret['git'] = self.remote.to_dict() | ||||
| *, | *, | ||||
| tag_fmt: str = '{}', | tag_fmt: str = '{}', | ||||
| git_url: str, | git_url: str, | ||||
| auto_lib: str = None) -> Package: | |||||
| auto_lib: str = None, | |||||
| description='(No description was provided)') -> Package: | |||||
| return Package(name, [ | return Package(name, [ | ||||
| Version( | Version( | ||||
| ver, | ver, | ||||
| description='\n'.join(textwrap.wrap(description)), | |||||
| remote=Git( | remote=Git( | ||||
| url=git_url, ref=tag_fmt.format(ver), auto_lib=auto_lib)) | url=git_url, ref=tag_fmt.format(ver), auto_lib=auto_lib)) | ||||
| for ver in versions | for ver in versions | ||||
| ), | ), | ||||
| git_url='https://github.com/ericniebler/range-v3.git', | git_url='https://github.com/ericniebler/range-v3.git', | ||||
| auto_lib='Niebler/range-v3', | auto_lib='Niebler/range-v3', | ||||
| description= | |||||
| 'Range library for C++14/17/20, basis for C++20\'s std::ranges', | |||||
| ), | ), | ||||
| many_versions( | many_versions( | ||||
| 'nlohmann-json', | 'nlohmann-json', | ||||
| ), | ), | ||||
| git_url='https://github.com/vector-of-bool/json.git', | git_url='https://github.com/vector-of-bool/json.git', | ||||
| tag_fmt='dds/{}', | tag_fmt='dds/{}', | ||||
| description='JSON for Modern C++', | |||||
| ), | ), | ||||
| Package('ms-wil', [ | Package('ms-wil', [ | ||||
| Version( | Version( | ||||
| '2019.11.10', | '2019.11.10', | ||||
| description='The Windows Implementation Library', | |||||
| remote=Git('https://github.com/vector-of-bool/wil.git', | remote=Git('https://github.com/vector-of-bool/wil.git', | ||||
| 'dds/2019.11.10')) | 'dds/2019.11.10')) | ||||
| ]), | ]), | ||||
| '0.2.0', | '0.2.0', | ||||
| '0.2.1', | '0.2.1', | ||||
| ), | ), | ||||
| description='A modern and low-level C++ SQLite API', | |||||
| git_url='https://github.com/vector-of-bool/neo-sqlite3.git', | git_url='https://github.com/vector-of-bool/neo-sqlite3.git', | ||||
| ), | ), | ||||
| Package('neo-fun', [ | Package('neo-fun', [ | ||||
| Version( | Version( | ||||
| '0.1.0', | '0.1.0', | ||||
| description='Some library fundamentals that you might find useful', | |||||
| remote=Git('https://github.com/vector-of-bool/neo-fun.git', | remote=Git('https://github.com/vector-of-bool/neo-fun.git', | ||||
| '0.1.0')) | '0.1.0')) | ||||
| ]), | ]), | ||||
| Package('semver', [ | Package('semver', [ | ||||
| Version( | Version( | ||||
| '0.2.1', | '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', | remote=Git('https://github.com/vector-of-bool/semver.git', | ||||
| '0.2.1')) | '0.2.1')) | ||||
| ]), | ]), | ||||
| '0.1.2', | '0.1.2', | ||||
| '0.2.0', | '0.2.0', | ||||
| ), | ), | ||||
| description= | |||||
| 'A C++ implementation of the Pubgrub version solving algorithm', | |||||
| git_url='https://github.com/vector-of-bool/pubgrub.git', | git_url='https://github.com/vector-of-bool/pubgrub.git', | ||||
| ), | ), | ||||
| many_versions( | many_versions( | ||||
| git_url='https://github.com/gabime/spdlog.git', | git_url='https://github.com/gabime/spdlog.git', | ||||
| tag_fmt='v{}', | tag_fmt='v{}', | ||||
| auto_lib='spdlog/spdlog', | auto_lib='spdlog/spdlog', | ||||
| description='Fast C++ logging library', | |||||
| ), | ), | ||||
| many_versions( | many_versions( | ||||
| 'fmt', | 'fmt', | ||||
| ), | ), | ||||
| git_url='https://github.com/fmtlib/fmt.git', | git_url='https://github.com/fmtlib/fmt.git', | ||||
| auto_lib='fmt/fmt', | auto_lib='fmt/fmt', | ||||
| description='A modern formatting library : https://fmt.dev/', | |||||
| ), | ), | ||||
| ] | ] | ||||