https://github.com/binpash/libbash
https://github.com/binpash/libbash
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/binpash/libbash
- Owner: binpash
- License: gpl-3.0
- Created: 2023-10-18T01:09:31.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-03-19T22:06:50.000Z (over 2 years ago)
- Last Synced: 2024-03-20T21:56:23.480Z (over 2 years ago)
- Language: Python
- Size: 10.8 MB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# libbash
**NOTE: This project is mostly functional, however there are a few minor bugs with the Bash source code causing issues with our API. Take a look at `test.py` to see which tests we are currently not testing because they will fail!**
`libbash` can be installed via pip: https://pypi.org/project/libbash/
## API
*The `libbash` module contains the following functions.*
`bash_to_ast` takes as input a file containing a bash script. It returns a `list` of `Command`s (see AST Classes below) representing the AST of the script. This function will throw an Exception if the script is invalid.
`ast_to_json` takes as input a `list` of `Command`s and returns a list of json-style object's representing the `Command`s (we say that a json-style object is either a `map` from `str` to json-style object or a `str`, `int`, `null`, or `list` of json-style object).
`ast_to_bash` takes as input a list of `Command`s and a filename and writes pretty-prints the script to the file. This function does not preserve line numbers, spacing, or other stylistic components.
`==` the equality operator has been implemented in the `Command` class. This operator ignores stylistic fields stored in the AST, and considers two `Commands` to be equal if they are structurally equal. In most cases, a round-trip from `ast_to_bash` to `bash_to_ast` will result in the same script, but this is not guaranteed. In a few occasional cases, this round trip will wrap certain commands in a `Group` command, which doesn't change the functionality of the script but does change the AST.
`run_tests` runs a testing suite on the above functions. If this fails, please consider creating a *New Issue* or making a *Pull Request* to fix the bug.
## Command Objects
*The `libbash.bash_command` module contains the classes which comprise our representation of a Bash command*
This library chooses to represent the AST of a bash script as a list of `Command` objects. To best understand what these objects look like, users are encouraged to understand the classes defined in [this directory](./libbash/bash_command). A great starting place to look at is the `Command` class in [command.py](./libbash/bash_command/command.py) class.
## Limitations
For a Bash parser to be completely correct, it would actually need to execute the entire script! Consider the following script:
```
current_hour=$(date +"%H")
if [ "$current_hour" -lt 12 ]; then
alias while=random_string
else
echo "It's after noon, no alias will be created."
fi
counter=1
while [ $counter -le 5 ]; do
echo "Counter: $counter"
((counter++))
done
```
Whether `while` is aliased or not depends on the time of day that the script is run, and this affects the functionality of the `while` loop. This is because alias expansion is done
*before* parsing in Bash. As this example shows, determining alias expansions is not possible without executing a Bash script. Therefore, one can not expect any uses of `alias` or
other programs that change the script before parse-time to be reflected.
## Additional Documents
- [Difficulties Encountered During Development](https://docs.google.com/document/d/1Jn4z_QSTCoth_HvBtGE_DkAR0Z8O4B9eRKOKeV8njas/edit?usp=sharing) (just some notes I took)
- [Bash Source Code Parsing Outline](https://docs.google.com/document/d/1qZ4OX3BBX7esKu_wB-GmGvgEL5VFEFFTtifKwQdwTDw/edit?usp=sharing) (a brief guide on how parsing works in the Bash source)