Modules
Modules can be used to apply global updates, or other configuration which needs to be done more frequently than just at package installation. This commonly takes the form of updating configuration files.
Modules can also provide interfaces for the user to manually configure their system.
Modules are python files, similar to pybuilds, and contain functions of
the form do_{name}
or describe_{name}
, where name is the name of
the operation. Do variants should execute the function, while describe
should return a string which describes the operation.
They use the .pmodule
extension.
Installation
Modules must be installed into the MODULEPATH
for them to be activated.
Special Functions
The update
operation is invoked by default (if present) after
installation or removal of mods. It is recommended that update not
produce any output unless changes are necessary. Other helper functions
can be included, but will not have any special meaning.
The prerm
operation is invoked before the module is removed from the
system. Any changes made should be reverted if possible.
Functions of the form describe_{name}_options
and
describe_{name}_parameters
can also be used to describe function
parameters. The should each return a list of strings, one for each
parameter.
Module Description
Module files which contain operations other than update must also
contain a docstring, which is used to describe the module when invoking
portmod <prefix> select
.
Function arguments
Module functions take up to two arguments: state
, which is an object
with a number of constants that describe the module’s environment, and
args
, which contains the arguments passed by the user (if any), in
the form of an object.
do_update
only gets passed thestate
and is not provided with args.All other
do_
functions are provided bothstate
andargs
.
Note that functions expecting too many or too few arguments will case runtime exceptions.
Module state
New constants may be introduced, however they will not be removed between major versions of Portmod.
Valid variables include:
Name |
Value |
---|---|
ROOT |
The root of the module’s installed tree. This location can be used to store custom files which are designed to be used at runtime (e.g. patches) |
CACHE |
A directory that can be used to cache temporary files between runs. It is not guaranteed to persist, however its contents are not automatically deleted |
TEMP |
A directory which can be used to store temporary files during module execution. This directory and all files will be removed after the module has finished executing |
VERSION |
The currently installed version number of the module. Useful for determining if information needs to be regenerated due to an update to the module itself |
Sandbox
Module files execute within the Sandbox.
File access is only permitted within the ROOT
, CACHE
and TEMP
directories passed in the state objects (see above).
The python module portmod.module_util
provides access to two helper
functions:
execute(command)
: Permits execution of binaries. The interface is the same as the pybuild.Pybuild2.execute function.create_file(path)
: Permits access to arbitrary files on the filesystem via redirection. This returns a path to a file within a temporary directory, and the user will be shown the difference between the existing file and the contents of this new file and prompted to allow the changes to proceed after the module is done executing.
Example module
"""Shopping list module"""
import os
def do_update(state):
"""This function isn't actually necessary here. We're not updating anything"""
def do_list(state, args):
"""
Displays shopping list.
This docstring will describe the operation in `portmod <prefix> select`
"""
with open(os.path.join(state.ROOT, "shopping.txt"), "r") as file:
for line in file.readlines():
print(line)
# Essentials!
print("Eggs")
print("Milk")
print("Carrots")
print("Marmite")
print("Hackle-lo leaves")
def do_add(state, args):
"""Add to list"""
with open(os.path.join(state.ROOT, "shopping.txt"), "a") as file:
print(args.item, file)
def describe_add_parameters():
return ["item"]
def describe_add_options():
return ["item to add to the list"]
Note: while it may be possible to use Portmod for shopping lists, this is outside the scope of the project and is not something which is officially supported. The above is provided as an example of the format only.
Notes
Like Pybuilds, global scope code is not permitted!
Modules must be sourced to get information such as descriptions when running
portmod <prefix> select
, and global code running at this point would
be undesirable.