Dep

Dep is a Dependency Management Tool; its primary job is using SCM (eg. git) to record and keep the dependencies between different repositories up-to-date.

Note that as the software is currently (January 2015) under development the software and document may not match in functionality.

Background

The Purpose of Dep

Dep automates retrieving the right dependencies at the right version in a predictable, portable, automatable and sensible fashion:

Supported Source Code Revision Systems

Currently:

Proposed:

By Example

Let’s show how to use Dep with an example. Here we will use Git as a source code revision system, but eventually it will be possible to mix Git, Mercurial, Subversion, Perforce or any other supported system in any way; each dependency can be in a different source code revision system.

Our “project” will have a “main” component, which depends on a “helper” component.

Initialise

Let’s assume that the “main” component already exists and has an associated Git repository. First we need initialise the use of Dep style dependencies in a “main” component:

$ cd .../project/main
$ dep init
Writg Config ".../project/main/.depconfig"

This will create a default .depconfig in the current directory such that dependent components can be added. Also Dep will automatically call git add .depconfig to register the newly added .depconfig file with Git.

A dependent component need not have a .depconfig file, in which case it is a “leaf” component (it is assumed that it does not depend on anything else, unless that is completely automated by the component itself).

The .depconfig should be eventually be committed to the “main” component source repository, perhaps with other changes. In this example we use Git:

$ git commit -m "Added dependency information."

Add A Dependency

Add a Dep managed dependency on a “helper” component stored in Git:

$ dep add http://example.com/cool-components/helper.git
Downloading GitRepository '.../project/main/dep/helper.git'
    from 'http://example.com/cool-components/helper.git'
Cloning into '.../project/main/dep/helper'...
done.
Checkout GitRepository '.../project/main/dep/helper/.git'
    in '.../project/main/dep/helper'
Your branch is up-to-date with 'origin/master'.
Recording GitRepository '.../project/main/dep/helper/.git'
    at commit 'f2a356f08f536dd91e64996bbf9ac2f4ec6edc4b'
    on branch 'refs/heads/master'
Writing Config '.../project/main/.depconfig'

By default the dependency source code system and name is determined from the URL.

By default the dependency is downloaded from the source code system at the latest revision on the default branch, and stored under the dep directory in a sub-directory of the same name as the component, in this example dep/helper.

The dependency is added to the .depconfig file at this particular revision, and is automatically added to Git using git add .depconfig.

With Git the .gitingore file is modified to include the new dependency directory dep/helper such that it is ignored in the main repository; the component itself has it’s own Git repository. This change is also automatically added using git add .gitignore.

These two files should be committed to “main” source repository, in this example using Git:

$ git commit -m "Added helper component."

Changing Dependency Version

Changing the revision or version of “component” is typically a four step process:

In this example we’ll change to a specific tagged version using Git:

$ cd .../project/main/dep/helper
$ git checkout v1.0.0
$ cd ../..
$ make build test
...
$ dep record
Recording GitRepository '.../project/main/dep/helper'
    at commit '16a2b4e8b7c66f16cf25b74f9740a582f6a25f95'
    on branch 'refs/heads/master'
Writing Config '.../project/main/.depconfig'
$ git commit -m 'Changed helper to v1.0.0'

Ensure Dependencies Are Present

When the primary component is first cloned, sync’d or retrieved from it’s source code revision system, the dependencies will not be present. To ensure they are present and correct use dep refresh:

$ cd .../project
$ git clone http://example.com/cool-components/main.git
Cloning into 'main'...
done.
$ cd main
$ dep refresh
Downloading GitRepository '.../project/main/dep/helper/.git'
    from 'http://example.com/cool-components/helper.git'
Cloning into '.../project/main/dep/helper'...
done.
Checkout GitRepository '.../project/main/dep/helper/.git'
    on branch 'refs/heads/master'
    at commit '16a2b4e8b7c66f16cf25b74f9740a582f6a25f95'
    in '.../project/main/dep/helper'

Checking The Status of Dependencies

Since a project consists of many components with many different source revisions Dep provides a way to briefly show the status of all dependencies and their repositories:

$ cd .../project
$ dep status
M  Branch           Commit                                    Ahead Behind Path
-- ---------------  ---------------------------------------- ------ ------ -----------------------
   master           7e67b94b71edffc569045c2fe67d67fea1413603      0      0 .
   master           16a2b4e8b7c66f16cf25b74f9740a582f6a25f95      0      0 dep/helper

Listing All Components

List all the components using dep list.

The default is to list only the names of all components, including the root. The list includes both implicit and explicit, as if the DAG was visited in a unique depth first ordering; that is all dependencies from the deepest up to the root component in the order that each would need building:

$ dep list
helper
main

There are various aliases and options that can change what is listed. For example; list all the components as absolute path names:

$ dep list --path
.../project/main/dep/helper
.../project/main

Run A Command For All Components

You can run a shell command for each component using dep foreach. This runs a command on all dependencies in the unique depth-first ordering.

For example the following would run git push in each component including the root:

$ dep foreach git push
##================================================================================
-> pushd .../project/main/dep/helper:
-> git push
Counting objects: 79, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (79/79), done.
Writing objects: 100% (79/79), 8.53 KiB | 0 bytes/s, done.
Total 79 (delta 45), reused 0 (delta 0)
To http://example.com/cool-components/helper.git
   9f23f65..123f788  master -> master
-> popd
##================================================================================
-> pushd .../project/main
-> git push
Counting objects: 79, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (79/79), done.
Writing objects: 100% (79/79), 8.53 KiB | 0 bytes/s, done.
Total 79 (delta 45), reused 0 (delta 0)
To http://example.com/cool-components/main.git
   8e73fdd..103e878  master -> master
-> popd

This would run “pwd” on all components:

$ dep -q foreach pwd
.../project/main/dep/helper
.../project/main

The command may also include variables which are expanded for each repository. These names always start with a ‘%’ symbol and include:

$ dep -q foreach echo Name: %name Path: %path VCS: %vcs
Name: helper Path: .../project/main/dep/helper VCS: git
Name: main Path: .../project/main VCS: git

Helpers And Shortcuts

There are some often used commands which have short-cuts:

Further Reading

comments powered by Disqus