This commit is contained in:
kristof 2025-04-02 08:45:47 +02:00
parent d79ea2ef4f
commit efd29eeb99
4 changed files with 229 additions and 33 deletions

View File

@ -1,2 +1,73 @@
# sal # SAL (System Abstraction Layer)
A Rust library that provides a unified interface for interacting with operating system features across different platforms. It abstracts away platform-specific details, allowing developers to write cross-platform code with ease.
## Features
- **File System Operations**: Simplified file and directory management
- **Process Management**: Create, monitor, and control processes
- **System Information**: Access system details and metrics
- **Git Integration**: Interface with Git repositories
- **Redis Client**: Robust Redis connection management and command execution
- **Text Processing**: Utilities for text manipulation and formatting
## Modules
### Redis Client
The Redis client module provides a robust wrapper around the Redis client library for Rust, offering:
- Automatic connection management and reconnection
- Support for both Unix socket and TCP connections
- Database selection via environment variables
- Thread-safe global client instance
- Simple command execution interface
[View Redis Client Documentation](src/redisclient/README.md)
### OS Module
Provides platform-independent interfaces for operating system functionality.
### Git Module
Tools for interacting with Git repositories programmatically.
### Process Module
Utilities for process creation, monitoring, and management.
### Text Module
Text processing utilities for common operations.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
sal = "0.1.0"
```
Basic example:
```rust
use sal::redisclient::execute;
use redis::cmd;
fn main() -> redis::RedisResult<()> {
// Execute a Redis command
let mut cmd = redis::cmd("SET");
cmd.arg("example_key").arg("example_value");
execute(&mut cmd)?;
// Retrieve the value
let mut get_cmd = redis::cmd("GET");
get_cmd.arg("example_key");
let value: String = execute(&mut get_cmd)?;
println!("Value: {}", value);
Ok(())
}
```

View File

@ -1,32 +0,0 @@
in @/sal/git/git_executor.rs
create a GitExecutor which is the one executing git commands
and also checking if ssh-agent is loaded
or if there is an authentication mechanism defined in redis
how is this done use src/env/redisclient.rs
this allows us to execute redis commands
check there is herocontext:git in the redis
if yes fetch the object, its a json representing a struct
- status (error, ok) as enum
- auth which is a map
- key is the server part of our git url (see parse_git_url in git module)
- val is another object with following properties
- sshagent as bool (means if set just use loaded sshagent)
- key (is the sshkey as needs to be used when talking to the server)
- username (if username then there needs to be a password)
- password
we need to deserialize this struct
this now tells based on the server name how to authenticate for the git server
if sshagent then rest needs to be empty
if key rest needs to be empty
if username then password set, rest empty
the git executor needs to use above to talk in right way to the server

75
src/process/README.md Normal file
View File

@ -0,0 +1,75 @@
# Process Module
====================
## Overview
The process module is responsible for managing and running system processes.
## Usage
To use the process module, import it in your Rust file and call the desired functions.
## Functions
### mgmt.rs
The mgmt.rs file contains functions for managing system processes.
### run.rs
The run.rs file contains functions for running system processes.
#### Input Flexibility
The `run` function in run.rs is designed to be flexible with its input:
1. **One-liner Commands**: If the input is a single line, it's treated as a command with arguments.
```rust
run("ls -la"); // Runs the 'ls -la' command
```
2. **Multi-line Scripts**: If the input contains newlines, it's treated as a script. The script is automatically dedented using the `dedent` function from `src/text/dedent.rs` before execution.
```rust
run(" echo 'Hello'\n ls -la"); // Common indentation is removed before execution
```
## Examples
### Example 1: Running a Process
To run a process, use the `run` function from the `run.rs` file:
```rust
use process::run;
fn main() {
run("ls -l");
}
```
### Example 2: Running a Multi-line Script
```rust
use process::run;
fn main() {
let result = run(r#"
echo "Hello, world!"
ls -la
echo "Script complete"
"#);
}
```
### Example 2: Managing a Process
To manage a process, use the `mgmt` function from the `mgmt.rs` file:
```rust
use process::mgmt;
fn main() {
mgmt("start");
}
```
## Automatic Dedentation
When a multi-line script is provided to the `run` function, it automatically uses the `dedent` function from `src/text/dedent.rs` to remove common leading whitespace from all lines. This allows you to write scripts with proper indentation in your code without affecting the execution.
For example, this indented script:
```rust
run(r#"
echo "This line has 4 spaces of indentation in the source"
echo "This line also has 4 spaces"
echo "This line has 8 spaces (4 more than the common indentation)"
"#);
```
Will be executed with the common indentation (4 spaces) removed, preserving only the relative indentation between lines.

82
src/redisclient/README.md Normal file
View File

@ -0,0 +1,82 @@
# Redis Client Module
A robust Redis client wrapper for Rust applications that provides connection management, automatic reconnection, and a simple interface for executing Redis commands.
## Features
- **Singleton Pattern**: Maintains a global Redis client instance, so we don't re-int all the time.
- **Connection Management**: Automatically handles connection creation and reconnection
- **Flexible Connectivity**:
- Tries Unix socket connection first (`$HOME/hero/var/myredis.sock`)
- Falls back to TCP connection (localhost) if socket connection fails
- **Database Selection**: Uses the `REDISDB` environment variable to select the Redis database (defaults to 0)
- **Error Handling**: Comprehensive error handling with detailed error messages
- **Thread Safety**: Safe to use in multi-threaded applications
## Usage
### Basic Usage
```rust
use crate::redisclient::execute;
use redis::cmd;
// Execute a simple SET command
let mut set_cmd = redis::cmd("SET");
set_cmd.arg("my_key").arg("my_value");
let result: redis::RedisResult<()> = execute(&mut set_cmd);
// Execute a GET command
let mut get_cmd = redis::cmd("GET");
get_cmd.arg("my_key");
let value: redis::RedisResult<String> = execute(&mut get_cmd);
if let Ok(val) = value {
println!("Value: {}", val);
}
```
### Advanced Usage
```rust
use crate::redisclient::{get_redis_client, reset};
// Get the Redis client directly
let client = get_redis_client()?;
// Execute a command using the client
let mut cmd = redis::cmd("HSET");
cmd.arg("my_hash").arg("field1").arg("value1");
let result: redis::RedisResult<()> = client.execute(&mut cmd);
// Reset the Redis client connection
reset()?;
```
## Environment Variables
- `REDISDB`: Specifies the Redis database number to use (default: 0)
- `HOME`: Used to determine the path to the Redis Unix socket
## Connection Strategy
1. First attempts to connect via Unix socket at `$HOME/hero/var/myredis.sock`
2. If socket connection fails, falls back to TCP connection at `redis://127.0.0.1/`
3. If both connection methods fail, returns an error
## Error Handling
The module provides detailed error messages that include:
- The connection method that failed
- The path to the socket that was attempted
- The underlying Redis error
## Testing
The module includes both unit tests and integration tests:
- Unit tests that mock Redis functionality
- Integration tests that require a real Redis server
- Tests automatically skip if Redis is not available
## Thread Safety
The Redis client is wrapped in an `Arc<Mutex<>>` to ensure thread safety when accessing the global instance.