Module: Buildr::Package

Includes:
Extension
Included in:
Project
Defined in:
lib/buildr/packaging/package.rb

Overview

Methods added to Project to support packaging and tasks for packaging, installing and uploading packages.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Extension

included

Instance Attribute Details

#groupObject

Group used for packaging. Inherited from parent project. Defaults to the top-level project name.



64
65
66
# File 'lib/buildr/packaging/package.rb', line 64

def group
  @group
end

#versionObject

Version used for packaging. Inherited from parent project.



67
68
69
# File 'lib/buildr/packaging/package.rb', line 67

def version
  @version
end

Instance Method Details

#idObject

The project’s identifier. Same as the project name, with colons replaced by dashes. The ID for project foo:bar is foo-bar.



59
60
61
# File 'lib/buildr/packaging/package.rb', line 59

def id
  name.gsub(':', '-')
end

#package(*args) ⇒ Object

:call-seq:

package(type, spec?) => task

Defines and returns a package created by this project.

The first argument declares the package type. For example, :jar to create a JAR file. The package is an artifact that takes its artifact specification from the project. You can override the artifact specification by passing various options in the second argument, for example:

package(:zip, :classifier=>'sources')

Packages that are ZIP files provides various ways to include additional files, directories, and even merge ZIPs together. Have a look at ZipTask for more information. In case you’re wondering, JAR and WAR packages are ZIP files.

You can also enhance a JAR package using the ZipTask#with method that accepts the following options:

  • :manifest – Specifies how to create the MANIFEST.MF. By default, uses the project’s #manifest property.

  • :meta_inf – Specifies files to be included in the META-INF directory. By default, uses the project’s #meta-inf property.

The WAR package supports the same options and adds a few more:

  • :classes – Directories of class files to include in WEB-INF/classes. Includes the compile target directory by default.

  • :libs – Artifacts and files to include in WEB-INF/libs. Includes the compile classpath dependencies by default.

For example:

 define 'project' do
   define 'beans' do
     package :jar
   end
   define 'webapp' do
     compile.with project('beans')
     package(:war).with :libs=>MYSQL_JDBC
   end
   package(:zip, :classifier=>'sources').include path_to('.')
end

Two other packaging types are:

  • package :sources – Creates a ZIP file with the source code and classifier ‘sources’, for use by IDEs.

  • package :javadoc – Creates a ZIP file with the Javadocs and classifier ‘javadoc’. You can use the javadoc method to further customize it.

A package is also an artifact. The following tasks operate on packages created by the project:

buildr upload     # Upload packages created by the project
buildr install    # Install packages created by the project
buildr package    # Create packages
buildr uninstall  # Remove previously installed packages

If you want to add additional packaging types, implement a method with the name package_as_ that accepts a file name and returns an appropriate Rake task. For example:

def package_as_zip(file_name) #:nodoc:
  ZipTask.define_task(file_name)
end

The file name is determined from the specification passed to the package method, however, some packagers need to override this. For example, package(:sources) produces a file with the extension ‘zip’ and the classifier ‘sources’. If you need to overwrite the default implementation, you should also include a method named package_as__spec. For example:

def package_as_sources_spec(spec) #:nodoc:
  # Change the source distribution to .jar extension
  spec.merge({ :type=>:jar, :classifier=>'sources' })
end


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/buildr/packaging/package.rb', line 133

def package(*args)
  spec = Hash === args.last ? args.pop.dup : {}
  no_options = spec.empty? # since spec is mutated
  if spec[:file]
    rake_check_options spec, :file, :type
    spec[:type] = args.shift || spec[:type] || spec[:file].split('.').last.to_sym
    file_name = spec[:file]
  else
    rake_check_options spec, *ActsAsArtifact::ARTIFACT_ATTRIBUTES
    spec[:id] ||= self.id
    spec[:group] ||= self.group
    spec[:version] ||= self.version
    spec[:type] = args.shift || spec[:type] || compile.packaging || :zip
  end

  packager = method("package_as_#{spec[:type]}") rescue fail("Don't know how to create a package of type #{spec[:type]}")
  if packager.arity == 1
    unless file_name
      spec = send("package_as_#{spec[:type]}_spec", spec) if respond_to?("package_as_#{spec[:type]}_spec")
      file_name = path_to(:target, Artifact.hash_to_file_name(spec))
    end
    package = (no_options && packages.detect { |pkg| pkg.type == spec[:type] && 
              (spec[:classifier].nil? || pkg.classifier == spec[:classifier])}) ||
      packages.find { |pkg| pkg.name == file_name }                             ||
      packager.call(file_name)
  else
    Buildr.application.deprecated "We changed the way package_as methods are implemented.  See the package method documentation for more details."
    file_name ||= path_to(:target, Artifact.hash_to_file_name(spec))
    package = packager.call(file_name, spec)
  end

  # First time: prepare package for install, uninstall and upload tasks.
  unless packages.include?(package)
    # We already run build before package, but we also need to do so if the package itself is
    # used as a dependency, before we get to run the package task.
    task 'package'=>package
    package.enhance [task('build')]
    package.enhance { info "Packaging #{File.basename(file_name)}" }

    if spec[:file]
      class << package ; self ; end.send(:define_method, :type) { spec[:type] }
    else
      # Make it an artifact using the specifications, and tell it how to create a POM.
      package.extend ActsAsArtifact
      package.send :apply_spec, spec.only(*Artifact::ARTIFACT_ATTRIBUTES)
      # Another task to create the POM file.
      pom = package.pom
      pom.enhance do
        mkpath File.dirname(pom.name)
        File.open(pom.name, 'w') { |file| file.write pom.pom_xml }
      end
      file(Buildr.repositories.locate(package)=>package) { package.install }

      # Add the package to the list of packages created by this project, and
      # register it as an artifact. The later is required so if we look up the spec
      # we find the package in the project's target directory, instead of finding it
      # in the local repository and attempting to install it.
      Artifact.register package, pom
    end

    task('install')   { package.install if package.respond_to?(:install) }
    task('uninstall') { package.uninstall if package.respond_to?(:uninstall) }
    task('upload')    { package.upload if package.respond_to?(:upload) }

    packages << package
  end
  package
end

#packagesObject

:call-seq:

packages => tasks

Returns all packages created by this project. A project may create any number of packages.

This method is used whenever you pass a project to Buildr#artifact or any other method that accepts artifact specifications and projects. You can use it to list all packages created by the project. If you want to return a specific package, it is often more convenient to call #package with the type.



211
212
213
# File 'lib/buildr/packaging/package.rb', line 211

def packages
  @packages ||= []
end