cmeta.utils.common module
Common reusable functions
cMeta author and developer: (C) 2025-2026 Grigori Fursin
See the cMeta COPYRIGHT and LICENSE files in the project root for details.
Functions
- cmeta.utils.common.compare_versions(version1: str, version2: str)[source]
Compare two version strings.
- Parameters:
version1 (str) – First version string (e.g., “0.3.1”, “1.2”, “3.2.0-dev”)
version2 (str) – Second version string
- Returns:
- {‘return’: 0, ‘comparison’: ‘<’ | ‘=’ | ‘>’}
- where ‘<’ means version1 < version2
’=’ means version1 == version2 ‘>’ means version1 > version2
or {‘return’: 1, ‘error’: str} on error
- Return type:
dict
- cmeta.utils.common.copy_text_to_clipboard(text: str = '', add_quotes: bool = False, do_not_fail: bool = False)[source]
Copy text to system clipboard using pyperclip.
- Parameters:
text (str) – Text string to copy to clipboard.
add_quotes (bool) – If True, wraps text in double quotes before copying.
do_not_fail (bool) – If True, returns warning instead of error if pyperclip not installed.
- Returns:
Dictionary with ‘return’: 0 on success, or ‘return’ > 0 and ‘error’/’warning’ on failure.
- Return type:
dict
- cmeta.utils.common.deep_merge(target: dict, source: dict, append_lists: bool = False, ignore_root_keys: list = [])[source]
Recursively updates the target dictionary with values from the source dictionary.
- Parameters:
target (dict) – The original dictionary to be updated.
source (dict) – The new dictionary with updates.
append_lists (bool) – If True, lists will be appended instead of overwritten.
ignore_root_keys (list) – List of keys to ignore from source at the root level.
- cmeta.utils.common.deep_remove(target: dict, source: dict)[source]
Recursively removes keys/values from target dictionary based on source dictionary.
- Parameters:
target (dict) – The dictionary to remove keys/values from (modified in place).
source (dict) – The dictionary specifying what to remove. - If value is a dict, recursively remove nested keys - If value is a list, remove list elements from target list - Otherwise, remove the entire key from target
- Returns:
The modified target dictionary
- Return type:
dict
- cmeta.utils.common.detect_cid_in_the_current_directory(cmeta, path: str | None = None, debug: bool = False, logger=None)[source]
Detect CMeta repository, category, and artifact from current or specified directory.
Traverses the directory tree to find CMeta repository information and determine which artifact the current path corresponds to.
- Parameters:
cmeta – CMeta instance.
path (str | None) – Directory path to check. If None, uses current working directory.
debug (bool) – If True, enables debug logging.
logger – Logger instance for debug output.
- Returns:
- Dictionary with ‘return’: 0 and detected information including:
artifact_repo_name: Name of the artifact repository
artifact_path: Relative path within repository
category_alias, category_uid: Category identifiers
category_obj: Category object string
artifact_alias, artifact_uid, artifact_name: Artifact identifiers
Or ‘return’ > 0 and ‘error’ on failure.
- Return type:
dict
- cmeta.utils.common.generate_timestamp(cut: int | None = None, slices: list | None = None)[source]
Generate timestamp string and optionally create sharded path.
Creates a timestamp in format YYYYMMDD-MMSS and optionally creates a sharded directory path from it.
- Parameters:
cut (int | None) – If specified, truncates timestamp to this many characters.
slices (list | None) – List of slice sizes for creating sharded path.
- Returns:
Dictionary with ‘return’: 0, ‘timestamp’ (string), and ‘path’ (sharded if slices provided).
- Return type:
dict
- cmeta.utils.common.normalize_tags(tags, fail_on_error: bool = False)[source]
Normalize tags from string or list format to clean list of strings.
Converts comma-separated string to list and strips whitespace from each tag.
- Parameters:
tags (str | list) – Tags as comma-separated string or list of strings.
fail_on_error (bool) – If True, raises exception on error instead of returning error dict.
- Returns:
Dictionary with ‘return’: 0 and ‘tags’ list, or ‘return’ > 0 and ‘error’ on failure.
- Return type:
dict
- cmeta.utils.common.safe_print_json(obj, indent: int = 2, non_serializable_text: str | None = None, ignore_keys: list = [], sort: bool = True)[source]
Print object as JSON with safe serialization of non-serializable objects.
- Parameters:
obj – Python object to print as JSON.
indent (int) – Number of spaces for indentation. Default is 2.
non_serializable_text (str | None) – Text to use for non-serializable objects.
ignore_keys (list) – List of top-level keys to exclude from output.
sort (bool) – If True, sort dictionary keys. Default is True.
- Returns:
Dictionary with ‘return’: 0.
- Return type:
dict
- cmeta.utils.common.safe_print_json_to_str(obj, indent: int = 2, non_serializable_text: str | None = None, ignore_keys: list = [], sort: bool = True)[source]
Convert object to JSON string with safe serialization.
- Parameters:
obj – Python object to convert to JSON string.
indent (int) – Number of spaces for indentation. Default is 2.
non_serializable_text (str | None) – Text to use for non-serializable objects.
ignore_keys (list) – List of top-level keys to exclude from output.
sort (bool) – If True, sort dictionary keys. Default is True.
- Returns:
JSON string representation of obj.
- Return type:
str
- cmeta.utils.common.safe_serialize_json(obj, non_serializable_text: str | None = None)[source]
Recursively serialize Python objects to JSON-compatible format.
Handles objects that are not JSON serializable by converting them to strings or nested structures. Sets, tuples, and non-serializable objects are handled.
- Parameters:
obj – Python object to serialize.
non_serializable_text (str | None) – Text to use for non-serializable objects. Default is “#NON-SERIALIZABLE#”.
- Returns:
JSON-serializable version of obj (dict, list, str, int, float, bool, None).