Packaging an application¶
Packaging examples
There are example applications showing how to use Batis with popular technologies like Electron or PyQt.
You’ve got your application running smoothly, and you’re ready to invite other people to use it. Here’s how to package it from scratch using Batis:
Prepare a directory containing your built application, so that it can run regardless of where the directory is located (i.e. everything inside the application is loaded by relative paths).
Add a
batis_info
subdirectory in the top level of this application directory. This should contain:metadata.json
- a JSON object containing information about your application, including:name
andbyline
- brief, human readable information about the application, which may be displayed by tools for managing applications.icon_name
oricon_file
- an icon for your application, which tools for managing applications may display.icon_name
, which is preferred, identifies an icon from thebatis_info/icons
directory described below.icon_file
is a relative path to an icon file within the application directory.index_url
- the URL of the application’s index file. Future versions of Batis will use this to look for application updates. Optional but strongly recommended.commands
- list of objects, each with ‘name’ and ‘target’ keys.target
, a path relative to the root of your application directory, will be symlinked asname
to a location onPATH
. E.g.:"commands": [{"target": "bin/launch.sh", "name": "myapp"}]
format_version
-[1, 0]
with the details described in this document. Future releases may increment the second number for backwards compatible changes to the package format, and the first for incompatible changes.
dependencies.json
- optional, a JSON object with details about external packages that need to be installed for you application. See Dependencies for more details.system_packages
- a specification of distro packages that the user must have installed. See Dependencies for details.description
- a string listing the same distro packages in human-readable form. This will be shown to the user if Batis can’t automatically install the dependencies. E.g. for a PyQt application, this could be"Python 3, PyQt5"
.
desktop/*.desktop
- Zero to many desktop entry files (spec). These can add your application to desktop menus or launchers, and associate it with given mime types. You can use{{INSTALL_DIR}}
inside these to refer to your application’s directory:Exec="{{INSTALL_DIR}}/bin/foo" %F
mime/*.xml
- Zero to many mime database XML source files (spec, tutorial). These can define new file types for your application.icons/theme/sizexsize/category/name.png
- icons for your application and new mime types. Theme will normally be ‘hicolor’, which is used as the fallback theme, and you should include hicolor variants in addition to any other theme you want to add icons for. You should install at least a 48x48 pixel icon; other square sizes are optional. Category will typically be either ‘apps’ or ‘mimetype’. (Icon theme spec)
Use
batis verify
to check that all the necessary information is in place:batis verify path/to/app_directory
Fix any problems that this reports.
Pack the directory into a tarball:
batis pack path/to/app_directory -n myapp -o myapp-0.1.app.tgz
This makes a gzipped tarball of the directory you’re using, and adds an
install.sh
script, along with the necessary Batis files, so that users without Batis can easily install your application. Upload the tarball somewhere publicly accessible.Prepare a build index file, and make it accessible on the web over HTTPS.
You can now invite users with Batis to install your application using a link to
the index file, replacing https://
with batis://
. For instance:
<a href="batis://example.com/myapp/batis_index.json">
Click to install
</a>
For users without Batis installed, provide links directly to the tarballs, and
instructions to download, un-tar and run ./install.sh
.
Dependencies¶
Dependencies are third party code or resources that your application uses. Batis lets you choose whether to bundle dependencies inside your tarball, or specify that they should be installed by a system package manager. Each has advantages:
- Bundled dependencies isolate you from API changes in your dependency, because the version your code uses is fixed until you decide to update it.
- Separately installed dependencies mean your users can benefit from security and performance improvements in the dependencies without you needing to make a new release. It also means your tarball is smaller.
In general, I recommend that you specify only large, stable dependencies - such as Python, Java or Qt - for external installation.
Different distributions use different naming schemes for packages, so the
system_packages
field in dependencies.json is a list of possible specifications,
allowing Batis to choose one suited to the user’s distribution. For instance:
[
{
"package_manager": "apt-get",
"packages": ["python3", "python3-pyqt5", "python3-pyqt5.qtsvg"]
},
{
"package_manager": "yum",
"packages": ["python3", "python3-qt5"]
}
]
Each specification has either a package_manager
field or a
distribution
field. Use package_manager
where possible, because it’s
less specific: "package_manager": "apt-get"
will work on Debian,
Ubuntu, Linux Mint, and many other derivatives. Batis recognises these
package managers:
apt-get, yum, zypper, urpmi, pacman, sbopkg, equo, emerge
If you need to do something different for a specific distribution, run
lsb_release -i
to find the name to use. Put it before the more general
specification in the list; Batis will use the first one that matches when
installing.
The user will be prompted for their password for sudo access to install the necessary system packages.
If no specification matches, or installing the system packages fails, Batis
will ask the user to ensure the dependencies are installed. It uses the
description
field in dependencies.json
for this.
If your package doesn’t require any system packages, you can leave the
dependencies.json
file out.
The index file¶
Users will install applications by pointing Batis at an index file. This is the entry point which describes your application and points to the available tarballs.
The index file must be available over HTTPS. Hosting your website on Github Pages is one easy and free way to support HTTPS.
The index should be JSON, looking like this:
{
"name": "My App",
"byline": "Easily frobulate pufoos on demand",
"icon_url": "https://example.com/myapp_logo.png",
"format_version": [1, 0],
"builds": [
{
"url": "https://example.com/downloads/myapp_0.1_linux_64bit.app.tar.gz",
"sha512": "48157035840[...]bd4a14146b9",
"version": "0.1",
"kernel": "Linux",
"arch": "x86_64"
},
...
]
}
Checking your index
When you create or update your index, check that it has the necessary information by running:
batis verify-index <path_or_url>
The name
, byline
and icon_url
fields are like those inside
metadata.json
, except that icon_url
is a URL. These fields are
duplicated so that installer tools can display information about the application
before downloading a tarball.
format_version
is [1, 0]
with the details described here. This is for the
index format, and is not connected to the package format version stored in
metadata.json
.
Batis will select an appropriate build for the user’s system from the builds
array, based on the
kernel
and arch
fields. These should match the results of uname -s
and uname -m
respectively, and are not case sensitive. As a special case,
"arch": "x86"
will match i386
, i686
, and any i<N>86
.
If your application doesn’t need separate builds for different kernels or architectures—for instance, if it only contains Python code with no C extensions —you can set these fields to “any”, or omit them entirely.
If there are multiple suitable builds, Batis will take the one with the highest
version number. The version number should contain one or more numeric parts,
separated by non-numeric characters such as .
. Batis ignores any non-numeric
parts. You can use negative numbers for pre-releases (e.g. 2.0.-1.3
).
The preferred build will be downloaded from the URL given. HTTP URLs are allowed here, but they must have a hash.
The sha512
field is recommended if you specify an https URL, and mandatory
for http. If provided, it must match the SHA-512 hash of the tarball available
for download.
Future extensions
Future versions of Batis may use extra fields in the index to download incremental upgrades, smaller packages containing just the differences between two versions of the application. The index could also contain information for downloading tarballs using peer-to-peer mechanisms like IPFS or BitTorrent.