"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/', | |||||
), | ), | ||||
] | ] | ||||