This document details how to create a.unisonConfig
file 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.unisonConfig
in 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.unisonConfig
file and continue with the new configuration.
What is the configuration file format?
The.unisonConfig
file uses theData.Configurator
file 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. 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 by usingUnison Share,Unison's native code-hosting platform, or by using GitHub.
# The Remote Mapping config block sets up default push and pull
# namespaces for integrating with Unison Share. The left side
# of the configuration block represents your local codebase and
# the right side of the equals sign is the mapping to the
# hosted namespace
RemoteMapping {
# On Unison Share, your Unison code is hosted under your user name
# in a namespace called "public". Currently everything hosted
# under "public" is visible. Calling ''push'' within your
# ''.> public'' namespace here will push all the code in that
# namespace to Unison Share.
public = "myUser.public"
# Say you maintain a library that you'd like to host publically,
# this configures a local namespace to push and pull from the
# "main" remote branch.
public.myLibrary = "myUser.public.myLibrary.main"
# We support projects that are still hosted using git, with the
# following url conventions:
json = "git(git@github.com:myuser/json.git)" # '.git' is optional!
project1 = "git(git@github.com:myorg/coolproject)"
# Some projects I occasionally make PRs against.
# Example: from UCM, ''.prs.base> pull'' will get latest trunk
prs.base = "unison.public.base.main"
prs.distributed = "unison.public.distributed.main"
# Another example with a nested namespace.
http.client = "myUser.public.http.client"
}
# 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 topush
your work to a shared repository andpull
code from the repository into your codebase. To do so, you can use UCM'spush
andpull
.These commands take a Unison Share namespace path or aGit URL.Since the URL you'll want to push to or pull from generally remains constant for a given Unison namespace, the.unisonConfig
file allows you to set aRemoteMapping
per namespace.
For example, while you can always supply an explicit argument topull
,like so:
.project1> pull myUser.public.project1
… to avoid having to type or paste the URL every time, you could instead add the following to your.unisonConfig
:
RemoteMapping.project1 = "myUser.public.project1"
Then you can simply issue apull
from UCM while sitting in theproject1
namespace:
.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:
RemoteMapping.project1 = "myUser.public.project1"
RemoteMapping.foo.bar = "myUser.public.foo.bar"
RemoteMapping {
project1 = "myUser.public.project1"
foo.bar = "myUser.public.foo.bar"
}
Configuration groups can be nested as well:
RemoteMapping {
project1 = "myUser.public.project1"
foo {
bar = "myUser.public.foo.bar"
}
}
If both a Unison-share namespace and a Git url config block are present for the same local namespace, the UCM will prioritize Unison Share for code hosting.
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.term
orcopy
command.)
Now add the following to your.unisonConfig
file 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 theDefaultMetadata
configuration group, but rather than having a global license, just have a license per project:
DefaultMetadata = [".project1.metadata.authors.aliceCoder"]
DefaultMetadata {
project1 = [".project1.main.metadata.licenses.aliceCoder_bsd3_2020"]
httpclient = [".project1.main.metadata.licenses.aliceCoder_bsd3_2020"]
org.example.foo = [".project1.main.metadata.licenses.aliceCoder_apache2_2020"]
}
With this configuration, UCM will link thealiceCoder_apache2_2020
license to any definitions you add to theorg.example.mylibrary
namespace and any subnamespaces and will usealiceCoder_bsd3_2020
when inproject1
orhttpclient
namespaces.