Commands
Generating code for an mobile application
The simplest invocation is in this form:
% nimbus-fml generate --language <LANGUAGE> --channel <CHANNEL> <INPUT> <OUTPUT>
LANGUAGE
can bekotlin
orswift
.CHANNEL
is one of the channels specified in the FML file.INPUT
may be a local file or directory.OUTPUT
should be a local file or directory.
If INPUT
is a directory, it is recursively searches for any files with names ending in .fml.yaml
.
This command should be called at build time of components and the build time of the application.
Adding repo-file
s
Adding repo files can be done with one or more --repo-file
argument.
% nimbus-fml generate --language <LANGUAGE> --repo-file ./app-structure.json <INPUT> <OUTPUT>
Getting different versions of the same manifest
For remote manifests, the default branch to fetch from is main
. This can be changed with the --ref
option.
Using a ref
is equivalent to taking the remote repo of the manifest path and creating a repo-file
with that repo mapped to the given ref
.
This command uses feature manifest from the releases_v118
branch of the https://github.com/mozilla-mobile/firefox-android repository:
% nimbus-fml generate --language <LANGUAGE> --ref releases_v118 @mozilla-mobile/firefox-android/fenix/app/nimbus.fml.yaml <OUTPUT>
Caching remote files
% nimbus-fml generate --language <LANGUAGE> --channel CHANNEL --cache-dir ./build/cache-dir <INPUT> <OUTPUT>
For include
and import
directives in the FML, a remote file may be referenced. The cache directory is a local cache of these remote files.
For each of the following, --ref
, --cache-dir
and --repo-file
flags are supported.
Generating a manifest file for experimenter
The reason to use a custom manifest format a language specific JSON serialization library is to do with keeping the code in sync with the experimenter web server.
For legacy reasons, this is a different format of yaml file, which should be checked in to version control and is periodically pulled in by experimenter.
% nimbus-fml generate-experimenter <INPUT> <OUTPUT>
This should only be called at the application level, with the one main fml file as an input.
--cache-dir
, --ref
, and --repo-file
arguments are also supported.
Validating a manifest file
% nimbus-fml validate <INPUT>
This gives a view of the validation process for all channels.
% nimbus-fml validate @mozilla-mobile/firefox-android/fenix/app/nimbus.fml.yaml
gives
ℹ️ Loaded modules:
- https://raw.githubusercontent.com/mozilla-mobile/firefox-android/main/fenix/app/onboarding.fml.yaml
- https://raw.githubusercontent.com/mozilla-mobile/firefox-android/main/fenix/app/nimbus.fml.yaml
- https://raw.githubusercontent.com/mozilla-mobile/firefox-android/main/fenix/app/pbm.fml.yaml
- https://raw.githubusercontent.com/mozilla-mobile/firefox-android/main/android-components/components/browser/engine-gecko/geckoview.fml.yaml
- https://raw.githubusercontent.com/mozilla-mobile/firefox-android/main/android-components/components/service/nimbus/messaging.fml.yaml
Validating manifest for different channels:
✅ release.............valid
✅ beta................valid
✅ nightly.............valid
✅ developer...........valid
Re-write a complicated distributed manifest into a single file
The FML spec allows you to import and include dependencies' manifests. This is convenient for engineers to place the feature manifest close to where the feature code lives.
However, for some circumstances, it may not be good for packagers or distributers of the software: e.g. if the file is to be distributed with the software.
To help this, the single-file
command is used to merge all imports and includes into the top level file, with a single channel.
% nimbus-fml single-file --channel release @mozilla-mobile/firefox-android/fenix/app/nimbus.fml.yaml single-file.fml.yaml
Generating a machine readable overview of a feature
% nimbus-fml info [--channel CHANNEL] [--json] <MANIFEST> [--feature FEATURE]
This prints a simplified YAML or JSON representation for each feature. e.g.
{
"file": "https://raw.githubusercontent.com/mozilla-mobile/firefox-android/main/fenix/app/nimbus.fml.yaml",
"features": {
"homescreen": {
"description": "The homescreen that the user goes to when they press home or new tab.",
"types": [
"Boolean",
"HomeScreenSection",
"Map<HomeScreenSection, Boolean>"
],
"hashes": {
"schema": "7a15570b",
"defaults": "423ab0bd"
}
}
}
}
Hashes
The hashes
object shows truncated SHA256 hashes for:
- the schema (the types, variable names, the enum variants available)
- the defaults (the default values of the feature variables)
- Changes in the schema hash might indicate a change in the feature code.
- Changes in the defaults hash would indicate a different configuration being used for the same code.
- Changes in the schema hash will almost always be accompanied by a change in the defaults hash, with the exception of changing variable types from
a
String
type to astring-alias
type (or vice-versa).
Types
The types
list is a sorted list of the types involved used to define the feature. This list may be used as a proxy for a measure of complexity of the feature configuration space.
Feature metadata
In addition, the feature metadata is also displayed.
If a --feature
argument is supplied, then restrict the output to just this feature.
If a --channel
argument is supplied, then use this channel. This will affect the defaults
hashes.
info
with JQYou can use --json
JQ to output some interesting data:
Get the features for this app:
% nimbus-fml info <INPUT> --json | jq '.features|keys'
Get the channels for this app:
% nimbus-fml channels <INPUT> --json
Get the hashes for just the homescreen
feature:
% nimbus-fml info <INPUT> --json | jq '.features.homescreen.hashes'
--cache-dir
, --ref
and --repo-file
arguments are also supported.