1. 11
  1.  

  2. 3

    I’m pleased to see additional redo implementations. Apenwarr’s redo, the most frequently cited implementation, was not something I could make work reliably. There was a fork that might address many of the issues I had, but one made a lot of structural changes to the behavior of the program that I found difficult to follow.

    A common mistake was writing to the output file, rather than the temporary file:

    $ cat > foo.do
    redo-ifchange bar
    touch $2 # oops, should be $3
    ^D
    $ redo foo
    redo  foo
    redo  foo.do modified foo directly!
    redo  ...you should update $3 (a temp file) or stdout, not $1.
    redo  bar: exit code 206
    

    With apenwar’s redo, it was not enough to correct the bug in the script. Accidentally creating foo made redo shy about removing it:

    $ redo foo
    redo  bar: exists and not marked as generated; not redoing.
    

    The file foo should simply be deleted, but I can understand why redo is shy about it: it is possible the file is precious and redo can’t be certain. However, I believe it to be reasonable to remove the output file for exit code 206, to save the user a step in this case.

    I’ve not tested this redo to see if it behaves the same way.

    1. 2

      People forget about environment variables: They’re stored (in memory) very near the positional arguments, and while convention seems to have given uppercase names some strange dynamic effects, lowercase names are rarely exported, so I have been using them as named arguments.

      Consider:

      touch $out
      

      versus:

      touch $in
      

      I might not easily remember the difference between two and three, but in and out seems a bit more clear to me. When we run our build script:

        sh -e "$buildfile" 0 "$basefile" .redo/"$i---redoing" \
        > .redo/"$i---redoing"
      

      we could simply:

        in="$basefile" out=".redo/$i---redoing" sh -e "$buildfile" 0 "$basefile" .redo/"$i---redoing" \
        > .redo/"$i---redoing"
      
      1. 1

        This can interact badly with child processes which inherit env vars - if there’s an optional param in the child with the same name as the parent, you have to remember to clear it out.

        1. 3

          Can you explain what you mean by “can interact badly”?

          Do you have any examples of people using a lower-cased environment variable as an argument as I suggest, who call a subprocess who also does the same thing, but uses the same lower-cased environment variable to mean something completely different?

          1. 1

            If adopted as a widespread practice, sooner or later someone is going to accidentally pass an unexpected param to a child process, via environment inheritance.

            Flag arguments do not have that class of bug as they aren’t copied to children.

            In your provided example, this could happen if the “out” param defaults to stdout in a child process.

            1. 1

              So, the answer is “no.”