make evil monkey nag you back to work

Update: fixed the cron entry

I’ve read a very interesting article about “Why programmers work at night”. One of the points the author talks about is “how we get engrossed in twitter/hacker news/reddit”. I’ve felt the same. I think one of the reasons why we(programmers/developers) spend a lot of our time on twitter/hacker news/reddit is, because, we don’t have any idea of the time. Time just flies by. So, I created a small ruby script which nags you to get back to work :)

~/.scripts/nagger

 1 #!/usr/bin/env ruby
 2 require 'time'
 3 
 4 exit if File.exists?("/tmp/stop-nagging")
 5 #see what I did here ;)
 6 
 7 #run the below command to find your display
 8 #env | grep DISPLAY
 9 ENV['DISPLAY'] = ':0.0'
10 
11 last_line = `tail -2 ~/.gtimelog/timelog.txt`.lines.map{|x| x.chomp}.reject{|x| x.empty?}.reverse.first
12 minutes = ((Time.now - Time.parse(last_line[11, 5])) / 60).round
13 evil_monkey = File.expand_path File.join(File.dirname(__FILE__), 'evil-monkey.gif')
14 
15 if minutes > 30
16   `notify-send -i '#{evil_monkey}' "It's been #{minutes} minutes since your last log"`
17 end

cron entry

1 0,5,10,15,20,25,30,35,40,45,50,55 * * * * /bin/bash -l -c '/home/minhajuddin/.scripts/nagger'

Evil monkey nagging me to get back to work

Hope it helps you get back to work too :). By the way, I use the awesome gtimelog app to log my time.

View Comments »

script to do a global search and replace in a git repository

There are many instances where I had to replace some variable name in all my files. I use a small script to do this, Hope it helps you too.

 1 #!/bin/bash
 2 #~/.scripts/git-sub
 3 #Author: Khaja Minhajuddin <minhajuddin@cosmicvent.com>
 4 #script which does a global search and replace in the git repository
 5 #it takes two arguments
 6 #e.g. git sub OLD NEW
 7 
 8 old=$1
 9 new=$2
10 
11 for file in $(git grep $old | cut -d':'  -f 1 | uniq)
12 do
13   echo "replacing '$old' with '$new' in '$file'"
14   sed -i -e "s/$old/$new/g" $file
15 done

Just remember to add it to a directory which is in the $PATH. I have it in my ~/.scripts directory which is included in the $PATH. Name it git-sub and give it executable permissions using chmod +x ~/.scripts/git-sub. Now, you can just call git sub old_var new_var on terminal and it will do a global search and replace of all the files in the repository.

View Comments »

elegance of functional programming

Functional programming allows you to write concise and elegant code. Mainstream languages like Ruby and C# support a lot of functional programming paradigms, and learning them makes you a better programmer. Below is a small example which demonstrates that:

 1 #6 lines of ugly code
 2 i = 0
 3 tasks = list.tasks
 4 while(i < tasks.length - 2)
 5   tasks[i].priority.should >= tasks[i + 1].priority
 6   i += 1
 7 end
 8 
 9 
10 #3 lines of elegant functional code
11 list.tasks.each_cons(2).each do |t1, t2|
12   t1.priority.should >= t2.priority
13 end
View Comments »

gc your git repositories automatically with a cron task

I have a lot of git code repositories, and I usually gc (garbage collect) them manually by running the git gc command every now and then. Tasks like these are prime candidates for automating with cron. Below is a cron entry and the script which gcs my repositories. Hope you guys find it useful.

the script

 1 #!/bin/bash
 2 #author: Khaja Minhajuddin
 3 #email: minhajuddin.k@gmail.com
 4 #path /home/minhajuddin/.cron/reboot.sh
 5 #description: script which is executed everytime computer starts
 6 
 7 #git gc repos
 8 REPO_DIRS=$(cat <<EOS
 9 $HOME/repos
10 $HOME/repos/core
11 EOS
12 )
13 
14 for repo_dir in $REPO_DIRS
15 do
16   echo "checking for git repos in $repo_dir"
17   for repo in $(ls $repo_dir)
18   do
19     cd $repo_dir/$repo
20     if [[ -d .git ]]
21     then
22       echo "garbage collecting $repo"
23       git gc
24     fi
25   done
26 done

the crontab entry

1 $ crontab -e
2 #add the line below into the editor and save it
3 @reboot   $HOME/.cron/reboot.sh

Bonus tip: If you have a gitosis server, put the following script at ~git/.cron/reboot.sh and perform the above step for your git user.

the gitosis git user script

1 #!/bin/bash
2 
3 for repo in $(ls ~/repositories)
4 do
5   cd ~/repositories/$repo
6   echo "garbage collecting $repo"
7   git gc
8 done
View Comments »

automatically push your git repo to a server on shutdown

Sometimes, I forget to push my git commits to our git server at the end of the day. This causes inconvenience to others as they can’t review my code or build upon it. So, today I wrote a small script which syncs all my git repositories with a remote server. Hope it helps you too :)

The setup consists of three files:

core syncing script at ~/.scripts/sync-repos

 1 #!/usr/bin/env ruby
 2 require 'rubygems'
 3 require 'yaml'
 4 
 5 #replace google.com with your git servers domain
 6 `ping -c 1 google.com`
 7 if $?.exitstatus != 0
 8   puts 'UNABLE TO SYNC REPOS AS NW IS DOWN'
 9   exit $?.exitstatus
10 end
11 
12 puts 'syncing repositories'
13 
14 @repos = YAML::load_file File.expand_path( '~/.sync-repos')
15 
16 @repos.each do |repo|
17   path = File.expand_path repo[:path]
18   remotes = repo[:remotes].is_a?(String) ? [repo[:remotes]] : repo[:remotes]
19   unless File.exist? path
20     puts "skipping #{path} as directory not found"
21     next
22   end
23 
24   remotes.each do |remote|
25     cmd = "cd #{path} && git push #{remote}"
26     puts "executing: '#{cmd}'"
27     system(cmd)
28   end
29 end
30 
31 puts 'done syncing repositories'

config file pointing to all the repos at ~/.sync-repos

1 ---
2 - :path: ~/repos/search
3   :remotes:
4   - origin
5 - :path: ~/repos/logbin
6   :remotes:
7   - origin
8   - local

upstart shutdown trigger script at /etc/init/syncrepos.conf

1 start on runlevel [06]
2 
3 /bin/bash -l -c /home/minhajuddin/.scripts/sync-repos
View Comments »