diff options
author | John Hodge <tpg@mutabah.net> | 2017-08-24 11:13:08 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-08-24 11:13:08 +0800 |
commit | 1b8e3f06112449dbd60d784c69f7f41d7b24666c (patch) | |
tree | e2477e317b0a32e88166e247960f08f42cd0f403 /tools/minicargo | |
parent | 84d683422f497fb10c4f3c88fe788c0405c40d68 (diff) | |
download | mrust-1b8e3f06112449dbd60d784c69f7f41d7b24666c.tar.gz |
minicargo manifest - Version parsing/checking, extra keys
Diffstat (limited to 'tools/minicargo')
-rw-r--r-- | tools/minicargo/manifest.cpp | 125 | ||||
-rw-r--r-- | tools/minicargo/manifest.h | 69 |
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 |