SBOPKG HACKING

INTRODUCTION

    We welcome contributions to sbopkg. If you have a bug report or a
    feature request, please use the Issue Tracker so your bug report/feature
    request does not get lost.

        https://github.com/sbopkg/sbopkg/issues

    If you cannot post to the Issue Tracker, there is an #sbopkg channel on
    the Libera IRC network.

    If you cannot post to the Issue Tracker, please consider joining the
    sbopkg mailing list and post your bug report or feature request
    there.

	https://sbopkg.org/mailman/listinfo/sbopkg-users

    As far as hacking on the code, the best thing to do is to checkout
    the latest version from git using something like the
    following command:

        git checkout https://github.com/sbopkg/sbopkg.git

    (See https://www.sbopkg.org/devel.php for more information.)
    Then contribute patches with something like 'diff -Naurp'.

    Please try to make each patch do one thing and do it well. Also,
    please do not combine whitespace or other non-functional changes
    with functional changes in the same patch (unless the same lines
    contain both types of changes). Basically, just use common sense --
    a one line functional change and a typo correction can be a single
    patch, rather than two one-line patches.

PATCH/SCRIPT GUIDELINES

    * Write code compatible with bash 3.1.17 to the latest stable
      version.

    * Wrap lines at 78 columns.

    * Expand tabs to spaces.

    * Indent with four spaces at all levels.

    * Use '[[' wherever possible, vs. '['.

    * Negate tests like '[[ ! foo ]]' instead of '! [[ foo ]]'.

    * write functions in the form:

          my_func() {
              # comments here

              stuff
          }

    * In general, variables do not need to be quoted except in cases
      where the variable may contain spaces. If unsure, quote the
      variable just to be safe.

    * Use variable names in the form: MYVARNAME except when MYVARNAME is
      ambiguous or made of more than two or three components. In that
      case, use MY_VAR_NAME.

    * If you are going to need a bit of data repeatedly, try to grab it
      once and assign it to a variable rather than re-obtaining it.

    * If you are going to use a combination of several concatenated
      variables multiple times, consider creating a new variable like:
      'NEWVAR=$OLDVAR1-$OLDVAR2-$OLDVAR3'.

    * Prefer the style:

          if [[ foo ]]; then
              bar
          fi

      instead of:

          if [[ foo ]]
          then
              bar
          fi

      (same goes with 'for' and 'while' loops).

    * The spacing in numeric 'for' loops is:

          for ((i=0; i<=10; i++)); do

    * Prefer shell redirection to piping 'echo' or 'cat'.

    * Prefer bash variable substitutions to 'tr', 'sed', 'cut', ...,
      when possible.

    * Error messages should go to standard error:

          echo "Things have gone nuts" >&2

    * Make return codes meaningful (i.e. if you redirect to stderr try
      to return or exit 1 at the same time).

    * When both 'foo' is simple and 'bar' is a one-liner, the
      conditional form:

          [[ foo ]] && bar

      can be used instead of:

          if [[ foo ]]; then
              bar
          fi

      However, do not use the following form:

          if [[ foo ]]; then bar; fi

    * Use:

          [[ foo ]] || bar

      only when 'bar' is simple and supposed to be executed on error
      conditions (i.e. almost never)

    * Multiple conditionals can be done either as:

          if [[ $FOO == 1 ]] || [[ $FOO == 0 && -z $BAR ]]; then

      or

          if [[ $FOO == 1 || ( $FOO == 0 && -z $BAR ) ]]; then

      but not:

          if [ $FOO = 1 ] || [ $FOO = 0 -a "$BAR" = "" ]; then

      The reasons the third example is not as good as the first two are
      that it uses single brackets instead of double brackets and uses
      '-a' instead of '&&'.

    * 'case' statements should be indented as:

          case $FOO in
              bar ) # Comment goes here
                  commands
                  ;;
              baz* ) # Comment goes here
                  commands
                  ;;
          esac

      unless the statements can be short one-liners, in which case the
      form

          case $FOO in
              bar ) short_simple_command ;;
              baz* ) simple_short_command; exit ;;
          esac

      is preferred.

    * Avoid chaining commands with ';' (with the above exceptions).

    * Declare local variables as such at the function start.

    * Positional parameters to functions should be assigned to local
      variables, one per 'local' statement, before declaring the other
      local variables (which can share a single 'local' statement):

          local FILE="$1"
          local DIR="$2"
          local FOO BAR BAZ

    * In general, when wrapping long lines, the part going on the next
      line should be indented 8 spaces beyond the initial line if there
      is ambiguity so as to distinguish the wrap from other lines before
      and after it. The same would be true for line wraps in conditions.
      For example:

          if ASD ||
                  FGH; then
              echo "Success"
          fi

      as opposed to:

          if ASD ||
              FGH; then
              echo "Success"
          fi

      In the latter case, having 'FGH; then' at the same indent level as
      the echo is ambiguous. On the other hand:

          APP=$(grep foo \
              really/long/path/to/file)
          if foo; then
              echo "Success"
          fi

      is ok since there really is no ambiguity.

    * Prefer 'foo | bar' over 'foo |bar' or 'foo|bar'. However, if the
      line barely goes over 78 columns, then removing spaces is OK to
      keep it on a single line. In other words:

          foo |bar |baz

      is better than

          foo | bar |
                  baz

    * When wrapping between two piped commands, the pipe should be the
      last character of the former line. For example, prefer:

          some stuff here foo |
              bar

      instead of:

          some stuff here foo \
              | bar

      when possible.

    * Always use $( ... ) instead of ` ... `.

    * 'Break' and 'continue' should never be used to influence a loop
      outside of the function they belong to.

    * Avoid indirect recursion (A calls B that calls A).

    * [[ -z "$VAR" ]] vs. [[ ! "$VAR" ]] and [[ "$VAR" ]] vs.
      [[ -n "$VAR" ]]: -n/-z should be used when $VAR contains a
      computational result and the other form should be used where $VAR
      is a functional flag. For example:

          VAR=$(grep "^something=" <$SBOPKG_RENAMES)
          if [[ -z $VAR ]]; then

      and

          if [[ $DIAG ]]; then

    * For indices, use FILE and DIR instead of 'f' and 'd'. However, 'i'
      is OK as a counter since that is fairly universal.

    * When deciding whether or not to use the =~ operator in [[
      commands, make sure that they work across bash 3.1, 3.2, and 4.0.
      This means the regexes must be unquoted for bash >=3.2 and still
      work in bash 3.1 (i.e., no 'foo|bar' expressions).

MANUAL PAGE STYLE GUIDELINES

    * Separate all text header and section header requests with
      commented lines of equal (=) signs. Separate all subsections and
      tagged paragraphs that serve as subsections with commented lines
      of minus (-) signs.

    * Leave no blank lines in the file. E.g., .PP will often serve under
      .SH and .IP under .TP.

    * Wrap lines at 72 columns and begin all sentences on new lines.

    * If variables are being used in the sense of their value, use $VAL
      but if they are being used in reference to themselves, use VAR.

    * Where sensible, try to make .TPs have a consistent indent.

    * Try to use standard headers where possible, filing other
      information under subsections of the relevant section header.

    * Add options as .TP 5 (or current default), with \- and bold
      options, followed by italic replaceable arguments to those options
      or bold literal arguments, if any. Brackets, bars, etc., should be
      regular font, though.

    * More generally, italicize filenames, URLs, replaceable terms
      (including references to unspecified variable values ($VARs)).

    * Embolden variables (when used literally rather than replaceably),
      option values, programs, program flags, and all references to
      sbopkg itself.

    * Make all option dashes in the form \- (or \-\-) unless in a code
      example.

    * Try to refer to the user as 'the user' rather than 'you'.

    * Collect all referenced programs (unless used purely as an example)
      in the SEE ALSO section. (The SEE ALSO section is not *limited* to
      referenced programs, however.)

    * Try to be as specific as conveniently possible, where 'convenient'
      means to generalize wherever constant updates might be necessary
      and such generalization wouldn't compromise clarity and accuracy.

    * Use `` and '' for double-quotes so groff does the fancy stuff for
      ps output.

    * .EX doesn't seem to be very well supported or necessarily what is
      wanted - code examples can be done with the following
      cookie-cutter code:

          .RS
          .IP \" or .PP or whatever's appropriate
          .nf
          \fCline_of_code\fP
          .fi
          .RE

      If inline, at least embolden them so they're set off in ascii
      overstrike output.

      In command line examples, prefix the commands with the root prompt
      (#).

    * Start configuration file option sections with a statement of type,
      a description, and the following cookie-cutter code:

          The default assignment is:
          .IP
          \fCxxxVARxxx\fP

      ('xxxVARxxx' will be replaced by whatever value VAR has in the
      default sbopkg.conf file.)

    * Try to refer to SlackBuilds as SlackBuilds rather than SlackBuild
      scripts unless for a particular need (for instance, explaining
      what SlackBuilds are in the first place). And once SlackBuilds.org
      has been properly introduced, try to refer to it as SBo.
