Elia Schito

Archive for the ‘Programming’ Category

Introducing TimeTap: unobtrusive time-tracking for TextMate

In GitHub, Programming, Projects, Ruby, TextMate, Time Tracking on October 4, 2010 at 9:41 am

TimeTap helps you track the time you spend coding on each project while in TextMate.

Once it’s launched you don’t have to bother anymore starting/stopping timers or inventing some arbitrary amount of time to fill your fancy time tracker.

How does it work

TimeTap keeps an eye on (tracks) the modification time of the frontmost file and tells you how much time you spent on each project.

If you stop coding for a while while squeezing your brains TimeTap understands. TimeTap will consider “coding time” pauses to up to 30 minutes between to saves in the same project.

Technically it saves a timestamp+path of the frontmost file in TextMate every 30 seconds, then it digests all this information in a nice Sinatra webapp.

The server will respond on http://0.0.0.0:1111/.

Instructions

Run ruby tap.rb or run rake launcher && launchctl load ~/Library/LaunchAgents to add a plist for OSX’s launchd and have it launched automatically at login.

Setting up config file

timetap uses a config file to control where projects are kept, etc. Put this config file in ~/.tap_config.

cp config.yaml ~/.tap_config

Keys Explained

root - where the timetap logs should be saved. Recommended value: ~
code - where all you project live, in a flat hierachy.
nested_project_layers - see below, on nested projects. Default is 1

Nested Projects allows you to keep your projects inside a hierarchy, instead of the original assumption of timetap (which is that all projects are flat).

For example, you could keep your directory structure might look like:

~/Code/
  Clients/
    AcmeCorp/
      website/
        intranet
    BetaCorp/
      skunkworks/
  OpenSource/
    project_one/
    timetap/

A nested_project_layers setting of 2 (in your .tap_config file) would mean we track “AcmeCorp”, “BetaCorp”, and everything under OpenSource, as their own projects

Assumptions

  • You code on TextMate.
  • You save often (like me), at least every 30 minutes.
  • You keep your code organized (I use ~/Code as main code folder).

TODO

  • support other text editors, or at least make it easy to do so
  • (r)spec it!
  • make it more configurable
  • gemify (with jeweler)
  • flatten encoding quick-fixes with proper solutions (eat and spit only utf8)
  • integration with external (online) time tracking tools
  • export to csv (?)

Get input in Rake Tasks

In Programming, rake, Ruby, Ruby snippets, Snippets on November 7, 2008 at 2:47 pm

This won’t work:

cvs_username = gets

to get it working you have to ask input from STDIN:

cvs_username = STDIN.gets

And this is a helper method:

def ask message
print message
STDIN.gets.chomp
end
# ...
cvs_username = ask('Please insert your CVS username')

How to declare top rake prerequisites from within a namespace

In Programming, Ruby, Ruby snippets, Snippets, Tutorials on May 28, 2008 at 12:48 pm

Here’s the problem

task :mytask do
  # ...
end

namespace :myscope do
  task :mytask => :mytask
end

This will end up with loop dependency error, so how we can call a top level task with the same name of one from our current scope?

The solution is not documented, i found it directly in the rake’s library code.

task :mytask do
  # ...
end

namespace :myscope do
  task :mytask => "rake:mytask"
end

rails runner… with a relative path

In Programming, Rails, Ruby, Ruby on Rails, Snippets on January 23, 2008 at 10:43 am

Well, you know what ./script/runner is?

If so, you’ll know you can’t use it to build script without using an absolute path in the shebang line in your custom scripts:

> ./script/runner -h
Usage: ./script/runner [options] ('Some.ruby(code)' or a filename)
You can also use runner as a shebang line for your scripts like this:
#!/usr/bin/env /path/to/your/app/script/runner
...

 So here’s the solution! (here the script is saved in the script dir)

#!/usr/bin/env ruby
unless $0 =~ /runner/
  exec("#{File.dirname(__FILE__)}/runner #{__FILE__}")
  # "exec" exits the current processing, so this comment won't reached (thanks to Arthaey Angosii)
end
# Your great script goes here!

 Alternative:

#!/usr/bin/env ruby
$: << File.dirname(__FILE__)
ARGV[0] = __FILE__
load 'runner'
#your code here

Rails inflector uncountable troubles? Just remember Why’s Dr. Cham!

In Inflector, pluralize, Programming, Rails, Ruby on Rails, Ruby snippets, Tricks, Tutorials, uncountables, Why's Dr. Cham on July 26, 2007 at 6:00 pm
Inflector.inflections do |inflect|
  #this will do nothing, uncountables have precedence
  inflect.irregular 'equipment', 'equipments'

  def inflect.remove_uncountable(word)
    @uncountables.delete word
  end
  inflect.remove_uncountable 'equipment'
end