How do I get subproject jars into my zip? - ruby

I'm trying to make a top-level zip in my buildr buildfile, but the jar files don't seem to end up in the resulting zip.
The project structure has sub-projects:
desc 'Main project'
define 'hex' do
#... omitting top-level config ...
desc 'Hex Utilities'
define 'util' do
package :jar
end
#... omitting other sub-projects, they're all the same ...
binaries_id = "#{id}-components-#{version}"
package(:zip, :file => _("target/#{binaries_id}.zip")).path(binaries_id).tap do |path|
path.include 'COPYING', 'COPYING.LESSER', 'CHANGELOG', 'README.markdown'
%w{anno binary interpreter util viewer}.each do |proj|
path.include project(proj).packages
end
end
end
I have also tried:
path.include project(proj).package(:jar)
explicitly selecting only the jar, though it's the only package anyway, and also:
path.include project(proj).packages.map{|p| "#{p}"}
which maps them to strings, since I noticed all the other path.include lines take strings and suspected that it simply might not work with arrays of package objects, but this doesn't work either. Then my last thought was to just jam in the strings like what I am doing with the rest of the includes:
path.include "#{proj}/target/hex-#{proj}-#{version}.jar"
But even this doesn't work, so I have no idea how to proceed.

I can not seem to reproduce the behaviour. With the most recent release of buildr I created a buildfile that looks like
define 'foo' do
project.version = '1.0'
define 'bar' do
package :jar
end
package(:zip, :file => _("somepath.zip")).path('somepath').tap do |path|
path.include project('bar').packages
end
end
Run "buildr clean package" and then "unzip -t somepath.zip" produces;
Archive: somepath.zip
testing: somepath/ OK
testing: somepath/foo-bar-1.0.jar OK
No errors detected in compressed data of somepath.zip.
Which is what I would expect.

Related

`require`ing files in a common codebase

I'm new to writing big Ruby projects (only mods and application scripting till now). I've made a project with some files in the project root and others in subfolders, including a "Test" folder.
So far I've tried:
Adding all folders and subfolders to the load path in RubyMine.
Declaring all the files to be part of the same module.
I've thought of using require_relative for loading all files needed but it seems tiresome and very Java-esque... Is there a better way?
Here is an example of a typical folder structure, its modules and how to include everything into the library. You would then only need to require 'lib' wherever you want to pull in the library for use.
# Root folder structure of project
lib.rb
./lib/a.rb
./lib/b.rb
./lib/b/c.rb
# lib.rb
require 'lib/a'
require 'lib/b'
module Lib
end
# ./lib/a.rb
module Lib
module A
end
end
# ./lib/b.rb
require 'lib/b/c'
module Lib
module B
end
end
# ./lib/b/c.rb
module Lib
module B
module C
end
end
end

How do I Declare a Rake::PackageTask with Prerequisites?

In Rake, I can use the following syntax to declare that task charlie requires tasks alpha and bravo to have been completed first.
task :charlie => [:alpha, :bravo]
This seems to work fine if charlie is a typical Rake task or a file task but I cannot figure out how to do this for a Rake::PackageTask. Here are the relevant parts of the rakefile so far:
require 'rake/packagetask'
file :package_jar => [:compile] do
puts("Packaging library.jar...")
# code omitted for brevity, but this bit works fine
end
Rake::PackageTask.new("library", "1.0") do |pt|
puts("Packaging library distribution artefact...")
pt.need_tar = true
pt.package_files = ["target/library.jar"]
end
task :package => :package_jar
What's happening here is that, for a clean build, it complains that it doesn't "know how to build task 'target/library.jar'". I have to run rake package_jar from the command line manually to get it to work, which is a bit of a nuisance. Is there any way I can make package depend on package_jar?
For what it's worth, I am using Rake version 0.9.2.2 with Ruby 1.8.7 on Linux.
When you run rake package (without previously running anything else to create any needed files) Rake sees that the package task needs the file target/library.jar. Since this file doesn’t yet exist Rake checks to see if it knows how to create it. It doesn’t know of any rules that will create this file, so it fails with the error you see.
Rake does have a task that it thinks will create a file named package_jar, and that task in fact creates the file target/library.jar, but it doesn’t realise this.
The fix is to tell Rake exactly what file is created in the file task. Rake will then automatically find the dependency.
Change
file :package_jar => [:compile] do
to
file 'target/library.jar' => [:compile] do
and then remove the line
task :package => :package_jar
since package_jar no longer exists and Rake will find the dependency on the file by itself.
In general in rake, if you want to add a dependency to a task, you need that task's name. So you need to figure out the name of the actual rake task that Rake::PackageTask is registering.
The easiest way to do this is by running with --trace — it lists each task's name as it is executing.
(I believe the name of a buildr package task is the filename of the package it produces, but I don't remember for certain. Use --trace to find out.)
You can add a dependency to any task by writing,
someTask.enhance [other, tasks]
where other and tasks can be either task names or task objects.
So in your case, you could write:
library = Rake::PackageTask.new(...) do
...
end
task(:package).enhance([library])

Include Require.JS (r.js build) into the Middleman build

I work with Middleman to develop, test and build my HAML & SASS Projects.
Now I also like to work with require.js. Is there any way i could integrate the R.js build into the Middleman build?
Did you make any experience with it? How do you handle require.js in middleman?
As far as just "running r.js" is concerned, it's pretty straightforward:
Save r.js into the project's root.
Define a custom extension (config.rb) which executes r.js after the build:
module RequireJS
class << self
def registered(app)
app.after_build do |builder|
exec('node r.js -o build/javascripts/app.build.js');
end
end
alias :included :registered
end
end
::Middleman::Extensions.register(:requirejs, RequireJS)
Activate custom extension (config.rb):
configure :build do
…
activate :requirejs
end
r.js can be used with node via the command line, just like middleman. I don't know how exactly you use middleman, but incorporating another command in your workflow shouldn't be a problem. You can find instructions on how to use r.js from the command line here.

Rake delete files task

In msbuild I can delete part of files in certain directory like this
<ItemGroup>
<FilesToDelete Include="$(DeploymentDir)\**\*" exclude="$(DeploymentDir)\**\*.log"/>
</ItemGroup>
<Delete Files="#(FilesToDelete)" />
It will delete all files except *.txt
Is there some rake task I can similar thing?
Ruby has built in classes to make this easy:
Dir['deployment_dir/**/*'].delete_if { |f| f.end_with?('.txt') }
However, for some built in tasks, rake has helpers for this. Adapted from the API docs you can select files like so:
files_to_delete = FileList.new('deployment_dir/**/*') do |fl|
fl.exclude('*.txt')
end
Then you can feed this into your delete task.
Better yet, you can use the built in CLEAN/CLOBBER tasks:
# Your rake file:
require 'rake/clean'
# [] is alias for .new(), and we can chain .exclude
CLEAN = FileList['deployment_dir/**/*'].exclude('*.txt')
Then you can say on the cmd line:
rake clean
Read up the tutorial.
#adzdavies's answer is good, but assigning to CLEAN will produce the following warning since CLEAN is a constant:
warning: already initialized constant CLEAN
You should instead use CLEAN's instance methods. It is a Rake::FileList, so you can add something like this to your Rakefile:
require 'rake/clean'
# this is untested, but you get the idea
CLEAN.include('deployment_dir/**/*').exclude('*.txt')
Then run:
rake clean

Using generated sources in a buildr project

I'm trying to use a code generator inside a buildr-based java project. I would like to...
call the generator
compile the generated classes, package them
eclipse to see the generated stuff (i.e. have the .classpath contain those sources)
I've spend lots of time googling around for a complete example, but to no avail. the example here: https://cwiki.apache.org/confluence/display/BUILDR/How+to+generate+sources+before+compilation
gives be plenty of errors. this is what I've tried:
define 'generator' do
compile.with ALL_COMMON_MODULES
end
define 'extras' do
p 'calling generator..'
Java.classpath << ALL_COMMON_MODULES
Java.classpath << projects('generator')
Java.org.foo.generator.Main.main(['../modules/daos', 'target/generated-sources'])
sources = FileList[_("src/main/jeannie/*.*")]
generate = file(_("target/generated-sources") => sources).to_s do |dir|
puts 'generating...'
mkdir_p dir.to_s # ensure directory is created
end
compile.from generate
end
gives me an error like this:
RuntimeError: Circular dependency detected: TOP ...
so I'm obviously doing something very very wrong. I'd be very glad to see a working example or project that uses code generation.
I finally got it working with help from the buildr mailinglist. for anyone interested: The example mentioned here contains a problem. this:
compile.from generate
should be:
compile.from generate.to_s
Now it works beautifully! buildr also automatically extends the .classpath for eclipse (and idea, in case you use that) if 'compile.from' points to another location.
You cause the circular dependency by calling the parent project in your 'extras' project.
At that line: Java.classpath << projects('generator')
Maybe you should put everything on the same level, which is also what the example shows.
In this scenario your "generate" reference wouldn't be available either as it is in the 'extras' scope.
Something like this (untested):
define "generator" do
generate = file(_("target/generated-sources") => sources).to_s do |dir|
p 'calling generator..'
Java.classpath << ALL_COMMON_MODULES
Java.classpath << projects('generator')
Java.org.foo.generator.Main.main(['../modules/daos', 'target/generated-sources'])
sources = FileList[_("src/main/jeannie/*.*")]
puts 'generating...'
mkdir_p dir.to_s # ensure directory is created
end
compile.with ALL
compile.from generate
end

Resources