<!--
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.
-->

<project>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-rar-plugin</artifactId>
		<configuration>
		  <rarSourceDirectory>${basedir}/src/test/resources/unit/basic-rar-with-manifest/src/main/rar</rarSourceDirectory>
		  <raXmlFile>${basedir}/src/test/resources/unit/basic-rar-with-manifest/src/main/rar/META-INF/ra.xml</raXmlFile>
		  <includeJar>false</includeJar>
		  <manifestFile>${basedir}/src/test/resources/unit/basic-rar-with-manifest/src/main/rar/META-INF/MANIFEST.MF</manifestFile>
		  <workDirectory>${basedir}/target/unit/basic-rar-with-manifest/target/rar-test-with-manifest</workDirectory>
		  <outputDirectory>${basedir}/target/unit/basic-rar-with-manifest/target</outputDirectory>
		  <finalName>test-rar-with-manifest</finalName>
		  <project implementation="org.apache.maven.plugin.rar.stubs.RarMavenProjectStub3" />
		</configuration>
      </plugin>
    </plugins>
  </build>
</project>
