Archive for the ‘Howto’ tag
RubyMine 2 Debugging Issue Resolved
If you are trying to debug Ruby code in RubyMine 2 IDE, but are having difficulties such as, the IDE freezes after you try to step in, step over, or step next and are wondering if your configuration is wrong? It is not, if you happen to have installed the ruby-debug-ide19 gem from the command line (not from IDE), you need to patch the actual gem code to get things working nicely.
- Open the following file with your favorite text editor (part of
ruby-debug-ide19gem) - Add the following code at line ~120 (look below for full code location):
- After the modifications, the code should look like:
$GEM_HOME/ruby-debug-ide19-0.4.12/lib/ruby-debug/command.rb
return "" if str == "$FILENAME"
def debug_eval(str, b = get_binding)
begin str = str.to_s
return "" if str == "$FILENAME"
max_time = 10
Thats it, you should be able to debug your Rails/Ruby code in RubyMine without issues.
With Grape, Groovy Is On Par with Native Scripting Languages
If you haven’t heard, the latest version of Groovy was released this week and included with it, among many other great features, was Grape (Groovy Advanced Packaging Engine). Grape is an annotation based dependency management system that provides functionality similar to that of Maven and Ivy with one clear advantage, namely, no build file.
If Grape doesn’t use a build file, how does it know what dependencies are necessary to run the code? Does it figure it out for you on the fly? Unfortunately, it is not that smart (yet), perhaps the next release. If it doesn’t figure it out for you, then how do you specify your dependencies? You configure your dependencies by using the@Grapes or @Grab annotations.
What is so good about being able to configure your dependencies via annotations?
If you are working with Groovy scripts, it frees you up from having to worry about dependency management and allows you to focus more on what the script needs to do much like when working with other scripting languages like Ruby or Perl. In order to clearly demonstrate the advantages of Grape, lets walk through an example.
The problem
Trying to keep up with my ever changing IP address after switching ISP’s earlier this year. There are several services running at my home that I need access to on a daily basis. If my IP changes over night, after a brown out, or for some other reason, I need to know about it asap.
In order to keep up with my IP address, I wrote a set of scripts that perform the following:
- Obtains the current IP address of the server where it is running
- Looks up the most recent IP address of the server in a log file
- If the current IP address is different that the most recent IP address:
- Updates the log file with the current IP address
- Send the new IP address in a customizable email to a configurable address
- If the IP address’s are the same, it does nothing.
The Solution
It took a total of three Groovy classes/scripts to solve this problem. We are not going to get in to the details of the solution because I want to stay focused on Grape.
You can find all of the code discussed in this post on github. Please feel free to download and use it. Feedback is welcome as well.
This simple Groovy class first connects to a mail server, and then sends the change of address message.
import javax.mail.Session
import javax.mail.Message
import javax.mail.internet.MimeMessage
import javax.mail.internet.InternetAddress
@Grapes([
@Grab(group = 'javax.activation', module = 'activation', version = '1.1'),
@Grab(group = 'javax.mail', module = 'mail', version = '1.4')
])
class Mailer {
static def s_config = new ConfigSlurper("message").parse(new File('MailProperties.groovy').toURL())
static def deliverIpAddressChangeMessage(ipAddress) {
def subject = "IP Address Changed to ${ipAddress}"
def message = "IP Address changed to ${ipAddress}.\nPlease update your configurations."
sendMail("${s_config.message.to}".toString(), "${s_config.message.from}".toString(), subject, message)
}
//...
}
Download Source: Mailer.groovy
The most interesting things to pay attention to are:
- The
@Grapesblock after all of the imports, you can see this groovy class depends on javax.activation and javax.mail jars. - Thanks to Grapes, you can compile this class simply by invoking
groovyc Mailer.groovyas opposed to having to configure either Maven, Gant, Ant, or some other build tool to manage the dependencies and classpath for you. - What’s the big deal? Read more to find out!
This next code snipped represents the “main” entry point of my solution. It simply obtains the current IP address of the machine it is running on, checks the current address against the most recent known address stored in a log file, and then uses the previous class to send an email if the IP address has changed.
#!/usr/bin/env groovy
// IP Address Regex http://www.regular-expressions.info/examples.html
currentIp = ("http://whatsmyip.us/".toURL().text =~ /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/)[0]
println currentIp
def ipLog = new File("ip-log.txt")
recentIp = ipLog.readLines().last().tokenize(",").last().trim()
if (currentIp != recentIp) {
Mailer.deliverIpAddressChangeMessage currentIp
println "IP Address has changed, it is now: ${currentIp}. Sending Message."
ipLog << "${new Date()}, ${currentIp}\n"
}
Download Source: whatsMyIp.groovy
The most interesting thing to pay attention to in this script is:
- The
#!/usr/bin/env groovyon the first line on the script. - This line enables the script to be called directly from the command line like:
./whatsMyIp.groovyinstead ofgroovy whatsMyIp.groovy
The Big Deal!
If Grape didn’t exist the only way to invoke this script would be to invoke it with a build tool such as Maven, GAnt, or some other. If a build tool didn’t suit you then you would have to invoke groovy -classpath=/path/activation.jar... and manage the dependencies there. Both of these solutions work fine, but are clunky.
If you were to solve this problem using a language such as Ruby, you would not have to worry about dependency management since Ruby is so closely integrated with the OS. You would simply run gem install some gem, and this would install the dependencies at the OS level. Thus allowing you to focus on your script and letting the Ruby runtime focus on the dependencies. Invoking ./someScript.rb is common in Ruby.
Grape gives Groovy scripts the same clean dependency abstraction. It is possible to invoke ./whatsMyIp.groovy without having to worry about any dependency management. Once the groovy runtime comes across the Grape annotations, it loads the dependencies on demand freeing the Groovy script from having to be wrapped with a dependency management layer.
This is a huge deal because now simple Groovy scripts can leverage the entire Java ecosystem from the command line without having to wrap the invocation with a build tool. Groovy Scripts are now clean, simple, and easy. I hope this inspires you to go out and convert some Ruby or Perl script to Groovy.
Time Machine over a Network Drive
This post describes the steps involved when setting up Time Machine to backup to a Network Drive. These steps are only required if you want to back up to a device other than a Time Capsule. It is pretty quick and easy, so without further due, lets get started.
Step 1: Enable network backups in Time Machine
In a terminal window cut/paste the following command:
defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
Step 2: Create Timemachine backup volume
In a terminal window cut/paste the following command:
hdiutil create -fs HFS+J -volname "Backup of computer-name" computer-name_[mac address without':'].sparsebundle
The simplest way to obtain your mac address is to open a terminal window and type the command: ifconfig -a, and look for the section of the output where it says: ether 00:33:44:55:66:77
The simplest way to obtain your computer name is to open a terminal window and type the command: hostname, it will return the name of your computer, example, my-hostname.
Putting it all together, based on the above examples, you would run the following command:
hdiutil create -fs HFS+J -volname "Backup of my-hostname" my-hostname_003344556677.sparsebundle
Step 3: Copy file created in step 2 to network Time Machine backup destination
Using finder or terminal, copy the newly created .sparsebundle file to the place you want your Time Machine backup to reside.
Step 4: Open Timemachine preferences, and the network drive should show up as a backup target
If for some reason it doesn’t, try opening and closing the Time Machine preferences, as it may take a moment for it to detect the newly available network drive.
Step 5: Rest easy knowing your mac is now backed up to a network storage volume.
Simple Applescript For The Traveling Mac
The Problem
You have a MacBook and a nice Apple Cinema display (this doesn’t sound like a problem so far), and you travel with the MacBook every day. When you open the lid of your MacBook you like to have the Dock on the left side of the screen giving you the most top to bottom space, but when you come home and connect the MacBook to your Cinema display and set up dual monitors, you want the dock on the bottom of the Cinema, not on the left side of the MacBook.
You don’t want to have to go in to preferences every time to switch the location. (or maybe you do?) For me it was becoming a very tedious task, so I began researching ways to automate it.
The Solution
Leverage Apple’s “Language of Automation”, Applescript to handle the task. Applescript has lots of useful hooks in to OS X.
The requirements for the script are quite simple:
- Obtain the current resolution of the primary monitor
- if the resolution is > 1900 (Cinema Display) configure the Dock for large display
- else configure the Dock for laptop display
For the moment, that is my goal, simple, yet time saving.
Step 1: Open AppleScript Editor
Step 2: Paste the following code in
Future requirements
- Figure out how to hook the script in to sleep/wake events in Snow Leopard.
- Customize more than just the Dock.
- Migrate it in to a startup script that brings up all necessary applications based upon current mood (reading/blogging/coding).
- Others???
Overall, I find Applescript a very easy way to automate things in Snow Leopard.
All of the source for this post can be found on github.com. Please feel free to fork and improve.
Enjoy.
