Thank you for this tutorial.
.paclet
files can also be created without using the Workbench. While GUI tools can be convenient, it is often useful to understand what they do exactly. Scripts and configuration files provide a level of reproducibility that GUIs cannot. All the following information is from inspecting GitLink, and I am going to demonstrate it using MaTeX (which I'm using to experiment with these things). This is far from the complete story, but it's sufficient to package up application as a paclet.
Also posted on Mathematica.SE.
Introduction
.paclet
files appear to be simply zip files that can contain a Mathematica package or other extensions to Mathematica, along with some metadata in a PacletInfo.m
. The metadata makes it possible to manage installation, uninstallation and update automatically.
How to add the required metadata?
First make sure that your package is following the standard directory structure.
Then create a PacletInfo.m
file in the package root with a minimum amount of metadata. Make sure the Name
and Version
are present. For MaTeX I could start e.g. with this:
Paclet[
Name -> "MaTeX",
Version -> "1.6.2",
MathematicaVersion -> "10.0+",
Description -> "Create LaTeX-typeset labels within Mathematica.",
Creator -> "Szabolcs Horvát"
]
This is sufficient to make it possible to pack and install a paclet. But it is not sufficient for making it loadable with Needs
. For that we need to add the "Kernel"
extension:
Paclet[
Name -> "MaTeX",
Version -> "1.6.2",
MathematicaVersion -> "10.0+",
Description -> "Create LaTeX-typeset labels within Mathematica.",
Creator -> "Szabolcs Horvát",
Extensions ->
{
{"Kernel", Root -> ".", Context -> "MaTeX`"}
}
]
The two critical arguments to the `"Kernel"`` extension are:
Context
sets the context of the package. Whatever you put here will be recognized by Needs
and FindFile
, but ideally it should also be compatible with the package name and the standard file name resolution.
Root
sets the application root. FindFile
seems to resolve the context to a path through this, but also following the standard rules.
Of course you can also add the "Documentation"
extension to integrate with the Documentation Centre, but that is not required for the functionality I describe here.
How to bundle a package into a .paclet
file?
Simple use the PackPaclet
function on the application directory. It will use the information from PacletInfo.m
. It is a good idea to remove any junk files and hidden files to avoid them from getting packed up.
Warning: Before doing this, make a copy of the application directory. Don't accidentally delete any files used by your version control system.
After making a copy of the package directory, in my case called MaTeX
I did this:
Make sure we're in the parent directory of the application directory:
In[2]:= FileNames[]
Out[2]= {".DS_Store", "MaTeX"}
Delete any junk files like `.DS_Store
(which macOS likes to create):
In[4]:= DeleteFile /@ FileNames["*.", "MaTeX", Infinity]
Create .paclet
file:
In[5]:= PackPaclet["MaTeX"]
Out[5]= "/Users/szhorvat/Desktop/pacletbuild/MaTeX-1.6.2.paclet"
Install it permanently:
In[6]:= PacletInstall[%]
Out[6]= PacletManager`Paclet[
"Name" -> "MaTeX", "Version" -> "1.6.2",
"MathematicaVersion" -> "10.0+",
"Description" -> "Create LaTeX-typeset labels within Mathematica.",
"Creator" -> "Szabolcs Horvát",
"Extensions" -> {{"Kernel", "Root" -> ".", "Context" -> "MaTeX`"}},
"Location" -> "/Users/szhorvat/Library/Mathematica/Paclets/Repository/MaTeX-1.6.2"]
Multiple versions may be installed at the same time. Finds all installed versions using:
In[7]:= PacletFind["MaTeX"]
Out[7]= {
PacletManager`Paclet[
"Name" -> "MaTeX", "Version" -> "1.6.2",
"MathematicaVersion" -> "10.0+",
"Description" -> "Create LaTeX-typeset labels within Mathematica.",
"Creator" -> "Szabolcs Horvát",
"Extensions" -> {{"Kernel", "Root" -> ".", "Context" -> "MaTeX`"}},
"Location" -> "/Users/szhorvat/Library/Mathematica/Paclets/Repository/MaTeX-1.6.2"]}
FindFile
(and therefore also Needs
) will always resolve to the latest version:
In[8]:= FindFile["MaTeX`"]
Out[8]= "/Users/szhorvat/Library/Mathematica/Paclets/Repository/MaTeX-1.6.2/Kernel/init.m"
Uninstall all versions:
In[9]:= PacletUninstall /@ PacletFind["MaTeX"]
Out[9]= {Null}
How to work with paclets during development
During development we don't want to pack the paclet and install it after every change. It is much more convenient to be able to load it directly from the development directory.
I can do this by adding the parent directory of the application directory (i.e. MaTeX
in the above example) as a paclet directory. Since I keep the development version of MaTeX in ~/Repos/MaTeX-wb/MaTeX
, I can simply use
PacletDirectoryAdd["~/Repos/MaTeX-wb"]
After this Needs["MaTeX`"]
will load the dev version.