RepoLib

The repolib-module module simplifies working with APT sources, especially those stored in the DEB822 format. It translates these sources into Python Objects for easy reading, parsing, and manipulation of them within Python programs. The program takes a user-defined sources filename and reads the contents, parsing it into a Python object which can then be iterated upon and which uses native data types where practicable. The repolib-module module also allows easy creation of new DEB822-style sources from user-supplied data.

repolib Module

The repolib Module is the main module for the package. It allows interfacing with the various Classes, Subclasses, and Functions provided by RepoLib.

Module-level Attributes

There are a couple of module-level attributes and functions provided directly in the module.

VERSION

repolib.VERSION
Provides the current version of the library.

LOG_FILE_PATH

repolib.LOG_FILE_PATH
Stores the current path to the log file
repolib.LOG_LEVEL
Stores the current logging level. Note: Change this level using the module_set_logging_level function.

Configuration directories

repolib.KEYS_DIR repolib.SOURCES_DIR

Stores the current Pathlib.Path pointing at the signing key and sources directories, respectively. Used for building path names and reading configuration.

DISTRO_CODENAME

repolib.DISTRO_CODENAME
The current CODENAME field from LSB. If LSB is not available, it will default to linux.

CLEAN_CHARS

repolib.CLEAN_CHARS
A dict which maps invalid characters for the ident attributes which cannot be used and their replacements. These limitations are based on invalid characters in unix-compatible filenames.

sources

repolib.sources
A dict storing all current sources configured on the system. To save resources, this list is only loaded/parsed when module_load_all_sources is called, since many simple operations don’t need the full list of currently-configured sources.

files

repolib.files
A dict containing any source file objects present in the configured sources dir (See module_dirs). This list is empty until module_load_all_sources is called, since many simple operations don’t need the full list of currently-installed config files.

keys

repolib.keys
A :obj`dict` containing any installed repository signing keys on the system. This list is empty until module_load_all_sources is called, since many simple operations don’tneed the full list of currently-installed keys.

compare_sources()

repolib.compare_sources(source1, source2, excl_keys:list) -> bool

Compares two sources based on arbitrary criteria.

This looks at a given list of keys, and if the given keys between the two given sources are identical, returns True.

Returns: bool
True if the sources are identical, otherwise False.

source1, source2

The two source objects to compare.

excl_keys

list A list of DEB822key names to ignore when comparing. Even if these items don’t match, this function still returns true if all other keys match.

combine_sources()

repolib.combine_sources(source1, source2) -> None

Copies all of the data in source2 and adds it to source1.

This avoids duplicating data and ensures that all of both sources’ data are present in the unified source

source1

The source into which both sources should be merged

source2

The source from which to copy to source1

url_validator()

repolib.url_validator(url: str) -> bool
Validates a given URL and attempts to see if it’s a valid Debian respository URL. Returns True if the URL appears to be valid and False if not.

url

:obj:`str`The url to validate

validate_debline()

repolib.util.validate_debline(line: str) -> bool

Validate if the provided debline line is valid or not.

Returns True if line is valid, otherwise False.

str The line to validate

strip_hashes()

repolib.strip_hashes(line: str) -> str
Strips leading hash (#) characters from a line and returns the result.

line

str The line to strip

load_all_sources()

repolib.load_all_sources() -> None

Loads all sources from the current system configuration.

set_testing()

repolib.set_testing(testing: bool = True) -> None

Enables or disables testing mode in Repolib

When in testing mode, repolib will operate within a temporary directory rather tan on your live system configuration. This can be used for testing out changes to the program without worry about changes to the system config. It’s also used for unit testing.

testing

bool - Wether testing mode should be enabled (True) or not (False)

Example

The following code as a Python program that creates in example.sources file in /etc/apt/sources.list.d with some sample data, then modifies the suites used by the source and prints it to the console, before finally saving the new, modified source to disk:

import repolib
source = repolib.Source()
file = repolib.SourceFile(name='example')

source.ident = 'example-source'
source.name = 'Example Source'
source.types = [repolib.SourceType.BINARY]
source.uris = ['http://example.com/software']
source.suites = ['focal']
source.components = ['main']
file.add_source(source)

print(source.ui)

file.save()

When run with the appropriate arguments, it prints the contents of the source to console and then saves a new example.sources file:

$
example-source:
Name: Example Source
Enabled: yes
Types: deb
URIs: http://example.com/software
Suites: focal
Components: main

$ ls -la /etc/apt/sources.list.d/example.sources
-rw-r--r-- 1 root root 159 May  1 15:21 /etc/apt/sources.list.d/example.sources

Below is a walkthrough of this example.

Creating Source and File Objects

The first step in using RepoLib is creating Source object and File object:

source = repolib.Source()
file = repolib.SourceFile(name='example')

The Source object will hold all of the information for the source to be created. The File object represents the output file on disk, and allows for advanced usage like multiple sources per file.

Adding and Manipulating Data

The Source object contains attributes which describe the connfiguration aspects of the source required to fetch and install software. Generally, these attributes are lists of strings which describe different aspects of the source. They can be set or retrieved like any other attributes:

source.uris = ['http://example.com/software']
source.suites = ['focal']

This will add a focal suite to our source and add a URI from which to download package lists.

Source object also presents a dict-like interface for setting and getting configuration data. Key names are case-insensitive and their order within the object are preserved.

Adding the Source to the File

Before the Source object can be saved, it needs to be added to a File object:

file.add_source(source)

This will add source to the file’s lists of sources, as well as setting the source’s file attribute to file.

Saving Data to Disk

Once a source has the correct data and has been added to a file object, it can be saved into the system configuration using file-save:

file.save()

When called, this writes the sources stored in the file to disk. This does not destroy the object, so that it may be further manipulated by the program.

Note

While data within the source or file objects can be manipulated after calling file-save, any subsequent changes will not be automatically written to disk as well. The file-save method must be called to commit changes to disk.