API¶
Package et-micc¶
Top-level package for et-micc.
Module et_micc.project¶
An OO interface to micc projects.
-
class
et_micc.project.Project(options)[source]¶ An OO interface to micc projects.
Parameters: options (types.SimpleNameSpace) – all options from the miccCLI.-
add_auto_build_code(db_entry)[source]¶ Add auto build code for binary extension modules in
__init__.pyof the package.
-
add_dependencies(deps)[source]¶ Add dependencies to the
pyproject.tomlfile.Parameters: deps (dict) – (package,version_constraint) pairs.
-
app_exists(app_name)[source]¶ Test if there is already an app with name
app_namein this project.<package_name>/cli_<app_name>.py
Parameters: app_name (str) – app name Returns: bool
-
cpp_module_exists(module_name)[source]¶ Test if there is already a cpp module with name py:obj:module_name in this project.
Parameters: module_name (str) – module name Returns: bool
-
f90_module_exists(module_name)[source]¶ Test if there is already a f90 module with name py:obj:module_name in this project.
Parameters: module_name (str) – module name Returns: bool
-
module_exists(module_name)[source]¶ Test if there is already a module with name py:obj:module_name in this project.
This can be either a Python module, package, or a binary extension module.
Parameters: module_name (str) – module name Returns: bool
-
module_to_package(module_py)[source]¶ Move file
module.pytomodule/__init__.py.Parameters: module_py (str|Path) – path to module.py
-
module_to_package_cmd()[source]¶ Convert a module project (
module.py) to a package project (package/__init__.py).
-
mv_component()[source]¶ Rename or Remove a component (sub-module, sub-package, Fortran module, C++ module, app (CLI).
-
py_module_exists(module_name)[source]¶ Test if there is already a python module with name
module_namein the project atproject_path.Parameters: module_name (str) – module name Returns: bool
-
py_package_exists(module_name)[source]¶ Test if there is already a python package with name
module_namein the project atproject_path.Parameters: module_name (str) – module name Returns: bool
-
replace_in_file(filepath, cur_name, new_name, contents_only=False)[source]¶ Replace <cur_name> with <new_name> in the filename and its contents.
-
serialize_db(db_entry=None, verbose=False)[source]¶ Write self.db to file
db.json.Self.options is a SimpleNamespace object which is not default json serializable. This function takes care of that by converting to
strwhere possible, and ignoring objects that do not need serialization, as e.g. self.options.logger.
-
version_cmd()[source]¶ Bump the version according to
self.options.ruleor show the current version if no rule is specified.The version is stored in pyproject.toml in the project directory, and in
__version__variable of the top-level package, which is either in<package_name>.py,<package_name>/__init__.py, or in<package_name>/__version__.py.
-
Module et_micc.expand¶
Helper functions for dealing with Cookiecutter templates.
-
et_micc.expand.expand_templates(options)[source]¶ Expand a list of cookiecutter
templatesin directoryproject_path.Expanding templates may require overwriting pre-existing files. Micc handles this situation in different ways:
- If
options.overwriteequalsFalsethe exansion will fail without overwriting any pre-existing files. The project is not modified. A warning is produced. This is the default. To continue, rerun the command with one of the two options below. - If
options.overwriteequalsTruethe exansion will overwrite any pre-existing files without backup, and produce a warning, listing the overwritten files. - If
options.backupequalsTruepre-existing files will be backed up (.bak) before the new files are expanded. If anything went wrong, you can inspect the backup files, and correct the errors manually.
Parameters: options (types.SimpleNamespace) – namespace object with options accepted by et_micc commands. Relevant attributes are
- templates: ordered list of (paths to) cookiecutter templates that will be expanded as they appear. The template parameters are propagated from each template to the next.
- verbosity
- project_path: Path to the project on which the command operates.
- template_parameters: extra template parameters not read from micc_file
- If
-
et_micc.expand.get_preferences(micc_file)[source]¶ Get the preferences from micc_file.
(This function requires user interaction if no micc_file was provided!)
Parameters: micc_file (Path) – path to a json file.
Module et_micc.logger¶
Helper functions for logging.
-
class
et_micc.logger.IndentingLogger(name, level=0)[source]¶ Cuastom Logger class for creating indented logs.
This is the class for the et_micc logger.
-
et_micc.logger.create_logger(path_to_log_file, filemode='a')[source]¶ Create a logger object for et_micc.
It will log to:
- the console
- file path_to_log_file. By default log message will be appended to the
-
et_micc.logger.log(logfun=None, before='doing', after='done.', bracket=True)[source]¶ Print a message before and after executing the body of the contextmanager.
Parameters: - logfun (callable) – a function that can print a log message, e.g.
print(),info(). - before (str) – print this before body is executed
- after (str) – print this after body is executed
- bracket (bool) – append ‘ [‘ to before and prepend ‘] ‘ to after.
This works best with the
IndentingLogger.- logfun (callable) – a function that can print a log message, e.g.
-
et_micc.logger.logtime(project=None)[source]¶ Log start time, end time and duration of the task in the body of the context manager to the et_micc logger.
This logs on debug level. To see in in the console output you must pass
-vvto et_micc.Parameters: global_options (SimpleNameSpace) – pass verbosity to the et_micc logger.
Created on 18 Nov 2019
@author: etijskens
Module et_micc.utils¶
Utility functions for et_micc.
-
et_micc.utils.execute(cmds, logfun=None, stop_on_error=True, env=None, cwd=None)[source]¶ Executes a list of OS commands, and logs with logfun.
Parameters: cmds (list) – list of OS commands (=list of list of str) or a single command (list of str) Parma callable logfun: a function to write output, typically logging.getLogger('et_micc').debug.Returns int: return code of first failing command, or 0 if all commanbds succeed.
-
et_micc.utils.get_project_path(p)[source]¶ Look for a project directory in the parents of path
p.Parameters: p (Path) – Returns: the nearest directory above pthat is project directory.Raise: RuntimeError if pis noe inside a project directory.
-
et_micc.utils.in_directory(path)[source]¶ Context manager for changing the current working directory while the body of the context manager executes.
-
et_micc.utils.insert_in_file(file, lines=[], before=False, startswith=None)[source]¶ Insert lines at a specific position in a <file>.
Parameters: - file (Path) – path to file in which to insert
- lines (list) – list of lines to insert. If a line does not end with a newline, it is added.
- before (bool) – insert before or after a reference line.
- startswith (str) – find the reference line as the first line that starts with <startswith>. If no such line is found the text is inserted at the end.
-
et_micc.utils.intersect(version_range_1, version_range_2)[source]¶ Compute the intersection of two version ranges
-
et_micc.utils.is_project_directory(path, project=None)[source]¶ Verify that the directory
pathis a project directory.Parameters: - path (Path) – path to a directory.
- project (Project) –
if not None these variables are set:
- project.project_name
- project.package_name
- project.pyproject_toml
Returns: bool.
As a sufficident condition, we request that
- there is a pyproject.toml file, exposing the project’s name:py:obj:[‘tool’][‘poetry’][‘name’]
- that there is a python package or module with that name, converted by
pep8_module_name().
-
et_micc.utils.is_publishable(package_name, verbose=True)[source]¶ Is the name <package_name> available for publishing on PyPI?
This is achieved by running
pip search <package_name>and examining the output. If <package_name> is in use, it will appear in the output.Parameters: - package_name (str) – name of the package for which we want to verify the availability.
- verbose (bool) – show the output of
pip search <package_name>and the examination process.
Returns: the answer as a bool, if the command
pip search <package_name>was successful, and None otherwise (e.g. because of no connection).
-
et_micc.utils.operator_version(version_constraint_string)[source]¶ Split version_constraint_string in operator and version.
Returns: (str,semantic_version.Version)
-
et_micc.utils.pep8_module_name(name)[source]¶ Convert a module name to a PEP8 compliant module name.
- lowercase
- whitespace -> underscore
- dash -> underscore
-
et_micc.utils.replace_in_file(file_to_search, look_for, replace_with)[source]¶ Replace the text
look_forwithreplace_within filefile_to_search
-
et_micc.utils.validate_intersection(intersection)[source]¶ Test if the intersection is not empty. :returns: bool
-
et_micc.utils.verify_project_name(project_name)[source]¶ Project names must start with a char, and contain only chars, digits, underscores and dashes.
Returns: bool
-
et_micc.utils.verify_project_structure(path, project=None)[source]¶ Verify that there is either a Python module
<package_name>.py, or a package<package_name>/__init__.py(and not both).Returns: a list with what was found. This list should have length 1. If its length is 0, neither module.py, nor module/__init__.py were found. If its length is 2, both were found.
Module et_micc.tomlfile¶
-
class
et_micc.tomlfile.TomlFile(path)[source]¶ Read/write access to
.tomlfiles (pyproject.tomlin particular).Open a
.tomlfile and read its contentThe content is accessed by subscripting:
toml = TomlFile('path/to/toml') # Read an item from the .toml file's content: old_name = toml['tool']['poetry']['name'] # Modify an item in the .toml file's content (but not yet in the file): toml['tool']['poetry']['name'] = 'new_name' # Now modify the file with the modified content: toml.save()
Parameters: path (str|Path) – path to the .toml file. Raises: FileNotFoundError if the file does not exist. -
path¶ Path object of the
.tomlfile
-
Module et_micc.static_vars¶
A decorator for adding static variables to a function. see https://stackoverflow.com/questions/279561/what-is-the-python-equivalent-of-static-variables-inside-a-function