summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/minicargo/manifest.cpp165
-rw-r--r--tools/minicargo/manifest.h15
2 files changed, 127 insertions, 53 deletions
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index f817fb91..b468e1da 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -60,7 +60,14 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
// TODO: Warn/error
throw ::std::runtime_error("Build script path set twice");
}
- rv.m_build_script = key_val.value.as_string();
+ if( key_val.value.m_type == TomlValue::Type::Boolean ) {
+ if( key_val.value.as_bool() )
+ throw ::std::runtime_error("Build script set to 'true'?");
+ rv.m_build_script = "-";
+ }
+ else {
+ rv.m_build_script = key_val.value.as_string();
+ }
if(rv.m_build_script == "")
{
// TODO: Error
@@ -74,6 +81,7 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
|| key == "repository"
|| key == "readme"
|| key == "categories"
+ || key == "keywords"
|| key == "license"
)
{
@@ -141,57 +149,8 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
{
it = rv.m_dependencies.insert(it, PackageRef{ depname });
}
- auto& ref = *it;
-
- if( key_val.path.size() == 2 )
- {
- // Shorthand, picks a version from the package repository
- if(!was_added)
- {
- throw ::std::runtime_error(::format("ERROR: Duplicate dependency `", depname, "`"));
- }
- const auto& version_spec_str = key_val.value.as_string();
- ref.m_version = PackageVersionSpec::from_string(version_spec_str);
- }
- else
- {
-
- // (part of a) Full dependency specification
- const auto& attr = key_val.path[2];
- if( attr == "path" )
- {
- // Set path specification of the named depenency
- ref.m_path = key_val.value.as_string();
- }
- else if( attr == "git" )
- {
- // Load from git repo.
- TODO("Support git dependencies");
- }
- else if( attr == "branch" )
- {
- // Specify git branch
- TODO("Support git dependencies (branch)");
- }
- else if( attr == "version" )
- {
- assert(key_val.path.size() == 3);
- // Parse version specifier
- ref.m_version = PackageVersionSpec::from_string(key_val.value.as_string());
- }
- else if( attr == "optional" )
- {
- assert(key_val.path.size() == 3);
- ref.m_optional = key_val.value.as_bool();
- // TODO: Add a feature with the same name as the dependency.
- }
- else
- {
- // TODO: Error
- throw ::std::runtime_error(::format("ERROR: Unkown depencency attribute `", attr, "` on dependency `", depname, "`"));
- }
- }
+ it->fill_from_kv(was_added, key_val, 2);
}
else if( section == "build-dependencies" )
{
@@ -214,6 +173,10 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
{
// TODO: Features
}
+ else if( section == "workspace" )
+ {
+ // TODO: Workspaces?
+ }
// crates.io metadata
else if( section == "badges" )
{
@@ -233,6 +196,26 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
}
}
+ // Auto-detect the build script if required
+ if( rv.m_build_script == "-" )
+ {
+ // Explicitly disabled `[package] build = false`
+ rv.m_build_script = "";
+ }
+ else if( rv.m_build_script != "" )
+ {
+ // Not set, check for a "build.rs" file
+ if( ::std::ifstream( ::helpers::path(path).parent() / "build.rs").good() )
+ {
+ DEBUG("- Implicit build.rs");
+ rv.m_build_script = "build.rs";
+ }
+ }
+ else
+ {
+ // Explicitly set
+ }
+
return rv;
}
@@ -290,6 +273,14 @@ namespace
{
// TODO: Support crate types
}
+ else if( key == "required-features" )
+ {
+ assert(kv.path.size() == base_idx + 1);
+ for(const auto& sv : kv.value.m_sub_values)
+ {
+ target.m_required_features.push_back( sv.as_string() );
+ }
+ }
else
{
throw ::std::runtime_error( ::format("TODO: Handle target option `", key, "`") );
@@ -297,6 +288,71 @@ namespace
}
}
+void PackageRef::fill_from_kv(bool was_added, const TomlKeyValue& key_val, size_t base_idx)
+{
+ if( key_val.path.size() == base_idx )
+ {
+ // Shorthand, picks a version from the package repository
+ if(!was_added)
+ {
+ throw ::std::runtime_error(::format("ERROR: Duplicate dependency `", this->m_name, "`"));
+ }
+
+ const auto& version_spec_str = key_val.value.as_string();
+ this->m_version = PackageVersionSpec::from_string(version_spec_str);
+ }
+ else
+ {
+
+ // (part of a) Full dependency specification
+ const auto& attr = key_val.path[base_idx];
+ if( attr == "path" )
+ {
+ assert(key_val.path.size() == base_idx+1);
+ // Set path specification of the named depenency
+ this->m_path = key_val.value.as_string();
+ }
+ else if( attr == "git" )
+ {
+ // Load from git repo.
+ TODO("Support git dependencies");
+ }
+ else if( attr == "branch" )
+ {
+ // Specify git branch
+ TODO("Support git dependencies (branch)");
+ }
+ else if( attr == "version" )
+ {
+ assert(key_val.path.size() == base_idx+1);
+ // Parse version specifier
+ this->m_version = PackageVersionSpec::from_string(key_val.value.as_string());
+ }
+ else if( attr == "optional" )
+ {
+ assert(key_val.path.size() == base_idx+1);
+ this->m_optional = key_val.value.as_bool();
+ }
+ else if( attr == "default-features" )
+ {
+ assert(key_val.path.size() == base_idx+1);
+ //this->m_use_default_features = key_val.value.as_bool();
+ }
+ else if( attr == "features" )
+ {
+ for(const auto& sv : key_val.value.m_sub_values)
+ {
+ this->m_features.push_back( sv.as_string() );
+ }
+ }
+ else
+ {
+ // TODO: Error
+ throw ::std::runtime_error(::format("ERROR: Unkown depencency attribute `", attr, "` on dependency `", this->m_name, "`"));
+ }
+ }
+}
+
const PackageTarget& PackageManifest::get_library() const
{
auto it = ::std::find_if(m_targets.begin(), m_targets.end(), [](const auto& x) { return x.m_type == PackageTarget::Type::Lib; });
@@ -393,6 +449,7 @@ void PackageManifest::load_build_script(const ::std::string& path)
void PackageRef::load_manifest(Repository& repo, const ::helpers::path& base_path)
{
+ TRACE_FUNCTION_F(this->m_name);
// If the path isn't set, check for:
// - Git (checkout and use)
// - Version and repository (check vendored, check cache, download into cache)
@@ -420,6 +477,8 @@ void PackageRef::load_manifest(Repository& repo, const ::helpers::path& base_pat
assert(m_manifest);
}
+ // TODO: Set features on this dependency
+
m_manifest->load_dependencies(repo);
}
@@ -520,7 +579,7 @@ bool PackageVersionSpec::accepts(const PackageVersion& v) const
case Bound::Type::Compatible:
// To be compatible, it has to be higher?
// - TODO: Isn't a patch version compatible?
- if( !(v > b.ver) )
+ if( !(v >= b.ver) )
return false;
if( !(v < b.ver.next_breaking()) )
return false;
@@ -530,7 +589,7 @@ bool PackageVersionSpec::accepts(const PackageVersion& v) const
return false;
break;
case Bound::Type::Equal:
- if( v < b.ver || v > b.ver )
+ if( v != b.ver )
return false;
break;
case Bound::Type::Less:
diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h
index c8193e6a..cd39f6c4 100644
--- a/tools/minicargo/manifest.h
+++ b/tools/minicargo/manifest.h
@@ -7,6 +7,7 @@
class PackageManifest;
class Repository;
+class TomlKeyValue;
struct PackageVersion
{
@@ -55,6 +56,11 @@ struct PackageVersion
if( minor != x.minor ) return minor > x.minor;
return patch > x.patch;
}
+ bool operator>=(const PackageVersion& x) const {
+ if( major != x.major ) return major > x.major;
+ if( minor != x.minor ) return minor > x.minor;
+ return patch >= x.patch;
+ }
friend ::std::ostream& operator<<(::std::ostream& os, const PackageVersion& v) {
os << v.major << "." << v.minor << "." << v.patch;
@@ -112,6 +118,11 @@ class PackageRef
bool m_optional = false;
::std::string m_path;
+
+ // Features requested by this reference
+ ::std::vector<::std::string> m_features;
+ bool m_use_default_features = true;
+
::std::shared_ptr<PackageManifest> m_manifest;
PackageRef(const ::std::string& n) :
@@ -119,6 +130,8 @@ class PackageRef
{
}
+ void fill_from_kv(bool was_created, const TomlKeyValue& kv, size_t ofs);
+
public:
const ::std::string& name() const { return m_name; }
//const ::std::string& get_repo_name() const { return m_repo; }
@@ -160,6 +173,8 @@ struct PackageTarget
bool m_is_proc_macro = false;
bool m_is_own_harness = false;
+ ::std::vector<::std::string> m_required_features;
+
PackageTarget(Type ty):
m_type(ty)
{