Buildr 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ 0.17 (3/14/2007)
2
+ * Added: project.task acts like Rake's task but can also fetch a task from
3
+ a project using the project's namespace.
4
+ * Added: project.file acts like Rake's file but resolve relative paths
5
+ based on the project base directory.
6
+ * Added: Rake tasks execute in the directory in which they were defined.
7
+ * Added: enhanced Rake with circular dependency, and you can find all circular
8
+ dependencies by running rake check.
9
+ * Added: enhanced Rake in_namespace, if the namespace starts with colon,
10
+ creates a namespace relative to the root instead of the current namespace.
11
+ * Changed: a project definition is now a task definition.
12
+ * Changed: use enhance to extend the project definition instead of after_define.
13
+ * Changed: LocalDirectoryTask replaced with Project.local_task.
14
+ * Changed: projects method accepts multiple names, returning only these project
15
+ definitions, returns all of them with no arguments.
16
+ * Changed: package only defines the essentials once, so you can call package
17
+ on a project to retrieve a specific package by type/id.
18
+ * Changed: zip task (and jar/war) no longer resolve artifacts for you,
19
+ must call artifacts directly.
20
+ * Changed: cannot access a project before it's defined, but can do that with
21
+ sub-projects to establish dependencies.
22
+
23
+ 0.16 (3/7/2007)
24
+ * Added: zip.include :as=> to include file under specified name.
25
+ * Added: zip.merge to include the (expanded) contents of one zip file in another.
26
+ * Added: experimental test task using JUnit and JMock.
27
+ * Changed: project.to_s returns name, projects returns sorted by name.
28
+ * Changed: project definition now executed using project's base directory
29
+ as the current directory.
30
+ * Fixed: artifact test cases and minor code cleanup.
31
+ * Fixed: attempts to download artifact even if created by task.
32
+ * Fixed: release task now deletes old tagged copy and reports SVN usage.
33
+ * Fixed: OpenJPA not including target directory in classpath.
34
+
35
+ 0.15 (2/28/2007)
36
+ * Fixed: tasks fail unless deployment server specified.
37
+ * Changed: deploy method executes deployment, instead of returning a task.
38
+
39
+ 0.14 (2/28/2007)
40
+ * Added: check task that looks for obvious errors in the Rakefile.
41
+ * Added: deploy task for managing deployment.
42
+ * Added: release task that updates version numbers, commits and tags SVN.
43
+ * Changed: the project name is now the fully qualified name, e.g. ode:axis2
44
+ * Changed: you can now lookup a project before it's defined; you still can
45
+ only define a project once.
46
+ * Changed: you can lookup projects by full qualified name.
47
+ * Changed: release_to changed to deploy_to, which is now a getter/setter.
48
+ * Fixed: removed Java.home which conflicted with JRuby.
49
+ * Fixed: install task did not re-install modified files.
50
+ * Fixed: deploying only uploads one artifact.
51
+ * Fixed: timing issues.
52
+ * Fixed: Maven classifier now used properly.
53
+
54
+ 0.13 (2/26/2007)
55
+ * Added: global java method.
56
+ * Added: project build method.
57
+ * Added: OpenJPA mapping_tool method.
58
+ * Added: Rakefile to generate Gem.
59
+ * Changed: you can now lookup a sub-project from the top project method.
60
+ * Changed: the projects methods return all sub-projects.
61
+ * Fixed: bug in JarTask that resolved artifacts too early.
62
+ * Fixed: global tasks (clean, build, etc) now complain if executed from a directory
63
+ that does not map to any project.
64
+ * Fixed: to work with Rake 0.7.2.
65
+
66
+ 0.12 (2/24/2007)
67
+ * Added: call prepare with list of tasks to add them as prerequisites.
68
+ * Added: project.id returns the compound name, e.g. foo, foo-bar, foo-bar-baz.
69
+ * Added: JavaCC, XMLBeans schema compiler, OpenJPA enhancer, APT tasks.
70
+ * Changed: the default package ID is take from the project ID instead of its name.
71
+ * Changed: renamed buildr and moved here.
72
+ * Changed: moved all code into Buildr module.
73
+ * Fixed: download breaking when POM not found.
74
+ * Fixed: compile task fails if classpath is empty.
75
+ * Fixed: zip task fails if target directory does not exist.
76
+ * Fixed: packaging task does not require build.
77
+ * Fixed: compiler not showing command when trace is on.
78
+ * Fixed: zip dependencies were all fucked up.
79
+ * Fixed: package should not depend on build.
80
+
81
+ 0.11 (2/16/2007)
82
+ * Added: test cases for unzip task
83
+ * Added: prepare method to access prepare task
84
+ * Added: prepare, compile and resources accept a block you can use to enhance the task
85
+ * Changed: ZipTask executes all includes files as prerequisites, and now includes
86
+ directories correctly
87
+ * Changed: Jar/WarTask are now extended using with(options) method
88
+ * Changed: JarTask now accepts array of sections (each being a hash) for the manifest,
89
+ and a proc/method to generate it
90
+ * Changed: added HighLine to hide password entry on the command line
91
+ * Changed: unzip now using UnzipTask with its own shorthand syntax.
92
+ * Changed: filter task gets a consistent syntax to unzip
93
+
94
+ 0.10 (2/13/2007)
95
+ * Added: modifier for artifacts
96
+ * Added: ZipTask, WarTask
97
+ * Added: get POM artifact directly from artifact
98
+ * Changed: JAR and WAR packaging based on new and improved Zip task
99
+ * Changed: options for packaging, but not affecting current Rakefile
100
+ * Remove: delete task
101
+
102
+ 0.9 (2/9/2007)
103
+ * Added: attributes for configuring compile (sources, classpath, target, options)
104
+ * Added: shorthand notation for specifying compilation (to, with, using)
105
+ * Changed: copy task is dead (name conflict), instead we get the better filter
106
+ task with include/exclude patterns
107
+ * Changed: rewrite of compile task, now better than ever
108
+ * Changed: compile can be used inside and outside project
109
+ * Changed: compiler no longer infers anything from its prerequisites
110
+ * Changed: compiler accepts files, artifacts and tasks on the classpath
111
+ * Changed: resources task now working as expected
112
+ * Remove: global task artifacts was the root of all evil and got canned.
113
+
114
+ 0.8 (2/5/2007)
115
+ * Added: release task and release_to configuration for repositories
116
+ * Added: SFTP uploader for releases
117
+ * Added: convenience method group() for specifying multiple artifacts in same
118
+ group and version number
119
+ * Added: install target copies package to local repository and adds a POM,
120
+ uninstall package removes package (and POM) from local repository
121
+ * Changed: project lookup now happens through project() method
122
+ * Changed: locating file in the local repository now happens through Repositories
123
+ * Changed: downloading file into the local repository now happens through Repositories
124
+ * Changed: notation for specifying multiple artifacts in a string is now foo,bar,baz
125
+ * Changed: artifact identifier is now specified with the key :id
126
+ * Changed: download POM alongside artifact and install in local repository
127
+ * Changed: no more scoping artifacts collection in project, use compile.with instead
128
+ * Changed: moved HTTP download logic to transports.rb
129
+ * Removed: deprecated grouping with multiple artifacts under id key
130
+
131
+ 0.6 (2/1/2007)
132
+ * Added: Artifact resolution introduces the notion of a spec,
133
+ which can be supported using ActsAsArtifact
134
+ * Added: You can now use a project as an artifact, resulting in all its
135
+ packages being added, or use a task as artifact
136
+ * Changed: project.sub_projects renamed project.projects
137
+ * Changed: what used to be called dependencies is now called artifacts
138
+ * Changed: all artifacts are now created as tasks that know how to download
139
+ themselves unless some other behavior is specified
140
+ * Changed: local and remote repositories are now defined on the Rakefile
141
+ instead of individual projects
142
+ * Changed: attributes now stored directly as instance variables
143
+ * Changed: ANSI colors and progress bar now using Ruby Facets
144
+
145
+ 0.5 (1/24/2007)
146
+ * Added: Build number for each top-level project, build_number method for accessing
147
+ it and build:increment task for updating the build number file.
148
+ * Added: to_path method on project to resolve paths relative to base_dir.
149
+ * Added: recursive_task method on project to create task in project/sub-project.
150
+ * Added: compiler property for passing any options to Javac.
151
+ * Changed: remove task renamed uninstall.
152
+ * Changed: and to confuse more remove task (RemoveTask) renamed delete.
153
+ * Changed: consolidated before_create/after_create to on_create.
154
+ * Changed: version, group, artifact added as accessors to project.
155
+ * Changed: project definition block takes project as argument.
156
+ * Changed: project enhanced only if new settings or block.
157
+ * Changed: local_repository is now separate attribute from repositories.
158
+ * Changed: Directory structure, now split into rbs, rbs-java and tasks.
159
+ * Removed: project.options. Using a different attributes mechanism.
160
+
161
+ 0.4 (1/23/2007)
162
+ * Added: CopyTask now deals with files and directories, can copy multiple files,
163
+ and applies filter to all of them. Filter can be a hash or a proc.
164
+ * Added: Project gets resources_filter attribute that can be used to set the
165
+ filter on all copied resources.
166
+ * Added: HTTP module for getting and downloading files, and a download task.
167
+ * Changed: Dependencies now check signatures for every file, if available,
168
+ and show download progress.
169
+
170
+ 0.3 (1/22/2007)
171
+ * Added: Dependencies loaded from Maven repositories if not existing or built by project.
172
+ Use rake dependencies to force update, or let compilation take care of it.
173
+ * Added: Copy task for copying one file to another, and filtering support.
174
+
175
+ 0.2 (1/21/2007)
176
+ * Added: remove task to get rid of packages added to the local repository.
177
+ * Changed: recompile project if any of its dependencies is newer than the source code.
178
+ Will cause recompile if any of the dependencies was compiled and packaged again.
179
+ * Changed: compile task depends on javac task and resource copy tasks.
180
+ This might change when adding filtering later on.
181
+
182
+ 0.1 (1/19/2007)
183
+ * Added: build and clean tasks
184
+ * Added: resources are now copied over during compilation
185
+ * Added: POM file generated in local repository (keep Maven happy)
186
+ * Added: compile scope for use by javac
187
+ * Added: WAR packaging.
188
+ * Changed: Root project operates on the current directory, sub-projects on sub
189
+ directories. See Rakefile for example.
data/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2006, Intalio Inc.
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
data/README ADDED
File without changes
@@ -0,0 +1,55 @@
1
+ # returning(obj)
2
+ require "facet/kernel/with"
3
+ # &:symbol goodness.
4
+ require "facet/symbol/to_proc"
5
+ # blank? on string and nil
6
+ require "facet/string/blank"
7
+ require "facet/nilclass/blank"
8
+ # x.in?(y) is better than y.include?(x)
9
+ require "facet/kernel/in"
10
+ # What it says.
11
+ require "facet/kernel/__DIR__"
12
+ require "facet/kernel/instance_exec"
13
+ require "facet/module/alias_method_chain"
14
+ require "facet/module/memoize"
15
+ require "facet/string/starts_with"
16
+
17
+
18
+ module Buildr
19
+ VERSION = "0.17.0"
20
+ end
21
+
22
+ $LOAD_PATH.unshift File.join(__DIR__)
23
+ require "core/core.rb"
24
+ require "core/project.rb"
25
+ require "core/artifact.rb"
26
+ require "core/build.rb"
27
+ require "core/transports.rb"
28
+
29
+ require "tasks/download"
30
+ require "tasks/filter"
31
+ require "tasks/zip"
32
+
33
+ require "java/java"
34
+ require "java/jetty"
35
+ require "java/compile"
36
+ require "java/eclipse"
37
+ #require "java/test"
38
+ require "java/javacc"
39
+ require "java/openjpa"
40
+ require "java/packaging"
41
+ require "java/xmlbeans"
42
+
43
+ include Buildr
44
+
45
+ # The greate method_missing/Object extend bug requires us to load
46
+ # XMLBuilder after we're done enhancing Object.
47
+ require "builder"
48
+
49
+ # Load the settings files.
50
+ if File.exist?(File.join(ENV["HOME"], "buildr.rb"))
51
+ load File.join(ENV["HOME"], "buildr.rb")
52
+ end
53
+ if File.exist?(File.join(Rake.application.original_dir, "buildr.rb"))
54
+ load File.join(Rake.application.original_dir, "buildr.rb")
55
+ end
@@ -0,0 +1,405 @@
1
+ module Buildr
2
+
3
+ # This module gives you a way to access the individual properties of an
4
+ # artifact: id, group, type, classifier and version. It also provides other
5
+ # methods commonly used on an artifact, specifically #to_hash and #to_spec.
6
+ module ActsAsArtifact
7
+
8
+ ARTIFACT_ATTRIBUTES = [:group, :id, :type, :classifier, :version]
9
+
10
+ class << self
11
+ def included(mod)
12
+ mod.extend self
13
+ end
14
+ end
15
+
16
+ # The artifact identifier.
17
+ attr_reader :id
18
+ # The group identifier.
19
+ attr_reader :group
20
+ # The file type.
21
+ attr_reader :type
22
+ # The version number.
23
+ attr_reader :version
24
+ # Optional artifact classifier.
25
+ attr_reader :classifier
26
+
27
+ # Returns the artifact specification as a hash.
28
+ def to_spec_hash()
29
+ base = { :group=>group, :id=>id, :type=>type, :version=>version }
30
+ classifier.blank? ? base : base.merge(:classifier=>classifier)
31
+ end
32
+ alias_method :to_hash, :to_spec_hash
33
+
34
+ # Returns the artifact specification, in the structure:
35
+ # <group>:<artifact>:<type>:<version>
36
+ # or
37
+ # <group>:<artifact>:<type>:<classifier><:<version>
38
+ def to_spec()
39
+ classifier.blank? ? "#{group}:#{id}:#{type}:#{version}" : "#{group}:#{id}:#{type}:#{classifier}:#{version}"
40
+ end
41
+
42
+ # Apply specification to this artifact.
43
+ def apply_spec(spec)
44
+ spec = Artifact.to_hash(spec)
45
+ ARTIFACT_ATTRIBUTES.each { |key| instance_variable_set("@#{key}", spec[key]) }
46
+ self
47
+ end
48
+
49
+ # Convenience method that returns a POM artifact.
50
+ def pom()
51
+ return self if type.to_s == "pom"
52
+ artifact(:group=>group, :id=>id, :version=>version, :type=>"pom", :classifier=>classifier)
53
+ end
54
+
55
+ end
56
+
57
+
58
+ # The Artifact task maps to an artifact file in the local repository
59
+ # and knows how to download the file from a remote repository.
60
+ #
61
+ # The task will only download the file if it does not exist. You can
62
+ # enhance the task to create the artifact yourself.
63
+ class Artifact < Rake::FileCreationTask
64
+
65
+ # The default file type for artifacts, if not specified.
66
+ DEFAULT_FILE_TYPE = "jar"
67
+
68
+ include ActsAsArtifact
69
+
70
+ class << self
71
+
72
+ # Lookup a previously registered artifact task based on the
73
+ # artifact specification (string or hash).
74
+ def lookup(spec)
75
+ @artifacts ||= {}
76
+ @artifacts[to_spec(spec)]
77
+ end
78
+
79
+ # Register an artifact task(s) for later lookup (see #lookup).
80
+ def register(*tasks)
81
+ @artifacts ||= {}
82
+ fail "You can only register an artifact task, strings and hashes are just not good enough" unless
83
+ tasks.all? { |task| task.respond_to?(:to_spec) && task.respond_to?(:invoke) }
84
+ tasks.each { |task| @artifacts[task.to_spec] = task }
85
+ tasks
86
+ end
87
+
88
+ # Turn a spec into a hash. This method accepts a string, hash or any object
89
+ # that responds to the method to_spec. There are several reasons to use this
90
+ # method:
91
+ # * You can pass anything that could possibly be a spec, and get a hash.
92
+ # * It will check that the spec includes the group identifier, artifact
93
+ # identifier and version number and set the file type, if missing.
94
+ # * It will always return a new specs hash.
95
+ #
96
+ # :nodoc:
97
+ def to_hash(spec)
98
+ if spec.respond_to?(:to_spec)
99
+ to_hash spec.to_spec
100
+ elsif Hash === spec
101
+ # Sanitize the hash and check it's valid.
102
+ spec = ARTIFACT_ATTRIBUTES.inject({}) { |h, k| h[k] = spec[k] ; h }
103
+ fail "Missing group identifier for #{spec.inspect}" if spec[:group].blank?
104
+ fail "Missing artifact identifier for #{spec.inspect}" if spec[:id].blank?
105
+ fail "Missing version for #{spec.inspect}" if spec[:version].blank?
106
+ spec[:type] = DEFAULT_FILE_TYPE if spec[:type].blank?
107
+ spec
108
+ elsif String === spec
109
+ group, id, type, version, *rest = spec.split(":")
110
+ unless rest.empty?
111
+ # Optional classifier comes before version.
112
+ classifier, version = version, rest.shift
113
+ fail "Expecting <project:id:type:version> or <project:id:type:classifier:version>, found <#{spec}>" unless rest.empty?
114
+ end
115
+ to_hash :group=>group, :id=>id, :type=>type, :version=>version, :classifier=>classifier
116
+ else
117
+ fail "Expecting a String, Hash or object that responds to to_spec"
118
+ end
119
+ end
120
+
121
+ # Convert a hash back to a spec string. This method accepts
122
+ # a string, hash or any object that responds to to_spec.
123
+ # :nodoc:
124
+ def to_spec(hash)
125
+ hash = to_hash(hash) unless Hash === hash
126
+ version = ":#{hash[:version]}" unless hash[:version].blank?
127
+ classifier = ":#{hash[:classifier]}" unless hash[:classifier].blank?
128
+ "#{hash[:group]}:#{hash[:id]}:#{hash[:type] || DEFAULT_FILE_TYPE}#{classifier}#{version}"
129
+ end
130
+
131
+ # Convert a hash to a file name.
132
+ # :nodoc:
133
+ def hash_to_file_name(hash)
134
+ version = "-#{hash[:version]}" unless hash[:version].blank?
135
+ classifier = "-#{hash[:classifier]}" unless hash[:classifier].blank?
136
+ "#{hash[:id]}#{version}#{classifier}.#{hash[:type] || DEFAULT_FILE_TYPE}"
137
+ end
138
+
139
+ end
140
+
141
+ def execute()
142
+ # Default behavior: download the artifact from one of the remote
143
+ # repositories if the file does not exist. But this default behavior
144
+ # is counter useful if the artifact knows how to build itself
145
+ # (e.g. download from a different location), so don't perform it
146
+ # if the task found a different way to create the artifact.
147
+ super
148
+ unless Rake.application.options.dryrun || File.exist?(name)
149
+ repositories.download(to_spec)
150
+ end
151
+ end
152
+
153
+ end
154
+
155
+
156
+ # Holds the path to the local repository, URLs for remote repositories, and
157
+ # settings for the deployment repository.
158
+ class Repositories
159
+ include Singleton
160
+
161
+ # Returns the path to the local repository.
162
+ #
163
+ # The default path is .m2/repository relative to the home directory.
164
+ # You can change the location of the local repository by using a symbol
165
+ # link or by setting a different path. If you set a different path, do it
166
+ # in the buildr.rb file instead of the Rakefile.
167
+ def local()
168
+ @local ||= ENV["local_repo"] || File.join(ENV["HOME"], ".m2", "repository")
169
+ end
170
+
171
+ # Sets the path to the local repository.
172
+ def local=(dir)
173
+ @local = dir ? File.expand_path(dir) : nil
174
+ end
175
+
176
+ # Locates an artifact in the local repository based on its specification.
177
+ #
178
+ # For example:
179
+ # locate :group=>"log4j", :id=>"log4j", :version=>"1.1"
180
+ # => ~/.m2/repository/log4j/log4j/1.1/log4j-1.1.jar
181
+ def locate(spec)
182
+ spec = Artifact.to_hash(spec)
183
+ File.join(local, spec[:group].split("."), spec[:id], spec[:version], Artifact.hash_to_file_name(spec))
184
+ end
185
+
186
+ # Returns a hash of all the remote repositories. The key is the repository
187
+ # identifier, and the value is the repository base URL.
188
+ def remote()
189
+ @remote ||= {}
190
+ end
191
+
192
+ # Sets the remote repositories from a hash. See #remote.
193
+ def remote=(hash)
194
+ case hash
195
+ when nil
196
+ @remote = {}
197
+ when Hash
198
+ @remote = hash.clone
199
+ else
200
+ raise ArgumentError, "Expecting a hash" unless Hash === hash
201
+ end
202
+ end
203
+
204
+ # Adds more remote repositories from a hash. See #remote.
205
+ #
206
+ # For example:
207
+ # repositories.remote.add :ibiblio=>"http://www.ibiblio.org/maven2"
208
+ def add(hash)
209
+ remote.merge!(hash)
210
+ end
211
+
212
+ # Attempts to download the artifact from one of the remote repositories
213
+ # and store it in the local repository. Returns the path if downloaded,
214
+ # otherwise raises an exception.
215
+ def download(spec)
216
+ spec = Artifact.to_hash(spec) unless Hash === spec
217
+ path = locate(spec)
218
+
219
+ puts "Downloading #{Artifact.to_spec(spec)}" if Rake.application.options.trace
220
+ return path if remote.any? do |repo_id, repo_url|
221
+ begin
222
+ rel_path = spec[:group].gsub(".", "/") +
223
+ "/#{spec[:id]}/#{spec[:version]}/#{Artifact.hash_to_file_name(spec)}"
224
+ Transports.perform URI.parse(repo_url.to_s) do |http|
225
+ mkpath File.dirname(path), :verbose=>false
226
+ http.download(rel_path, path)
227
+ begin
228
+ http.download(rel_path.ext("pom"), path.ext("pom"))
229
+ rescue Transports::NotFound
230
+ end
231
+ end
232
+ true
233
+ rescue Exception=>error
234
+ warn error if Rake.application.options.trace
235
+ false
236
+ end
237
+ end
238
+ fail "Failed to download #{Artifact.to_spec(spec)}, tried the following repositories:\n#{repositories.remote.values.join("\n")}"
239
+ end
240
+
241
+ # Specifies the deployment repository. Accepts a hash with the different
242
+ # repository settings (e.g. url, username, password). Anything else is
243
+ # interepted as the URL.
244
+ #
245
+ # For example:
246
+ # repositories.deploy_to = { :url=>"sftp://example.com/var/www/maven/",
247
+ # :username="john", :password=>"secret" }
248
+ # or:
249
+ # repositories.deploy_to = "sftp://john:secret@example.com/var/www/maven/"
250
+ def deploy_to=(options)
251
+ options = { :url=>options } unless Hash === options
252
+ @deploy_to = options
253
+ end
254
+
255
+ # Returns the current deployment repository configuration. This is a more
256
+ # convenient way to specify deployment in the Rakefile, and override it
257
+ # locally. For example:
258
+ # # Rakefile
259
+ # repositories.deploy_to[:url] ||= "sftp://example.com"
260
+ # # buildr.rb
261
+ # repositories.deploy_to[:url] = "sftp://acme.org"
262
+ def deploy_to()
263
+ @deploy_to ||= {}
264
+ end
265
+
266
+ end
267
+
268
+
269
+ # Returns a global object for setting local, remote and deploy repositories.
270
+ # See Repositories.
271
+ def repositories()
272
+ Repositories.instance
273
+ end
274
+
275
+ # Creates a file task to download and install the specified artifact.
276
+ #
277
+ # The artifact specification can be a string or a hash.
278
+ # The file task points to the artifact in the local repository.
279
+ #
280
+ # You can provide alternative behavior to create the artifact instead
281
+ # of downloading it from a remote repository.
282
+ #
283
+ # For example, to specify an artifact:
284
+ # artifact("log4j:log4j:jar:1.1")
285
+ #
286
+ # To use the artifact in a task:
287
+ # unzip artifact("org.apache.pxe:db-derby:zip:1.2")
288
+ #
289
+ # To specify an artifact and the means for creating it:
290
+ # download(artifact("dojo:dojo-widget:zip:2.0")=>
291
+ # "http://download.dojotoolkit.org/release-2.0/dojo-2.0-widget.zip")
292
+ def artifact(spec, &block)
293
+ spec = Artifact.to_hash(spec)
294
+ unless task = Artifact.lookup(spec)
295
+ task = Artifact.define_task(repositories.locate(spec))
296
+ Artifact.register(task)
297
+ end
298
+ task.apply_spec spec
299
+ task.enhance &block
300
+ end
301
+
302
+ # Creates multiple artifacts from a set of specifications and returns
303
+ # an array of tasks.
304
+ #
305
+ # You can pass any number of arguments, each of which can be:
306
+ # * An artifact specification, string or hash. Returns a new task for
307
+ # each specification, by calling #artifact.
308
+ # * An artifact task or any other task. Returns the task as is.
309
+ # * A project. Returns all packaging tasks in that project.
310
+ # * An array of artifacts. Returns all the artifacts found there.
311
+ #
312
+ # This method handles arrays of artifacts as if they are flattend,
313
+ # to help in managing large combinations of artifacts. For example:
314
+ # xml = [ xerces, xalan, jaxp ]
315
+ # ws = [ axis, jax-ws, jaxb ]
316
+ # db = [ jpa, mysql, sqltools ]
317
+ # base = [ xml, ws, db ]
318
+ # artifacts(base, models, services)
319
+ #
320
+ # You can also pass tasks and project. This is particularly useful for
321
+ # dealing with dependencies between projects that are part of the same
322
+ # build.
323
+ #
324
+ # For example:
325
+ # artifacts(base, models, services, module1, module2)
326
+ #
327
+ # When passing a project as argument, it expands that project to all
328
+ # its packaging tasks. You can then use the resulting artifacts as
329
+ # dependencies that will force these packages to be build inside the
330
+ # project, without installing them in the local repository.
331
+ def artifacts(*specs)
332
+ specs.inject([]) do |set, spec|
333
+ case spec
334
+ when Hash
335
+ set |= [artifact(spec)]
336
+ when /:/
337
+ set |= [artifact(spec)]
338
+ when String
339
+ set |= [file(spec)]
340
+ when Project
341
+ set |= artifacts(spec.packages)
342
+ when Rake::Task
343
+ set |= [spec]
344
+ when Array
345
+ set |= artifacts(*spec)
346
+ else
347
+ fail "Invalid artifact specification: #{spec.to_s || 'nil'}"
348
+ end
349
+ set
350
+ end
351
+ end
352
+
353
+ # Convenience method for defining multiple artifacts that belong
354
+ # to the same version and group. Accepts multiple artifact identifiers
355
+ # (or arrays of) followed by two has keys:
356
+ # * :under -- The group identifier
357
+ # * :version -- The version number
358
+ #
359
+ # For example:
360
+ # group "xbean", "xbean_xpath", "xmlpublic", :under=>"xmlbeans", :version=>"2.1.0"
361
+ # Or:
362
+ # group %w{xbean xbean_xpath xmlpublic}, :under=>"xmlbeans", :version=>"2.1.0"
363
+ def group(*args)
364
+ hash = args.pop
365
+ args.flatten.map { |id| artifact :group=>hash[:under], :version=>hash[:version], :id=>id }
366
+ end
367
+
368
+ # Deploys all the specified artifacts/files. Specify the deployment
369
+ # server by passing a hash as the last argument, or have it use
370
+ # repositories.deploy_to.
371
+ #
372
+ # For example:
373
+ # deploy(*process.packages, :url=>"sftp://example.com/var/www/maven")
374
+ def deploy(*args)
375
+ # Where do we release to?
376
+ if Hash === args.last
377
+ options = args.pop
378
+ else
379
+ options = repositories.deploy_to
380
+ options = { :url=>options.to_s } unless Hash === options
381
+ end
382
+ url = options[:url]
383
+ options = options.reject { |k,v| k === :url }
384
+ fail "Don't know where to deploy, perhaps you forgot to set repositories.deploy_to" if url.blank?
385
+
386
+ args.each { |arg| arg.invoke if arg.respond_to?(:invoke) }
387
+ Transports.perform url, options do |session|
388
+ args.each do |artifact|
389
+ if artifact.respond_to?(:to_spec)
390
+ # Upload artifact relative to base URL, need to create path before uploading.
391
+ puts "Deploying #{artifact.to_spec}" if verbose
392
+ spec = artifact.to_spec_hash
393
+ path = spec[:group].gsub(".", "/") + "/#{spec[:id]}/#{spec[:version]}/"
394
+ session.mkpath path
395
+ session.upload artifact.to_s, path + Artifact.hash_to_file_name(spec)
396
+ else
397
+ # Upload artifact to URL.
398
+ puts "Deploying #{artifact}" if verbose
399
+ session.upload artifact, File.basename(artifact)
400
+ end
401
+ end
402
+ end
403
+ end
404
+
405
+ end