Pimp your $PS1 with source control information

words by Brian Racer

I recently found a useful tip of appending source control information of the current working directory to your shell’s $PS1 line. It might look something like the following image:

The method I saw suggested using vcprompt, a small program that outputs a short string basic version control info. Although it worked well, there were a couple issues I had with it. First, it’s subversion support was somewhat lacking. Second, it was written in C which made it more of a pain to modify, and I wasn’t a huge fan of keeping the binary in version control.

After a little searching I stumbled across vcprompt.py, a python script that did the same thing. This version also had wider support for source control systems, and being a standard python text script it was something I could easily modify and put into my dotfiles git repo. I wasn’t happy with how this one displayed subversion information either(just a revision number which I didn’t find very helpful), so I made my own modification to display the branch you are in. Please pardon my lacking Python skills.

Anyway, on to pimping your prompt. Before we modify the PS1 variable, we need to make sure the vcprompt.py is in your $PATH. I like to put scripts like this in a custom bin directory in my homedir. One way to accomplish that might be the following:

$ mkdir -p ~/bin
$ cd ~/bin
$ wget http://github.com/anveo/dotfiles/raw/master/scripts/vcprompt.py
$ chmod +x vcprompt.py
$ export PATH=~/bin:$PATH

Displayed next is the PS1 line I use – it takes up two lines: the first line contains the current user, hostname, current working directory, and possibly version control info, and the second is just a nice looking arrow for my input. Your terminal will need to support Unicode if you want to use that symbol.

# .bashrc
PS1="\n\u@\h:\w \[\e[1;30m\]$(vcprompt)\[\e[0m\] \n→"
 
# If you are using zsh you may also need the following in .zshrc
setopt prompt_subst

If you use the colors specified, you may need to define those too.

You should now have a prompt similar to the image above! For more shell customizations checkout the rest of my dotfiles, and consider buying Peepcode’s Advanced Command Line screencasts for more productive tips!


Useful PHP Subversion Commit Hook

words by Brian Racer

Here is a subversion pre-commit hook script we use on PHP projects to make sure the developer making the commit is providing a meaningful description, and then PHP lint is run on each PHP script to make sure it will compile correctly.

#!/bin/bash
 
REPOS="$1"
TXN="$2"
 
PHP="/usr/bin/php"
SVNLOOK="/usr/bin/svnlook"
AWK="/usr/bin/awk"
GREP="/bin/egrep"
SED="/bin/sed"
 
CHANGED=`$SVNLOOK changed -t "$TXN" "$REPOS" | $AWK '{print $2}' | $GREP \\.php$`
 
for FILE in $CHANGED
do
    MESSAGE=`$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | $PHP -l`
    if [ $? -ne 0 ]
    then
        echo 1>&2
        echo "***********************************" 1>&2
        echo "PHP error in: $FILE:" 1>&2
        echo `echo "$MESSAGE" | $SED "s| -| $FILE|g"` 1>&2
        echo "***********************************" 1>&2
        exit 1
    fi
done
 
# Make sure that the log message contains some text.
SVNLOOKOK=1
SVNLOOK=/usr/bin/svnlook
$SVNLOOK log -t "$TXN" "$REPOS" | \
   grep "[a-zA-Z0-9]" > /dev/null || SVNLOOKOK=0
if [ $SVNLOOKOK = 0 ]; then
  echo Empty log messages are not allowed. Please provide a proper log message. 1>&2
  exit 1
fi
 
# Make sure text might be meaningful
LOGMSGLEN=$($SVNLOOK log -t "$TXN" "$REPOS" | grep [a-zA-Z0-9] | wc -c)
if [ "$LOGMSGLEN" -lt 6 ]; then
  echo -e "Please provide a meaningful comment when committing changes." 1>&2
  exit 1
fi
 
# All checks passed, so allow the commit.
exit 0

SVN autobackup restore

words by Brian Racer

I have been using Doug Hellman’s useful svnautobackup script for our subversion backups. I think it is a pretty useful script, but it only focuses on backups and not restoration.

During a recent server upgrade I needed to restore a large amount of repositories from our dumpfiles. I made the following shell script in php that will loop through all of the backup dumps and restore them. There is a similar tool that uses ruby, but it can only restore one repository and I do not know enough ruby to modify it 🙂

#!/usr/bin/php -q
<?php 
// edit this
$repo_dir = '/svn/';
$backup_dir = '/home/backup/svn/';
 
// don't edit this
foreach(new DirectoryIterator($backup_dir) as $file)
{ 
  if(isDir() && !$file->isDot())
  {
    // get files
    $dumpfiles = glob($backup_dir.$file.'/dumpfile*.bzip2');
    // sort them
    natsort($dumpfiles);
 
    // create the repo if not exists
    if(!is_dir($repo_dir.$file))
    {
      $cmd =  "svnadmin create {$repo_dir}{$file}";
      system(escapeshellcmd($cmd));
    }
 
    // restore dump files
    foreach($dumpfiles as $dumpfile)
    {
      $cmd = "bzcat {$dumpfile} | svnadmin load {$repo_dir}{$file}";
      system(escapeshellcmd($cmd));
    }
  }
}

For reference, here is the script that runs nightly though cron

#!/bin/bash
 
files=`ls /svn`
for file in $files
do
  if [ -d /svn/$file ]
  then
    mkdir -p $file
    /home/backup/scripts/svnautobackup/svnbackup.sh -v -i 100 --history-file /home/backup/svn/$file-hist --out-dir /home/backup/svn/$file /svn/$file
  fi
done