Tatin User Settings

1. Introduction

Tatin uses a file to remember all Tatin Registries you want to work with, and possibly other user-specific settings as well. We refer to this file as the user settings file.

When you start using Tatin for the very first time there is no such file, and therefore Tatin will create one in a specific location.

Once Tatin is installed, when you fire up an instance of Dyalog APL the contents of the file is used to instantiate the Tatin.UserSettings class. The instance is assigned to βŽ•SE.Tatin.MyUserSettings. From then on any changes to the file with an external editor do not affect βŽ•SE.Tatin.MyUserSettings!

βŽ•SE.Tatin.MyUserSettings provides several properties that can be referenced as well as several methods that can be issued to manipulate the user settings.

For example, this call:

      ]Tatin.ListRegistries
Alias                    URL         ID  Port  Priority No-Caching Proxy
-----------------------  ----------  --- ----  -------- ---------- -----
https://tatin.dev/       tatin       ...    0       100           0
https://test.tatin.dev/  tatin-test  ...    0         0           0

shows most of the data that is saved in the user settings for registries, except the API key(s).

If you would like to see the API keys as well specify the -full flag.

1.1. The default file

That default file will have two Tatin Registries defined in it:

1.2. Where does the file live?

This default file will be created in the user's home folder; the API function βŽ•SE.Tatin.GetUserHomeFolder'' does return that folder.

You may also ask the user command with:

]UserSettings -home

1.3. What's the name of the file?

The name of the file is tatin-client.json.

1.4. May I edit the file?

Of course you are free to edit that file with any editor. However, keep in mind that you are in charge of making sure that the contents of the file is valid JSON5[1]: if it's not, Tatin will crash.

If you are familiar with JSON5 syntax and want to edit the file it is recommended to use:

]TATIN.UserSettings -edit

This will allow you to edit the file contents, but Tatin will check it afterward to make sure that nothing invalid ever goes into the file.

Note that Dyalog 18.2 and later recognize JSON5 and highlight any syntax errors.

1.5. What does Tatin do at start-up time?

When Tatin is initialized[2] it creates an instance of the UserSettings class with the name MyUserSettings which lives in βŽ•se.Tatin. (Strictly speaking it lives actually in βŽ•SE._Tatin; in βŽ•SE.Tatin there is just a niladic function MyUserSettings that returns a reference to βŽ•SE._Tatin.MyUserSettings)

If the constructor does not get a fully qualified name of the user settings file as an argument then it performs two steps:

  1. It looks for a file .tatin in the user's home folder.

    If the file exists and is not empty then it is expected to point to a user settings file, and Tatin will go for that file.

    We will discuss soon under which circumstances such a file might be useful.

  2. In case there is no file .tatin in that folder, or the file is empty, Tatin will look for a user settings file in the default folder.

1.6. Synchronizing file and workspace

1.6.1. Changes made to the file

If you change the file that Tatin has instantiated by editing it with an external editor, and have an APL session up and running, then your change does not have an impact on the APL session.

However, you can force Tatin to bring the session in line with the file by executing:

      ]TATIN.Init

1.6.2. Changes made in the workspace

If you manipulate the instance in the workspace, then the changes won't be written to disk. You need to call the monadic Save method (with a 1 as the right argument) to make your changes permanent.

1.6.3. Comments

Note that JSON5 allows two different types of comments:

1.6.3.1. Block comments

Everything between /* and */ is recognized as a comment, like this:

/*
  This is a comment that...
  stretches over several lines
*/.
1.6.3.2. Line comments

This is an example of a line that is recognized as a comment:

// This is a comment line

1.7. Summary

In most scenarios, you will probably be happy with having just one user settings file for Tatin, and having it in its default location.

You may however want to have your own Tatin Registries, for example for private projects.

2. Adding and removing Registries

You can manipulate the MyUserSettings instance via its methods.

We are now going to add a registry, list all registries, and then delete that registry, getting us back to where we started.

2.1. What have we got?

Let's list all registries currently defined:

      βŽ•se.Tatin.MyUserSettings.ListRegistries 0
Alias      URL                     Port  Priority No caching Proxy API-key
-----      ------------------      ----  -------- ---------- ----- -------
tatin      https://tatin.dev/         0       100          0           ***
tatin-test https://test.tatin.dev/    0         0          0           ***

This is because originally Tatin only knows about the principal Tatin server and its cousin, the test server.

Note that the API key is not listed when a zero is provided as the right argument.

Let's add a made-up registry.

2.1.1. Create an instance of the DefineRegistry class.

Let's assume that you work for a company β€œMyCompany”, and that this company entertains a Tatin Server with the URL https://tatin.mycompany.com.

To add that Registry to the user settings file you must first instantiate the DefineRegistry class. You may specify the URL and the alias in several ways; for details on the DefineRegistry class execute this:

]adoc βŽ•se.Tatin.DefineRegistry

We will pass a simple text vector that specifies the alias (between []) and the URI:

      #.myRegβ†βŽ•NEW βŽ•SE.Tatin.DefineRegistry (,βŠ‚'[myc]https://tatin.mycompany.com')
      #.myReg.varsList
 uri  alias  port  api_key  priority
      ]box on
      {⍡,βͺ#.myReg.(⍎¨⍡)}'uri' 'alias' 'port' 'api_key' 'priority'
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚uri     β”‚https://tatin.mycompany.com/β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚alias   β”‚myc                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚port    β”‚0                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚api_key β”‚                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚priorityβ”‚[Null]                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      ]box off

β€œid” is not mentioned here, because it is optional, and DefineRegistry will assign a freshly generated UUID to it for you. Refer to The β€œid” for details.

2.1.2. Settings in the file

2.1.3. Adding the Registry

Adding a registry is achieved by calling the AddRegistry method, and providing an instance of the DefineRegistry class as an argument:

      βŽ•se.Tatin.MyUserSettings.AddRegistry #.myReg

Now we would expect three Registries:

      β†‘βŽ•se.Tatin.MyUserSettings.registries.(alias uri priority)
 tatin       https://tatin.dev/           100
 myc         https://tatin.mycompany.com/  90
 tatin-test  https://test.tatin.dev/        0

The priority is not βŽ•NULL anymore but 90: any βŽ•NULL is replaced by the lowest number yet minus 10.

Regarding priorities

What happens when you add a Registry with priority being βŽ•NULL and the lowest Registry so far is 1?

In that case Tatin assigns new values to all Registries except those with a priority of zero which will remain untouched.

The new priorities will not change the order of the priorities, and the lowest one will be 100 or greater.

So far we have changed the user settings in the workspace, not on file. This allows you to experiment with certain settings without making the change permanent; other sessions won't be affected.

If you want to make your changes permanent you must call the Save method and provide a 1 as the right argument.

3. Putting the user config file elsewhere

There might be scenarios when the default location for the user config file is not suitable for you.

In the aforementioned cases as well as other scenarios you need more freedom than what is provided by default.

For that, you must create a user settings file in a specific location. To achieve that we re-instantiate the class UserConfig, and we provide a path to the folder where the file should live:

      p←,βŠ‚'/path2/user_config_file/'
      βŽ•SE._Tatin.Client.MyUserSettingsβ†βŽ•SE._Tatin.Client.βŽ•NEW βŽ•SE.Tatin.UserSettings p
      β΄βŽ•β†1 βŽ•se.Tatin.ListRegistries 0
tatin      https://tatin.dev       ... 0 100 0
tatin-test https://test.tatin.dev  ... 0   0 0
2 7
      β΄βŽ•β†βŽ•se.Tatin.MyUserSettings.ListRegistries 0
 Alias  URL                  Port  Priority No caching Proxy API-key
 -----  ------------------   ----  -------- ---------- ----- -------
 tatin  https://tatin.dev/      0       100          0           ***
 test-tatin  https://tatin.dev/ 0       100          0           ***
2 7

Notes:

3.1. Make the switch permanent

To make this user settings file the default file, meaning that this file will be instantiated the next time Dyalog APL is fired up, we need to make sure that a file .tatin in the default folder (that's the one returned by βŽ•SE.Tatin.GetUserHomeFolder'') contains a path pointing to that folder.

You can do this yourself, but you can also ask the instance for doing the job for you:

      βŽ•SE.Tatin.MyUserSettings.MakeDefaultFile 1

From now on, the file MyUserSettings.path2config is pointing to, will be used to determine the user settings.

4. Other settings

You can specify these pieces of information as well:

group

The name your packages will use.

license

The license you usually use to publish a package.

maintainer

The email address of the maintainer of your packages (most likely your email address).

source

The name of a folder in your package where all source files are stored.

These define the defaults to be used when a new package is created.

id

A unique key that can be used to identify a Registry definition in the user settings file when neither the URL nor an alias can be used for this.

However, because mot of the time URL or alias are sufficient for this, setting id is optional.

5. Editing the file

Editing the file with an editor is possible but has the disadvantage that you might make a mistake without noticing.

If you find using an instance of DefineRegistry and the Add method too cumbersome but want to edit the file use this:

]UserSettings -edit

This checks the file and tries hard to make sure that it is valid and fulfils Tatin's needs.

5.1. The β€œid”

Because it must be possible to define more than one set for the same URL β€” for different groups! β€” in the user settings, the URL does not necessarily qualify as a unique key for a Registry. Neither does the alias, because it is optional, and you may reset it to β€œundefined”.

So we need a unique key for this (though admittedly not many will be in need for this). That's why you may set β€œid”.

If you use the DefineRegistry class then β€œid” will be a newly created UUID. If you prefer to add a new Registry to the user settings by editing the user settings file then you should add β€œid” yourself.

This has only an impact locally in a scenario mentioned above, and that's why this is optional.


Footnotes

  1. Tatin uses JSON5 rather than JSON.

  2. Tatin will be initialized either explicitly or as a side effect when the first Tatin user command is issued. See β€œInstalling and updating the Tatin Client” for details.