diff --git a/.gitignore b/.gitignore index a8ff770..b895c18 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ docusaurus.config.ts sidebars.ts tsconfig.json +Cargo.toml.bak \ No newline at end of file diff --git a/README.md b/README.md index 20b8f13..ebe150f 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ SAL is a comprehensive Rust library designed to provide a unified and simplified ## ๐Ÿ—๏ธ **Cargo Workspace Structure** -SAL is organized as a **Cargo workspace** with 16 specialized crates: +SAL is organized as a **Cargo workspace** with 15 specialized crates: - **Root Package**: `sal` - Umbrella crate that re-exports all modules -- **13 Library Crates**: Specialized SAL modules (git, text, os, net, etc.) +- **12 Library Crates**: Core SAL modules (os, process, text, net, git, vault, kubernetes, virt, redisclient, postgresclient, zinit_client, mycelium) - **1 Binary Crate**: `herodo` - Rhai script execution engine - **1 Integration Crate**: `rhai` - Rhai scripting integration layer @@ -31,20 +31,11 @@ SAL is designed to be modular - install only the components you need! Install only the modules you need: ```bash -# Core system operations -cargo add sal-os sal-process sal-text sal-net +# Currently available packages +cargo add sal-os sal-process sal-text sal-net sal-git sal-vault sal-kubernetes sal-virt -# Database clients -cargo add sal-redisclient sal-postgresclient - -# Infrastructure tools -cargo add sal-git sal-vault sal-kubernetes sal-virt - -# Service clients -cargo add sal-zinit-client sal-mycelium - -# Scripting support -cargo add sal-rhai +# Coming soon (rate limited) +# cargo add sal-redisclient sal-postgresclient sal-zinit-client sal-mycelium sal-rhai ``` ### Option 2: Meta-crate with Features @@ -52,17 +43,13 @@ cargo add sal-rhai Use the main `sal` crate with specific features: ```bash -# Install specific modules -cargo add sal --features os,process,text +# Coming soon - meta-crate with features (rate limited) +# cargo add sal --features os,process,text +# cargo add sal --features core # os, process, text, net +# cargo add sal --features infrastructure # git, vault, kubernetes, virt +# cargo add sal --features all -# Install feature groups -cargo add sal --features core # os, process, text, net -cargo add sal --features clients # redisclient, postgresclient, zinit_client, mycelium -cargo add sal --features infrastructure # git, vault, kubernetes, virt -cargo add sal --features scripting # rhai - -# Install everything -cargo add sal --features all +# For now, use individual crates (see Option 1 above) ``` ### Quick Start Examples @@ -161,15 +148,17 @@ SAL is published as individual crates, allowing you to install only what you nee **Currently Available on crates.io:** - โœ… [`sal-os`](https://crates.io/crates/sal-os) - Operating system operations +- โœ… [`sal-process`](https://crates.io/crates/sal-process) - Process management - โœ… [`sal-text`](https://crates.io/crates/sal-text) - Text processing utilities - โœ… [`sal-net`](https://crates.io/crates/sal-net) - Network operations - โœ… [`sal-git`](https://crates.io/crates/sal-git) - Git repository management - โœ… [`sal-vault`](https://crates.io/crates/sal-vault) - Cryptographic operations - โœ… [`sal-kubernetes`](https://crates.io/crates/sal-kubernetes) - Kubernetes management +- โœ… [`sal-virt`](https://crates.io/crates/sal-virt) - Virtualization tools **Publishing Soon** (hit crates.io rate limit): - โณ `sal-redisclient`, `sal-postgresclient`, `sal-zinit-client`, `sal-mycelium` -- โณ `sal-process`, `sal-virt`, `sal-rhai` +- โณ `sal-rhai` - โณ `sal` (meta-crate), `herodo` (binary) **Estimated Timeline**: Remaining packages will be published within 24 hours once the rate limit resets. @@ -265,42 +254,58 @@ For more examples, check the individual module test directories (e.g., `text/tes ## Using SAL as a Rust Library -Add SAL as a dependency to your `Cargo.toml`: +### Option 1: Individual Crates (Recommended) + +Add only the SAL modules you need: ```toml [dependencies] -sal = "0.1.0" # Or the latest version +sal-os = "0.1.0" +sal-process = "0.1.0" +sal-text = "0.1.0" ``` -### Rust Example: Using Redis Client - ```rust -use sal::redisclient::{get_global_client, execute_cmd_with_args}; -use redis::RedisResult; +use sal_os::fs; +use sal_process::run; +use sal_text::template; -async fn example_redis_interaction() -> RedisResult<()> { - // Get a connection from the global pool - let mut conn = get_global_client().await?.get_async_connection().await?; +fn main() -> Result<(), Box> { + // File operations + let files = fs::list_files(".")?; + println!("Found {} files", files.len()); - // Set a value - execute_cmd_with_args(&mut conn, "SET", vec!["my_key", "my_value"]).await?; - println!("Set 'my_key' to 'my_value'"); + // Process execution + let result = run::command("echo 'Hello SAL!'")?; + println!("Output: {}", result.stdout); - // Get a value - let value: String = execute_cmd_with_args(&mut conn, "GET", vec!["my_key"]).await?; - println!("Retrieved value for 'my_key': {}", value); + // Text templating + let template_str = "Hello {{name}}!"; + let mut vars = std::collections::HashMap::new(); + vars.insert("name".to_string(), "World".to_string()); + let rendered = template::render(template_str, &vars)?; + println!("Rendered: {}", rendered); Ok(()) } - -#[tokio::main] -async fn main() { - if let Err(e) = example_redis_interaction().await { - eprintln!("Redis Error: {}", e); - } -} ``` -*(Note: The Redis client API might have evolved; please refer to `src/redisclient/mod.rs` and its documentation for the most current usage.)* + +### Option 2: Meta-crate with Features (Coming Soon) + +```toml +[dependencies] +sal = { version = "0.1.0", features = ["os", "process", "text"] } +``` + +```rust +use sal::os::fs; +use sal::process::run; +use sal::text::template; + +// Same code as above, but using the meta-crate +``` + +*(Note: The meta-crate `sal` will be available once all individual packages are published.)* ## ๐ŸŽฏ **Why Choose SAL?** diff --git a/scripts/publish-all.sh b/scripts/publish-all.sh index 8273e01..21dcaa5 100755 --- a/scripts/publish-all.sh +++ b/scripts/publish-all.sh @@ -141,56 +141,143 @@ if [ "$DRY_RUN" = false ]; then fi fi +# Function to check if a crate version is already published +is_published() { + local crate_name="$1" + local version="$2" + + # Use cargo search to check if the exact version exists + if cargo search "sal-$crate_name" --limit 1 | grep -q "sal-$crate_name.*$version"; then + return 0 # Already published + else + return 1 # Not published + fi +} + +# Function to update dependencies in a crate's Cargo.toml +update_dependencies() { + local crate_dir="$1" + local version="$2" + + if [ ! -f "$crate_dir/Cargo.toml" ]; then + return + fi + + # Create backup + cp "$crate_dir/Cargo.toml" "$crate_dir/Cargo.toml.bak" + + # Update all SAL path dependencies to version dependencies + sed -i.tmp "s|sal-text = { path = \"../text\" }|sal-text = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-os = { path = \"../os\" }|sal-os = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-process = { path = \"../process\" }|sal-process = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-git = { path = \"../git\" }|sal-git = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-vault = { path = \"../vault\" }|sal-vault = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-net = { path = \"../net\" }|sal-net = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-kubernetes = { path = \"../kubernetes\" }|sal-kubernetes = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-redisclient = { path = \"../redisclient\" }|sal-redisclient = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-postgresclient = { path = \"../postgresclient\" }|sal-postgresclient = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-virt = { path = \"../virt\" }|sal-virt = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-mycelium = { path = \"../mycelium\" }|sal-mycelium = \"$version\"|g" "$crate_dir/Cargo.toml" + sed -i.tmp "s|sal-zinit-client = { path = \"../zinit_client\" }|sal-zinit-client = \"$version\"|g" "$crate_dir/Cargo.toml" + + # Clean up temporary files + rm -f "$crate_dir/Cargo.toml.tmp" +} + +# Function to restore dependencies from backup +restore_dependencies() { + local crate_dir="$1" + + if [ -f "$crate_dir/Cargo.toml.bak" ]; then + mv "$crate_dir/Cargo.toml.bak" "$crate_dir/Cargo.toml" + fi +} + # Publish individual crates echo -e "${BLUE}๐Ÿ“ฆ Publishing individual crates...${NC}" echo "" for crate in "${CRATES[@]}"; do echo -e "${YELLOW}Publishing sal-$crate...${NC}" - + if [ ! -d "$crate" ]; then echo -e "${RED} โŒ Directory $crate not found${NC}" continue fi - + + # Check if already published + if [ "$DRY_RUN" = false ] && is_published "$crate" "$VERSION"; then + echo -e "${GREEN} โœ… sal-$crate@$VERSION already published, skipping${NC}" + echo "" + continue + fi + + # Update dependencies to use version numbers + echo -e "${BLUE} ๐Ÿ“ Updating dependencies for sal-$crate...${NC}" + update_dependencies "$crate" "$VERSION" + cd "$crate" - + if [ "$DRY_RUN" = true ]; then echo -e "${BLUE} ๐Ÿ” Would run: cargo publish --allow-dirty${NC}" + if is_published "$crate" "$VERSION"; then + echo -e "${YELLOW} ๐Ÿ“ Note: sal-$crate@$VERSION already exists${NC}" + fi else if cargo publish --allow-dirty; then echo -e "${GREEN} โœ… sal-$crate published successfully${NC}" else echo -e "${RED} โŒ Failed to publish sal-$crate${NC}" cd .. + restore_dependencies "$crate" exit 1 fi fi - + cd .. - - if [ "$DRY_RUN" = false ] && [ "$crate" != "${CRATES[-1]}" ]; then - echo -e "${BLUE} โณ Waiting $WAIT_TIME seconds for crates.io to process...${NC}" - sleep "$WAIT_TIME" + + # Restore original dependencies + restore_dependencies "$crate" + + # Wait between publishes (except for the last one) + if [ "$DRY_RUN" = false ]; then + # Get the last element of the array + last_crate="${CRATES[${#CRATES[@]}-1]}" + if [ "$crate" != "$last_crate" ]; then + echo -e "${BLUE} โณ Waiting $WAIT_TIME seconds for crates.io to process...${NC}" + sleep "$WAIT_TIME" + fi fi - + echo "" done # Publish main crate echo -e "${BLUE}๐Ÿ“ฆ Publishing main sal crate...${NC}" -if [ "$DRY_RUN" = true ]; then - echo -e "${BLUE}๐Ÿ” Would run: cargo publish --allow-dirty${NC}" +# Check if main crate is already published +if [ "$DRY_RUN" = false ] && cargo search "sal" --limit 1 | grep -q "sal.*$VERSION"; then + echo -e "${GREEN}โœ… sal@$VERSION already published, skipping${NC}" else - if cargo publish --allow-dirty; then - echo -e "${GREEN}โœ… Main sal crate published successfully${NC}" + if [ "$DRY_RUN" = true ]; then + echo -e "${BLUE}๐Ÿ” Would run: cargo publish --allow-dirty${NC}" + if cargo search "sal" --limit 1 | grep -q "sal.*$VERSION"; then + echo -e "${YELLOW}๐Ÿ“ Note: sal@$VERSION already exists${NC}" + fi else - echo -e "${RED}โŒ Failed to publish main sal crate${NC}" - exit 1 + if cargo publish --allow-dirty; then + echo -e "${GREEN}โœ… Main sal crate published successfully${NC}" + else + echo -e "${RED}โŒ Failed to publish main sal crate${NC}" + exit 1 + fi fi fi +# Clean up any remaining backup files +echo -e "${BLUE}๐Ÿงน Cleaning up backup files...${NC}" +find . -name "Cargo.toml.bak" -delete 2>/dev/null || true + echo "" echo -e "${GREEN}===============================================${NC}" echo -e "${GREEN} Publishing Complete!${NC}"