Guard::Java
This guard allows you to build and test your Java code automatically when files are altered.
Install
Install the gem with:
gem install guard-java
Or add it to your Gemfile:
gem 'guard-java'
And then add a basic setup to your Guardfile:
guard init java
Usage
If you can do something in your shell, or in Ant, you can do it when a file changes
with guard-java.
You simply provide paths to watch, including how to map a class to it's unit-test class name
and some other options.
Examples
require 'guard/java_translator'
guard :java, :project_name => 'My Java Project',
:all_after_pass => false,
:focused_cli => 'ant clean debug',
:all_cli => 'ant package-and-test',
:classpath => './bin/classes.jar:./libs/*:/usr/share/java/junit.jar'
do
watch (%r{^tests/src/*/(.+)\.java$}) { |m| ::Guard::JavaTranslator.filename_to_classname(m[0]) }
watch(%r{^src/*/(.+)\.java$}) { |m|
test_filename = "tests/src/#{m[1]}Test.java"
::Guard::JavaTranslator.filename_to_classname(test_filename)
}
end
Using Guard
From the project's root directory, simply run:
$ guard
20:28:01 - INFO - Guard uses GNTP to send notifications.
20:28:01 - INFO - Guard uses Tmux to send notifications.
20:28:01 - INFO - Guard uses TerminalTitle to send notifications.
20:28:01 - INFO - Guard::Java is running
20:28:01 - INFO - Guard is now watching at '/Users/tchype/Projects/some_java_project'
[1] guard(main)>
It tells you what notification methods it will use to tell you when it has detected changes,
when it is building/testing, and whether those things have succeeded or failed. In the example
above, I am running Growl as my system notifier and Tmux as my Terminal Multiplexer within
Mac OSX's Terminal program.
You can see that it detected those things and is using GNTP to send Growl notifications
(popups with detailed messages), Tmux color coding (Yellow for building/testing, Red for
failures, and Green for success), as well as updating the Terminal window/tab's title
when guard detects a change.
Other Useful Tips
Working with Android
The template Guardfile you get when you run guard init
has some samples in it. You will want to include your Android SDK jar
file in the classpath
argument. You can write a ruby function that reads it from a local or project
properites file that you call when setting your classpath. For example:
require 'guard/java_translator'
def android_sdk_dir
sdk_dir = ''
%w{project.properties local.properties}.each do |prop_file|
File.open(File.join(File.dirname(__FILE__), prop_file)).each do |line|
sdk_dir = line[8..-1] if line[0..7] == 'sdk.dir='
end
end
sdk_dir.strip
end
guard :java, :project_name => 'Search SDK',
:all_on_start => false,
:all_after_pass => false,
:focused_cli => 'ant guard-debug',
:all_cli => 'ant clean debug',
:classpath => "/bin/classes.jar:./libs/*:/usr/share/java/junit.jar:#{android_sdk_dir}/android-10/*" do
ignore(%r{^src/com/infospace/some_project/BuildTimeUpdatedFile.java})
watch (%r{^tests/src/com/infospace/some_project/*/(.+)\.java$}) { |m|
::Guard::JavaTranslator.filename_to_classname(m[0])
}
watch(%r{^src/com/infospace/some_project/*/(.+)\.java$}) { |m|
test_filename = "tests/src/com/infospace/some_project/#{m[1]}Test.java"
::Guard::JavaTranslator.filename_to_classname(test_filename)
}
end
note: The android jar path must go after the junit.jar path in the classpath, or you will get an exception about no method "main"
and method Stub message. Android only stubs out the JUnitCore runner logic, and if the android jar is placed earlier in the path,
it won't be able to run any tests.
Latency
In the case where many files are changing close together (e.g., saving a test file and saving the class under test), you can tell
guard to wait a certain number of seconds when it detects a file change before triggering a test cycle using the
--latency
(or -l
) command line option. For example, to wait 10 seconds after a change is detected for other changes
to also accumulate:
$ guard -l 10