summaryrefslogtreecommitdiff
path: root/tools/minicargo
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-08-24 11:13:08 +0800
committerJohn Hodge <tpg@mutabah.net>2017-08-24 11:13:08 +0800
commit1b8e3f06112449dbd60d784c69f7f41d7b24666c (patch)
treee2477e317b0a32e88166e247960f08f42cd0f403 /tools/minicargo
parent84d683422f497fb10c4f3c88fe788c0405c40d68 (diff)
downloadmrust-1b8e3f06112449dbd60d784c69f7f41d7b24666c.tar.gz
minicargo manifest - Version parsing/checking, extra keys
Diffstat (limited to 'tools/minicargo')
-rw-r--r--tools/minicargo/manifest.cpp125
-rw-r--r--tools/minicargo/manifest.h69
2 files changed, 179 insertions, 15 deletions
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index 4e7ec305..f817fb91 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -35,12 +35,7 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
{
assert(key_val.path.size() > 1);
const auto& key = key_val.path[1];
- if(key == "authors")
- {
- // TODO: Use the `authors` key
- // - Ignore ofr now.
- }
- else if( key == "name" )
+ if( key == "name" )
{
if(rv.m_name != "" )
{
@@ -72,6 +67,18 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
throw ::std::runtime_error("Build script path cannot be empty");
}
}
+ else if( key == "authors"
+ || key == "description"
+ || key == "homepage"
+ || key == "documentation"
+ || key == "repository"
+ || key == "readme"
+ || key == "categories"
+ || key == "license"
+ )
+ {
+ // Informational only, ignore
+ }
else
{
// Unknown value in `package`
@@ -207,6 +214,10 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
{
// TODO: Features
}
+ // crates.io metadata
+ else if( section == "badges" )
+ {
+ }
else
{
// Unknown manifest section
@@ -396,6 +407,9 @@ void PackageRef::load_manifest(Repository& repo, const ::helpers::path& base_pat
{
DEBUG("Load dependency " << this->name() << " from repo");
m_manifest = repo.find(this->name(), this->get_version());
+ if( !m_manifest ) {
+ throw ::std::runtime_error(::format("Unable to load manifest for ", this->name(), ":", this->get_version()));
+ }
}
}
else
@@ -403,6 +417,7 @@ void PackageRef::load_manifest(Repository& repo, const ::helpers::path& base_pat
DEBUG("Load dependency " << m_name << " from path " << m_path);
// Search for a copy of this already loaded
m_manifest = repo.from_path(base_path / ::helpers::path(m_path) / "Cargo.toml");
+ assert(m_manifest);
}
m_manifest->load_dependencies(repo);
@@ -424,11 +439,105 @@ PackageVersion PackageVersion::from_string(const ::std::string& s)
PackageVersionSpec PackageVersionSpec::from_string(const ::std::string& s)
{
+ struct H {
+ static unsigned parse_i(const ::std::string& istr, size_t& pos) {
+ char* out_ptr = nullptr;
+ long rv = ::std::strtol(istr.c_str() + pos, &out_ptr, 10);
+ if( out_ptr == istr.c_str() + pos )
+ throw ::std::invalid_argument(istr.c_str() + pos);
+ pos = out_ptr - istr.c_str();
+ return rv;
+ }
+ };
PackageVersionSpec rv;
- throw "";
+ size_t pos = 0;
+ do
+ {
+ while( pos < s.size() && isblank(s[pos]) )
+ pos ++;
+ if(pos == s.size())
+ break ;
+ auto ty = PackageVersionSpec::Bound::Type::Compatible;
+ switch(s[pos])
+ {
+ case '^':
+ // Default, compatible
+ pos ++;
+ break;
+ case '=':
+ ty = PackageVersionSpec::Bound::Type::Equal;
+ pos ++;
+ break;
+ case '>':
+ ty = PackageVersionSpec::Bound::Type::Greater;
+ pos ++;
+ break;
+ case '<':
+ ty = PackageVersionSpec::Bound::Type::Greater;
+ pos ++;
+ break;
+ default:
+ break;
+ }
+ while( pos < s.size() && isblank(s[pos]) )
+ pos ++;
+ if( pos == s.size() )
+ throw ::std::runtime_error("Bad version string");
+
+ PackageVersion v;
+ v.major = H::parse_i(s, pos);
+ if( s[pos] != '.' )
+ throw ::std::runtime_error("Bad version string");
+ pos ++;
+ v.minor = H::parse_i(s, pos);
+ if(s[pos] == '.')
+ {
+ pos ++;
+ v.patch = H::parse_i(s, pos);
+ }
+ else
+ {
+ v.patch = 0;
+ }
+
+ rv.m_bounds.push_back(PackageVersionSpec::Bound { ty, v });
+
+ while( pos < s.size() && isblank(s[pos]) )
+ pos ++;
+ if(pos == s.size())
+ break ;
+ } while(pos < s.size() && s[pos++] == ',');
+ if( pos != s.size() )
+ throw ::std::runtime_error(::format( "Bad version string, pos=", pos ));
return rv;
}
bool PackageVersionSpec::accepts(const PackageVersion& v) const
{
- throw "";
+ for(const auto& b : m_bounds)
+ {
+ switch(b.ty)
+ {
+ case Bound::Type::Compatible:
+ // To be compatible, it has to be higher?
+ // - TODO: Isn't a patch version compatible?
+ if( !(v > b.ver) )
+ return false;
+ if( !(v < b.ver.next_breaking()) )
+ return false;
+ break;
+ case Bound::Type::Greater:
+ if( !(v > b.ver) )
+ return false;
+ break;
+ case Bound::Type::Equal:
+ if( v < b.ver || v > b.ver )
+ return false;
+ break;
+ case Bound::Type::Less:
+ if( !(v < b.ver) )
+ return false;
+ break;
+ }
+ }
+ return true;
}
diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h
index 7f93e2c4..c8193e6a 100644
--- a/tools/minicargo/manifest.h
+++ b/tools/minicargo/manifest.h
@@ -15,14 +15,50 @@ struct PackageVersion
unsigned patch;
static PackageVersion from_string(const ::std::string& s);
+
+ PackageVersion next_breaking() const {
+ if(major == 0) {
+ return PackageVersion { 0, minor + 1, 0 };
+ }
+ else {
+ return PackageVersion { major + 1, 0, 0 };
+ }
+ }
+ PackageVersion prev_compat() const {
+ if(major == 0) {
+ // Before 1.0, there's no patch levels
+ return *this;
+ }
+ else {
+ // Anything from the same patch series
+ return PackageVersion { major, minor, 0 };
+ }
+ }
+
+ bool operator==(const PackageVersion& x) const {
+ if( major != x.major ) return false;
+ if( minor != x.minor ) return false;
+ return patch == x.patch;
+ }
+ bool operator!=(const PackageVersion& x) const {
+ if( major != x.major ) return true;
+ if( minor != x.minor ) return true;
+ return patch != x.patch;
+ }
bool operator<(const PackageVersion& x) const {
- if( major < x.major ) return true;
- if( major > x.major ) return false;
- if( minor < x.minor ) return true;
- if( minor > x.minor ) return false;
- if( minor < x.patch ) return true;
- if( patch > x.patch ) return false;
- return false;
+ if( major != x.major ) return major < x.major;
+ 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;
+ return os;
}
};
struct PackageVersionSpec
@@ -32,6 +68,7 @@ struct PackageVersionSpec
enum class Type
{
Compatible,
+ Greater,
Equal,
Less,
};
@@ -47,6 +84,24 @@ struct PackageVersionSpec
/// Check if this spec accepts the passed version
bool accepts(const PackageVersion& v) const;
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const PackageVersionSpec& v) {
+ bool first = true;
+ for(const auto& b : v.m_bounds) {
+ if(!first)
+ os << ",";
+ first = false;
+ switch(b.ty)
+ {
+ case Bound::Type::Compatible: os << "^"; break;
+ case Bound::Type::Greater: os << ">"; break;
+ case Bound::Type::Equal: os << "="; break;
+ case Bound::Type::Less: os << "<"; break;
+ }
+ os << b.ver;
+ }
+ return os;
+ }
};
class PackageRef