diff options
-rw-r--r-- | tools/minicargo/main.cpp | 99 | ||||
-rw-r--r-- | tools/minicargo/manifest.cpp | 18 | ||||
-rw-r--r-- | tools/minicargo/manifest.h | 4 | ||||
-rw-r--r-- | tools/minicargo/repository.cpp | 13 | ||||
-rw-r--r-- | tools/minicargo/repository.h | 2 |
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); }; |