First off, thank you for considering contributing to SENTINEL! It's people like you that make SENTINEL such a great tool.
If you've noticed a bug or have a question, search the issue tracker to see if someone else has already reported the issue. If not, feel free to open a new issue.
If you're looking to contribute code, you can check out the open issues to see what we're looking for.
If this is something you think you can fix, then fork SENTINEL and create a branch with a descriptive name.
A good branch name would be (where issue #38 is the ticket you're working on):
git checkout -b 38-add-awesome-new-featureMake sure you're running the tests before you start making changes. We've got a suite of tests that you can run with:
bats tests/At this point, you're ready to make your changes! Feel free to ask for help; everyone is a beginner at first 😸
At this point, you should switch back to your master branch and make sure it's up to date with SENTINEL's master branch:
git remote add upstream git@github.com:yourusername/sentinel.git
git checkout master
git pull upstream masterThen update your feature branch from your local copy of master, and push it!
git checkout 38-add-awesome-new-feature
git rebase master
git push --force origin 38-add-awesome-new-featureFinally, go to GitHub and make a Pull Request
SENTINEL uses a hybrid autocompletion system. Understanding its components is key to extending it.
sentinel-completion.bash: This script (typically installed to/usr/share/bash-completion/completions/sentinelor a similar user-local path) handles completions for the mainsentinelcommand, its global options, and any subcommands implemented directly as Bash functions within the mainsentinelscript.argcomplete: Python scripts (especially those incontrib/or those acting as implementations forsentinelsubcommands likesentinel process) use theargcompletelibrary. This allows Python scripts to define their own completions based on theirargparsedefinitions.
The sentinel-completion.bash script contains a main completion function, typically _sentinel_completions.
- Location: Find this script in the SENTINEL source or its installed location.
- Structure:
- The function uses Bash built-ins like
compgenand helper variables likeCOMP_WORDS,COMP_CWORD,cur,prev. - The
_get_comp_words_by_reffunction (often included or sourced) is useful for robustly parsing words, especially those containing=,:. - A central
case "$cmd"block (wherecmdis the current subcommand) dispatches to logic for that subcommand.
- The function uses Bash built-ins like
- Adding a New Bash Subcommand (e.g.,
sentinel newbashcmd):- Add
"newbashcmd"to thesubcommandsarray in_sentinel_completions. - Add a new case to the main
case "$cmd" in ... esacblock:newbashcmd) # Logic for completing args for newbashcmd # Example: complete from a list of actions if [[ "$cword" -eq 2 ]]; then # Assuming sentinel newbashcmd <action> local actions="action1 action2" COMPREPLY=( $(compgen -W "${actions}" -- "$cur") ) # Add more logic for further arguments/options fi ;;
- Add
- Adding Options to a Bash Subcommand:
- Locate the
caseblock for that subcommand. - If completing an option (e.g.,
if [[ "$cur" == -* ]]; then), add your new option to thecompgen -W "..."list for that subcommand's option completions. - If the option takes an argument, add logic to complete that argument when
previs your new option.
- Locate the
- Dynamic Completions: You can call other shell commands or read files within your completion logic to generate
COMPREPLYdynamically. For example,sentinel module unloadreads from/tmp/sentinel_loaded_modules.txt. - File/Directory Completions: Use the
_filedirfunction (provided bybash-completion).
For Python scripts (e.g., new tools in contrib/ or scripts that implement a sentinel subcommand):
- Use
argparse: Ensure your Python script usesargparseto define its command-line arguments.import argparse parser = argparse.ArgumentParser() parser.add_argument("--my-option", choices=["a", "b"]) # ... other arguments
- Add
PYTHON_ARGCOMPLETE_OKMarker: Place this comment at the top of your Python script:#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK
- Import and Call
argcomplete:Callimport argcomplete # ... (define your parser) ... argcomplete.autocomplete(parser) args = parser.parse_args()
argcomplete.autocomplete(parser)beforeparser.parse_args(). - Ensure Script is Executable:
chmod +x your_script.py. - Registration (for testing/development):
- Run
eval "$(register-python-argcomplete your_script.py)"in your shell. - The
install.shscript should handle advising users to installargcompletesystem-wide or for the user, which often enables these completions automatically without manual registration for every script if global completion is active.
- Run
- Integration with
sentinelmain command (if applicable):- If your Python script is called by the main
sentinelBash script (e.g.,sentinel processcallssentinel_process.py), thesentinel-completion.bashscript should "step aside" when it detects that theprocesssubcommand is being completed for its options. It typically does this by returning emptyCOMPREPLYfor option arguments ofprocess, allowingargcomplete's hooks to take over. - Ensure the
sentinelscript calls the Python script directly (e.g.,./path/to/script.py "$@") rather than viapython ./path/to/script.py "$@", asargcompleteoften relies on the executable name inCOMP_LINE.
- If your Python script is called by the main
By following these guidelines, developers can extend SENTINEL's autocompletion capabilities effectively, maintaining a consistent and helpful user experience.