Archive of articles classified as' "osx"

Back home

Quick Shell Function to Bootstrap a Gradle Groovy Project

2012/02/29

Gradle is a great build tool. It’s easy to download and install. If you’re on a mac and have homebrew, it’s as easy as:

brew install gradle

It’s very easy to use with a little experience, but I find having a good starting place to base your work from can help.

Here’s a quick function that I’ve got in my .zshrc to bootstrap a new groovy gradle project in the current directory (it should also work in in a .profile/.bash_profile/.bashrc).

function newgradle() {
    echo "Creating files for new gradle project"
 
    cat <<EOF>.gitignore
*.un~
*.iml
*.ipr
*.iws
build
.gradle
EOF
 
    cat <<EOF>build.gradle
apply plugin: 'groovy'
apply plugin: 'idea'
 
repositories {
    mavenCentral()
}
 
dependencies {
    groovy 'org.codehaus.groovy:groovy-all:1.8.6'
    groovy 'org.apache.ivy:ivy:2.2.0'
    testCompile 'junit:junit:4.10'
}
 
task createSourceDirs(description : 'Create empty source directories for all defined sourceSets') << {
    sourceSets*.allSource.srcDirs.flatten().each { File sourceDirectory ->
        if (!sourceDirectory.exists()) {
            println "Making \$sourceDirectory"
            sourceDirectory.mkdirs()
        }
    }
}
 
idea {
    project {
        jdkName = '1.6'
    }
}
EOF
 
    gradle createSourceDirs
 
    git init
    ls -a1 && find src    # list all created assets
}

It creates a build.gradle file ready to work with java and groovy projects, including IDEA integration (just execute gradle idea).

This gives you all of the tasks necessary to compile, jar, test, and distribute your code. For more information, check out the gradle docs on the java, groovy, and idea tasks.

It also creates all the necessary source directories for you and initializes a new git repository (with starting .gitignore file) for you to save your work.

You can easily tweak the build.gradle or .gitignore files to fit your needs. If you don’t use git, you can either delete those lines, or subsitute the equivalent lines for the source control tool you use. These are just a good starting place for me.

Here’s the sample output from the script above:

% mkdir testapp
% cd testapp
% newgradle                                                                   
Creating files for new gradle project
:createSourceDirs
Making /Users/tnaleid/Documents/workspace/testapp/src/main/resources
Making /Users/tnaleid/Documents/workspace/testapp/src/main/java
Making /Users/tnaleid/Documents/workspace/testapp/src/main/groovy
Making /Users/tnaleid/Documents/workspace/testapp/src/test/resources
Making /Users/tnaleid/Documents/workspace/testapp/src/test/java
Making /Users/tnaleid/Documents/workspace/testapp/src/test/groovy
 
BUILD SUCCESSFUL
 
Total time: 2.344 secs
Initialized empty Git repository in /Users/tnaleid/Documents/workspace/testapp/.git/
.
..
.git
.gitignore
.gradle
build.gradle
src
src
src/main
src/main/groovy
src/main/java
src/main/resources
src/test
src/test/groovy
src/test/java
src/test/resources

Then you’ve got all this gradle functionality ready to use:

% gradle tasks                                                           
:tasks
 
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
 
Build tasks
-----------
assemble - Assembles all Jar, War, Zip, and Tar archives.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles the main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles the test classes.
 
Documentation tasks
-------------------
groovydoc - Generates Groovydoc API documentation for the main source code.
javadoc - Generates Javadoc API documentation for the main source code.
 
Help tasks
----------
dependencies - Displays the dependencies of root project 'test'.
help - Displays a help message
projects - Displays the sub-projects of root project 'test'.
properties - Displays the properties of root project 'test'.
tasks - Displays the tasks runnable from root project 'test' (some of the displayed tasks may belong to subprojects).
 
IDE tasks
---------
cleanIdea - Cleans IDEA project files (IML, IPR)
idea - Generates IDEA project files (IML, IPR, IWS)
 
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
 
Other tasks
-----------
cleanIdeaWorkspace
createSourceDirs - Create empty source directories for all defined sourceSets
 
Rules
-----
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
Pattern: clean<TaskName>: Cleans the output files of a task.
 
To see all tasks and more detail, run with --all.
 
BUILD SUCCESSFUL
 
Total time: 4.871 secs
2 Comments

Finding and Purging Big Files From Git History

2012/01/17

On a recent grails project, we’re using a git repo that was originally converted from a SVN repo with a ton of large binary objects in it (lots of jar files that really should come from an ivy/maven repo). The .git directory was over a gigabyte in size and this made it very cumbersome to clone and manipulate.

We decided to leverage git’s history rewriting capabilities to make a much smaller repository (and kept our previous repo as a backup just in case).

Here are a few questions/answers that I figured out how to answer with git and some shell commands:

What object SHA is associated with each file in the Repo?

Git has a unique SHA that it associates with each object (such as files which it calls blobs) throughout it’s history.

This helps us find that object and decide whether it’s worth deleting later on:

git rev-list --objects --all | sort -k 2 > allfileshas.txt

Take a look at the resulting allfileshas.txt file for the full list.

What Unique Files Exist Throughout The History of My Git Repo?

If you want to see the unique files throughout the history of your git repo (such as to grep for .jar files that you might have committed a while ago):

    git rev-list --objects --all | sort -k 2 | cut -f 2 -d\  | uniq

How Big Are The Files In My Repo?

We can find the big files in our repo by doing a git gc which makes git compact the archive and stores an index file that we can analyse.

Get the last object SHA for all committed files and sort them in biggest to smallest order:

git gc && git verify-pack -v .git/objects/pack/pack-*.idx | egrep "^\w+ blob\W+[0-9]+ [0-9]+ [0-9]+$" | sort -k 3 -n -r > bigobjects.txt

Take that result and iterate through each line of it to find the SHA, file size in bytes, and real file name (you also need the allfileshas.txt output file from above):

for SHA in `cut -f 1 -d\  < bigobjects.txt`; do
echo $(grep $SHA bigobjects.txt) $(grep $SHA allfileshas.txt) | awk '{print $1,$3,$7}' >> bigtosmall.txt
done;

(there’s probably a more efficient way to do this, but this was fast enough for my purposes with ~50k files in our repo)

Then, just take a look at the bigtosmall.txt file to see your biggest file culprits.

Purging a file or directory from history

Use filter-branch to remove the file/directory (replace MY-BIG-DIRECTORY-OR-FILE with the path that you’d like to delete relative to the root of the git repo:

git filter-branch --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch MY-BIG-DIRECTORY-OR-FILE' --tag-name-filter cat -- --all

Then clone the repo and make sure to not leave any hard links with:

git clone --no-hardlinks file:///Users/yourUser/your/full/repo/path repo-clone-name

You can use this command from the parent directory that contains your git repository and it’s clone to see how much space each of them take, and how much you’ve shrunk the repo in size:

du -s *(/)     # add the -h flag to see the output in human readable size formats, just like ls -lah vs ls -la

With these commands, I was able to reduce the file size of our repo with a few thousand commits down below the size of the checked out repository (more than an order of magnitude smaller). I only removed old binary files, we still have full history for all code files.

3 Comments

How to use kdiff3 as a 3-way merge tool with mercurial, git, and Tower.app

2012/01/12

There are a few very nice looking, mac-like diff tools for OSX (Kaleidoscope and Changes come to mind), but none for doing “real” merges. By this, I mean real, 3-way merges with all of the information you need in front of you.

There are no good-looking, “mac-like” merge tools, but if you swallow your pride there are a few different options for 3-way merges, including Araxis Merge ($$$!), DiffMerge, DeltaWalker, and FileMerge which comes free with XCode.

I’ve tried them all, and find them all confusing. They all tend use a 3-pane display to do the merging with your file in the left pane, the file you’re merging in the right pane, and the messy half-merged file in the middle.

That’s not enough information.

A 3-way merge actually has four important sources of information: Read the rest of this article »

1 Comment

Using Dropbox to Share (most of) Your Home Directory Across Multiple Computers

2011/10/3

I’m a very happy customer of Dropbox. It allows painless syncing of files across multiple computers without extra features to complicate it. The top rated answer on Quora to the question “Why is Dropbox more popular than other programs with similar functionality?” sums things up perfectly.

One of my favorite uses of Dropbox is to sync almost all of the non-machine specific configuration files and directories in my home directory across all my OSX computers (currently my iMac, MacBook Air, and my work laptop).

Doing this lets me make a configuration change to one computer and have it almost instantly available on any other computer without any manual steps.

This is especially important for my zshell and Vim configurations as I’m always tweaking those, but it’s also helpful to have my Documents, Downloads and Pictures shared.

I have a folder in my Dropbox directory called home, I use a script called link.sh to automatically create symlinks in my home directory to the things I’ve got stored in Dropbox.

Dropbox/home currently has these files and directories in it:

.ackrc
.dbvis
.groovy
.gvimrc
.hg
.hgignore_global
.ssh
.subversion
.vim
.viminfo
.vimrc
.zshenv
Desktop-starling.local/   # unique Desktop for my MacBook Air
Desktop-kestrel.local/    # unique Desktop for my iMac
Desktop-thrush.local/     # unique Desktop for my work MacBook Pro
Documents/
Downloads/
Pictures/
bin/

My Dropbox/home directory also has a shell script in it called link.sh:

#! /usr/bin/env bash
cd $(dirname $0)
 
function linkFile() {
    LINK_TO_NAME=$2
    if [ -z $LINK_TO_NAME ]; then
        LINK_TO_NAME=$1
    fi
    if [ -a $HOME/$LINK_TO_NAME ]; then
        echo "**** Found existing $LINK_TO_NAME, skipping..."
    elif [ -h $HOME/$LINK_TO_NAME ]; then
        echo "Already symlinked $LINK_TO_NAME, skipping..."
    else
        echo "Linking $1 to $LINK_TO_NAME"
        ln -s $PWD/$1 $HOME/$LINK_TO_NAME 
    fi
}
 
 
for F in $(ls -a1 | grep -v link.sh | grep -v Desktop | egrep -v "^..?$" | egrep -v "^.*un~$" | grep -v .DS_Store); do
    linkFile $F
done
 
export HOSTNAME=$(hostname)
 
if [ -d "Desktop-$HOSTNAME" ]; then
    linkFile "Desktop-$HOSTNAME" "Desktop"
else 
    echo "Unable to find Desktop-$HOSTNAME to link to Desktop"
fi

What the script does is:

  1. cd into the directory that the script is located in (it only symlinks files in the same directory)
  2. list out all of the files and directories in the same directory as the script
  3. filter out the things we don’t want to link (like ., .., the link.sh script itself, etc)
  4. For all of the files/directories that pass the filter, call linkFile to create a symlink in the current user’s home directory as long as there isn’t already a file or a symlink there
  5. Then look for a file called Desktop-$HOSTNAME where $HOSTNAME is the name of the current machine and create a ~/Dropbox symlink to it if it’s found.

It should be safe and non-destructive and only create symlinks when there isn’t anything else there with the same name.

I didn’t have my Pictures, Documents, and Downloads in my Dropbox for quite a while and was able to get away with the free 2GB plan. I recently upgraded to a paid Dropbox plan as I wanted those directories shared as well (though I exclude a couple of them from my work MacBook Pro).

For “special” directories like Desktop, Pictures, Documents, and Downloads, I needed to use sudo rm -r [dirname] to remove it before I could create the symlink (BACKUP THE DIRECTORY FIRST).

I’ve been using this for over a year, and haven’t noticed any apps that care that those directories are symlinks.

Also? I have used this shell script many times on my systems, and I think it’s safe, but PLEASE backup before using it, or deleting any directories. An adult crying is not a pretty sight :).

6 Comments

big – A Quick Shell/AppleScript/LaunchBar Script to Shout Results

2011/05/17

I threw together a quick shell script, called big that leverages AppleScript and LaunchBar to display results in a huge font.

Often, when I’m demoing something, the results of what I’m doing don’t really jump out at my audience.

If I really want to get a point across to someone it’s nice to be able to do it in a really big, clear font. Just up arrow/ctrl-p to get the last command and append “| big” to get this:

This script takes the results of anything you pipe to it and sends it to LaunchBar to display in a really big font. It get smaller the more text that you send to it, but starts at a ~200pt font.

#! /bin/bash
 
TMP_FILE=`mktemp /tmp/big.XXXXXX` || exit 1
cat - | head -20 > $TMP_FILE
 
osascript <<EOF
tell application "LaunchBar"
    display in large type (do shell script("cat $TMP_FILE"))
end tell
EOF
 
rm $TMP_FILE

It uses the head command to take only the first 20 lines, in case you’re trying to display something HUGE (which can kill LaunchBar if you feed it too much). Adjust the head command appropriately to cap big to more/less output.

1 Comment

Running Redis as a User Daemon on OSX with launchd

2011/03/5

If you’re developing on the mac using redis and want it to start automatically on boot, you’ll want to leverage the OSX launchd system to run it as a User Daemon. A User Daemon is a non-gui program that runs in the background as part of the system. It isn’t associated with your user account. If you only want redis to launch when a particular user logs in, you’ll want to make a User Agent instead.

From the command line, create a plist file as root in the /Library/LaunchDaemons directory with your favorite text editor:

sudo vim /Library/LaunchDaemons/io.redis.redis-server.plist

Paste in the following contents and modify it to point it to wherever you’ve got redis-server installed and optionally pass the location of a config file to it (delete the redis.conf line if you’re not using one):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>io.redis.redis-server</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/bin/redis-server</string>
		<string>/optional/path/to/redis.conf</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

You’ll then need to load the file (one time) into launchd with launchctl:

sudo launchctl load /Library/LaunchDaemons/io.redis.redis-server.plist

Redis will now automatically be started after every boot. You can manually start it without rebooting with:

sudo launchctl start io.redis.redis-server

You can also shut down the server with

sudo launchctl stop io.redis.redis-server

Or you could add these aliases to your bash/zsh rc file:

alias redisstart='sudo launchctl start io.redis.redis-server'
alias redisstop='sudo launchctl stop io.redis.redis-server'

If you’re having some sort of error (or just want to watch the logs), you can just fire up Console.app to watch the redis logs to see what’s going on.

4 Comments

Vim Movement Shortcuts Wallpaper

2010/10/4

I’ve recently moved back to vim (actually MacVim) after a 5 year hiatus using TextMate. A big part of that move was inspired by Steve Losh’s recent post Coming Home to Vim which has a number of really great tips.

I’ve cribbed many of them and have my .vimrc / .vim dotfiles checked into a public bitbucket repo.

There have been some big changes in the last 5 years since I’ve been away from vim (or else I just didn’t know what the hell I was doing, which is also possible). The addition of pathogen for plugin management makes configuration much easier. All plugins are completely contained in their own directory. You can try something out and if it doesn’t work, just delete the plugin’s directory to uninstall it.

NerdTree is nice, but PeepOpen‘s integration with MacVim for finding/opening files beats TextMate’s cmd-T hands down.

I tend to be a hands-on, visual learner, so I looked around for a nice wallpaper to help me learn and retain the panoply of vim movement commands, but all I was able to find were simple lists of commands, so I decided to whip my own version up.

It shows all of the default movement commands, each command is placed relative to the center of the image and are ordered based on how far your cursor will likely travel. All of these are active in vim’s “normal” mode (though I believe most if not all of them will also work in “visual” mode.

I also find it useful to set my MacVim window to be slightly transparent so that I can see the shortcuts through the window if I need to. In MacVim 7.3 you need to turn on the Advanced->”Use experimental renderer” option. Then you can “:set transp=20″ to make it 20% transparent (which feels right to me, but you might want to move it up/down depending on your preferences).

You can download the full size (1900×1200) (or 2560×1600) image for yourself.

Vim Shortcuts Wallpaper

I’ve also got the original OmniGraffle file that I used to create it checked in to a BitBucket repo if anyone feels like remixing it or adding their own shortcuts or customizations to it.

49 Comments

Using a Unique Grails Working Directory for each Mercurial Branch

2010/05/7

At work, we’re using mercurial for our source control. As we’ve released code to production we’ve needed to branch our repository to support what’s in production as well as ongoing development.

By default, grails uses ~/.grails as the working directory. If you’re doing branchy development, you can run into problems with this if you’ve got plugins installed in one branch that aren’t in the other. Having a unique directory per branch prevents you from having to run grails clean all the time.

Here’s a quick shell script that changes the grails working directory to have the branch name as a suffix if your source is contained in a mercurial repository (ex: the default branch would be ~/.grails_default and the 1.0 branch would be ~/.grails_1.0). If your application is not in a repo, it just uses the regular ~/.grails directory.

#!/bin/sh
HG_BRANCH=`hg branch 2>/dev/null`
GRAILS_SCRIPT=$GRAILS_HOME/bin/grails
 
if [ $HG_BRANCH ]; then
	GRAILS_WORK_DIR=`echo ~`/.grails_$HG_BRANCH
	echo "** grails working directory: $GRAILS_WORK_DIR"
	$GRAILS_SCRIPT -Dgrails.work.dir=$GRAILS_WORK_DIR $@
else
	echo "** default grails working directory"
	$GRAILS_SCRIPT $@
fi

Just save this script as “grails” and put it in your PATH before the $GRAILS_HOME/bin directory (also make sure that you’ve defined $GRAILS_HOME). I have a ~/bin directory that’s the first thing in my PATH.

If you use the grails-debug command, you can repeat these steps for that, just change GRAILS_SCRIPT to $GRAILS_HOME/bin/grails-debug.

This same technique could easily be modified to be used for other source control systems such as git or subversion.

3 Comments

Grails Testing Alias to Rerun Failed Tests

2009/11/3

A while ago I blogged about my grails testing aliases and how much time they save me.

I’ve made some enhancements to them in the interim that have made them even easier to use.

The most important alias is gtaf, which is short for “grails test-app” for failed tests.

It will search through your test output directory and look for any tests that failed. If it finds any, it will rerun only those tests. Otherwise, it will rerun all tests. That makes it easy to just use gtaf all the time. If any tests fail, it will open them up using Console.app.

If you’re not on OSX, or would like to use something else to view the failed test logs, just modify the testlog alias to do something different.
Read the rest of this article »

7 Comments

Snow Leopard Shared Printer Job “On Hold: Authentication Required” fix

2009/11/1

I’ve had problems since installing snow leopard with sharing my printer with my wife’s macbook pro.

Whenever she’d try to print, the job would say “On Hold: Authentication Required”. After some fiddling around I found a solution:

  1. Go into System Preferences and go to the Print & Fax panel.
  2. Right click on the printer and choose “Reset Printing System…”. This will remove all of your printers.
  3. Hit the “+” and add the printer back, it should now be reset and have fixed whatever was fubar before.
  4. Click on the “Sharing Preferences” button (or go to the “Sharing” System Preference panel)
  5. Make sure that “Printer Sharing” is checked and that your printer’s name is also checked and that “Everyone” is set to “Can Print”
  6. On the remote machine you want to remove the printer and add it back in through the System Preferences Print & Fax panel

(This is on 10.6.1, not sure if this works in 10.6.0 (where I first had the problem), you should update to the latest).

After doing all that, I was able to print from my remote computers without any problems or any issues around authentication.

92 Comments