Distributed bug tracking 0

Rather than bothering with setting up and maintaining external tools, I usually prefer to simply have a TODO file in my repository where I collect issues and ideas. However, I’m starting to want more of an ability to maybe attach certain metadata, categorize issues etc.

There is ciss-tracker, which is basically a command line interface on top of a plaintext file like I’m already using, and I’m currently playing around with it.

Then there are these “distributed bug trackers”, an idea I find quite interesting. Unfortunately, it doesn’t seem to have a lot of traction. Most tools aren’t actively developed.

Most trackers store their issue database in the repository itself, in a hidden directory or file. Some git-specific tools use a separate branch. I much prefer the latter approach. I think if you were to add native support for bug tracking to a DVCS, you’d want to use a separate storage area. git’s branches allow you to simulate this somewhat.

Benefits:

  • I’m not cluttering my source’s history with the bug data. The two seem like distinct things. You can get a log for only the bug changes.
  • Merging the bugs would be separate from merging the source tree, making it easier to implement a custom merge code specifically for the bug tracking part. Different from source code, conflicts could be resolved by a command line tool asking the right questions.
  • You also have only a single bug database for the repository – something like github could easily base their web bug tracker UI on the repository storage. And you could still have the ability to link bugs to individual branches.

So far, I’ve only found git-issues and ticgit. Both don’t seem to be worked on though, and I did have my problems with them.

Update: There’s also Simple Defects, which has a unique approach: Instead of trying to build on a DVCS, it’s a completely self-contained system, though there is at least some basic git-integration.

Interesting posts on the subject:

init.d script for smuxi-server 0

Quick&Dirty:

#!/bin/bash

USER=michael
GROUP=michael
PIDFILE=/var/run/smuxi.pid

case "${1:-''}" in
  'start')
           start-stop-daemon -S -c $USER -g $GROUP --make-pidfile --pidfile $PIDFILE --background --startas /usr/bin/smuxi-server -v
        ;;
  'stop')
           start-stop-daemon -K --pidfile $PIDFILE -v
        ;;
  *)
        echo "Usage: $SELF start|stop"
        exit 1
        ;;
esac

Upgrading an OpenVZ VE to Jaunty 0

After upgrading a VE to Jaunty through do-release-upgrade, the network stopped working.

A post in the OpenVZ forum suggests a fix that works for me:

On the host:

vzctl set XXX --features "sysfs:on" --save

In the container:

vi /etc/init.d/networking

After the comments at the top, add the line:

mkdir -p /var/run/network

Note the post suggested the directory var/run/networking, my init script wanted /var/run/network for some reason. I also added -p to mkdir.

Presumably, there’s a smoother solution creating the directory through the OpenVZ init scripts.

Update: Here’s a more detailed explanation of what’s going on.

Another problem I had was klogd hanging and preventing the boot process from finishing. The only solution seems to be to remove klogd from autostart (update-rc.d -f remove klogd) [1] [2].

Online Translation Services 0

All of these allow editing translations through a webinterface.

Transifex: hosted, .po files, Open Source projects only.
Crowdin: hosted, many formats, free for Open Source, eventually pay for closed-source software.
Pootle: install on your own server; .po and xliff support, not all that great an UI unfortunately.
Get Localization
Amanuens

Android: Check if SD card storage is available 1

As used in the Android 2.1 Camera app, in com.android.camera.ImageManager:

public static boolean hasStorage(boolean requireWriteAccess) {
    String state = Environment.getExternalStorageState();

    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    } else if (!requireWriteAccess
            && Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

FRITZ!Box WLAN 3270: Customize DNS Servers 0

I finally had enough with my providers DNS mishandling, so I decided to change the DNS servers, preferably on the router level, since we have multiple clients connected. Alas, the Fritz!Box 3270 doesn’t support this; or, more specifically, it doesn’t expose the functionality in the UI.

As described in a number of places, you can actually do this by editing a config file on the box, which you can do by enabling telnetd first, which AVM is nice enough to let you do, either through dialing a magic number, or, if your particular box doesn’t have a phone socket, by uploading a prepared fake-firmware, which is easy because they don’t need to be signed.

This is just to confirm that this process indeed works with the 3270 as well.

Step 1: Enable telnetd. Here’s one of the better pages explaining this. Short version: the custom image really is just a .tar file, containing a /var/install script with the content /usr/sbin/telnetd -l /sbin/ar7login.

Step 2 (optional): Make it permanent. I had to hurry somewhat, because the box rebooted on my after like a minute or two of asking me on the web interface after the image upload (and getting no response). telnet fritz.box and echo ‘/usr/sbin/telnetd -l /sbin/ar7login’ > /var/flash/debug.cfg did the trick.

Step 3: Configure custom DNS servers. I followed the steps outlined here. Yes, that link worked just fine a couple days ago, now the entry seems to be gone, so let me replicate the steps here:

  • While in telnet, open the file we need to edit: nvi /var/flash/ar7.cfg
  • Search for “overwrite”: /overwrite. There are multiple occurances, the correct one is the one wrapped in the target { } with name=”internet”.
  • Change both values to your preferred servers. You need to press i to enter insert mode.
  • Leave the insert mode with ESC and save and exit with :wq.
  • Reboot, through the web interface, or by typing reboot.

Exporting a NovellForge CVS project 0

A long time ago, the initial development of NTFS Link was done in CVS and hosted on Novell Forge. Novell Forge shut down at the end of March 2010, a deadline I totally missed, considering the project hasn’t been work on in quite a while. I still wanted the preserve the version control history though.

Fortunately, the repository was still online and accessible. Since there didn’t seem to be any official way to download the repository anymore, I was happy to come across cvssuck, which reconstructs the CVS repository locally with client access only.

One problem I ran into: The Novell Forge CVS repository is served through SSH, and I wasn’t able to use public key authentication, with all the Novell Forge facilities seemingly having shut down already. So cvssuck was going to ask me for the password (“anonymous”) about a million times.

Someone in #linux was kind enough to point me to sshpass, which allows us to use ssh while given the password on the command line (apparently, the same thing could be achieved using expect as well).

Ultimately, here’s the commands I used:

$ echo "sshpass -panonymous ssh $*" > customssh.sh
$ chmod +x customssh.sh
$ CVS_RSH="`pwd`/customssh.sh" cvssuck -v :ext:anonymous@forgecvs1.novell.com:/cvsroot/ntfslink/ -o ntfslink-repo .

Now, on to the migration to git!

[Note: git cvsimport would have almost worked as well, but I couldn't get it to work without explicitly specifying a CVS module (strange assertion error); since the NTFS Link repository had no root directory that could serve as a module, I needed to export all modules via "." - cvs2git handles this fine]

Python Standalone Packager 0

I need them so infrequently, I forget what different projects are out there:

android2po: Managing Android translations 2

I’ve always liked gettext a lot. Rather than asking you to maintain a database of strings, assigning an id to each, it simply uses the original strings itself as the string id. To me, it’s a classical example of choosing practicality over purity.

The Android localization system, of course, uses the former approach. Each string is a resource with an id, each each language, essentially, has one or more XML files with the proper localized string mapped to each id.

For my apps, I initially used to have only the original English version, and a German translation, those being the only languages I speak, more or less anyway. Now, whenever I added a new English string, or changed an existing one, I immediately updated the German version as well – simply enough.

For A World Of Photo, I decided to ask the community for help with translations into more languages. Clearly, things were not so simple anymore.

See, with gettext, when the set of strings an app uses changes as part of a new version, you can simply “merge” the new string catalog into each of the translations. Strings that have been removed from the app are removed from the translations files, new strings are added, and strings that have been changed are flagged as “fuzzy”, at least to the extend that the merge tool detects it as a change, rather than a completely new string. That last part is possible because each translation file contains contains not only the translations, but also the original string that was translated. Remember, it’s the string that is the database key.

As a result, translators simply have to go through the list of new or fuzzy, update those, and they’re done.

Now, Android’s system has no equivalent tools. Frankly, I wonder how other people do this. I mean, you surely don’t want have your localization team go through the full list of strings every time you release a new version. Even if you decide you don’t need to ability to detect strings that have changed (you could simply have a policy of using a new id when such a change is necessary), you still need tools to merge changes in your main strings.xml file into each language’s XML resource with new/removed strings (do any such tools exist?).

I suppose you could also ask have your translators work off a diff, but that seems inconvenient. There’s this huge ecosystem around gettext with all kinds of desktop and web apps that could be utilized.

Google seems to use something internally, because Android’s own string resources are marked with msgid= attributes.

So, I decided the best way for me to deal with this would be to simply convert Android’s XML resources to gettext, do the translations, then import the result back to Android. I found out that the OpenIntents project was doing the same, essentially using a generic xml2po tool found somewhere in the depths of gnome-doc-utils. I kinda got it to work, but ran into a lot of little issues; in the end it felt just too hacky.
The final thing that convinced me that writing a special purpose tool might be worth my while was the fact that Android’s XML resource format has a bunch of different escaping rules and peculiarities (which I plan to write a separate post on), with which translators shouldn’t really have to deal with.

So, have a look at android2po. You can install via PyPi:

easy_install android2po

There’s also a README file which explains the basic usage; which is really just a2po init, a2po export and a2po import calls, though at this point there’s also various configuration options that should make it really quite flexible.

The biggest thing it doesn’t support yet are the <plurals> tags, mainly because I didn’t need them myself yet. Apart from that, I do believe it should work just fine for most projects.

git fast-import: Empty path component found in input 0

When you get “fatal: Empty path component found in input” errors from git fast-import, check that your export tool doesn’t write out path values that start with a slash. In my case, my rule file for svn-all-fast-export matched paths like “/project/trunk”, when I should’ve used “/project/trunk/” (note the trailing slash).

Pro-Tip for svn-all-fast-export: Use –metadata=no to get rid of the svn info in the generated git commits. It’s not really advertised as an option.

-->