syntaxis/shared/rust/README.md

364 lines
9.7 KiB
Markdown
Raw Permalink Normal View History

# Tools Shared Rust Library
Shared utilities for all Tools ecosystem Rust CLIs.
## Overview
This library provides common functionality used across all Tools CLIs:
- **Configuration Discovery** - Automatic search for configuration files in standard locations
- **Manifest Management** - Track installed resources and their types
- **Database Path Resolution** - Smart database file location detection
- **Project Detection** - Auto-detect projects from `.project/` or `.vapora/`
- **Project Selection** - Interactive project picker with arrow keys
- **Database Migrations** - SQL migration discovery and execution
- **XDG Directories** - Cross-platform standard directory support
- **Global Database Support** - Multi-project database management
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
tools-shared = { path = "../../shared/rust" }
```
From a tools CLI (e.g., `crates/tracking-cli`):
```toml
tools-shared = { path = "../../../shared/rust" }
```
## Usage
### Configuration Discovery
Find configuration files automatically:
```rust
use tools_shared::find_config_path;
use std::path::PathBuf;
// Search for a config file (returns first found)
let config_path = find_config_path("tracking.toml");
match config_path {
Some(path) => println!("Using config: {}", path.display()),
None => println!("No config found"),
}
```
### Database Path Resolution
Find or create database paths:
```rust
use tools_shared::find_db_path;
// Automatically searches and returns PathBuf with fallback
let db_path = find_db_path("tracking.db");
// Returns: .project/tracking.db (with fallback to .project/ if not found)
println!("Database: {}", db_path.display());
```
### Manifest Management
Track installed resources (requires `manifest` feature):
```rust
use tools_shared::{Manifest, ResourceType};
use std::path::Path;
// Load manifest
let manifest = Manifest::load(Path::new(".project/manifest.toml"))?;
// Check if config is enabled
if manifest.is_enabled("tracking") {
println!("Tracking is enabled");
}
// Get all enabled configs
for config in manifest.enabled_configs() {
println!("Using: {}", config.name);
}
```
## Configuration Discovery Order
All Tools CLIs automatically search for configurations in this order:
1. **`.project/{name}`** - External projects using Tools (PRIORITY)
2. **`.vapora/{name}`** - VAPORA platform projects
3. **`.coder/{name}`** - Documentation tracking projects
4. **Current directory** - Fallback
The library uses **first found** - it stops searching once it finds a match.
## Examples
### In a CLI main.rs
```rust
use tools_shared::find_db_path;
use std::path::PathBuf;
#[tokio::main]
async fn main() -> Result<()> {
// Resolve database path using smart search
let db_path = find_db_path("tracking.db");
let db_url = format!("sqlite:///{}", db_path.display());
// Initialize database
let db = TrackingDb::new(&db_url).await?;
Ok(())
}
```
### With explicit fallback
```rust
use tools_shared::find_config_path_or;
// Find config or use explicit default
let config = find_config_path_or("app.toml", "config/app.toml");
```
### Project Detection
Automatically detect projects from configuration files in the current working directory or parents:
```rust
use tools_shared::detect_project_from_cwd;
// Auto-detect project from CWD searching upward
if let Some(project) = detect_project_from_cwd("config.toml") {
println!("Project: {}", project.name);
println!("Config: {}", project.config_path.display());
println!("Root: {}", project.root_path.display());
}
```
The detection searches in this order:
1. `.project/lifecycle.toml` (Tools projects)
2. `.vapora/lifecycle.toml` (VAPORA projects)
3. Parent directories recursively
### Project Selection
Interactively select from a list of projects with arrow keys (requires `interactive` feature):
```rust
use tools_shared::{select_project, SelectableProject};
let projects = vec![
SelectableProject {
id: "proj-1".to_string(),
name: "My Project".to_string(),
path: Some("/home/user/projects/my-project".to_string()),
metadata: Some("Phase: Development".to_string()),
},
];
match select_project(projects, "Select a project:", None) {
Ok(selected_id) => println!("Selected: {}", selected_id),
Err(e) => println!("Cancelled: {}", e),
}
```
### Database Migrations
Find and manage SQL migration files in `data/migration/`:
```rust
use tools_shared::{find_migration_files, run_migration_file, has_migration_directory};
// Find all migration files
let migrations = find_migration_files(".")?;
println!("Found {} migrations", migrations.len());
// Check if migration directory exists
if has_migration_directory(".") {
// Get migration file list
let filenames = list_migration_files(".")?;
}
// Run a single migration
run_migration_file("migrations/001_initial.sql")?;
```
### XDG Directories
Cross-platform standard directory support:
```rust
use tools_shared::{tool_data_dir, tool_config_dir, tool_cache_dir, ensure_dir};
// Get standard directories
let data_dir = tool_data_dir("my-tool"); // ~/.local/share/tools/my-tool
let config_dir = tool_config_dir("my-tool"); // ~/.config/tools/my-tool
let cache_dir = tool_cache_dir("my-tool"); // ~/.cache/tools/my-tool
// Ensure directory exists
ensure_dir(&data_dir)?;
```
### Global Database Support
Use a single global database for multiple projects:
```rust
use tools_shared::find_global_db_path;
// Get global database path
let global_db = find_global_db_path("my-tool");
// Returns: ~/.local/share/tools/my-tool/my-tool.db
```
## Features
### `config-discovery` (default)
Provides configuration file discovery utilities:
- `find_config_path(filename)` - Returns `Option<PathBuf>`
- `find_config_path_or(filename, default)` - Returns `PathBuf` with fallback
- `find_db_path(filename)` - Returns `PathBuf` for database files
- `find_config_path_warn_conflicts(filename)` - Warns if multiple config locations exist
### `interactive` (optional)
Enables interactive project selection with arrow keys:
- `select_project()` - Interactive project picker using inquire
- Requires `inquire` crate
Enable in `Cargo.toml`:
```toml
tools-shared = { path = "../../shared/rust", features = ["interactive"] }
```
### `manifest` (optional, requires serde, toml)
Provides manifest management:
- `Manifest` struct
- `ConfigEntry` struct
- `ResourceType` enum
- TOML serialization/deserialization
Enable in `Cargo.toml`:
```toml
tools-shared = { path = "../../shared/rust", features = ["manifest"] }
```
### Always Included
**Project Detection:**
- `DetectedProject` struct
- `detect_project_from_cwd(config_filename)` - Auto-detect from CWD
- `detect_project_from_path(path, config_filename)` - Auto-detect from specific path
- `load_last_project(tool_name)` - Load cached project selection
- `save_last_project(tool_name, project_id)` - Cache project selection
**Project Selection Helpers:**
- `SelectableProject` struct
- `format_project_option()` - Format project for display
**XDG Directories:**
- `tool_data_dir(tool_name)` - Standard data directory
- `tool_config_dir(tool_name)` - Standard config directory
- `tool_cache_dir(tool_name)` - Standard cache directory
- `ensure_dir(path)` - Create directory if needed
**Global Databases:**
- `find_global_db_path(tool_name)` - Get global database path
- `find_global_db_path_custom(tool_name, filename)` - Custom global database path
- `global_db_exists(tool_name)` - Check if global database exists
**Database Migrations:**
- `run_migration_file(file_path)` - Execute SQL migration from file
- `find_migration_files(root_path)` - Find all `.sql` files in `data/migration/`
- `list_migration_files(root_path)` - Get migration filenames only
- `migration_directory(root_path)` - Get migration directory path
- `has_migration_directory(root_path)` - Check if migration directory exists
## Testing
Run tests:
```bash
# All tests
cargo test -p tools-shared
# Specific module
cargo test -p tools-shared config_finder::tests
# With output
cargo test -p tools-shared -- --nocapture
```
## Module Structure
```
shared/rust/
├── lib.rs # Module exports
├── config_finder.rs # Configuration discovery
├── manifest_manager.rs # Manifest management
├── xdg.rs # XDG directories
├── global_db.rs # Global database paths
├── project_detection.rs # Project auto-detection
├── project_selector.rs # Interactive selection
├── db_migration.rs # SQL migrations
└── Cargo.toml # Package definition
```
## Integration Points
This library is used by all Tools ecosystem CLIs:
### Rust CLIs
- **syntaxis-cli** - All features (detection, selection, migrations, global DB)
- **tracking-cli** - Configuration discovery & database paths
- **doc-syntaxis-cli** - Configuration discovery & project detection
- **hello-tool** (example) - All features (detection, selection, migrations)
### Can Be Used By
- **presentation-generator** - Configuration discovery
- Any new Tools ecosystem CLI
## Maintenance
When updating the library:
1. Update version in `Cargo.toml`
2. Run tests: `cargo test -p tools-shared`
3. Check all CLIs still compile: `cargo check --workspace`
4. Update documentation
## API Stability
This library follows semantic versioning:
- Major version: Breaking changes to public API
- Minor version: New features, backward compatible
- Patch version: Bug fixes
Current version: 0.1.0 (experimental)
## Contributing
When adding new functionality:
1. Add to appropriate module (config_finder.rs or manifest_manager.rs)
2. Export from lib.rs
3. Add unit tests
4. Update this README
5. Verify all CLIs still compile
## License
MIT OR Apache-2.0
Same as all Tools projects.