Recursively adding files and directories in Gnu Arch

One of the little annoyances of Gnu Arch is that it does not add files and directories recursively. Not to worry, though. Here is a little shell script that can assist with that task:

#!/bin/bash

# Find all files and directories, skipping ./{arch}
for FILE in `find . -path './{arch}' -prune -o -print`
do
        # Get rid of the leading ./
        FILE=`echo $FILE | sed -e 's/\.\///'`
        tla add "$FILE"
done

Skipping the script itself is left as an exercise to the reader.

Update: Simplier method indeed is

tla inventory --source --names | xargs tla add

Subversion vs. Gnu Arch

I’ve spent some time today fighting with both Subversion and Gnu Arch. After the first few battles, it was decided that Subversion is not going to be used for the project, and that we’d go with Gnu Arch instead. There were three reasons for that.

  • Subversion is a pain to install. Especially on older machines. It requires a whole bunch of libraries and static compilation is not that easy. Gnu Arch is a charm to install.
  • Subversion does not keep owners/permissions information about files and directories. Gnu Arch does so.
  • Subversion does not support distributed development, which is practically a must in our case. Gnu Arch does so easily.

If you are confused about distributed development term above, here’s what I mean. We have bought a piece of software. We want to do some customizations and additional functionality development internally. Meanwhile, we also bought an upgrade plan, and it turned out that the vendor is releasing patches pretty often. Merging our internal development with vendor patches on a regular basis can be a real pain in the bottom, unless software version control system supports it natively. Gnu Arch does so and hence we’ll use it for the project.

But Gnu Arch is not perfect aswell. One of the things that we want to keep in the repository is the complete source package from the vendor. The source package consists of a couple of thousand files in few hundred directories. Files come in all variety – ZIP archives, GIF and PNG images, MS Word, PDF, RTF, and plain text documentation, PHP source code files, HTML pages, and so on, and so forth. Importing all these stuff into Gnu Arch repository turned out to be, well, slightly more difficult than it should have been.

For now, I’ll leave you on your own and give you some time to write a bash script for importing of such a source tree. You can post it in the comments. You have time until I will finish with my script some time tomorrow. I will post it here than.

Update: I decided to create a new post with the script.

Have your breaks in time with KDE

I’ve already talked about KDialog and DCOP which are two magic KDE tools that could use more promotion. Today I came across another nice examlpe in this post.

#!/bin/bash

PROGRESS=$(kdialog --icon kalarm --title "Short rest" \
    --progressbar "Take a break..." 30)

if [ $PROGRESS ]; then
  for (( i=0; i<30; i++ )); do
    dcop $PROGRESS setProgress $i
    sleep 1
  done
  dcop $PROGRESS close
fi

This simple shell script will remind you to have timed 30 second breaks when executed at predefined intervals from KAlarm. You'll see a nice progress bar while having a break.

Handling arguments with spaces in bash

Way to often I get it wrong, so I decided to right this down…

When processing the list of arguments in your bash script, remember that often arguments such as file names contain spaces. The wrong way to go about this is:

#!/bin/bash
for FILE in $*
do
  echo "$FILE"
done

The right way to do it is:

#!/bin/bash
for FILE in "$@"
do
  echo "$FILE"
done

Advanced Bash-Scripting Guide explains the difference in “Internal Variables” chapter.

Perl obfuscations

The flexibility of Perl allows for extremely nicely looking code. On the other hand, the same flexibility allows people to do ugly things, which Perl is very well known for. Sometimes, though, I come across a piece of code which is both ugly and beautiful. Here is one example written by one of my collegues:

sub _uintvar {
    my ($v) = @_;
    $v = sprintf("%b",$v);
    $v = '0'x(-length($v)%7).$v;
    my @v = map {"1$_"} $v=~/(.{7})/g;
    substr($v[-1],0,1) = "0";
    $v = pack("B*",join('',@v));
}

This was found in the production system. It works. And it was tested.

Now imagine that the name of the subroutine would be different in some non-selfdescriptive way. Would you be able to parse it, understand it, and say what it does? How about fixing a bug in there?