# Dependency Management

> Share or distribute your Taxi projects amongst other teams or the community

Source: https://taxilang.org/docs/packages/publishing

Once built, Taxi projects can be packaged and published to a repository to allow other projects to depend on them.

## Adding dependencies

Dependencies are defined in the `taxi.conf` project, in the `dependencies` section.
Here's an example:

```json5
// Create a project in the acme organisation named "depends-on-sample"
name: acme/depends-on-sample
version: 0.3.0
sourceRoot: src/

dependencies: {
    // Depends on a project in the "acme" organisation called "sample", version 0.3.0
   "org.acme/sample": 0.3.0

    // Fetch from a github repository, at a specific branch / tag
    "com.orbitalhq/core" : "github:orbitalapi/orbital-core-taxi#0.34.0"
   
    // Fetch from a gitlab repository (at https://gitlab.com) on the default branch
    "org.test/dependencyA" : "gitlab:taxi-lang/test-project-a"

   // Depends on a project from git
   "org.acme/another-project" : "https://someGitProvider.com/taxi-lang/another-project.git"

   // Depends on a project from git, at a specific branch / tag
   "org.acme/project-3" : "https://someGitProvider.com/taxi-lang/project-3.git#1.2.0"
}
```

When running a `taxi build` command, the taxi-cli will first ensure that all dependent projects have been downloaded, and
are present in the local cache.

Dependencies are either fetched from git, or from a specified artifact registry (like Nexus) you to specify the repository to download it from:

For more details on how to define dependencies, and configure repositories to download them from, see [here](https://taxilang.org/language-reference/taxi-projects/#the-taxiconf-file).

> **Note**
>
> If you're editing your `taxi.conf` file in VSCode using our plugin, saving changes to your `taxi.conf` will trigger the download of any dependencies as soon as you save the file.

## Sharing projects using Git
To avoid the need for a [nexus](#sharing-projects-with-nexus) server, you can pull projects directly from a git repository.

Declare them as follows:

```json5
// Create a project in the acme organisation named "depends-on-sample"
name: acme/depends-on-sample
version: 0.3.0
sourceRoot: src/

dependencies: {
   // Depends on a project from git
   "org.acme/another-project" : "https://gitlab.com/taxi-lang/another-project.git"

   // Depends on a project from git, at a specific branch / tag
   "org.acme/project-3" : "https://gitlab.com/taxi-lang/project-3.git#1.2.0"
}
```

If working exclusively with git repos, you don't need to declare a `repositories` section.

### Github / Gitlab shorthand
To use dependencies from github.com or gitlab.com, you can use the format `github:org/project` (or `github:org/project#tag`)

For example:

```hocon
dependencies: {
    // Fetch from a github repository, at a specific branch / tag
    "com.orbitalhq/core" : "github:orbitalapi/orbital-core-taxi#0.34.0"
   
    // Fetch from a gitlab repository (at https://gitlab.com) on the default branch
    "org.test/dependencyA" : "gitlab:taxi-lang/test-project-a"
}
```

### Authenticating to Git repos
To provide authentication credentials, use a Username + Personal Authentication Token (supported in Github and Gitlab).

For example:

```hocon
dependencies: {
    "com.orbitalhq/core" : "https://alexhamilton:glpat-dundadadadundundun@github.com/taxi-conf/reynolds-pamphlet.git"
}
```

HOCON supports env variable substitution, so you can also move sensitive credentials into an env variable:

```hocon
dependencies: {
    // Note the variable is outside of quotes.
    "com.orbitalhq/core" : "https://"${GH_PAT}"@github.com/taxi-conf/reynolds-pamphlet.git"
}
```

However, be careful of gotcha's with variable substitution in HOCON - see more information in [this issue](https://github.com/lightbend/config/issues/633) in the HOCON library

## Sharing projects with Nexus
Currently, [Sonatype Nexus](https://www.sonatype.com/nexus/repository-oss) is the only non-git supported repository.

This guide does not cover the basics of installing and getting Nexus running, and assumes you've already got a Nexus instance running somewhere.
However, for a quick getting started, you can always use the [Nexus Docker image](https://hub.docker.com/r/sonatype/nexus3), as follows:

```bash
$ mkdir /some/dir/nexus-data && chown -R 200 /some/dir/nexus-data
$ docker run -d -p 8081:8081 --name nexus -v /some/dir/nexus-data:/nexus-data sonatype/nexus3
```

This will give you a local running nexus at `https://localhost:8081`.

### Creating a Taxi repository
In Nexus, Taxi repositories are defined as Raw repositories.

 * Log in to Nexus with admin credentials, and create a new repository.  From the list of repository types, select "raw (hosted)"
 * Give the repository a name.  This is the name that will be used in your repository config section in your taxi.conf file.
 * Configure the rest of the repository settings, including redeployment policies and blob store
 * Click "Create Repository"

#### Updating your taxi.conf file to publish
In the taxi.conf file of the project you wish to publish to your new repository, add the following:

```json5
publishToRepository: {
   // This name is used to look up credentials for auth
   name: "my-corporate-nexus"
   // The base url of the nexus
   url: "http://localhost:8081/"
   settings: {
      // The name you assigned to your repository when creating it in nexus
      repositoryName: taxi-on-nexus
   }
}
```

If necessary, also add credentials - either in your projects `taxi.conf` file (not recommended), or on your system's
taxi.conf at `~/.taxi/taxi.conf`:

```
credentials: [
   {repositoryName: "my-corporate-nexus", username: "jimmy", password: "pass123"}
]
```

### Configuring remote Nexus repositories
Orbital will check any remote repositories declared when trying to resolve dependencies.

Configure these repositories in your `taxi.conf` file:

```json5
repositories: [
   {
      // The name of the repository.  Optional, but used to reference credentials
      name: "my-corporate-nexus",
      url: "http://localhost:8081",
      // Optional.  Defines the type of repository being used.  Currently only 'nexus' is supported,
      // so this can be omitted.
      type : "nexus",

      // Settings specific to the repository provider.
      // Below settings shown are applicable to a nexus repository
      settings: {
         // The name of the repository as defined within nexus
         repositoryName : taxi
      }
   }
]
```

### Publishing Taxi projects

> **Tip**
>
> This section doesn't apply to projects with git urls, as projects are "published" as soon as they're pushed to the relevant Git repo / tag.

Projects are published by running the `taxi publish` command, from within the same directory that contains your `taxi.conf` file.

You must first configure a publishToRepository in your `taxi.conf` file:

```json5
publishToRepository: {
   url: "http://localhost:8081/"
   name : "nexus"
   settings: {
      repositoryName : taxi
   }
}
```

Credentials can be stored elsewhere, following the rules for `taxi.conf` merging, as discussed [here](https://taxilang.org/language-reference/taxi-projects/#the-taxiconf-file).

Having configured a repository to publish to, running `taxi publish` from the directory with your `taxi.conf` file will trigger the deployment:

Here's a sample output:

```bash
$  taxi publish
Taxi version @22a6a51
Adding file /sample-project/taxi.conf
Adding file /sample-project/src/Test-enum.taxi
Adding file /sample-project/src/sub-src/Test-C.taxi
Adding file /sample-project/src/Test-D.taxi
Adding file /sample-project/src/Test-B.taxi
Adding file /sample-project/src/Test-A.taxi
Publishing package taxi/sample/0.3.0 from /tmp/sample-0.3.0.zip to http://localhost:8081/
Will attempt to publish to http://localhost:8081//repository/taxi/taxi/sample/0.3.0/sample-0.3.0.zip using basic auth credentials supplied
Artifact uploaded successfully

```
