blob: f2b8ee0cc333a782d9fc925a94ee479a65442d5e [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with this
# work for additional information regarding copyright ownership. The ASF
# licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
module Buildr #:nodoc:
# :call-seq:
# struct(hash) => Struct
#
# Convenience method for creating an anonymous Struct.
#
# For example:
# COMMONS = struct(
# :collections =>'commons-collections:commons-collections:jar:3.1',
# :lang =>'commons-lang:commons-lang:jar:2.1',
# :logging =>'commons-logging:commons-logging:jar:1.0.3',
# )
#
# compile.with COMMONS.logging
def struct(hash)
Struct.new(nil, *hash.keys).new(*hash.values)
end
# :call-seq:
# write(name, content)
# write(name) { ... }
#
# Write the contents into a file. The second form calls the block and writes the result.
#
# For example:
# write 'TIMESTAMP', Time.now
# write('TIMESTAMP') { Time.now }
#
# Yields to the block before writing the file, so you can chain read and write together.
# For example:
# write('README') { read('README').sub("${build}", Time.now) }
def write(name, content = nil)
filename = name.to_s
mkpath File.dirname(filename)
content = yield if block_given?
File.open(filename, 'wb') { |file| file.write content.to_s }
content.to_s
end
# :call-seq:
# read(args) => string
# read(args) { |string| ... } => result
#
# Reads and returns the contents of a file. The second form yields to the block and returns
# the result of the block. The args passed to read are passed on to File.open.
#
# For example:
# puts read('README')
# read('README') { |text| puts text }
def read(*args)
args[0] = args[0].to_s
contents = File.open(*args) { |f| f.read }
if block_given?
yield contents
else
contents
end
end
# :call-seq:
# download(url_or_uri) => task
# download(path=>url_or_uri) =>task
#
# Create a task that will download a file from a URL.
#
# Takes a single argument, a hash with one pair. The key is the file being
# created, the value if the URL to download. The task executes only if the
# file does not exist; the URL is not checked for updates.
#
# The task will show download progress on the console; if there are MD5/SHA1
# checksums on the server it will verify the download before saving it.
#
# For example:
# download 'image.jpg'=>'http://example.com/theme/image.jpg'
def download(args)
args = URI.parse(args) if String === args
if URI === args
# Given only a download URL, download into a temporary file.
# You can infer the file from task name.
temp = Tempfile.open(File.basename(args.to_s))
file(temp.path).tap do |task|
# Since temporary file exists, force a download.
class << task ; def needed? ; true ; end ; end
task.sources << args
task.enhance { args.download temp }
end
else
# Download to a file created by the task.
fail unless args.keys.size == 1
uri = URI.parse(args.values.first.to_s)
key = args.keys.first
if key.is_a?(Buildr::Artifact)
if RUBY_VERSION < '1.9.0'
class << key
def singleton_class
class << self
self
end
end
def define_singleton_method(name, &block)
self.singleton_class.send(:define_method, name, &block)
end
end
end
key.define_singleton_method(:source) do
uri
end
key.define_singleton_method(:download) do
trace "Downloading #{to_spec}"
begin
download_artifact(uri)
true
rescue URI::NotFoundError
false
rescue Exception => error
info error
trace error.backtrace.join("\n")
false
end || fail_download([])
end
key
else
file(key.to_s).tap do |task|
task.sources << uri
task.enhance { uri.download task.name }
end
end
end
end
# A file task that concatenates all its prerequisites to create a new file.
#
# For example:
# concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
#
# See also Buildr#concat.
class ConcatTask < Rake::FileTask
def initialize(*args) #:nodoc:
super
enhance do |task|
content = prerequisites.inject("") do |content, prereq|
content << File.read(prereq.to_s) if File.exists?(prereq) && !File.directory?(prereq)
content
end
File.open(task.name, "wb") { |file| file.write content }
end
end
end
# :call-seq:
# concat(target=>files) => task
#
# Creates and returns a file task that concatenates all its prerequisites to create
# a new file. See #ConcatTask.
#
# For example:
# concat("master.sql"=>["users.sql", "orders.sql", reports.sql"]
def concat(args)
file, arg_names, deps = Buildr.application.resolve_args([args])
ConcatTask.define_task(File.expand_path(file)=>deps)
end
end