workspace_tools
Stop fighting with file paths in Rust. workspace_tools
provides foolproof, workspace-relative path resolution that works everywhere: in your tests, binaries, and examples, regardless of the execution context.
It's the missing piece of the Rust development workflow that lets you focus on building, not on debugging broken paths.
🎯 The Problem: Brittle File Paths
Every Rust developer has faced this. Your code works on your machine, but breaks in CI or when run from a different directory.
// ❌ Brittle: This breaks if you run `cargo test` or execute the binary from a subdirectory.
let config = read_to_string?;
// ❌ Inconsistent: This relies on the current working directory, which is unpredictable.
let data = new;
✅ The Solution: A Reliable Workspace Anchor
workspace_tools
gives you a stable anchor to your project's root, making all file operations simple and predictable.
use workspace;
// ✅ Reliable: This works from anywhere.
let ws = workspace?; // Automatically finds your project root!
let config = read_to_string?;
let data = ws.data_dir.join; // Use standard, predictable directories.
🚀 Quick Start in 60 Seconds
Get up and running with a complete, working example in less than a minute.
1. Add the Dependency
In your project's root directory, run:
2. Use it in Your Code
workspace_tools
automatically finds your project root by looking for the Cargo.toml
file that contains your [workspace]
definition. No configuration is required.
use workspace;
use fs;
use Path;
// Helper function to create a dummy config file for the example.
3. Run Your Application
Run your code from different directories to see workspace_tools
in action:
# Run from the project root (this will work)
# Run from a subdirectory (this will also work!)
You have now eliminated brittle, context-dependent file paths from your project!
📁 A Standard for Project Structure
workspace_tools
helps standardize your projects, making them instantly familiar to you, your team, and your tools.
your-project/
├── .cargo/
├── .secrets.sh # (Optional) Securely manage secrets
├── .workspace/ # Internal workspace metadata
├── Cargo.toml # Your workspace root
├── config/ # ( ws.config_dir() ) Application configuration
├── data/ # ( ws.data_dir() ) Databases, caches, user data
├── docs/ # ( ws.docs_dir() ) Project documentation
├── logs/ # ( ws.logs_dir() ) Runtime log files
├── src/
└── tests/ # ( ws.tests_dir() ) Integration tests & fixtures
🎭 Advanced Features
workspace_tools
is packed with powerful, optional features. Enable them in your Cargo.toml
as needed.
Eliminate boilerplate for loading .toml
, .json
, and .yaml
files.
Enable: cargo add serde
and add workspace_tools = { workspace = true, features = ["serde_integration"] }
to Cargo.toml
.
use Deserialize;
use workspace;
let ws = workspace?;
// Automatically finds and parses `config/app.{toml,yaml,json}`.
let config : AppConfig = ws.load_config?;
println!;
// Load and merge multiple layers (e.g., base + production).
let final_config : AppConfig = ws.load_config_layered?;
// Partially update a configuration file on disk.
let updates = json!;
let updated_config : AppConfig = ws.update_config?;
Find files anywhere in your workspace using glob patterns.
Enable: Add workspace_tools = { workspace = true, features = ["glob"] }
to Cargo.toml
.
use workspace;
let ws = workspace?;
// Find all Rust source files recursively.
let rust_files = ws.find_resources?;
// Intelligently find a config file, trying multiple extensions.
let db_config = ws.find_config?; // Finds config/database.toml, .yaml, etc.
Load secrets from a dedicated, git-ignored .secrets.sh
file, with fallbacks to environment variables.
Enable: Add workspace_tools = { workspace = true, features = ["secret_management"] }
to Cargo.toml
.
// .gitignore
.*
// .secrets.sh
API_KEY="your-super-secret-key"
use workspace;
let ws = workspace?;
// Loads API_KEY from .secrets.sh, or falls back to the environment.
let api_key = ws.load_secret_key?;
🛠️ Built for the Real World
workspace_tools
is designed for production use, with features that support robust testing and flexible deployment.
Testing with Confidence
Create clean, isolated environments for your tests.
// In tests/my_test.rs
use create_test_workspace_with_structure;
use fs;
Flexible Deployment
Because workspace_tools
can be configured via WORKSPACE_PATH
, it adapts effortlessly to any environment.
Dockerfile:
# Your build stages...
# Final stage
FROM debian:bookworm-slim
WORKDIR /app
ENV WORKSPACE_PATH=/app # Set the workspace root inside the container.
COPY --from=builder /app/target/release/my-app .
COPY config/ ./config/
COPY assets/ ./assets/
CMD ["./my-app"] # Your app now runs with the correct workspace context.
Resilient by Design
workspace_tools
has a smart fallback strategy to find your workspace root, ensuring it always finds a sensible path.
graph TD
A[Start] --> B{Cargo Workspace?};
B -->|Yes| C[Use Cargo Root];
B -->|No| D{WORKSPACE_PATH Env Var?};
D -->|Yes| E[Use Env Var Path];
D -->|No| F{.git folder nearby?};
F -->|Yes| G[Use Git Root];
F -->|No| H[Use Current Directory];
C --> Z[Success];
E --> Z[Success];
G --> Z[Success];
H --> Z[Success];
🚧 Vision & Roadmap
workspace_tools
is actively developed. Our vision is to make workspace management a solved problem in Rust. Upcoming features include:
- Project Scaffolding: A powerful
cargo workspace-tools init
command to create new projects from templates. - Configuration Validation: Schema-based validation to catch config errors before they cause panics.
- Async & Hot-Reloading: Full
tokio
integration for non-blocking file operations and live configuration reloads. - Official CLI Tool: A
cargo workspace-tools
command for managing your workspace from the terminal. - IDE Integration: Rich support for VS Code and RustRover to bring workspace-awareness directly into your editor.
🤝 Contributing
This project thrives on community contributions. Whether it's reporting a bug, suggesting a feature, or writing code, your help is welcome! Please see our task list and contribution guidelines.
⚖️ License
This project is licensed under the MIT License.