//
// Licensed 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.
//

=== Repository

A Cave repository is a container for:

* Artifacts (files)
* Repository metadata

By default, a repository uses a filesystem backend for the storage, the directory used is KARAF_BASE/cave.

You can change the storage location in the 'etc/org.apache.karaf.cave.server.storage.cfg' configuration file:

----
################################################################################
#
#    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.
#
################################################################################

#
# Storage location where Apache Karaf Cave create repositories by default
#
cave.storage.location=cave
----

For instance, you can define `/var/cave/store` for the `storage.location` property.

==== Create

The `cave:repository-create` command creates a new repository:

----
karaf@root()> cave:repository-create my-repository
----

A repository is identified by a name, `my-repository` in our example.

Apache Karaf Cave creates the repository storage for you.

If you want to use an existing directory, and avoid Cave to create one in the storage location, you can use the `-l`
('--location') option:

----
karaf@root()> cave:repository-create -l /home/user/.m2/repository m2
----

By default, Apache Karaf Cave scans the repository storage and create the repository metadata. You can use the `-no` (`--no-generate`)
option to avoid this step:

----
karaf@root()> cave:repository-create -no -l /home/user/.m2/repository m2
----

By default, Apache Karaf Cave registers (installs) a new repository into the repository service. You can use the `-ns` (`--no-start`)
option to avoid this step:

----
karaf@root()> cave:repository-create -ns -l /home/user/m2/repository m2
----

[NOTE]
====
The `-no` and `-ni` options are interesting when you use an existing location for the repository. If you create a
new empty repository, these options don't have really any effect.
====

==== List

You can list the repositories:

----
karaf@root()> cave:repositories
Name          | Location
----------------------------------------------------------------
my-repository | /opt/apache-karaf-4.0.0/data/cave/my-repository
----

