sublime_standard_tools 0.0.15

A collection of utilities for working with Node.js projects from Rust applications
Documentation
//! # `sublime_standard_tools`
//!
//! A comprehensive toolkit for working with Node.js projects from Rust applications.
//!
//! ## What
//! This crate provides a foundational set of utilities for interacting with Node.js
//! projects, package managers, and development workflows from Rust. It handles
//! project structure detection, command execution, environment management,
//! and various other tasks required when working with Node.js ecosystems.
//!
//! ## How
//! The crate follows a clean architectural approach with clear separation of concerns:
//!
//! ### Core Modules
//! - **`node`**: Generic Node.js concepts (repositories, package managers)
//! - **`project`**: Unified project detection and management
//! - **`monorepo`**: Monorepo-specific functionality and workspace management
//! - **`command`**: Robust command execution framework
//! - **`filesystem`**: Safe filesystem operations and path utilities
//! - **`error`**: Comprehensive error handling
//!
//! ### Architecture Overview
//! ```text
//! ┌─────────────────────────────────────────────────────────────┐
//! │                    sublime_standard_tools                    │
//! ├─────────────────────────────────────────────────────────────┤
//! │  project/     │  Unified project detection and management   │
//! │  ├─detector   │  ├─ ProjectDetector (any project type)     │
//! │  ├─manager    │  ├─ ProjectManager (lifecycle management)  │
//! │  └─types      │  └─ ProjectInfo trait (common interface)   │
//! ├─────────────────────────────────────────────────────────────┤
//! │  node/        │  Generic Node.js concepts                  │
//! │  ├─types      │  ├─ RepoKind (Simple vs Monorepo)         │
//! │  ├─package_*  │  ├─ PackageManager & PackageManagerKind   │
//! │  └─repository │  └─ RepositoryInfo trait                  │
//! ├─────────────────────────────────────────────────────────────┤
//! │  monorepo/    │  Monorepo-specific functionality           │
//! │  ├─detector   │  ├─ MonorepoDetector (workspace detection) │
//! │  ├─descriptor │  ├─ MonorepoDescriptor (full structure)    │
//! │  └─kinds      │  └─ MonorepoKind (npm, yarn, pnpm, etc.)  │
//! ├─────────────────────────────────────────────────────────────┤
//! │  command/     │  Robust command execution                  │
//! │  filesystem/  │  Safe filesystem operations               │
//! │  error/       │  Comprehensive error handling             │
//! └─────────────────────────────────────────────────────────────┘
//! ```
//!
//! ## Why
//! Interacting with Node.js projects from Rust typically involves a significant
//! amount of boilerplate code for path handling, command execution, and project
//! structure detection. This crate abstracts these common tasks into a reusable
//! library with consistent error handling and cross-platform support.
//!
//! The new architecture provides:
//! - **Clean separation of concerns**: Each module has a clear responsibility
//! - **Unified project handling**: Works with both simple and monorepo projects
//! - **Type-safe abstractions**: Strong typing prevents common errors
//! - **Extensible design**: Easy to add new project types and package managers
//!
//! ## Quick Start
//!
//! ### Detect any Node.js project
//! ```ignore
//! use sublime_standard_tools::project::{ProjectDetector, ProjectDetectorTrait};
//! use std::path::Path;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let detector = ProjectDetector::new();
//!
//! match detector.detect(Path::new("."), None).await {
//!     Ok(project) => {
//!         let info = project.as_project_info();
//!         println!("Found {} project", info.kind().name());
//!
//!         if let Some(pm) = info.package_manager() {
//!             println!("Using {} package manager", pm.command());
//!         }
//!     }
//!     Err(e) => eprintln!("Detection failed: {}", e),
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ### Auto-load configuration from project files
//! All major components support automatic configuration loading:
//! ```rust
//! use sublime_standard_tools::{
//!     project::ProjectDetector,
//!     monorepo::MonorepoDetector,
//!     filesystem::FileSystemManager,
//!     command::DefaultCommandExecutor,
//!     config::StandardConfig,
//! };
//! use std::path::Path;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! // Each component uses default config or accepts explicit configuration
//! let project_detector = ProjectDetector::new();
//! let monorepo_detector = MonorepoDetector::new(); // Uses default config
//! let filesystem = FileSystemManager::new(); // Uses default config
//! let executor = DefaultCommandExecutor::new(); // Uses default config
//!
//! // Or with explicit configuration
//! let config = StandardConfig::default();
//! let monorepo_detector_with_config = MonorepoDetector::new_with_config(config.monorepo);
//! # Ok(())
//! # }
//! ```
//!
//! ### Work with package managers
//! ```ignore
//! use sublime_standard_tools::node::{PackageManager, PackageManagerKind};
//! use std::path::Path;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! // Detect package manager
//! let manager = PackageManager::detect(Path::new(".")).await?;
//! println!("Using {}", manager.command());
//!
//! // Check capabilities
//! if manager.supports_workspaces() {
//!     println!("Workspaces supported");
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ### Analyze monorepos
//! ```ignore
//! use sublime_standard_tools::monorepo::{MonorepoDetector, MonorepoDetectorTrait};
//! use std::path::Path;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let detector = MonorepoDetector::new();
//! if let Some(kind) = detector.is_monorepo_root(".").await? {
//!     let monorepo = detector.detect_monorepo(".").await?;
//!
//!     println!("Found {} with {} packages",
//!              monorepo.kind().name(),
//!              monorepo.packages().len());
//!
//!     // Analyze dependencies
//!     let graph = monorepo.get_dependency_graph();
//!     for (pkg, deps) in graph {
//!         println!("{} has {} dependents", pkg, deps.len());
//!     }
//! }
//! # Ok(())
//! # }
//! ```

#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
#![deny(unused_must_use)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(clippy::todo)]
#![deny(clippy::unimplemented)]
#![deny(clippy::panic)]

pub mod command;
pub mod config;
pub mod error;
pub mod filesystem;
pub mod monorepo;
pub mod node;
pub mod project;

/// Version of the crate
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

/// Returns the version of the crate
#[must_use]
pub fn version() -> &'static str {
    VERSION
}