Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
joeycumines committed Feb 22, 2025
0 parents commit f6b59ff
Show file tree
Hide file tree
Showing 6 changed files with 511 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
on:
release:
types: [ created ]
permissions:
contents: write
packages: write
jobs:
releases-matrix:
name: Release Go Binary
runs-on: ubuntu-latest
strategy:
matrix:
goos: [ linux, windows, darwin ]
goarch: [ "386", amd64, arm64 ]
exclude:
- goarch: "386"
goos: darwin
- goarch: arm64
goos: windows
steps:
- uses: actions/checkout@v4
- uses: wangyoucao577/go-release-action@481a2c1a0f1be199722e3e9b74d7199acafc30a8 # /~https://github.com/wangyoucao577/go-release-action/releases/tag/v1.53
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
extra_files: LICENSE README.md
md5sum: false
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Joseph Cumines

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
155 changes: 155 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# randoo

randoo is a simple command-line utility written in Go that randomizes the order of command arguments before executing a
given command. It provides flexible options to control which arguments get shuffled, whether by shuffling all arguments
or only a subset delimited by special tokens.

---

## Overview

By design, randoo:

- **Shuffles arguments:** It randomizes the order of command arguments.
- **Executes commands:** After shuffling, it calls the specified command with the randomized arguments.
- **Offers selective shuffling:** You can control which arguments are shuffled using start (`-s`) and end (`-e`)
delimiters (consumed).
- **Supports input from stdin:** With the `-l` flag, you can supply additional arguments via standard input (one per
line).

---

## Usage

```bash
randoo [options] [--] command [args...]
```

- **command:** The executable you want to run.
- **args...:** The arguments for the command, which will be randomized according to the options provided.

---

## Command-Line Options

- **`-s string`**
*Shuffle args after the specified argument (start delimiter).*
The argument provided with this flag marks the beginning of the segment to be shuffled.
**Behavior:**
- The tool searches for this delimiter in the provided arguments.
- If found, the arguments after this token (or up to an end delimiter, if specified) are shuffled.
- The delimiter itself is not passed on to the command.
- **Error:** If the token is not found, randoo exits with an error.

- **`-e string`**
*Shuffle args before the specified argument (end delimiter).*
This flag designates the end of the segment to be shuffled.
**Behavior:**
- The tool searches for this token.
- If found, the arguments preceding it (or a segment defined between a start and this end delimiter) are randomized.
- Like the start delimiter, this token is not passed on.
- **Error:** If the token is not found, an error is reported.

- **`-l`**
*Read input from stdin, one argument per line.*
**Behavior:**
- Reads additional arguments from standard input.
- These arguments are appended to any trailing arguments (which are not shuffled unless affected by the delimiters).
- This is useful for dynamically supplying arguments at runtime.

---

## Implementation Details

### Shuffling Logic

- **Complete Shuffle:**
If neither `-s` nor `-e` is provided, all arguments are shuffled.

- **Single Delimiter Mode:**
When only one of the delimiters is specified:
- For **`-s` only:** randoo finds the delimiter, removes it, and shuffles all arguments that follow.
- For **`-e` only:** It shuffles all arguments preceding the found delimiter and then removes the delimiter.

- **Delimited Range Shuffle:**
If **both** `-s` and `-e` are provided:
- The program searches for the start delimiter (`-s`).
- It then looks for the end delimiter (`-e`) after the start delimiter.
- Only the arguments in between are shuffled.
- After shuffling, both delimiters are removed before execution.

- **Random Source:**
randoo uses a custom random source based on `crypto/rand` to seed the shuffle mechanism, ensuring that the
randomization is well-seeded and secure.

### Execution and Signal Handling

- **Command Execution:**
After processing and shuffling the arguments, randoo executes a subprocess, with the provided command, and processed
arguments.

- **Signal Forwarding:**
It sets up signal forwarding so that any signals received (like SIGINT) are passed to the spawned process, ensuring
proper signal handling during execution.

- **Error Handling:**
The tool validates that:
- A command is provided.
- Required delimiters exist in the arguments (if specified).

In case of errors (e.g., missing command, missing delimiter), it outputs a relevant error message and exits with a
non-zero status. It also attempts to propagate the exit code of the executed command, when possible.

---

## Examples

### 1. Basic Randomization

Shuffle all arguments before executing the command:

```bash
randoo ls -la file1.txt file2.txt file3.txt
```

This will shuffle the order of `file1.txt`, `file2.txt`, and `file3.txt` before calling `ls -la`.

### 2. Using a Single Delimiter

Shuffle only the arguments after a specified token:

```bash
randoo -s START echo START arg1 arg2 arg3
```

- **Behavior:**
- `START` is used as the start delimiter.
- The arguments following `START` (`arg1 arg2 arg3`) are shuffled.
- The delimiter is removed before executing the command.

### 3. Using Both Delimiters

Shuffle a specific range of arguments:

```bash
randoo -s START -e END echo START arg1 arg2 arg3 END extraArg
```

- **Behavior:**
- `START` marks the beginning and `END` marks the end of the segment to be shuffled.
- Only the arguments between `START` and `END` (`arg1 arg2 arg3`) are randomized.
- Both delimiters are stripped from the final command line.
- `extraArg` remains unshuffled.

### 4. Reading Arguments from Stdin

Shuffle arguments provided via standard input:

```bash
echo -e "arg1\narg2\narg3" | randoo -l mycommand
```

- **Behavior:**
- Reads each line from stdin as an argument.
- Shuffles the input arguments.
- Appends them to the command `mycommand` for execution.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/joeycumines/randoo

go 1.23.6
8 changes: 8 additions & 0 deletions hack/test-sigint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

trap 'echo "Debug: SIGINT received, exiting in 5 seconds..."; sleep 5; exit 1' INT

echo "Running... (Press Ctrl+C to trigger SIGINT)"
while :; do
sleep 1
done
Loading

0 comments on commit f6b59ff

Please sign in to comment.