Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shasta extension for libbash #5

Merged
merged 29 commits into from
Dec 17, 2024
Merged

Shasta extension for libbash #5

merged 29 commits into from
Dec 17, 2024

Conversation

BolunThompson
Copy link
Contributor

Integrates @sethsabar’s shasta for libbash work into the mainline. The tests pass (besides one bash expected failure).

Copy link
Member

@angelhof angelhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good! Two big questions:

  1. Is this backwards compatible?
  2. Can we add some text in README or another document that really describes the interplay between dash and abash shasta? And how should one navigate this repo if they need to use one of the two only?

shasta/subst.py Outdated Show resolved Hide resolved
shasta/ast_node.py Show resolved Hide resolved
shasta/ast_node.py Outdated Show resolved Hide resolved
shasta/bash_to_shasta_ast.py Outdated Show resolved Hide resolved
@BolunThompson
Copy link
Contributor Author

BolunThompson commented Dec 5, 2024

  1. The changes are mostly backwards compatible, but to accommodate bash some of the existing AstNodes are modified. Namely, the type of fds (and the arg field in DupRedirectNode) in the AST have been changed to the tuple (str, [list[ArgChar], int]) from int, since in bash commands can redirect to variables that are then assigned an fd. Besides that, it’s just adding new optional fields. Are there projects using shasta that would break on these changes? (besides PaSh).

The tests for dash still pass, both in shasta and my branch of PaSh with the bash changes merged in, which is a good sign.

  1. I’ll add some documentation on that. Repo file layout:
  • ast_node.py: AST nodes shared between dash and bash (by design). In principle, if you want to use libdash you can just ignore the bash fields.
  • json_to_ast.py: Libdash to shasta
  • bash_to_shasta_ast.py: Libbash to shasta
  • print_lib.py: Pretty prints the resulting AST in the same way for both bash and dash.
  • subst.py: Bash only helper functions.

If you’re using the library, the only difference is whether you import from json_to_ast (for dash) or bash_to_shasta_ast (for bash).

@angelhof
Copy link
Member

angelhof commented Dec 6, 2024

I now saw your overall comment, that is great, thanks a lot! The documentation plan sounds perfect!

Regarding the changes to AST nodes, could we have a dash-bash-diffs.md document that enumerates them? Are they only the ones you mentioned here? If so, things should be fine more or less, I don't suspect anything will break due to them (and if something does break we should be able to fix it pretty easily).

Once we get these merged we should also make a new major release of shasta so that downstream projects don't really break.

Thank you so much for the very diligent work here @BolunThompson !!

Somewhat of a bad practice but, otherwise, every class that calls
string_of_arg would have to have a bash_mode field to change behavior
for it
Currently, bash mode interprets all characters as CArgChar, relying
on the user to manually expand as necessary. This breaks string_of_arg,
since it escapes all '$' CArgChars, assuming that it shouldn't be
interprted as variable interpolation when it's pretty printed. This
disables escaping in bash mode.
Only requires adding a few "from __future__ import annotations"
to allow type hints like list[int] to be used instead of List[int]
Type hinting is only being used for documentation at this time,
but it's good to use specific and syntactically correct type hints.
However, to use the type checker in a useful way, you'd have to
use isinstance instead of string tags for the AstNodes
(or an equivalent "is_type(*AstNode)" function).
Copy link
Member

@angelhof angelhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great, what are peoples' thoughts on the libbash dependency?

dash-bash-diffs.md Outdated Show resolved Hide resolved
pyproject.toml Outdated
@@ -14,6 +14,7 @@ classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX",
]
dependencies = ["libbash"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am scared of this dependency because I am afraid of dependency hell (either due to circular dependencies or because a downstream program (like PaSh) might want a different version of one and the other).

I guess we don't have this issue with libdash because we use a JSON object? Could we do sth similar here (maybe in a different PR?)? Alternatively, is my fear irrational and we just have to bite the bullet and do it? I am wondering whether someone could use shasta without needing to import libbash and whatever that includes.

Copy link
Contributor Author

@BolunThompson BolunThompson Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your intuition — although I can’t think of an obvious scenario that would cause a problem. The code right now doesn’t actually import anything from libbash (in a runtime capacity) except a handful of enums, so I can easily remove the dependency after copying those over (± some minor changes).

BolunThompson added a commit to BolunThompson/shasta that referenced this pull request Dec 11, 2024
See binpash#5 (comment)
For tests, libbash (and now libdash) are dev dependencies.
@BolunThompson
Copy link
Contributor Author

BolunThompson commented Dec 11, 2024

That’s weird — the tests sometimes pass on my machine, and I’ve somehow messed up the state of my local git repo, so I‘ll fix this in a day or two.

@angelhof
Copy link
Member

No rush!

Caused very annoying bug in that bash_node was being set in the bash
parsing code, but then dash parsing code is called internally, then
bash parsed objects print out in dash mode.

Side note: this is why they teach that globals are bad in intro to CS!
Signed-off-by: Bolun Thompson <[email protected]>
@BolunThompson
Copy link
Contributor Author

BolunThompson commented Dec 15, 2024

Should be ready to review now!

I suspect shasta converts libbash into shasta incorrectly for a few edge cases because they compare roundtrip 1 and 2 (ex: there was a bug where shasta ignored whether a case node was supposed to fall through or not). Comparing the outputs of the original script and the roundtrips on valid bash tests could catch these (another issue?).

Signed-off-by: Bolun Thompson <[email protected]>
Signed-off-by: Bolun Thompson <[email protected]>
@angelhof
Copy link
Member

I suspect shasta converts libbash into shasta incorrectly for a few edge cases because they compare roundtrip 1 and 2 (ex: there was a bug where shasta ignored whether a case node was supposed to fall through or not). Comparing the outputs of the original script and the roundtrips on valid bash tests could catch these (another issue?).

Do you mean that to catch these bugs we would need to compare the original script and the output after the roundtrip? instead of roundtrip 1 vs roundtrip 2? I think this would catch some bugs but would also make things a bit flaky because our pretty printing would affect tests (even though semantically equivalent). In any case, we should look at this in a different PR :)

@angelhof angelhof merged commit be560cf into binpash:main Dec 17, 2024
1 check passed
@BolunThompson
Copy link
Contributor Author

BolunThompson commented Dec 17, 2024

That’d work, but as you said it’d be finicky. #6 is what I meant to say.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants