Skip to content

Commit

Permalink
feat: nep330 build info field of contract metadata (#1178)
Browse files Browse the repository at this point in the history
  • Loading branch information
dj8yfo authored Jun 19, 2024
1 parent 5970226 commit 8077e9f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 10 deletions.
46 changes: 46 additions & 0 deletions near-sdk-macros/src/core_impl/contract_metadata/build_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#[derive(serde::Serialize)]
pub(crate) struct BuildInfo {
build_environment: String,
build_command: Vec<String>,
contract_path: String,
source_code_snapshot: String,
}

const ERR_EMPTY_BUILD_ENVIRONMENT: &str = "`NEP330_BUILD_INFO_BUILD_ENVIRONMENT` is set, \
but it's set to empty string!";
const ERR_EMPTY_BUILD_COMMAND: &str = "`NEP330_BUILD_INFO_BUILD_COMMAND` is required, \
when `NEP330_BUILD_INFO_BUILD_ENVIRONMENT` is set, \
but it's either not set or empty!";
const ERR_PARSE_BUILD_COMMAND: &str = "problem parsing `NEP330_BUILD_INFO_BUILD_COMMAND` value";

const ERR_UNSET_CONTRACT_PATH: &str = "`NEP330_BUILD_INFO_CONTRACT_PATH` was provided, \
but it's not set!";

const ERR_UNSET_OR_EMPTY_SOURCE_SNAPSHOT: &str = "`NEP330_BUILD_INFO_SOURCE_CODE_SNAPSHOT` is \
required, when `NEP330_BUILD_INFO_BUILD_ENVIRONMENT` \
is set, but it's either not set or empty!";

impl BuildInfo {
pub(super) fn from_env() -> Result<Self, String> {
let build_environment = std::env::var("NEP330_BUILD_INFO_BUILD_ENVIRONMENT")
.ok()
.filter(|build_environment| !build_environment.is_empty())
.ok_or(ERR_EMPTY_BUILD_ENVIRONMENT.to_string())?;

let build_command = std::env::var("NEP330_BUILD_INFO_BUILD_COMMAND")
.ok()
.filter(|build_command| !build_command.is_empty())
.ok_or(ERR_EMPTY_BUILD_COMMAND.to_string())?;
let build_command: Vec<String> = serde_json::from_str(&build_command)
.map_err(|err| format!("{}: {}", ERR_PARSE_BUILD_COMMAND, err))?;

let source_code_snapshot = std::env::var("NEP330_BUILD_INFO_SOURCE_CODE_SNAPSHOT")
.ok()
.filter(|source_code_snapshot| !source_code_snapshot.is_empty())
.ok_or(ERR_UNSET_OR_EMPTY_SOURCE_SNAPSHOT.to_string())?;
let contract_path = std::env::var("NEP330_BUILD_INFO_CONTRACT_PATH")
.map_err(|_| ERR_UNSET_CONTRACT_PATH.to_string())?;

Ok(Self { build_environment, build_command, contract_path, source_code_snapshot })
}
}
34 changes: 24 additions & 10 deletions near-sdk-macros/src/core_impl/contract_metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#![allow(clippy::manual_unwrap_or_default)]

use darling::{ast::NestedMeta, Error, FromMeta};
use proc_macro2::TokenStream;
use quote::quote;

mod build_info;

#[derive(FromMeta)]
struct MacroConfig {
contract_metadata: Option<ContractMetadata>,
Expand All @@ -11,8 +15,12 @@ struct MacroConfig {
pub(crate) struct ContractMetadata {
version: Option<String>,
link: Option<String>,

#[darling(multiple, rename = "standard")]
standards: Vec<Standard>,

#[darling(skip)]
build_info: Option<build_info::BuildInfo>,
}

impl quote::ToTokens for ContractMetadata {
Expand Down Expand Up @@ -47,17 +55,16 @@ struct Standard {

impl ContractMetadata {
fn populate(mut self) -> Self {
if self.version.is_none() {
let version = std::env::var("CARGO_PKG_VERSION").unwrap_or(String::from(""));
if !version.is_empty() {
self.version = Some(version);
if self.link.is_none() {
let field_val = std::env::var("NEP330_LINK").unwrap_or(String::from(""));
if !field_val.is_empty() {
self.link = Some(field_val);
}
}

if self.link.is_none() {
let repo = std::env::var("CARGO_PKG_REPOSITORY").unwrap_or(String::from(""));
if !repo.is_empty() {
self.link = Some(repo);
if self.version.is_none() {
let field_val = std::env::var("NEP330_VERSION").unwrap_or(String::from(""));
if !field_val.is_empty() {
self.version = Some(field_val);
}
}

Expand All @@ -66,7 +73,14 @@ impl ContractMetadata {
|| self.standards.iter().all(|s| s.standard.to_ascii_lowercase() != "nep330")
{
self.standards
.push(Standard { standard: "nep330".to_string(), version: "1.1.0".to_string() });
.push(Standard { standard: "nep330".to_string(), version: "1.2.0".to_string() });
}

if std::env::var("NEP330_BUILD_INFO_BUILD_ENVIRONMENT").is_ok() {
self.build_info = Some(
build_info::BuildInfo::from_env()
.expect("Build Details Extension field not provided or malformed"),
);
}

self
Expand Down

0 comments on commit 8077e9f

Please sign in to comment.