buildr-bnd 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 0.0.5 (September 8, 2010)
2
+ * Added: The bnd parameter "Include-Resource" defaults to project.resources.target if it exists.
3
+ * Added: The bnd.classpath setting was added.
4
+ * Changed: The extension no longer defaults the bnd parameters "Import-Package" and "Export-Package" to *
5
+ * Changed: Stop using absolute paths in requires.
6
+ * Changed: Renamed main.rb to core.rb.
7
+
1
8
  0.0.4 (July 5, 2010)
2
9
  * Changed: Separated code into separate files, moved project extension code into a separate module and moved
3
10
  the code into a hierarchy matching the module hierarchy.
data/README.rdoc CHANGED
@@ -48,15 +48,15 @@ repositories.remote << Buildr::Bnd.remote_repository
48
48
 
49
49
  The extension sets the following bnd parameters;
50
50
 
51
- * Bundle-Version defaults to the project version.
52
- * Bundle-SymbolicName defaults to the concaternation of the project group
51
+ * <tt>"Bundle-Version"</tt> defaults to the project version.
52
+ * <tt>"Bundle-SymbolicName"</tt> defaults to the concatenation of the project group
53
53
  and project id, replacing ':' characters with '.'.
54
- * Bundle-Name defaults to the project description if present else the project
54
+ * <tt>"Bundle-Name"</tt> defaults to the project description if present else the project
55
55
  name
56
- * Bundle-Description defaults to the project description.
57
- * Import-Package and Export-Package default to *
58
- * -classpath is set to the compile target directory and any compile time
56
+ * <tt>"Bundle-Description"</tt> defaults to the project description.
57
+ * <tt>"-classpath"</tt> is set to the compile target directory and any compile time
59
58
  dependencies.
59
+ * <tt>"Include-Resource"</tt> defaults to the dir project.resources.target if it exists.
60
60
 
61
61
  == Parameters
62
62
 
@@ -85,8 +85,48 @@ bnd.
85
85
  end
86
86
  end
87
87
 
88
+ === classpath
89
+
90
+ The user can specify the complete classpath using the 'classpath' method. The classpath
91
+ should be an array of elements. If the element is a task, artifact, artifact namespace etc.
92
+ then it will be resolved prior to invoking bnd.
93
+
94
+ define 'foo' do
95
+ ...
96
+ package(:bundle).tap do |bnd|
97
+ bnd.classpath [ project.compile.target,
98
+ 'someOtherExistingFile.zip',
99
+ artifact('com.sun.messaging.mq:imq:jar:4.4'),
100
+ project('bar'),
101
+ 'org.apache.ant:ant:jar:1.8.0',
102
+ file('myLocalFile.jar') ]
103
+ ...
104
+ end
105
+
106
+ project 'bar' do
107
+ ...
108
+ end
109
+ end
110
+
111
+
88
112
  == Examples
89
113
 
114
+ === Including non-class resources in a bundle
115
+
116
+ Bnd can be used to include non-class resources in a bundle. The following
117
+ example includes all resources in 'src/etc' into the bundle.
118
+
119
+ require 'buildr_bnd'
120
+
121
+ desc 'Including resources example'
122
+ define 'myproject' do
123
+ ...
124
+ package(:bundle).tap do |bnd|
125
+ bnd['Include-Resource'] = project._('src/etc') + '/'
126
+ ...
127
+ end
128
+ end
129
+
90
130
  === Using bnd to wrap an existing jar
91
131
 
92
132
  Bnd can be used to wrap an existing jar as an OSGi bundle. The following
@@ -143,12 +183,16 @@ parameter withy a local value.
143
183
  ...
144
184
  define 'fe' do
145
185
  ...
146
- package :bundle
186
+ package(:bundle).tap do |bnd|
187
+ ...
188
+ end
147
189
  end
148
190
 
149
191
  define 'fi' do
150
192
  ...
151
- package :bundle
193
+ package(:bundle).tap do |bnd|
194
+ ...
195
+ end
152
196
  end
153
197
 
154
198
  define 'fo' do
@@ -159,6 +203,27 @@ parameter withy a local value.
159
203
  end
160
204
  end
161
205
 
206
+ == Future Work
207
+
208
+ The following is a list of feature requests for future versions of the extension. Feel free to
209
+ jump in and supply a patch if you have gone ahead and implemented the feature.
210
+
211
+ === Support Embed-Dependency equivalent
212
+
213
+ The maven-bundle-plugin supports Embed-Dependency which can include a jar inside the bundle,
214
+ add manifest directives to include it in the export calculations. One "Embed-Dependency"
215
+ directive may turn into something like
216
+
217
+ -classpath=com.ibm.mq.jar
218
+ Include-Resource=com.ibm.mq.jar
219
+ Bundle-Classpath=.,com.ibm.mq.jar
220
+ Private-Package=!*
221
+ -exportcontents: com.ibm.mq.*
222
+
223
+ For further discussion on this see;
224
+ * http://www.mail-archive.com/users@felix.apache.org/msg06625.html
225
+ * http://www.mail-archive.com/users@felix.apache.org/msg06626.html
226
+
162
227
  == Credit
163
228
 
164
229
  The plugin was heavily inspired by the bnd tasks originally authored by Rhett Sutphin. It began
@@ -2,6 +2,7 @@ module Buildr
2
2
  module Bnd
3
3
  class BundleTask < Rake::FileTask
4
4
  attr_reader :project
5
+ attr_accessor :classpath
5
6
 
6
7
  def [](key)
7
8
  @params[key]
@@ -12,57 +13,46 @@ module Buildr
12
13
  end
13
14
 
14
15
  def classpath_element(dependencies)
15
- artifacts = self.class.to_artifacts([dependencies])
16
+ artifacts = Buildr.artifacts([dependencies])
16
17
  self.prerequisites << artifacts
17
18
  artifacts.each do |dependency|
18
- @classpath << dependency.to_s
19
+ self.classpath << dependency.to_s
19
20
  end
20
21
  end
21
22
 
22
23
  def to_params
23
- params = project.manifest.merge(@params).reject { |k, v| v.nil? }
24
- params["-classpath"] ||= @classpath.collect(&:to_s).join(", ")
25
- params['Bundle-SymbolicName'] ||= [project.group, project.name.gsub(':', '.')].join('.')
26
- params['Bundle-Name'] ||= project.comment || project.name
27
- params['Bundle-Description'] ||= project.comment
28
- params['Bundle-Version'] ||= project.version
29
- params['Import-Package'] ||= '*'
30
- params['Export-Package'] ||= '*'
31
-
24
+ params = self.project.manifest.merge(@params).reject { |k, v| v.nil? }
25
+ params["-classpath"] ||= self.classpath.collect(&:to_s).join(", ")
26
+ params['Bundle-SymbolicName'] ||= [self.project.group, self.project.name.gsub(':', '.')].join('.')
27
+ params['Bundle-Name'] ||= self.project.comment || self.project.name
28
+ params['Bundle-Description'] ||= self.project.comment
29
+ params['Bundle-Version'] ||= self.project.version
30
+ if params["Include-Resource"].nil? && !project.resources.target.nil?
31
+ params["Include-Resource"] = "#{project.resources.target}/"
32
+ end
33
+
32
34
  params
33
35
  end
34
36
 
35
37
  def project=(project)
36
38
  @project = project
37
- @classpath = [project.compile.target] + project.compile.dependencies
38
39
  end
39
40
 
40
- protected
41
-
42
- # Convert objects to artifacts, where applicable
43
- def self.to_artifacts(files)
44
- files.flatten.inject([]) do |set, file|
45
- case file
46
- when ArtifactNamespace
47
- set |= file.artifacts
48
- when Symbol, Hash
49
- set |= [Buildr.artifact(file)]
50
- when /([^:]+:){2,4}/ # A spec as opposed to a file name.
51
- set |= [Buildr.artifact(file)]
52
- when Project
53
- set |= Buildr.artifacts(file.packages)
54
- when Rake::Task
55
- set |= [file]
56
- when Struct
57
- set |= Buildr.artifacts(file.values)
58
- else
59
- # non-artifacts passed as-is; in particular, String paths are
60
- # unmodified since Rake FileTasks don't use absolute paths
61
- set |= [file]
62
- end
41
+ def classpath=(classpath)
42
+ @classpath = []
43
+ Buildr.artifacts([classpath.flatten.compact]).each do |dependency|
44
+ self.prerequisites << dependency
45
+ @classpath << dependency.to_s
63
46
  end
47
+ @classpath
48
+ end
49
+
50
+ def classpath
51
+ @classpath ||= ([project.compile.target] + project.compile.dependencies).flatten.compact
64
52
  end
65
53
 
54
+ protected
55
+
66
56
  def initialize(*args) #:nodoc:
67
57
  super
68
58
  @params = {}
File without changes
@@ -3,7 +3,7 @@ module Buildr
3
3
  class Version
4
4
  MAJOR = "0"
5
5
  MINOR = "0"
6
- MICRO = "4"
6
+ MICRO = "5"
7
7
 
8
8
  STRING = "#{MAJOR}.#{MINOR}.#{MICRO}"
9
9
  end
data/lib/buildr_bnd.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/buildr/bnd/version')
2
- require File.expand_path(File.dirname(__FILE__) + '/buildr/bnd/main')
3
- require File.expand_path(File.dirname(__FILE__) + '/buildr/bnd/bundle_task')
4
- require File.expand_path(File.dirname(__FILE__) + '/buildr/bnd/project_extension')
1
+ require 'buildr/bnd/version'
2
+ require 'buildr/bnd/core'
3
+ require 'buildr/bnd/bundle_task'
4
+ require 'buildr/bnd/project_extension'
@@ -20,6 +20,9 @@ describe "package :bundle" do
20
20
  write "src/main/java/com/biz/Foo.java", <<SRC
21
21
  package com.biz;
22
22
  public class Foo {}
23
+ SRC
24
+ write "src/main/resources/IRIS-INF/iris.config", <<SRC
25
+ some=setting
23
26
  SRC
24
27
  write "bar/src/main/java/com/biz/bar/Bar.java", <<SRC
25
28
  package com.biz.bar;
@@ -30,12 +33,15 @@ SRC
30
33
  project.group = "mygroup"
31
34
  manifest["Magic-Food"] = "Chocolate"
32
35
  manifest["Magic-Drink"] = "Wine"
33
- package :bundle
36
+ package(:bundle).tap do |bnd|
37
+ bnd["Export-Package"] = "com.*"
38
+ end
34
39
 
35
40
  define "bar" do
36
41
  project.version = "2.2"
37
42
  package(:bundle).tap do |bnd|
38
43
  bnd["Magic-Food"] = "Cheese"
44
+ bnd["Export-Package"] = "com.*"
39
45
  end
40
46
  end
41
47
  end
@@ -56,6 +62,12 @@ SRC
56
62
  end
57
63
  end
58
64
 
65
+ it "produces a .jar containing resoruces from resource directory root project" do
66
+ open_zip_file do |zip|
67
+ zip.file.exist?('IRIS-INF/iris.config').should be_true
68
+ end
69
+ end
70
+
59
71
  it "produces a .jar containing expected manifest entries derived from project.bnd for root project" do
60
72
  open_main_manifest_section do |attribs|
61
73
  attribs['Bundle-Name'].should eql('foo')
@@ -111,7 +123,9 @@ SRC
111
123
  @foo = define "foo" do
112
124
  project.version = "2.1.3"
113
125
  project.group = "mygroup"
114
- package :bundle
126
+ package(:bundle).tap do |bnd|
127
+ bnd["Export-Package"] = "*"
128
+ end
115
129
  end
116
130
  end
117
131
 
@@ -151,6 +165,38 @@ SRC
151
165
  end
152
166
  end
153
167
 
168
+ describe "using classpath to specify dependencies" do
169
+ before do
170
+ write "src/main/java/com/biz/Foo.java", <<SRC
171
+ package com.biz;
172
+ public class Foo {}
173
+ SRC
174
+ write "bar/src/main/java/com/biz/bar/Bar.java", <<SRC
175
+ package com.biz.bar;
176
+ public class Bar {}
177
+ SRC
178
+ @foo = define "foo" do
179
+ project.version = "2.1.3"
180
+ project.group = "mygroup"
181
+ package(:bundle).tap do |bnd|
182
+ bnd['Export-Package'] = 'org.apache.tools.zip.*'
183
+ bnd.classpath = bnd.classpath + Buildr::Ant.dependencies
184
+ end
185
+ end
186
+ end
187
+
188
+ it "should not raise an error during packaging" do
189
+ lambda { task('package').invoke }.should_not raise_error
190
+ end
191
+
192
+ it "should generate package with files exported from dependency" do
193
+ task('package').invoke
194
+ open_main_manifest_section do |attribs|
195
+ attribs['Export-Package'].should eql('org.apache.tools.zip')
196
+ end
197
+ end
198
+ end
199
+
154
200
  describe "using compile dependencies to specify dependency" do
155
201
  before do
156
202
  @foo = define "foo" do
@@ -3,10 +3,20 @@ require File.expand_path('../../../spec_helper', __FILE__)
3
3
  describe "project.bnd defaults" do
4
4
 
5
5
  before do
6
+ write "src/main/java/com/biz/Foo.java", <<SRC
7
+ package com.biz;
8
+ public class Foo {}
9
+ SRC
10
+ write "bar/src/main/java/com/biz/bar/Bar.java", <<SRC
11
+ package com.biz.bar;
12
+ public class Bar {}
13
+ SRC
14
+
6
15
  @foo = define "foo" do
7
16
  project.version = "2.1.3"
8
17
  project.group = "mygroup"
9
18
  package :bundle
19
+ compile.with Buildr::Ant.dependencies
10
20
  desc "My Bar Project"
11
21
  define "bar" do
12
22
  package :bundle
@@ -20,19 +30,33 @@ describe "project.bnd defaults" do
20
30
  @bar.packages[0].to_params['Bundle-Version'].should eql('2.1.3')
21
31
  end
22
32
 
33
+ it "defaults -classpath to compile path and dependencies" do
34
+ @foo.packages[0].to_params['-classpath'].should include(@foo.compile.target.to_s)
35
+ @foo.packages[0].to_params['-classpath'].should include(Buildr.artifacts(Buildr::Ant.dependencies[0]).to_s)
36
+ @bar.packages[0].to_params['-classpath'].should include(@bar.compile.target.to_s)
37
+ end
38
+
39
+ it "classpath method returns compile path and dependencies" do
40
+ @foo.packages[0].classpath.should include(@foo.compile.target)
41
+ Buildr::Ant.dependencies.each do |dependency|
42
+ @foo.packages[0].classpath.to_s.should include(Buildr.artifacts(dependency).to_s)
43
+ end
44
+ @bar.packages[0].classpath.should include(@bar.compile.target)
45
+ end
46
+
23
47
  it "defaults Bundle-SymbolicName to combination of group and name" do
24
48
  @foo.packages[0].to_params['Bundle-SymbolicName'].should eql('mygroup.foo')
25
49
  @bar.packages[0].to_params['Bundle-SymbolicName'].should eql('mygroup.foo.bar')
26
50
  end
27
51
 
28
- it "defaults Export-Package to *" do
29
- @foo.packages[0].to_params['Export-Package'].should eql('*')
30
- @bar.packages[0].to_params['Export-Package'].should eql('*')
52
+ it "defaults Export-Package to nil" do
53
+ @foo.packages[0].to_params['Export-Package'].should be_nil
54
+ @bar.packages[0].to_params['Export-Package'].should be_nil
31
55
  end
32
56
 
33
- it "defaults Import-Package to *" do
34
- @foo.packages[0].to_params['Import-Package'].should eql('*')
35
- @bar.packages[0].to_params['Import-Package'].should eql('*')
57
+ it "defaults Import-Package to nil" do
58
+ @foo.packages[0].to_params['Import-Package'].should be_nil
59
+ @bar.packages[0].to_params['Import-Package'].should be_nil
36
60
  end
37
61
 
38
62
  it "defaults Bundle-Name to project.name if comment not present" do
data/spec/spec_helper.rb CHANGED
@@ -1,60 +1,32 @@
1
1
  require 'spec'
2
2
 
3
3
  DEFAULT_BUILDR_DIR=File.expand_path(File.dirname(__FILE__) + '/../../buildr')
4
- BUILDR_DIR=ENV['BUILDR_DIR'] || DEFAULT_BUILDR_DIR
4
+ BUILDR_DIR =
5
+ begin
6
+ if ENV['BUILDR_DIR']
7
+ ENV['BUILDR_DIR']
8
+ elsif File.exist?(File.expand_path('../buildr_dir', __FILE__))
9
+ File.read(File.expand_path('../buildr_dir', __FILE__)).strip
10
+ else
11
+ DEFAULT_BUILDR_DIR
12
+ end
13
+ end
5
14
 
6
15
  unless File.exist?("#{BUILDR_DIR}/buildr.gemspec")
7
- raise "Unable to find buildr.gemspec in #{BUILDR_DIR == DEFAULT_BUILDR_DIR ? 'guessed' : 'specified'} $BUILD_DIR (#{BUILDR_DIR})"
16
+ raise "Unable to find buildr.gemspec in #{BUILDR_DIR == DEFAULT_BUILDR_DIR ? 'guessed' : 'specified'} $BUILDR_DIR (#{BUILDR_DIR})"
8
17
  end
9
18
 
10
- require 'rubygems'
11
-
12
- # For testing we use the gem requirements specified on the buildr.gemspec
13
- Gem::Specification.load(File.expand_path("#{BUILDR_DIR}/buildr.gemspec", File.dirname(__FILE__))).
14
- dependencies.each { |dep| gem dep.name, dep.requirement.to_s }
15
-
16
19
  # hook into buildr's spec_helpers load process
17
- unless defined?(SpecHelpers)
18
- module SandboxHook
19
- def SandboxHook.included(spec_helpers)
20
- $LOAD_PATH.unshift(File.dirname(__FILE__))
21
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
22
- require 'buildr_bnd'
23
- end
20
+ module SandboxHook
21
+ def SandboxHook.included(spec_helpers)
22
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
23
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
24
+ require 'buildr_bnd'
24
25
  end
26
+ end
25
27
 
26
- require "#{BUILDR_DIR}/spec/spec_helpers.rb"
27
-
28
- # Download deps into real local dir
29
- Buildr::repositories.remote << Buildr::Bnd.remote_repository
30
- Buildr::Bnd.requires.each { |spec| artifact(spec).invoke }
31
-
32
- # Adjust specs so that they do not attempt to constantly download helper artifacts
33
- module BuildrBndSpecHelpers
34
-
35
- HELPERS_REPOSITORY = "file://#{Buildr::repositories.local}"
36
- LOCAL_TEST_REPOSITORY = File.expand_path File.join(File.dirname(__FILE__), "..", "tmp", "test_m2_repository")
37
-
38
- class << self
39
-
40
- def included(config)
41
- config.before(:each) do
42
- repositories.remote << "file://#{HELPERS_REPOSITORY}"
43
- end
44
- config.after(:all) do
45
- FileUtils.rm_rf LOCAL_TEST_REPOSITORY
46
- end
47
- end
48
- end
49
-
50
- def createRepository(name)
51
- repo = File.join(LOCAL_TEST_REPOSITORY, name)
52
- mkpath repo
53
- return repo
54
- end
55
- end
28
+ require "#{BUILDR_DIR}/spec/spec_helpers.rb"
56
29
 
57
- Spec::Runner.configure do |config|
58
- config.include BuildrBndSpecHelpers
59
- end
60
- end
30
+ # Download deps into real local dir
31
+ Buildr::repositories.remote << Buildr::Bnd.remote_repository
32
+ Buildr::Bnd.requires.each { |spec| artifact(spec).invoke }
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Peter Donald
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-05 00:00:00 +10:00
17
+ date: 2010-09-08 00:00:00 +10:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -34,15 +34,14 @@ extra_rdoc_files:
34
34
  files:
35
35
  - lib/buildr_bnd.rb
36
36
  - lib/buildr/bnd/version.rb
37
- - lib/buildr/bnd/main.rb
38
37
  - lib/buildr/bnd/bundle_task.rb
39
38
  - lib/buildr/bnd/project_extension.rb
39
+ - lib/buildr/bnd/core.rb
40
40
  - spec/spec_helper.rb
41
41
  - spec/spec.opts
42
42
  - spec/buildr/bnd/project_extension_spec.rb
43
43
  - spec/buildr/bnd/bundle_package_spec.rb
44
44
  - spec/buildr/bnd/defaults_spec.rb
45
- - spec/buildr/bnd/to_artifacts_spec.rb
46
45
  - buildr-bnd.gemspec
47
46
  - LICENSE
48
47
  - README.rdoc
@@ -55,12 +54,13 @@ licenses: []
55
54
  post_install_message:
56
55
  rdoc_options:
57
56
  - --title
58
- - buildr-bnd 0.0.4
57
+ - buildr-bnd 0.0.5
59
58
  - --main
60
59
  - README.rdoc
61
60
  require_paths:
62
61
  - lib
63
62
  required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
@@ -68,6 +68,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
68
  - 0
69
69
  version: "0"
70
70
  required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
71
72
  requirements:
72
73
  - - ">="
73
74
  - !ruby/object:Gem::Version
@@ -77,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
78
  requirements: []
78
79
 
79
80
  rubyforge_project:
80
- rubygems_version: 1.3.6
81
+ rubygems_version: 1.3.7
81
82
  signing_key:
82
83
  specification_version: 3
83
84
  summary: Buildr extension for packaging OSGi bundles using bnd
@@ -1,52 +0,0 @@
1
- require File.expand_path('../../../spec_helper', __FILE__)
2
-
3
- DEPENDENCY_NAME = 'group:id:jar:1.0'
4
-
5
- describe "Buildr:Bnd:BundleTask.to_artifacts" do
6
- before do
7
- @artifact = artifact(DEPENDENCY_NAME) { |t| write t.to_s }
8
- @foo = define "foo" do
9
- project.version = "1.1"
10
- compile.with DEPENDENCY_NAME
11
- package :zip
12
- end
13
-
14
- @bar = define "bar" do
15
- project.version = "1.1"
16
- compile.with DEPENDENCY_NAME
17
- package :zip
18
- package :jar
19
- end
20
- end
21
-
22
- it "flattens nested arrays" do
23
- to_artifacts([["foo"]]).should eql(['foo'])
24
- end
25
-
26
- it "turns projects into tasks to build projects" do
27
- artifacts = to_artifacts([@foo])
28
- artifacts.length.should eql(1)
29
- artifacts[0].should be_a_kind_of(Rake::Task)
30
- artifacts[0].to_s.should match(/foo-1\.1\.zip/)
31
-
32
- artifacts = to_artifacts([@bar])
33
- artifacts.length.should eql(2)
34
- artifacts.each do |artifact|
35
- artifact.should be_a_kind_of(Rake::Task)
36
- artifact.to_s.should match(/bar-1\.1\.(zip|jar)/)
37
- end
38
- end
39
-
40
- it "converts hashes into artifacts" do
41
- artifacts = to_artifacts([{:group => 'group', :id => 'id', :version => '1.0', :type => 'jar'}])
42
- artifacts.length.should eql(1)
43
- artifacts[0].should be_a_kind_of(Rake::Task)
44
- artifacts[0].to_s.should match(/group\/id\/1.0\/id-1\.0\.jar/)
45
- end
46
-
47
- protected
48
-
49
- def to_artifacts(args)
50
- Buildr::Bnd::BundleTask.to_artifacts(args)
51
- end
52
- end