skaff package

Submodules

skaff.cli module

_images/cli.svg

Main command line driver program for skaff.

skaff.cli.main() → None[source]

Parses and validates command line option flags, then calls ‘skaff_drive’.

skaff.clitools module

A suite of command line based tools.

skaff.clitools.key_get() → str[source]

Waits for a single keypress on stdin.

This is a silly function to call if you need to do it a lot because it has to store stdin’s current setup, setup stdin for reading single keystrokes then read the single keystroke then revert stdin back after reading the keystroke.

Returns the character of the key that was pressed (zero on KeyboardInterrupt which can happen when a signal gets handled)

Reference (StackOverflow): /questions/983354/how-do-i-make-python-to-wait-for-a-pressed-key

skaff.clitools.timed_key_get(seconds: int) → str[source]

Gets a single key press from the terminal within the given number of ‘seconds’ and returns a ‘str’ representing the key pressed; returns empty “” string upon time out.

Based on the version from StackOverflow by Paul: http://stackoverflow.com/questions/3471461/raw-input-and-timeout/3911560

skaff.clitools.timeout(seconds: int) → typing.Callable[source]

Sets a timer on a function; should be used as a decorator. Raises ‘TimeOutError’ upon expiration.

Reference (StackOverflow): /questions/2281850/timeout-function-if-it-takes-too-long-to-finish

class skaff.clitools.ANSIColor[source]

Bases: object

BLUE = '\x1b[34m'
BOLD = '\x1b[1m'
CYAN = '\x1b[36m'
GREEN = '\x1b[32m'
KHAKI = '\x1b[1;33m'
MAGENTA = '\x1b[35m'
PURPLE = '\x1b[1;35m'
RED = '\x1b[31m'
RESET = '\x1b[0m'
YELLOW = '\x1b[33m'
class skaff.clitools.SmartFormatter(*args, **kwargs)[source]

Bases: argparse.HelpFormatter

You can only specify one formatter in standard argparse, so you cannot both have pre-formatted description (RawDescriptionHelpFormatter) and ArgumentDefaultsHelpFormatter. The SmartFormatter has sensible defaults (RawDescriptionFormatter) and the individual help text can be marked ( help=”R|” ) for variations in formatting. Version string is formatted using _split_lines and preserves any line breaks in the version string.

skaff.config module

Custom configuration type definition used for the ‘driver’ skaff module.

class skaff.config.SkaffConfig(directories, **kwargs)[source]

Bases: object

Configuration type used for the argument of ‘skaff’ function.

author_add(author)[source]

Adds ‘author’ to the internal ‘database’ if the name does not exist; otherwise do nothing.

author_discard(author)[source]

Discards ‘author’ from the internal ‘database’ if the name exists; otherwise do nothing.

static author_fetch()[source]

Gets the current logged-in username from GECOS or name field. This member function is called by the constructor by default.

Raises RuntimeError if both attempts fail.

Note this ‘staticmethod’ may be automatically called from ‘authors_get’ member function under certain scenarios.

authors_get()[source]

Gets a generator containing author(s) for the project(s).

authors_set(authors=None)[source]

Sets the author(s) of the project(s). ‘authors’ must be an iterable type containing ‘str’(s). This member function is called by the constructor by default.

Sets the single author to be the GECOS or name field of current logged-in user if ‘authors’ is left as default or ‘None’.

static basepath_fetch()[source]

Returns the base directory name containing the skaff ‘config’ module.

The extra ‘os.path.abspath’ invocation is to suppress relative path output; result includes a trailing path separator.

create(*args)[source]

Supported arguments:

‘tree’: ‘license’: ‘template’:

directories_get()[source]

Gets a generator containing name(s) for the outputting project-directory(ies).

directories_set(directories=None)[source]

Sets the name(s) of the outputting project-directory(ies). Platform-dependent path separator will be appended if missing. This member function is called by the constructor by default.

‘directories’ argument must be of ‘collections.Iterable’ type containing instance of ‘str’(s).

directory_add(directory)[source]

Adds ‘directory’ to the internal ‘database’ if the name does not exist; otherwise do nothing. Platform-dependent path separator will be appended if missing.

directory_discard(directory)[source]

Discards ‘directory’ from the internal ‘database’ if the name exists; otherwise do nothing. Platform-dependent path separator will be appended if missing.

hook_add(**kwargs)[source]
hook_discard(**kwargs)[source]
hooks_get(**kwargs)[source]
hooks_set(**kwargs)[source]
language_get()[source]

Gets the major programming language used.

language_set(language=None)[source]

Sets the major programming language used. Defaults to ‘c’ language if left as empty or ‘None’. This member function is called by the constructor by default.

‘language’ argument must be the ones listed in ‘languages_list’.

static languages_fetch()[source]

Gets a list containing the supported programming languages BY DEFAULT. User-defined programming languages are not shown.

languages_list()[source]

Gets a generator containing the supported programming languages.

By default they are the following: {“c”, “cpp”}.

languages_probe()[source]

This member function is called by the constructor by default.

license_get(fullname=False)[source]

Gets the type of license used if ‘fullname’ argument is set to ‘False’; otherwise gets a list containing current selected license with fully qualified paths and file extensions attached.

NOTE: The paths and file extensions associated with the current license are governed by the rules specified in the docstrings of ‘paths_set’ and ‘licenses_list’.

license_set(license=None)[source]

Sets the type of license used. Defaults to ‘bsd2’ license if left as empty or ‘None’. This member function is called by the constructor by default.

‘license’ argument must be the ones listed in ‘licenses_list’.

license_sign()[source]

Copies the license text (ends with ”.txt” extension) chosen by authors to all the ‘directories’, signs it with authors and current year prepended if applicable; also copies the license markdown (ends with ”.md” extension) chosen by authors to all the ‘directories’, prepends ‘Overview’ and ‘License’ section headers then rename it to ‘README.md’; ‘directories’ must already exist.

Note only licenses in {“bsd2”, “bsd3”, “mit”} will be signed by names in authors.

static licenses_fetch()[source]

Gets a list containing the supported licenses BY DEFAULT. User-defined licenses are not shown.

licenses_list(fullname=False)[source]

Gets a generator containing the supported licenses with or without paths and file exntensions, depending on whether ‘fullname’ is enabled. For new licenses added in the license path (refer to docstrings for ‘paths_set’ mutator member function for details), remember to call ‘licenses_probe’ mutator member function to actually add them to the internal database; otherwise they would not be listed.

NOTE: For overridden licenses (licenses with the same name as the stock licenses but appear in the license path set by ‘license_set’), this generator will only reflect the difference when ‘fullname’ argument is switched to ‘True’. For exmaple, with license path set to

“$HOME/.config/skaff/license/”

and a custom ‘bsd2’ license is set up as:

“$HOME/.config/skaff/license/bsd2.txt”

“$HOME/.config/skaff/license/bsd2.md”

then a licenses_list() invocation would only produce the SAME DEFAULT result as shown at the BOTTOM; only licenses_list(True) will generate fully qualified results like:

“$HOME/.config/skaff/license/bsd2.txt”

“$HOME/.config/skaff/license/bsd2.md”

(Note the rest default stock licenses are left untouched; the stock bsd2 license in the system path would not be shown since it is overridden)

“/usr/lib/python3/dist-packages/skaff/config/license/bsd3.txt”

“/usr/lib/python3/dist-packages/skaff/config/license/bsd3.md”

...

By default they are the following: {“bsd2”, “bsd3”, “gpl2”, “gpl3”, “mit”}.

licenses_probe()[source]

Probes the ‘license’ path set by the ‘paths_set’ member function for new licenses and add them to the internal ‘database’ to be returned by ‘licenses_list’ member function.

NOTE: normally this member function does not need to be called manually (if some new license files get copied to the ‘license’ path, for example) since ‘license_set’ automatically calls this member function; unless you just want to add those custom licenses to the internal ‘database’ WITHOUT switching the CURRENT license selected.

licenses_validate()[source]

Validates all the stock licenses distributed along with the ‘skaff’ program (does not change any internal states). By default they reside under license subdirectory of ‘system’ config path, which is not modifiable (see docstring of ‘paths_set’): “/usr/lib/python3/dist-packages/skaff/config/license/”

paths_get(*args)[source]

Gets the paths containing configuration, template, and license files. Accepted arguments are the following strings: ‘config’: ‘license’: ‘template’:

If called without any actual argument, returns a deep copy of the internal dictionary containing all the stored key-value pairs.

If called with multiple arguments, a list with corresponding results will be returned.

paths_set(**kwargs)[source]

Sets the paths containing configuration, template, and license files. This member function is called by the constructor by default.

NOTE: the paths containing configuration, template, and license files specified here will take precedence over files with identical name in the ‘system’ path. For example, if there is a file named ‘bsd.txt’ in the default path of license files: “$HOME/.config/skaff/license/bsd.txt” then the content within that file will be used instead of the supplied stock version “/usr/lib/python3/dist-packages/skaff/config/license/bsd.txt” when you create a project using ‘bsd’ license; same goes for templates. You can add new configuration, template, and licenses in this path and it will be discovered by corresponding _*probe member functions, which are called by the constructor by default.

Supported keyword arguments:

‘config’: path containing ‘skaff.conf’ configuration file. Default is: “$HOME/.config/skaff/”

‘license’: path containing license files to be copied to the directories specified in ‘directories_set’ or ‘directory_add’. Default is: “$HOME/.config/skaff/license/”

‘template’: path containing template files to be copied to the directories specified in ‘directories_set’, ‘directory_add’, ‘subdirectories_set’, or ‘subdirectory_add’. Default is: “$HOME/.config/skaff/template/”

quiet_get()[source]

Gets whether there is interactive CMakeLists.txt and Doxyfile editing.

quiet_set(quiet=None)[source]

Sets whether there is interactive CMakeLists.txt and Doxyfile editing. ‘True’ to turn off the interactive editing. Defaults to ‘True’ if left as empty or ‘None’. This member function is called by the constructor by default.

‘quiet’ argument must be of ‘bool’ type.

subdirectories_get()[source]

Gets a generator containing name(s) of the subdirectory(ies) within the project(s)’ base directory(ies).

subdirectories_set(subdirectories=None)[source]

Sets the name(s) of the subdirectory(ies) within the project(s)’ base directory(ies). Defaults to { “build”, “cmake”, “cmake” + os.sep + “modules”, “cmake” + os.sep + “platforms”, “contrib”, “doc”, “examples”, “include”, “misc”, “misc” + os.sep + “conf”, “misc” + os.sep + “img”, “src”, “tests”, “tools” } if left as empty or ‘None’. Platform-dependent path separator will be appended if missing. This member function is called by the constructor by default.

‘subdirectories’ argument must be of ‘collections.Iterable’ type containing instance of ‘str’(s).

subdirectory_add(subdirectory)[source]

Adds ‘subdirectory’ to the internal ‘database’ if the name does not exist; otherwise do nothing. Platform-dependent path separator will be appended if missing.

subdirectory_discard(subdirectory)[source]

Discards ‘subdirectory’ from the internal ‘database’ if the name exists; otherwise do nothing. Platform-dependent path separator will be appended if missing.

template_add(template)[source]
template_discard(template)[source]
templates_get(fullname=False)[source]
templates_probe()[source]
templates_set(templates=None)[source]

skaff.driver module

Main driver module of the skaff program.

skaff.driver.skaff_drive(config: skaff.config.SkaffConfig) → None[source]

Creates all the necessary subdirectories in addition to the project root.

skaff.manualtools module

A suite of manual-page processing tools.

skaff.manualtools.manual_check(manual: str) → bool[source]

Checks whether ‘manual’ actually is a valid unix man-page format manual; returns boolean value True if so, False otherwise.

Files that are considered to be unix manual page format must end with file extensions that are solely consists of digits 1 to 9 excluding 0.

NOTE: Man-page section 9 is a non-POSIX standard (convention adopted by both Linux and FreeBSD) commonly used for documenting “Kernel Routines”.

skaff.manualtools.manuals_install(directory: str, rebuild: bool = True, *manuals: str) → None[source]

Installs the gzipped manual page(s) in ‘manuals’ to the subdirectory of ‘directory’ that ends with an extra manual section number if it exists; for example, if one of the basename of manual in ‘manuals’ is named ‘git.1’ and a subdirectory ‘/usr/share/man/man1/’ exists, it will be installed to that subdirectory instead; otherwise falls back to ‘/usr/share/man/’.

If ‘rebuild’ is set to True, also invokes the ‘mandb’ program to rebuild the manual page index cache.

If ‘–record’ flag exists in sys.argv, writes the list of installed manual pages to the file following the ‘–record’ flag (setuptools compatibility).

NOTE: It is callers’ responsibility to ensure the proper write permission is satisfied for the ‘directory’ (affected by the real UID of the current process) and all the subdirectories of it that ends with an extra manual section number (see the example above); both ‘directory’ and all the ‘manuals’ must already exist.

skaff.manualtools.manuals_probe(*directories: str) → typing.List[str][source]

Probes all directory specified in ‘directories’ and returns a sorted list containing all the manual page(s) found. All the manual page(s) returned are prefixed by absolute path(s).

NOTE: This function does not recurse more than one level deep into the ‘directories’ specified; the order in the result does not necessarily correspond to the order the directory appears in ‘directories’, the results are sorted by the builtin ‘sorted’ function.

skaff.manualtools.manpath_select(select: bool = True) → typing.Union[str, typing.List[str]][source]

Parses the output of the ‘manpath’ program and returns one of its non-empty results (non-empty directory) if ‘select’ is set to True; otherwise returns all the results un-altered.

NOTE: A platform-dependent path separator will be appended to the result.

Module contents

Skaff is a Python library for building programming language dependent scaffolding of software projects, and a command-line tool that uses this library with built-in (CMake-based) C/C++ support.