-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add sovereign.toml manifest file (#792)
* feat: add sovereign.toml manifest file This commit introduces a manifest file that can be parsed by derive macros and have its contents read at compile-time. It will read recursively the directory of the call site of the macro until it either finds a `sovereign.toml` file, or the path is depleted. The implementation for the source file location of proc macros depends on `procmacro2_semver_exempt`, and it will fallback to the manifest path of the `sov-modules-macros` library. The fallback may contain multiple edge cases as cargo will cache the downloaded crate into a `$HOME/.cargo` dir, making a recursion tree impossible to reach the workspace under normal circumstances. The aforementioned problem will be handled on the issue #786 * update manifest fn to return computed path * fix unit tests for manifest path * adjust link check for manifest test
- Loading branch information
Showing
6 changed files
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export RUSTFLAGS='--cfg procmacro2_semver_exempt' |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# this file exists only for test purposes | ||
|
||
[section] | ||
value = 25 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use std::fs; | ||
use std::path::{Path, PathBuf}; | ||
|
||
use proc_macro2::Span; | ||
use toml::Table; | ||
|
||
const MANIFEST_NAME: &str = "sovereign.toml"; | ||
|
||
/// Reads a `sovereign.toml` manifest file from the directory tree of the sov-modules-macros. | ||
/// | ||
/// If the `RUSTFLAGS=--cfg procmacro2_semver_exempt` environment variable is set, then will read | ||
/// the file from the directory of the provided span. Otherwise, will recurse from the manifest of | ||
/// the `sov-modules-macros`. Warning: the latter approach might have edge cases as the compilation | ||
/// of the `sov-modules-macros` might be performed under the | ||
/// `$HOME.cargo/registry/src/index.crates.io-_/sov-modules-macros-_` folder. | ||
/// | ||
/// Tracking issue: https://github.com/Sovereign-Labs/sovereign-sdk/issues/786 | ||
#[allow(dead_code)] | ||
pub fn fetch_manifest_toml(span: Span) -> anyhow::Result<(PathBuf, Table)> { | ||
#[cfg(procmacro2_semver_exempt)] | ||
let initial_path = span | ||
.source_file() | ||
.path() | ||
.canonicalize() | ||
.map_err(|e| { | ||
anyhow::anyhow!("failed access base dir for sovereign manifest file from the span: {e}") | ||
})? | ||
.parent() | ||
.map(|p| p.to_path_buf()) | ||
.ok_or_else(|| { | ||
anyhow::anyhow!("Could not open the directory of the parent of the provided span") | ||
})?; | ||
|
||
let _ = span; | ||
|
||
#[cfg(not(procmacro2_semver_exempt))] | ||
let initial_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) | ||
.canonicalize() | ||
.map_err(|e| anyhow::anyhow!("failed access base dir for sovereign manifest file: {e}"))?; | ||
|
||
fetch_manifest_toml_from_path(initial_path) | ||
} | ||
|
||
fn fetch_manifest_toml_from_path<P>(initial_path: P) -> anyhow::Result<(PathBuf, Table)> | ||
where | ||
P: AsRef<Path>, | ||
{ | ||
let path: PathBuf; | ||
let mut current_path = initial_path.as_ref(); | ||
loop { | ||
if current_path.join(MANIFEST_NAME).exists() { | ||
path = current_path.join(MANIFEST_NAME); | ||
break; | ||
} | ||
|
||
current_path = current_path | ||
.parent() | ||
.ok_or_else(|| anyhow::anyhow!("Could not find a parent {MANIFEST_NAME}"))?; | ||
} | ||
|
||
let manifest = fs::read_to_string(&path) | ||
.map_err(|e| anyhow::anyhow!("Could not read the parent `{}`: {e}", path.display()))?; | ||
|
||
let manifest = toml::from_str(&manifest) | ||
.map_err(|e| anyhow::anyhow!("Could not parse `{}`: {}", path.display(), e))?; | ||
|
||
Ok((path, manifest)) | ||
} | ||
|
||
#[test] | ||
fn fetch_manifest_works() { | ||
let path = env!("CARGO_MANIFEST_DIR"); | ||
let path = PathBuf::from(path).join("src").join("invalid"); | ||
let (path, manifest) = fetch_manifest_toml_from_path(path).unwrap(); | ||
|
||
let expected_path = env!("CARGO_MANIFEST_DIR"); | ||
let expected_path = PathBuf::from(expected_path).join("sovereign.toml"); | ||
let expected = fs::read_to_string(&expected_path).unwrap(); | ||
let expected = toml::from_str(&expected).unwrap(); | ||
|
||
assert_eq!(path, expected_path); | ||
assert_eq!(manifest, expected); | ||
} |