DEV Community

bimlas
bimlas

Posted on • Edited on

Fosh: Execute shell commands in multiple directories grouped by tags

For developers who running the same command in different directories repeatedly, Fosh is a productivity tool that saves time by executing the command without having to change the directory. Unlike other similar tools, Fosh does not bound to a certain software (like Git for example), it can execute any shell command. It works at least on Windows and Linux.

If you prefer Bash, have a look at https://github.com/bimlas/bash-mosh/

  • Manage multiple Git repositors together
    • Checkout the same branch for project and its submodules
    • Commit with the same message: walk through the repos without interruption and copy / paste the same commit message
    • Prevent early push: you do not have to remember which repositories have modified, just look at them at the end of the day to see where you need to push
  • Control multiple vagrant machines at the same time

The essence of the code in a nutshell:

for(dir in selectedDirectories) { cd(dir); shellCommand(); } 

This also means the name: for ... shell ... -> fosh.

Installation

$ npm install -g fosh 

Get the source code, report bugs, open pull requests, or just star because you didn't know that you need it:

Commands

Tag: Assign tags to directories

The tags can be specified as command-line parameters prefixed with @, directories should be listed in the prompt, or piped to stdin.

$ fosh tag "@pictures" "@personal" fosh: tag > /home/myself/photos fosh: tag > /home/mom/my_little_family $ echo -e "/home/myself/photos \n /home/mom/my_little_family" | fosh tag "@pictures" "@personal" 

Find Git repositories

Tagging Git repositories under the current directory (./) with
"git-repos" tag:

# Linux / Windows Git Bash / ... $ find "./" -name ".git" -printf "%h\n" | fosh tag "@git-repos" # Windows PowerShell $ Get-ChildItem './' -Recurse -Directory -Hidden -Filter '.git' | ForEach-Object { Split-Path $_.FullName -Parent } | fosh tag '@git-repos' 

On Windows you can use Everything search engine's es command-line interface to find Git repositories rapidly. Use the following command in PowerShell for this (omit the path of the root directory (./src) to find everywhere):

$ es -regex '^\.git$' './src' | Split-Path -Parent | fosh tag '@git-repos' 

List: Prints the path of the tag list file

You can edit it in a texteditor (Notepad, Vim, etc.).

Run: Execute commands in multiple directories

Arguments can be tags and paths.

$ fosh run "@git-repos" "../wip-project" fosh: run > git status --short --branch __ @1 awesome-project (/home/me/src/) ________________________________________ ## master AM README.md M package.json __ @2 git-test (/home/me/src/) _______________________________________________ ## master...origin/master M README.adoc M encoding/cp1250-encoding-dos-eol.txt M encoding/dos-eol.txt __ @3 wip-project (/home/me/helping-tom/) ____________________________________ ## master...origin/master M example-code.js ============================================================================== fosh: run > another command and so on ... 

Filtering the directory list

If you want to execute a command only in certain directories, you can select them by their index.

fosh: run > @1,3 git status --short --branch __ @1 awesome-project (/home/me/src/) ________________________________________ ## master AM README.md M package.json __ @3 wip-project (/home/me/helping-tom/) ____________________________________ ## master...origin/master M example-code.js 

Execute in the most recently used directories

This is useful if the output is long and you want to execute additional commands on certain directories. In this case, open a new terminal window (so you can look back at results in the current terminal) and run the program without arguments: the directory list is always stored when tag or directory arguments are given, but if you run it without arguments, it executes the commands on the last specified directories.

$ fosh run "@git-repos" "../wip-project" fosh: run > git status --short --branch __ @1 awesome-project (/home/me/src/) ________________________________________ ## master AM README.md ... # Another terminal $ fosh run fosh: WARNING: Using most recently used directory list fosh: run > @3 git diff __ @3 wip-project (/home/me/helping-tom/) ____________________________________ example-code.js | 1 + 1 file changed, 1 insertion(+) diff --git a/example-code.js b/example-code.js index 12b5e40..733220f 100644 --- a/example-code.js +++ b/example-code.js ... 

Top comments (0)