summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2019-11-03 15:49:54 +0800
committerJohn Hodge <tpg@mutabah.net>2019-11-03 15:49:54 +0800
commit0b2d92ce3e79f47ddf28be080245eca574828433 (patch)
treed14781233678425afd1c14ad228a458fa08d64df
parent9ebc54d62808d6e6fb8387f245344bcafc870293 (diff)
downloadmrust-0b2d92ce3e79f47ddf28be080245eca574828433.tar.gz
minicargo - Hack in workspace support (for `[patch]`)
-rw-r--r--tools/minicargo/main.cpp99
-rw-r--r--tools/minicargo/manifest.cpp18
-rw-r--r--tools/minicargo/manifest.h4
-rw-r--r--tools/minicargo/repository.cpp13
-rw-r--r--tools/minicargo/repository.h2
5 files changed, 135 insertions, 1 deletions
diff --git a/tools/minicargo/main.cpp b/tools/minicargo/main.cpp
index 4e929653..07f14fbc 100644
--- a/tools/minicargo/main.cpp
+++ b/tools/minicargo/main.cpp
@@ -14,6 +14,8 @@
#include <helpers.h>
#include "repository.h"
#include "build.h"
+#include <toml.h> // TomlFile (workspace)
+#include <fstream> // for workspace enumeration
struct ProgramOptions
{
@@ -64,6 +66,7 @@ int main(int argc, const char* argv[])
{
Debug_DisablePhase("Load Repository");
Debug_DisablePhase("Load Root");
+ Debug_DisablePhase("Load Workspace");
Debug_DisablePhase("Load Dependencies");
Debug_DisablePhase("Enumerate Build");
Debug_DisablePhase("Run Build");
@@ -104,6 +107,102 @@ int main(int argc, const char* argv[])
auto m = PackageManifest::load_from_toml( dir / "Cargo.toml" );
m.set_features(opts.features, opts.features.empty());
+ Debug_SetPhase("Load Workspace");
+ auto workspace_manifest_path = m.workspace_path();
+ if( !workspace_manifest_path.is_valid() )
+ {
+ auto p = helpers::path( m.manifest_path() );
+ p.pop_component(); // remove `Cargo.toml`
+ // Search parent dir and up (pop current dir and then start checking)
+ while( p.pop_component() )
+ {
+ auto pp = p / "Cargo.toml";
+ bool exists = ::std::ifstream(pp.str()).is_open();
+ bool is_workspace = false;
+ if( exists )
+ {
+ // Parse toml, see if there's a `workspace` section at root
+ TomlFile toml_file(pp);
+
+ for(auto key_val : toml_file)
+ {
+ //assert(key_val.path.size() > 0);
+ if( key_val.path[0] == "workspace" )
+ {
+ is_workspace = true;
+ break;
+ }
+ }
+ }
+
+ if( is_workspace )
+ {
+ workspace_manifest_path = pp;
+ break;
+ }
+ }
+ }
+ if( !workspace_manifest_path.is_valid() )
+ {
+ DEBUG("Not part of a workspace");
+ }
+ else
+ {
+ DEBUG("Workspace manifest " << workspace_manifest_path);
+ TomlFile toml_file(workspace_manifest_path);
+
+ for(auto key_val : toml_file)
+ {
+ if( key_val.path[0] == "patch" )
+ {
+ if( key_val.path.size() < 4 ) {
+ DEBUG("Too-short path " << key_val.path);
+ continue ;
+ }
+ const auto& repo_name = key_val.path[1];
+ const auto& package_name = key_val.path[2];
+ // This is a dependency section
+ if( key_val.path[3] == "path" )
+ {
+ if( key_val.path.size() != 4 ) {
+ DEBUG("Wrong-length path " << key_val.path);
+ continue ;
+ }
+ if( key_val.value.m_type != TomlValue::Type::String ) {
+ DEBUG("Incorrect type " << key_val.value);
+ continue ;
+ }
+ if( repo_name == "crates-io" )
+ {
+ // Kinda hacky to do overrides in the repository, but it works
+ auto p = workspace_manifest_path.parent() / key_val.value.as_string();
+ DEBUG("Override " << package_name << " = path " << p);
+ repo.add_patch_path(package_name, p);
+ }
+ else
+ {
+ DEBUG("TODO: Handle patching other types of dependencies");
+ }
+ }
+ else
+ {
+ TODO("Handle workspace patch dependency frag '" << key_val.path[3] << "'");
+ }
+ }
+ else if( key_val.path[0] == "replace" )
+ {
+ TODO(toml_file.lexer() << ": Handle [replace]");
+ }
+ else if( key_val.path[0] == "profile" )
+ {
+ // Igonore for now
+ }
+ else
+ {
+ }
+ }
+ }
+
// 2. Load all dependencies
Debug_SetPhase("Load Dependencies");
m.load_dependencies(repo, !bs_override_dir.is_valid(), /*include_dev=*/opts.test);
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index c385072d..58e70438 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -140,6 +140,17 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
{
//rv.m_create_auto_bench = key_val.value.as_bool();
}
+ else if( key == "workspace" )
+ {
+ if( rv.m_workspace_manifest.is_valid() )
+ {
+ ::std::cerr << toml_file.lexer() << ": Duplicate workspace specification" << ::std::endl;
+ }
+ else
+ {
+ rv.m_workspace_manifest = key_val.value.as_string();
+ }
+ }
else
{
// Unknown value in `package`
@@ -292,7 +303,12 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
}
else if( section == "workspace" )
{
- // TODO: Workspaces?
+ // NOTE: This will be parsed in full by other code?
+ if( ! rv.m_workspace_manifest.is_valid() )
+ {
+ // TODO: if the workspace was specified via `[package] workspace` then error
+ rv.m_workspace_manifest = rv.m_manifest_path;
+ }
}
// crates.io metadata
else if( section == "badges" )
diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h
index d0c537e5..43b725aa 100644
--- a/tools/minicargo/manifest.h
+++ b/tools/minicargo/manifest.h
@@ -255,6 +255,7 @@ public:
class PackageManifest
{
::std::string m_manifest_path;
+ helpers::path m_workspace_manifest;
::std::string m_name;
PackageVersion m_version;
@@ -302,6 +303,9 @@ public:
const ::std::string& manifest_path() const {
return m_manifest_path;
}
+ const ::helpers::path& workspace_path() const {
+ return m_workspace_manifest;
+ }
const ::std::string& name() const {
return m_name;
}
diff --git a/tools/minicargo/repository.cpp b/tools/minicargo/repository.cpp
index 060c5207..f6def399 100644
--- a/tools/minicargo/repository.cpp
+++ b/tools/minicargo/repository.cpp
@@ -115,6 +115,19 @@ void Repository::load_vendored(const ::helpers::path& path)
return it->second;
}
}
+void Repository::add_patch_path(const std::string& package_name, ::helpers::path path)
+{
+ auto manifest_path = path / "Cargo.toml";
+
+ auto loaded_manifest = ::std::shared_ptr<PackageManifest>( new PackageManifest(PackageManifest::load_from_toml(manifest_path)) );
+
+ Entry cache_ent;
+ cache_ent.manifest_path = manifest_path;
+ cache_ent.version = loaded_manifest->version();
+ cache_ent.loaded_manifest = ::std::move(loaded_manifest);
+ m_cache.insert(::std::make_pair( package_name, ::std::move(cache_ent) ));
+ // TODO: If there's other packages with the same name, check for compatability (or otherwise ensure that this is the chosen version)
+}
::std::shared_ptr<PackageManifest> Repository::find(const ::std::string& name, const PackageVersionSpec& version)
{
DEBUG("FIND " << name << " matching " << version);
diff --git a/tools/minicargo/repository.h b/tools/minicargo/repository.h
index ca481166..6f672591 100644
--- a/tools/minicargo/repository.h
+++ b/tools/minicargo/repository.h
@@ -31,6 +31,8 @@ public:
void load_cache(const ::helpers::path& path);
void load_vendored(const ::helpers::path& path);
+ void add_patch_path(const std::string& package_name, ::helpers::path path);
+
::std::shared_ptr<PackageManifest> from_path(::helpers::path path);
::std::shared_ptr<PackageManifest> find(const ::std::string& name, const PackageVersionSpec& version);
};