|
| 1 | +<!-- markdownlint-configure-file { |
| 2 | + "no-inline-html": { |
| 3 | + "allowed_elements": [ "div" ] |
| 4 | + }, |
| 5 | + "no-multiple-blanks": { |
| 6 | + "maximum": 4 |
| 7 | + } |
| 8 | +} |
| 9 | +--> |
| 10 | +<div align="center"><img style="max-width: 450px;" src="./logo/Myce - Blue.png" alt="MyCE Logo"></div> |
| 11 | + |
| 12 | +# My Command Engine (MyCE) |
| 13 | + |
| 14 | + |
| 15 | +## Overview |
| 16 | + |
| 17 | +My Command Engine or MyCE (as in "Mice") is a powerful, context-aware command-line tool, written intirely in bash, and designed to streamline project workflows by utilizing custom command definitions stored in `.myCommand` files within the directory tree. |
| 18 | +It searches for `.myCommand` files from the root down to the current directory, merging commands to create a localized and context-sensitive command set. |
| 19 | +This tool is ideal for developers who frequently switch between projects or environments and need specific commands scoped to each context. |
| 20 | + |
| 21 | + |
| 22 | + |
| 23 | +## Features |
| 24 | + |
| 25 | +- **Context-Aware Commands**: Executes commands based on the .myCommand file located in the current directory or its parent directories. |
| 26 | +- **Scoped Command Aliases**: Each directory (or project) can define its own command aliases without impacting other directories. |
| 27 | +- **Ease of Use**: A simple command `my <key>` is all you need to invoke the corresponding full command defined in the .myCommand file. |
| 28 | +- **Recursive Lookup**: If a .myCommand file is not found in the current directory, the script searches parent directories until one is found. |
| 29 | +- **Merged Configurations**: Reads .myCommand files from the root directory down to the present working directory, merging them to build a complete command set. If duplicates are found, the command closest to the current directory takes precedence. |
| 30 | +- **Sectioned Commands**: Uses INI-style sections in .myCommand files to organize and access commands with dot-delimited syntax. This allows grouping related commands for better clarity and organization: |
| 31 | + |
| 32 | +```ini |
| 33 | +[server] |
| 34 | +start="docker-compose up" |
| 35 | +stop="docker-compose down" |
| 36 | +``` |
| 37 | + |
| 38 | +Running `my server.start` will execute docker-compose up. |
| 39 | + |
| 40 | +- **Argument Passing**: Additional arguments provided after the command alias are passed directly to the underlying command. This enables dynamic behavior and flexible command usage. |
| 41 | +- **Fallback to Shell**: If the requested alias is not found in the merged .myCommand configurations, the script will pass the command to the shell, allowing standard shell commands to work seamlessly with `my`. |
| 42 | +- **Cross-Domain Commands with Variables**: Commands can reference variables set in different .myCommand files, allowing for reusable, high-level command configurations across directories. This feature is useful for defining generic commands in higher-level folders and reusing them in specific contexts within the workspace. |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | +## Usage |
| 47 | + |
| 48 | +### Basic Structure of `.myCommand` File |
| 49 | + |
| 50 | +The `.myCommand` files uses INI-style sections to allow optional grouping, and key-value pairs where each key is an alias for a command, and the value is the corresponding command. |
| 51 | + |
| 52 | +Example `.myCommand` file: |
| 53 | + |
| 54 | +```ini |
| 55 | +# Variables |
| 56 | +LAST_CONTAINER="podman exec -it" |
| 57 | +DB_CONTAINER="pod-db" |
| 58 | + |
| 59 | +# Commands |
| 60 | +echo=echo "Custom Prefix: " |
| 61 | +npm="$LAST_CONTAINER npm" |
| 62 | + |
| 63 | +[db] |
| 64 | +backup=podman exec --interactive --tty --rm $DB_CONTAINER mongodump |
| 65 | +restore=podman exec --interactive --tty --rm $DB_CONTAINER mongorestore |
| 66 | +``` |
| 67 | + |
| 68 | +### Running the my Script |
| 69 | + |
| 70 | +Create a `.myCommand` file in the root of your project or any directory where you want to define custom commands. |
| 71 | +Run the `my` script followed by the *alias* you want to execute, and any additional arguments you may want to pass. |
| 72 | +For example, if you're in a directory with the previous `.myCommand` file: |
| 73 | + |
| 74 | +```bash |
| 75 | +# Usage: |
| 76 | +# my <alias> |
| 77 | + |
| 78 | +my echo Hello World |
| 79 | +#> Custom Prefix: Hello World |
| 80 | + |
| 81 | +my db.backup --gzip |
| 82 | +# Runs: podman exec --interactive --tty --rm pod-db mongodump --gzip |
| 83 | +``` |
| 84 | + |
| 85 | +### Arguments |
| 86 | + |
| 87 | +The `my` script has the following internal commands. |
| 88 | +These commands take priority over any keys or aliases of the same name that are defined in any `.myCommand` files, ***so consider them reserved keywords.*** |
| 89 | + |
| 90 | +`help`: |
| 91 | +Don't worry if you forget the basics. |
| 92 | +Simply type `my help` to view the usage details. |
| 93 | + |
| 94 | +`version`: |
| 95 | +Not sure if you have the latest version installed? |
| 96 | +Just run `my version` and compare against the latest version on [GitHub](https://github.com/jerrens/MyCE) |
| 97 | + |
| 98 | +`set <cmd> <value>`: |
| 99 | +**Experimental!** |
| 100 | +This command may be used to add a new value to the `.myCommand` file in the current directory. |
| 101 | +The first argument is the key/alias, all remaining arguments will be treated as the value. |
| 102 | +If the command should belong inside an INI section, then use a '.' to separate group from the key. |
| 103 | +For example: |
| 104 | + |
| 105 | +```bash |
| 106 | +my set group.key echo "Hello World" |
| 107 | +``` |
| 108 | + |
| 109 | +Will be stored as: |
| 110 | + |
| 111 | +```ini |
| 112 | +[group] |
| 113 | +key=echo "Hello World" |
| 114 | +``` |
| 115 | + |
| 116 | +`list [-l]`: |
| 117 | +Can't remember what you used as the key? |
| 118 | +Just enter `my list` to view the available commands. |
| 119 | +If you don't like columns, add the `-l` option at the end to show one command per line |
| 120 | + |
| 121 | + |
| 122 | +### Options |
| 123 | + |
| 124 | +Options for the `my` script should be added immediately following the `my` script call (before the key). |
| 125 | + |
| 126 | +`-v | -vv | -vvv`: |
| 127 | +Log prints can be enabled for debugging by including the `-v` option. |
| 128 | +Crank up the level by stacking more (`-vv`, `-vvv`). |
| 129 | +Three levels is currently the most verbosity used in log prints, but if you get a little trigger happy with the `v` key, it will be ok. |
| 130 | + |
| 131 | +Example: `my -vv build` |
| 132 | + |
| 133 | +`-d`: |
| 134 | +Curious how your `.myCommand` entries will expand, but not brave enough to just try? |
| 135 | +A dry run can be enabled by using the `-d` option. |
| 136 | +In dry run mode, the expanded command will be printed, but not executed |
| 137 | + |
| 138 | +Example: `my -d build` |
| 139 | + |
| 140 | + |
| 141 | +## Command Lookup Process |
| 142 | + |
| 143 | +1. **Merging and Overriding**: |
| 144 | + The script starts at the root directory, working down to the current directory (pwd), merging any `.myCommand` files found along the way. |
| 145 | + Commands defined in `.myCommand` files closer to the current directory override duplicates from higher-level directories. |
| 146 | + This makes the command engine adaptable for different projects without the need for globally defined aliases. |
| 147 | + |
| 148 | +2. **Sectioned Access**: |
| 149 | + Commands are referenced using `section.key` syntax if using INI-style sections. |
| 150 | + |
| 151 | +3. **Fallback to Shell**: |
| 152 | + If no matching alias is found, the command is sent to the shell for evaluation. |
| 153 | + |
| 154 | +### Handling Variables Across Directories |
| 155 | + |
| 156 | +Variables can be set in .myCommand files at any directory level and accessed by commands in lower directories, allowing for flexible and reusable configurations. |
| 157 | + |
| 158 | + |
| 159 | + |
| 160 | +## Installation |
| 161 | + |
| 162 | +1. **Download the script**: |
| 163 | + Ensure the script file (`my`) is placed in a directory that is included in your system's $PATH. |
| 164 | + |
| 165 | +1. **Make the script executable**: |
| 166 | + Run the following command to give the script execute permissions: `chmod +x /path/to/my` |
| 167 | + |
| 168 | +1. **Create `.myCommand` files**: |
| 169 | + Add a .myCommand file in the root directories of your projects. |
| 170 | + |
| 171 | +**Optional**: You can add my to your .bashrc or .zshrc for easier access: |
| 172 | + |
| 173 | +```bash |
| 174 | +alias my='/path/to/my' |
| 175 | +``` |
| 176 | + |
| 177 | + |
| 178 | +## Example Workflow |
| 179 | + |
| 180 | +You have two repositories, Repo1 and Repo2, both with their own .myCommand files. |
| 181 | + |
| 182 | +```ini |
| 183 | +# Repo1's .myCommand file: |
| 184 | +build="mvn clean package" |
| 185 | +run="java -jar target/app.jar" |
| 186 | +``` |
| 187 | + |
| 188 | +```ini |
| 189 | +# Repo2's .myCommand file: |
| 190 | + |
| 191 | +build="npm run build" |
| 192 | +run="npm start" |
| 193 | +``` |
| 194 | + |
| 195 | +When you are working in **Repo1**. To build and run the application: |
| 196 | + |
| 197 | +```bash |
| 198 | +my build # Executes 'mvn clean package' |
| 199 | +my run # Executes 'java -jar target/app.jar' |
| 200 | +``` |
| 201 | + |
| 202 | +You switch to **Repo2**. Now, running the same my build command: |
| 203 | + |
| 204 | +```bash |
| 205 | +my build # Executes 'npm run build' |
| 206 | +my run # Executes 'npm start' |
| 207 | +``` |
| 208 | + |
| 209 | +The command executed changes based on the directory you are in, as it reads the `.myCommand` file from that directory. |
| 210 | + |
| 211 | + |
| 212 | + |
| 213 | +## Troubleshooting |
| 214 | + |
| 215 | + |
| 216 | +License |
| 217 | +MIT License |
| 218 | + |
| 219 | +This README provides a comprehensive guide for users to install, configure, and use My Command Engine. For further assistance or contributions, feel free to open an issue or submit a pull request. |
0 commit comments