{"id":26608136,"url":"https://github.com/mobydeck/rufl","last_synced_at":"2025-03-23T23:38:15.032Z","repository":{"id":282152114,"uuid":"947654391","full_name":"mobydeck/rufl","owner":"mobydeck","description":"RunFlow (rufl) is a command line tool that allows executing other commands either in parallel or sequentially.","archived":false,"fork":false,"pushed_at":"2025-03-13T03:44:55.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-13T04:26:14.005Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mobydeck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-13T03:14:33.000Z","updated_at":"2025-03-13T03:44:50.000Z","dependencies_parsed_at":"2025-03-13T04:36:21.026Z","dependency_job_id":null,"html_url":"https://github.com/mobydeck/rufl","commit_stats":null,"previous_names":["mobydeck/rufl"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobydeck%2Frufl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobydeck%2Frufl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobydeck%2Frufl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobydeck%2Frufl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mobydeck","download_url":"https://codeload.github.com/mobydeck/rufl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245186921,"owners_count":20574553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-23T23:38:14.409Z","updated_at":"2025-03-23T23:38:15.025Z","avatar_url":"https://github.com/mobydeck.png","language":"Go","funding_links":[],"categories":["\u003ca name=\"system\"\u003e\u003c/a\u003eSystem tools"],"sub_categories":[],"readme":"# RunFlow (rufl)\n\nRunFlow is a command line tool that allows executing other commands either in parallel or sequentially.\n\n## Installation\n\nThe easiest way to install RunFlow is to download a pre-built binary from the [Releases](https://github.com/mobydeck/rufl/releases) page. Choose the appropriate version for your operating system and architecture:\n\n- Linux (amd64, arm64)\n- macOS (amd64, arm64)\n- Windows (amd64, arm64)\n\n### Linux and macOS\n\n1. Download the archive for your system\n2. Extract it: `tar xzf rufl_*_*.tar.gz`\n3. Move the binary to a directory in your PATH:\n   ```bash\n   sudo mv rufl /usr/local/bin/\n   ```\n\n### Windows\n\n1. Download the ZIP archive for Windows\n2. Extract the contents\n3. Add the directory containing `rufl.exe` to your system's PATH, or move the executable to a directory that's already in your PATH\n\n\n### Cross-Platform Builds\n\nRunFlow can be built for multiple platforms and architectures using the included justfile. You'll\nneed [just](https://github.com/casey/just) installed to use these commands.\n\nBuild for all platforms and architectures:\n\n```bash\njust build-all\n```\n\nBuild for a specific platform and architecture:\n\n```bash\njust build-linux-amd64\njust build-macos-arm64\njust build-windows-amd64\n```\n\nCreate release archives:\n\n```bash\njust package\n```\n\nAvailable build targets:\n\n- Linux (amd64, arm64)\n- macOS (amd64, arm64)\n- Windows (amd64, arm64)\n\nThe compiled binaries will be placed in the `dist/` directory. All builds are optimized for size using\n`-ldflags='-s -w'` and `-trimpath` flags, resulting in significantly smaller executables.\n\n## Usage\n\nRunFlow provides two main commands with multiple aliases:\n\n- `=`, `p` or `parallel`: Run commands in parallel\n- `+`, `s` or `sequential`: Run commands sequentially\n\n### Examples\n\nRun commands in parallel:\n\n```bash\nrufl = \"echo hello world\" \"cat /etc/hosts\" \"while true; do echo hello; sleep 1; done\"\n```\n\nRun commands sequentially:\n\n```bash\nrufl + \"echo hello world\" \"cat /etc/hosts\" \"while true; do echo hello; sleep 1; done\"\n```\n\n### Parallel Execution Order\n\nWhen running commands in parallel mode, RunFlow ensures that commands start in the order they are provided, even though they run concurrently. This means that the first command will start first, followed by the second command, and so on. However, the commands will run concurrently, so they may finish in a different order depending on their execution time.\n\nFor example:\n\n```bash\nrufl = \"sleep 2 \u0026\u0026 echo first\" \"sleep 1 \u0026\u0026 echo second\" \"echo third\"\n```\n\nIn this example, the commands will start in the order they are provided (first, second, third), but they will finish in a different order (third, second, first) because they have different execution times.\n\n### Command Tagging\n\nYou can tag commands with custom names to make the output more descriptive. This is especially useful when running\nmultiple commands, and you want to easily identify which command produced which output.\n\nThere are two ways to tag commands:\n\n#### Using the `-t` flag\n\nUse the `-t` or `--tag` flag with the format `NAME:COMMAND`:\n\n```bash\nrufl = -t \"greeting:echo hello\" -t \"hosts:cat /etc/hosts\" -t \"loop:while true; do echo hello; sleep 1; done\"\n```\n\n#### Using the `+tagname:command` syntax\n\nAlternatively, you can use the more concise `+tagname:command` syntax directly in your command arguments:\n\n```bash\nrufl = \"+greeting:echo hello\" \"+hosts:cat /etc/hosts\" \"+loop:while true; do echo hello; sleep 1; done\"\n```\n\nBoth methods produce the same result, with the output using the tag names instead of numbers:\n\n```\n[greeting] hello\n[hosts] 127.0.0.1 localhost\n[loop] hello\n```\n\nYou can mix tagged and untagged commands. Untagged commands will use numbers as identifiers:\n\n```bash\nrufl = \"echo untagged command\" \"+tagged:echo tagged command\"\n```\n\nOutput:\n\n```\n[1] untagged command\n[tagged] tagged command\n```\n\n#### Command Ordering\n\nCommands are executed in the order they are specified in the command line. When mixing positional arguments and tagged\ncommands:\n\n1. Positional arguments are executed in the order they appear\n2. If a tagged command matches a positional argument, the tag is applied to that command\n3. Any tagged commands that don't match positional arguments are executed after all positional arguments\n\nFor example:\n\n```bash\nrufl + \"echo first\" \"echo second\" \"+third:echo third\"\n```\n\nWill execute the commands in the order: \"echo first\", \"echo second\", \"echo third\".\n\nIf you tag a command that also appears as a positional argument:\n\n```bash\nrufl + \"echo first\" \"echo second\" \"+second:echo second\"\n```\n\nThe command will be executed in its original position, but with the tag applied.\n\n### Direct Command Execution\n\nRunFlow intelligently determines whether a command needs a shell to execute:\n\n- Simple commands like `echo hello` or `ls -la` are executed directly without a shell\n- Commands with shell features like pipes (`|`), redirections (`\u003e`, `\u003c`), environment variables (`$VAR`), or glob\n  patterns (`*.txt`) are executed using a shell\n\nThis provides better performance and security for simple commands while maintaining full shell functionality when\nneeded.\n\nYou can force all commands to use a shell with the `--shell` flag:\n\n```bash\nrufl = --shell \"echo hello\" \"ls -la\"\n```\n\n### Signal Handling\n\nRunFlow handles signals differently depending on the execution mode:\n\n#### Parallel Mode\n\nIn parallel mode, when signals like SIGINT (Ctrl+C), SIGTERM, or SIGHUP are received, they are forwarded to all running child processes. This ensures that when you press Ctrl+C or the terminal session is closed, all running commands are properly terminated.\n\n```bash\nrufl = \"while true; do echo hello; sleep 1; done\" \"while true; do echo world; sleep 1; done\"\n# Press Ctrl+C to terminate all commands and exit\n```\n\n#### Sequential Mode\n\nIn sequential mode, RunFlow provides a more nuanced signal handling approach:\n\n- **Single Ctrl+C**: Interrupts only the currently running command, then continues with the next command in the sequence\n- **Double Ctrl+C** (within 1 second): Interrupts the current command and exits RunFlow completely\n\nThis allows you to skip a long-running command without terminating the entire sequence:\n\n```bash\nrufl + \"sleep 10\" \"echo This will still run after Ctrl+C on the sleep command\"\n# Press Ctrl+C once during the sleep to skip to the next command\n# Press Ctrl+C twice quickly to exit RunFlow entirely\n```\n\nWhen you press Ctrl+C once, you'll see a message indicating that you can press it again to exit:\n\n```\nInterrupting current command. Press Ctrl+C again within 1 second to exit rufl.\n```\n\n### Environment Variables\n\nCommands executed by RunFlow inherit all environment variables from the parent process. This allows you to use\nenvironment variables in your commands:\n\n```bash\nexport MY_VAR=\"some value\"\nrufl = \"echo $MY_VAR\" \"env | grep MY_VAR\"\n```\n\nYou can also set additional environment variables using the `-e` or `--env` flag:\n\n```bash\nrufl = -e \"VAR1=value1\" -e \"VAR2=value2\" \"echo $VAR1 $VAR2\"\n```\n\nThese additional environment variables will be available to all commands being executed.\n\n### Output Format\n\nRunFlow formats command output differently based on whether color is enabled:\n\n#### With Color Enabled (Default)\n\nWhen color is enabled, the output is formatted with colored tags that indicate the command and stream type:\n\n- Standard output is displayed in green with just the command tag: `[tag]`\n- Standard error is displayed in red with just the command tag: `[tag]`\n\nExample:\n```\n[greeting] hello world\n[hosts] 127.0.0.1 localhost\n```\n\nThe color itself indicates whether the output is from stdout (green) or stderr (red).\n\n#### With Color Disabled\n\nWhen color is disabled (using `--no-color` flag or in environments without color support), the output includes both the command tag and the stream type:\n\n```\n[greeting:out] hello world\n[hosts:out] 127.0.0.1 localhost\n[error:err] some error message\n```\n\n### Color Support\n\nRunFlow uses colored output to make it easier to distinguish between different commands and output types:\n\n- Command execution messages are displayed in cyan\n- Standard output is displayed in green\n- Standard error is displayed in red\n- Command completion messages are displayed in green\n- Command error messages are displayed in yellow or red\n- Environment variable information is displayed in blue\n\nYou can disable colored output using the `--no-color` flag:\n\n```bash\nrufl = --no-color \"echo hello\" \"echo world\"\n```\n\nRunFlow also preserves ANSI color codes in command output. This means that if a command produces colored output (like `ls --color=always` or scripts that use color codes), those colors will be displayed correctly in RunFlow's output:\n\n```bash\nrufl = \"ls --color=always\" \"grep --color=always pattern file.txt\"\n```\n\n#### Windows Color Support\n\nOn Windows, ANSI color support is automatically enabled for Windows 10 version 1511 (November 2015) and later. For older\nWindows versions, colors may not be displayed correctly.\n\n## Features\n\n- Execute multiple commands in parallel or sequentially\n- Real-time output streaming (doesn't wait for commands to finish)\n- Intelligent shell detection (only uses a shell when necessary)\n- Proper shell command parsing using go-shlex\n- Clear output formatting with command number and stream type indicators\n- Colored output with automatic Windows support\n- Environment variable inheritance from the parent process\n- Setting additional environment variables with the `-e` flag\n- Command tagging for descriptive output with the `-t` flag or `+tagname:command` syntax\n- Advanced signal handling (double Ctrl+C detection in sequential mode)\n- Cross-platform support (Linux, macOS, Windows) on multiple architectures (amd64, arm64)\n\n## Dependencies\n\n- [github.com/spf13/cobra](https://github.com/spf13/cobra) - Command line interface framework\n- [github.com/anmitsu/go-shlex](https://github.com/anmitsu/go-shlex) - Shell-style lexical analyzer\n- [golang.org/x/sys/windows](https://pkg.go.dev/golang.org/x/sys/windows) - Windows system calls (for Windows color\n  support)\n\n## License\n\nMIT ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobydeck%2Frufl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmobydeck%2Frufl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobydeck%2Frufl/lists"}