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

A builtin returning the Bash version as a Num #622

Open
lens0021 opened this issue Nov 27, 2024 · 11 comments
Open

A builtin returning the Bash version as a Num #622

lens0021 opened this issue Nov 27, 2024 · 11 comments

Comments

@lens0021
Copy link
Contributor

lens0021 commented Nov 27, 2024

It's out of scope for this PR, but we should probably write a builtin returning the Bash version as a Num.

Originally posted by @hdwalters in #620 (comment)

Along with a builtin to return the Bash version (suggested in a comment on a different PR) we should also add an annotation specifying the minimum Bash version to support a given function or main block.

Originally posted by @hdwalters in #616 (comment)

@hdwalters
Copy link
Contributor

Thanks for creating this issue. I would have got round to it eventually!

@lens0021
Copy link
Contributor Author

lens0021 commented Jan 5, 2025

I think it should expose the fix version as well as the major and the minor.

@hdwalters
Copy link
Contributor

hdwalters commented Jan 5, 2025

I'm running Bash 5.2.21.1; the Amber function I wrote to bypass negative array index validity tests returns 502 for me:

#[allow_absurd_cast]
fun bash_version(): Num {
    let major = trust $ echo "\$\{BASH_VERSINFO[0]}" $ as Num
    let minor = trust $ echo "\$\{BASH_VERSINFO[1]}" $ as Num
    return (major * 100) + minor
}

main {
    if bash_version() >= 402 {
    ...

If we're going to include all four numeric components, extending this to 5022101 or 5002021001 will be unworkable.

Can I suggest that we consider returning an array, and implementing version comparison, at least for [Num] arrays:

let bashver = [5, 2, 21, 1]
if bashver >= [4, 3] {
    // Bash 4.3 or above
}

@lens0021
Copy link
Contributor Author

lens0021 commented Jan 6, 2025

I have not known the fourth one! Well, how about supporting bash_version_is_greater_than([5, 2, 21, 1]) and bash_version_is_less_than([5, 2, 21, 1]) calls?

@lens0021
Copy link
Contributor Author

lens0021 commented Jan 6, 2025

Or string as argument and supporting all the following, etc?

bash_version_is_greater_than("5.2.21(1)")
bash_version_is_less_than("5.2.21(1)")
bash_version_is_less_than("5.2.21.1")
bash_version_is_less_than("5.2.21")
bash_version_is_less_than("5.2")
bash_version_is_less_than("5")

@hdwalters
Copy link
Contributor

Having functions bash_version_is_greater_than and bash_version_is_less_than seems clunky, where array comparison operators are more intuitive:

if bashver >= [5, 2, 21, 1] {
}

@hdwalters
Copy link
Contributor

hdwalters commented Jan 6, 2025

Also, Text comparison would be a lot harder to do in Bash, especially if you want to support the full version string, with brackets and suffices:

$ echo $BASH_VERSION 
5.2.21(1)-release

I'm not saying [Num] comparison would be trivial, but at least the numbers would be cleaned up before you started; and obtaining them in the first place is easy:

$ echo ${BASH_VERSINFO[@]:0:4}
5 2 21 1

@lens0021
Copy link
Contributor Author

lens0021 commented Jan 6, 2025

tbh, I am hesitating because I think array comparison has not the standard definition and is not a common binary operator in programming. If string is not acceptable, how about the former, bash_version_is_greater_than([5, 2, 21, 1])?

@hdwalters
Copy link
Contributor

hdwalters commented Jan 6, 2025

tbh, I am hesitating because I think array comparison has not the standard definition and is not a common binary operator in programming.

On the contrary, lexicographic ordering is implemented for lists in Python and arrays in Ruby. It's also implemented for strings (treated as lists of characters) in every language I can think of, which is why it's called "lexicographic ordering" in the first place. I'd say this is the behaviour most programmers would expect.

If string is not acceptable, how about the former, bash_version_is_greater_than([5, 2, 21, 1])?

I still favour direct array comparison, but if we do decide on a standard library based solution, it would make more sense to implement a greater than or equal comparison, to implement functionality based on minimum supported Bash version. I'd also want a less cumbersome function name.

@lens0021
Copy link
Contributor Author

lens0021 commented Jan 7, 2025

I'd also want a less cumbersome function name.

I agree. bash_version_is_greater_than is too long.

On the contrary, lexicographic ordering is implemented for lists in Python and arrays in Ruby.

Thank you for pointing out. I never know that, and I did not use that before. Then I am okay.

Just to clarify:

  1. It is obvious that the array comparison should be implemented in the rust part.
  2. The function returning bash version should be a built-in, not a stdlib.

Are the two things right?

@hdwalters
Copy link
Contributor

hdwalters commented Jan 7, 2025

Array comparison would have to be written in Rust. The Bash version could be generated by a standard library function:

fun bash_version(): [Num] {
    let version = [Num]
    trust $ {nameof version}=("\$\{BASH_VERSINFO[@]:0:4}") $
    return version
}

let version = bash_version()
echo "Bash version [{version}] has {len version} components"

Obviously, this would become a lot nicer if we implement #623.

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

No branches or pull requests

2 participants