Browse Source

idl: Make safety comment checks fail silently when program path env is not set (#3045)

acheron 1 year ago
parent
commit
594169efd0
4 changed files with 31 additions and 10 deletions
  1. 3 1
      CHANGELOG.md
  2. 6 0
      lang/syn/src/idl/common.rs
  3. 2 3
      lang/syn/src/idl/external.rs
  4. 20 6
      lang/syn/src/idl/program.rs

+ 3 - 1
CHANGELOG.md

@@ -12,9 +12,11 @@ The minor version will be incremented upon a breaking change and the patch versi
 
 ### Features
 
+- ts: Add optional `commitment` parameter to `Program.addEventListener` ([#3052](https://github.com/coral-xyz/anchor/pull/3052)).
+
 ### Fixes
 
-- ts: add optional `commitment` parameter to `Program.addEventListener` ([#3052](https://github.com/coral-xyz/anchor/pull/3052))
+- idl: Make safety comment checks fail silently when program path env is not set ([#3045](https://github.com/coral-xyz/anchor/pull/3045])).
 
 ### Breaking
 

+ 6 - 0
lang/syn/src/idl/common.rs

@@ -22,6 +22,12 @@ pub fn get_no_docs() -> bool {
         .unwrap_or_default()
 }
 
+pub fn get_program_path() -> Result<PathBuf> {
+    std::env::var("ANCHOR_IDL_BUILD_PROGRAM_PATH")
+        .map(PathBuf::from)
+        .map_err(|_| anyhow!("Failed to get program path"))
+}
+
 pub fn get_idl_module_path() -> TokenStream {
     quote!(anchor_lang::idl::types)
 }

+ 2 - 3
lang/syn/src/idl/external.rs

@@ -7,7 +7,7 @@ use anyhow::{anyhow, Result};
 use cargo_toml::Manifest;
 use quote::ToTokens;
 
-use super::common::find_path;
+use super::common::{find_path, get_program_path};
 use crate::parser::context::CrateContext;
 
 pub fn get_external_type(name: &str, path: impl AsRef<Path>) -> Result<Option<syn::Type>> {
@@ -17,8 +17,7 @@ pub fn get_external_type(name: &str, path: impl AsRef<Path>) -> Result<Option<sy
         .ok_or_else(|| anyhow!("`{name}` not found in use statements"))?;
 
     // Get crate name and version from lock file
-    let program_path =
-        std::env::var("ANCHOR_IDL_BUILD_PROGRAM_PATH").expect("Failed to get program path");
+    let program_path = get_program_path()?;
     let lock_path = find_path("Cargo.lock", program_path)?;
     let lock_file = parse_lock_file(lock_path)?;
     let registry_path = get_registry_path()?;

+ 20 - 6
lang/syn/src/idl/program.rs

@@ -1,12 +1,10 @@
-use std::path::PathBuf;
-
 use anyhow::{anyhow, Result};
 use heck::CamelCase;
 use proc_macro2::TokenStream;
 use quote::{format_ident, quote};
 
 use super::{
-    common::{gen_print_section, get_idl_module_path, get_no_docs},
+    common::{gen_print_section, get_idl_module_path, get_no_docs, get_program_path},
     defined::gen_idl_type,
 };
 use crate::{
@@ -156,10 +154,26 @@ fn check_safety_comments() -> Result<()> {
         return Ok(());
     }
 
-    std::env::var("ANCHOR_IDL_BUILD_PROGRAM_PATH")
-        .map(PathBuf::from)
+    let program_path = get_program_path();
+    if program_path.is_err() {
+        // Getting the program path can fail in the following scenarios:
+        //
+        // - Anchor CLI version is incompatible with the current version
+        // - The error is coming from Rust Analyzer when the user has `idl-build` feature enabled,
+        // likely due to enabling all features (https://github.com/coral-xyz/anchor/issues/3042)
+        //
+        // For the first case, we have a warning when the user is using different versions of the
+        // lang and CLI crate. For the second case, users would either have to disable the
+        // `idl-build` feature, or define the program path environment variable in Rust Analyzer
+        // settings.
+        //
+        // Given this feature is not a critical one, and it works by default with `anchor build`,
+        // we can fail silently in the case of an error rather than panicking.
+        return Ok(());
+    }
+
+    program_path
         .map(|path| path.join("src").join("lib.rs"))
-        .map_err(|_| anyhow!("Failed to get program path"))
         .map(CrateContext::parse)?
         .map_err(|e| anyhow!("Failed to parse crate: {e}"))?
         .safety_checks()