Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,30 @@ This forwards to [reproducible-wasm](#reproducible-wasm) variant of `build` comm
See [`cargo_near_build::extended`](https://docs.rs/cargo-near-build/latest/cargo_near_build/extended/index.html) module documentation on
how to write `build.rs` for subcontracts.

## Debugging with tracing

The `cargo-near-build` library exports a `tracing_debug` feature that provides a default tracing subscriber configuration. This enables all `--teach-me` messages and detailed logging output, useful for debugging build scripts.

To use it, add the feature to your `Cargo.toml`:

```toml
[dependencies]
cargo-near-build = { version = "0.11", features = ["tracing_debug"] }
```

Then initialize tracing in your code:

```rust
#[cfg(feature = "tracing_debug")]
cargo_near_build::init_tracing_debug().expect("Failed to initialize tracing");
```

This will enable the same verbose logging that `cargo near --teach-me` provides, including:
- Command execution details
- Environment variable configurations
- File system operations
- Build process steps

## Special `cargo` environment variables

Both of the following are mentioned on https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags
Expand Down
3 changes: 3 additions & 0 deletions cargo-near-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ git2 = { version = "0.20", optional = true }
unix_path = { version = "1.0.1", optional = true }
humantime = { version = "2.1.0", optional = true }
regex = { version = "1.11.1", optional = true }
# tracing_debug
tracing-subscriber = { version = "0.3.20", features = ["env-filter"], optional = true }


[package.metadata.docs.rs]
Expand Down Expand Up @@ -78,3 +80,4 @@ docker = [
"dep:regex",
]
test_code = []
tracing_debug = ["dep:tracing-subscriber"]
8 changes: 8 additions & 0 deletions cargo-near-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
//! building in docker with WASM reproducibility.
//! * **test_code** -
//! Adds exports needed for integration tests.
//! * **tracing_debug** -
//! Exports [`crate::init_tracing_debug`] function which initializes tracing with a configuration
//! that enables all `--teach-me` messages and detailed logging output.
//!
//! ### Default features
//!
Expand Down Expand Up @@ -46,6 +49,11 @@ pub(crate) mod near;
pub(crate) mod pretty_print;
pub(crate) mod types;

#[cfg(feature = "tracing_debug")]
mod tracing_debug;
#[cfg(feature = "tracing_debug")]
pub use tracing_debug::init_tracing_debug;

#[cfg(feature = "build_internal")]
pub mod abi {
pub use crate::near::abi::build;
Expand Down
88 changes: 88 additions & 0 deletions cargo-near-build/src/tracing_debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! Tracing configuration for debugging and teach-me mode.
//!
//! This module provides a default tracing subscriber configuration that enables
//! all `--teach-me` messages and detailed logging output.
//!
//! # Example
//!
//! ```no_run
//! # #[cfg(feature = "tracing_debug")]
//! cargo_near_build::init_tracing_debug().expect("Failed to initialize tracing");
//! ```

use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};

/// Initializes a tracing subscriber with configuration suitable for debugging.
///
/// This function sets up a tracing subscriber that:
/// - Enables all `near_teach_me` target messages (INFO level)
/// - Shows WARN level messages from all sources
/// - Respects RUST_LOG environment variable if set
///
/// This is the same configuration used by `cargo near --teach-me` flag.
///
/// # Errors
///
/// Returns an error if:
/// - The tracing subscriber fails to initialize
/// - The environment filter configuration is invalid
///
/// # Example
///
/// ```no_run
/// # #[cfg(feature = "tracing_debug")]
/// cargo_near_build::init_tracing_debug().expect("Failed to initialize tracing");
/// ```
pub fn init_tracing_debug() -> Result<(), Box<dyn std::error::Error>> {
use tracing::{Event, Level, Subscriber};
use tracing_subscriber::{
fmt::{format::Writer, FmtContext, FormatEvent, FormatFields},
registry::LookupSpan,
};

// Note: This SimpleFormatter is duplicated from cargo-near/src/lib.rs to avoid
// introducing additional dependencies or making internal modules public.
// Future: Consider extracting to a shared module if this needs to be reused elsewhere.
struct SimpleFormatter;

impl<S, N> FormatEvent<S, N> for SimpleFormatter
where
S: Subscriber + for<'a> LookupSpan<'a>,
N: for<'a> FormatFields<'a> + 'static,
{
fn format_event(
&self,
ctx: &FmtContext<'_, S, N>,
mut writer: Writer<'_>,
event: &Event<'_>,
) -> std::fmt::Result {
let level = *event.metadata().level();
let (icon, color_code) = match level {
Level::TRACE => ("TRACE ", "\x1b[35m"), // Magenta
Level::DEBUG => ("DEBUG ", "\x1b[34m"), // Blue
Level::INFO => ("", ""), // Default
Level::WARN => ("Warning ", "\x1b[33m"), // Yellow
Level::ERROR => ("ERROR ", "\x1b[31m"), // Red
};

write!(writer, "{}├ {}", color_code, icon)?;
write!(writer, "\x1b[0m")?;

ctx.field_format().format_fields(writer.by_ref(), event)?;

writeln!(writer)
}
Comment on lines +46 to +74
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SimpleFormatter implementation is duplicated from cargo-near/src/lib.rs. While the comment at line 43-45 acknowledges this, this creates a maintenance burden where changes to formatting in one location must be manually replicated to the other. Consider extracting SimpleFormatter to a shared internal utility crate or module that both cargo-near and cargo-near-build can depend on, even if it's not part of the public API.

Copilot uses AI. Check for mistakes.
}

let env_filter = EnvFilter::from_default_env()
.add_directive(Level::WARN.into())
.add_directive("near_teach_me=info".parse()?)
.add_directive("near_cli_rs=info".parse()?)
.add_directive("tracing_instrument=info".parse()?);
Comment on lines +78 to +81
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter directives are duplicated from cargo-near/src/lib.rs (lines 107-111). While the comment explains this is intentional to avoid dependencies, consider extracting the filter configuration string (e.g., 'near_teach_me=info,near_cli_rs=info,tracing_instrument=info,warn') to a shared constant in a common location to ensure consistency when updates are made.

Copilot uses AI. Check for mistakes.

tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().event_format(SimpleFormatter))
.with(env_filter)
.try_init()
.map_err(|e| format!("Failed to initialize tracing subscriber: {}", e).into())
}
Loading