Configuring the Unison Codebase Manager

This document details how to create a.unisonConfigfile to store Unison Codebase Manager (UCM) configuration, as well as what UCM looks for in that file.

Where does Unison look for configuration?

When starting up, the Codebase Manager looks for a file named.unisonConfigin the same directory as your codebase. For example, if your codebase lives at~/.unison(which is the default codebase location), UCM will expect the configuration file to be~/.unisonConfig.

UCM loads the configuration on startup, but also watches the file for changes. If you edit the file and save it, UCM will reload the.unisonConfigfile and continue with the new configuration.

What is the configuration file format?

The.unisonConfigfile uses theData.Configuratorfile format.This is a temporary solution, and it's highly likely that the format will change in a future version of Unison.

What follows is an example configuration file. We'll explain the details of what this means below. Note that this is just an example and the values shown here will not actually work. (Though your file's basic structure will look similar to this if you are following therecommendations on how to organize your Unison namespace.)

Currently You can host Unison code either using traditional Git repos, or by using Unison share.

# I version my full namespace tree here, it's a snapshot
# of all my current workstreams. If I need to switch
# computers, I might just push here, then pull on the
# other computer.
# ''.> push'' will go here.
GitUrl = "git(git@github.com:myuser/allmycode)"

GitUrl {

  # Some projects I occasionally make PRs against.
  # Example: from UCM, ''._base> pull'' will get latest trunk

  _base = "unison.public.base.main"
  _distributed = "unison.public.distributed.main"

  # I help maintain these projects, so I track the full tree.
  # This makes it easy to create, review and merge pull requests.
  # Example: from UCM, ''._json> pull'' will get latest full dev tree

  _json = "git(git@github.com:myuser/json.git)"  # '.git' is optional!
  _httpclient = "git(git@github.com:myorg/unison-httpclient)"
  _project1 = "git(git@github.com:myorg/coolproject)"

  # This is just a "sandbox" namespace I sometimes use for
  # quickly iterating on code in progress. I don't keep it organized at all!
  # Example: from UCM, ''.sandbox> push'' will push here

  sandbox = "git(git@github.com:myuser/allMycode).sandbox"

  # Another example with a nested namespace

  ns3.example.foo = "git(git@github.com:someorganization/thing)"
}

# Attach myself as author and use BSD license.
DefaultMetadata = [ "._project1._trunk.metadata.authors.myself"
                  , "._project1._trunk.metadata.licenses.myself_bsd3_2020" ]

# If I needed to pick a different license for a sub-namespace
# I'd remove license from the root and add a license here instead
# DefaultMetadata {
#  _project1 = ["._project1._trunk.metadata.licenses.myself_bsd3_2020"]
#  org.example.foo = ["._project1._trunk.metadata.licenses.myself_apache2_2020"]
# }

Your file will look similar to this if you are following therecommendations on how to organize your Unison namespace.

Configuring a default push/pull URL for a namespace

When working on a project in Unison, you'll often want topushyour work to a shared repository andpullcode from the repository into your codebase. To do so, you can use UCM'spushandpull.These commands take aGit URLor Unison share namespace path and will push to and pull from Git, respectively. Since the URL you'll want to push to or pull from generally remains constant for a given Unison namespace, the.unisonConfigfile allows you to set aGitUrlper namespace.

For example, while you can always supply an explicit argument topull,like so:

._project1> pull git(git@github.com:myorg/coolproject)

… to avoid having to type or paste the URL every time, you could instead add the following to your.unisonConfig:

GitUrl._project1 = "git(git@github.com:myorg/coolproject)"

Then you can simply issue apullfrom UCM while sitting in the_project1namespace:

._project1> pull

If you have multiple configuration settings that have the same prefix, you can collect them into a "configuration group." For example, the next two configurations have the same meaning:

GitUrl._project1 = "git(git@github.com:myorg/coolproject)"
GitUrl.foo.bar = "git(git@github.com:foo/bar.git)"


GitUrl {
  _project1 = "git(git@github.com:myorg/coolproject)"
  foo.bar = "git(git@github.com:foo/bar.git)"
}

Configuration groups can be nested as well:

GitUrl {
      _project1 = "git(git@github.com:myorg/coolproject)"
      foo {
        bar = "git(git@github.com:foo/bar.git)"
      }
    }

Setting default metadata like License and Author

UCM allows you to "link" metadata to Unison definitions. These metadata are things likedocumentation,authors, as well as license and copyright information.

Usually you'll want to link yourself as the author of any code you write, and if you intend to publish that code for others to use, you'll want to specify a license laying out the conditions under which others may use your code.

The UCM has a special command,create.author,to help you construct some basic authorship information for use in the Unison ecosystem.

._project1> create.author aliceCoder "Alice Coder"

This adds the following values to your codebase:

1. metadata.authors.aliceCoder          : base.Author
2. metadata.authors.aliceCoder.guid     : GUID
3. metadata.copyrightHolders.aliceCoder : CopyrightHolder

Then, create a license under which to publish your code. The license is an ordinary Unison value of typemetadata.License:

metadata.licenses.aliceCoder2022 =
   License [copyrightHolders.aliceCoder] [Year 2022] licenseTypes.bsd3

Add that to your codebase:

._project1> add

(Though not strictly necessary, you can also alias these values to other projects where you are contributing, just using thealias.termorcopycommand.)

Now add the following to your.unisonConfigfile to make those values the default for any code you write:

DefaultMetadata = [ "._project1.metadata.authors.aliceCoder"
                   , "._project1.metadata.licenses.aliceCoder2020" ]

With this configuration, UCM will link these two values in to any Unison definitions you add to your codebase.

You might want to license different projects differently. In that case you should create a configuration value for your author under theDefaultMetadataconfiguration group, but rather than having a global license, just have a license per project:

DefaultMetadata = ["._project1.metadata.authors.aliceCoder"]

    DefaultMetadata {
      _project1 = ["._project1._trunk.metadata.licenses.aliceCoder_bsd3_2020"]
      _httpclient = ["._project1._trunk.metadata.licenses.aliceCoder_bsd3_2020"]
      org.example.foo = ["._project1._trunk.metadata.licenses.aliceCoder_apache2_2020"]
    }

With this configuration, UCM will link thealiceCoder_apache2_2020license to any definitions you add to theorg.example.mylibrarynamespace and any subnamespaces and will usealiceCoder_bsd3_2020when in_project1or_httpclientnamespaces.