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

feature: remove curl perl and coreutils as required dependencies #345

Merged
merged 7 commits into from
Oct 1, 2024

Conversation

skinner-m-c
Copy link
Contributor

@skinner-m-c skinner-m-c commented Sep 30, 2024

📚 Description

This set of changes removes some required dependencies and makes them optional. Most of the motivation for this work is to avoid having to install dependencies in Alpine, which is known for its small and lean OS. It would be nice not to have to install perl and coreutils get bashunit working in Alpine.

I know this a large change and may warrant some discussion or possible splitting into small PRs.

🔖 Changes

  • Changed from an operating system level logic to capabilities logic, which allow for more control on alternative approaches when certain programs are missing, such as curl, and perl. The intent is to allow for greater flexibility rather than forcing all uses to install Perl to get test duration times.
  • Move some initialization operations (OS checking, and time)
  • Added helper functions for tests (mock_true, mock_ubuntu_os).
  • Fallback to using EPOCHREALTIME to time tests if it exists. This means tests can be timed in more systems.
  • The following dependencies are now optional:
    • perl
    • coreutils
  • Install and upgrade scripts can now use wget or curl
  • Tests times are measured in nanoseconds
    • Times are scaled to nanosecond times when possible
    • Requires using bc to perform math instead of the shell because the shell cannot handle large numbers. awk may be used if bc is not available.
  • New modules:
    • math
    • dependencies
    • io
  • Timing of entire tests is more accurate because _START_TIME gets assigned later.

✅ To-do list

  • I updated the CHANGELOG.md to reflect the new feature or fix
  • I updated the documentation to reflect the changes

@skinner-m-c skinner-m-c force-pushed the feature/remove-dependencies branch 4 times, most recently from 2a8bb5f to 0aae7b7 Compare October 1, 2024 00:37
@skinner-m-c skinner-m-c force-pushed the feature/remove-dependencies branch from 0aae7b7 to ab451be Compare October 1, 2024 00:53
@Chemaclass Chemaclass added the enhancement New feature or request label Oct 1, 2024
Comment on lines +52 to +55
return 0
;;
*)
return 1
Copy link
Member

@Chemaclass Chemaclass Oct 1, 2024

Choose a reason for hiding this comment

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

You might have notice we are using everywhere in the project checking true|false for conditional booleans. However, they are raw strings are bools are not natively supported by bash. On the contrary, native conditions in bash are 0:true,>=1:false which is a bit odd if you come from other languages. In the end this is purely a detail implementation from the bashunit insides, so it should not matter to the external user.

I am saying this because I am wondering if there is a performance gain/benefit on using 0/1 for booleans intead of true/false in which case I would be in favor of refactoring the bools inside the project to use them. Otherwise, I would suggest keep using true/false. What do you think, @skinner-m-c ?

I am ok either way, I want to learn from your experience, in case you know what's better :)

Anyway, THIS comment should NOT be applied on this PR but in a follow up iteration.

Copy link
Contributor Author

@skinner-m-c skinner-m-c Oct 1, 2024

Choose a reason for hiding this comment

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

I agree that it is confusing that 0 being true and 1 being false is confusing. However it comes from Unix standard of program exit codes -- that use 0 meaning "normal exit and not errors" and anything else is an exit where the program executed with some problems.

true and false are programs, typically installed at /bin/true and /bin/false. They are provided by coreutils or busybox. Both of these programs are very simple and are unlikely to cause performance issues. There may be more of a performance hit starting these programs than their execution. See true.c in coreutils and busybox for what they actually do. So it is probably faster to use 0 and 1 for comparisons. When true and false are returned it is the output of these programs.

However, BASH also has built-in functions and that is what is actually being used here and so /bin/true and /bin/false is not actually being run. The built-in true and false is probably marginally slower than integers (see help in BASH to see the list of all built-in functions). I don't have any metric to support that idea, but it is probably too small to warrant choosing 0 over false for example. false and true also are more readable.

I agree that true and false should probably be used.

Copy link
Member

@Chemaclass Chemaclass Oct 1, 2024

Choose a reason for hiding this comment

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

In such a case, do you mind creating a PR refactoring/changing this to use true/false then? Then we can create an ADR to write down this as a project convention, so we can keep consistency over the project when dealing with booleans.

Extra thought: it's not the same true and "true", right? one is a program and the other one is a string, I assume, but I believe they are compatible and working intermixed? anyway, that's why the ADR is important to keep consistency.

Copy link
Member

@Chemaclass Chemaclass Oct 3, 2024

Choose a reason for hiding this comment

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

I've been thinking about this topic, and while I think it's a bit odd thinking this way if you are not familiar with sh/bash, and after more than a year working on the project and a lot of researching, I ended up believing that 0 (as true) and 1 (as false) is a good practice in bash itself, specially when defining conditions.


While you can do this in bash

function check_os::is_busybox() {
  case "$_DISTRO" in
    "Alpine")
        return 0
        ;;
    *)
      return 1
      ;;
  esac
}

but you cannot do this:

Screenshot 2024-10-03 at 16 01 52

TL;DR I would be in favor of using 0 (as true) and 1 (as false) when dealing with conditionals in the project. I will create an ADR for this and refactor the project to follow this convention.

Copy link
Member

Choose a reason for hiding this comment

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

Follow up: #346

Copy link
Member

Choose a reason for hiding this comment

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

This also gave me the idea to add assert_true and assert_false #350

Copy link
Contributor Author

@skinner-m-c skinner-m-c Oct 5, 2024

Choose a reason for hiding this comment

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

Glad it is inspiring some more improvements.

true and false are build-in functions in BASH. Functions in BASH cannot be returned (though you can return a string of a function name and then invoke it with eval). However, the return value of the last function is returned if return has no value. So it would be a two-liner or a one liner with a subshell. Subshells should be avoided if possible because it is slower.

function abc() {
  true
  return
function abc() (
  return $(true)
}

Copy link
Member

@Chemaclass Chemaclass Oct 5, 2024

Choose a reason for hiding this comment

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

Do you mind reviewing the last pr where I introduced assert_true and false? I would like your feedback:)

Copy link
Member

@Chemaclass Chemaclass left a comment

Choose a reason for hiding this comment

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

Awesome changes! I will take care of the failing macos tests.
Please, check the feedback I gave you and let me know your thoughts.

@Chemaclass Chemaclass force-pushed the feature/remove-dependencies branch from fa9c88b to 6cbeb1e Compare October 1, 2024 08:53
@Chemaclass Chemaclass merged commit 4153f03 into TypedDevs:main Oct 1, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants