Skip to content

Commit

Permalink
feat: update sovereign.toml resoultion to relative path (#855)
Browse files Browse the repository at this point in the history
* feat: update sovereign.toml resoultion to relative path

Prior to this commit, the resolution of the sovereign.toml dependend on
unstable features of proc-macro2, available only for recent toolchain
versions.

This commit introduces the path resolution of the manifest file to
recurse from the target directory. It will allow endpoints to set their
own manifest file, replacing the ones bundled with the modules.

It will also read an optional `SOVEREIGN_MANIFEST` that, if set, will
override the manifest path. The manifest path is expected to be resolved
at compile time, making it possible to construct const/static structures
with it.

* remove deprecated .env
  • Loading branch information
vlopes11 authored Sep 15, 2023
1 parent e1d747d commit f662415
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 51 deletions.
1 change: 0 additions & 1 deletion .env

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/target

.idea/
target-path

target/
fuzz/Cargo.lock
Expand Down
14 changes: 14 additions & 0 deletions module-system/sov-modules-macros/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::path::PathBuf;
use std::{env, fs, io};

fn main() -> io::Result<()> {
// writes the target output dir into the manifest path so it can be later read for the
// resolution of the sovereign.toml manifest file
let target = env::var("OUT_DIR").map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let target = PathBuf::from(target).canonicalize()?.display().to_string();
let manifest = env!("CARGO_MANIFEST_DIR");
let manifest = PathBuf::from(manifest).canonicalize()?.join("target-path");
fs::write(manifest, target)?;

Ok(())
}
4 changes: 0 additions & 4 deletions module-system/sov-modules-macros/sovereign.toml

This file was deleted.

87 changes: 41 additions & 46 deletions module-system/sov-modules-macros/src/manifest.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,43 @@
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::{env, fs};

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.
/// Reads a `sovereign.toml` manifest file, recursing from the target directory that builds the
/// current implementation.
///
/// 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
/// If the environment variable `SOVEREIGN_MANIFEST` is set, it will use that instead.
#[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")
})?;
pub fn fetch_manifest_toml() -> anyhow::Result<Table> {
let initial_path = match env::var("SOVEREIGN_MANIFEST") {
Ok(p) => PathBuf::from(&p).canonicalize().map_err(|e| {
anyhow::anyhow!("failed access base dir for sovereign manifest file `{p}`: {e}",)
}),
Err(_) => {
// read the target directory set via build script since `OUT_DIR` is available only at build
let initial_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.canonicalize()
.map_err(|e| {
anyhow::anyhow!("failed access base dir for sovereign manifest file: {e}")
})?
.join("target-path");

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}"))?;
let initial_path = fs::read_to_string(&initial_path).map_err(|e| {
anyhow::anyhow!("failed to read target path for sovereign manifest file: {e}")
})?;

fetch_manifest_toml_from_path(initial_path)
}
PathBuf::from(initial_path.trim())
.canonicalize()
.map_err(|e| {
anyhow::anyhow!("failed access base dir for sovereign manifest file: {e}")
})
}
}?;

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();
let mut current_path = initial_path.as_path();
loop {
if current_path.join(MANIFEST_NAME).exists() {
path = current_path.join(MANIFEST_NAME);
Expand All @@ -55,7 +46,7 @@ where

current_path = current_path
.parent()
.ok_or_else(|| anyhow::anyhow!("Could not find a parent {MANIFEST_NAME}"))?;
.ok_or_else(|| anyhow::anyhow!("Could not find a parent {}", MANIFEST_NAME))?;
}

let manifest = fs::read_to_string(&path)
Expand All @@ -64,20 +55,24 @@ where
let manifest = toml::from_str(&manifest)
.map_err(|e| anyhow::anyhow!("Could not parse `{}`: {}", path.display(), e))?;

Ok((path, manifest))
Ok(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 path = PathBuf::from(path)
.parent()
.unwrap()
.parent()
.unwrap()
.join(MANIFEST_NAME)
.canonicalize()
.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 = fs::read_to_string(path).unwrap();
let expected = toml::from_str(&expected).unwrap();

assert_eq!(path, expected_path);
let manifest = fetch_manifest_toml().unwrap();
assert_eq!(manifest, expected);
}
1 change: 1 addition & 0 deletions sovereign.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Base SDK configuration file

0 comments on commit f662415

Please sign in to comment.