fs
==

.. py:module:: fs

.. autoapi-nested-parse::

   High-Level file manipulation.



Attributes
----------

.. autoapisummary::

   fs.logger
   fs.VCS_IGNORE_LIST


Classes
-------

.. autoapisummary::

   fs.FSError


Functions
---------

.. autoapisummary::

   fs.cp
   fs.directory_content
   fs.echo_to_file
   fs.find
   fs.get_filetree_state
   fs.ls
   fs.mkdir
   fs.mv
   fs.rm
   fs.splitall
   fs.sync_tree
   fs.extension


Module Contents
---------------

.. py:data:: logger

.. py:class:: FSError

   Bases: :py:obj:`e3.error.E3Error`


.. py:function:: cp(source: str | pathlib.Path, target: str | pathlib.Path, copy_attrs: bool = True, recursive: bool = False, preserve_symlinks: bool = False) -> None

   Copy files.

   :param source: a glob pattern
   :param target: target file or directory. If the source resolves as
       several files then target should be a directory
   :param copy_attrs: If True, also copy all the file attributes such as
       mode, timestamps, ownership, etc.
   :param recursive: If True, recursive copy. This also preserves
       attributes; if copy_attrs is False, a warning is emitted.
   :param preserve_symlinks: if True symlinks are recreated in the
       destination folder
   :raise FSError: if an error occurs


.. py:function:: directory_content(path: str | pathlib.Path, include_root_dir: bool = False, unixpath: bool = False) -> list[str]

   Return the complete directory content (recusrsively).

   :param path: path for the which the content should be returned
   :param include_root_dir: if True include the root directory in the paths
       returned by the function. Otherwise return relative paths
   :param unixpath: if True return unix compatible paths (calling unixpath on
       all elements returned
   :return: a list of of path. Note that directories will end with a path
       separator


.. py:function:: echo_to_file(filename: str | pathlib.Path, content: str | list[str], append: bool = False) -> None

   Output content into a file.

   This function is useful when writing few content to a file for which we
   don't want to keep a file descriptor opened . In other cases, it's more
   efficient to open a file and use the regular python I/O functions.

   :param filename: file to write into
   :param content: string to be written
   :param append: if True append to the file, otherwise overwrite.


.. py:function:: find(root: str | pathlib.Path, pattern: str | None = None, include_dirs: bool = False, include_files: bool = True, follow_symlinks: bool = False) -> list[str]

   Find files or directory recursively.

   :param root: directory from which the research start
   :param pattern: glob pattern that files or directories should match in
       order to be included in the final result
   :param include_dirs: if True include directories
   :param include_files: if True include regular files
   :param follow_symlinks: if True include symbolic links

   :return: a list of files


.. py:function:: get_filetree_state(path: str | pathlib.Path, ignore_hidden: bool = True, hash_content: bool = False) -> str

   Compute a hash on a filetree to reflect its current state.

   :param path: root path of the file tree to be checked
   :param ignore_hidden: if True (default) then files and directories
       tarting with a dot are ignored.
   :param hash_content: if True, include the content in the hash.

   :return: a hash as a string

   By default, the function will not report changes in the hash if a file is
   modified and its attributes (size, modification time and mode) are not
   changed.
   This case is quite uncommon. By ignoring it we can compute efficiently a
   hash representing the state of the file tree without having to read the
   content of all files.


.. py:function:: ls(path: str | Iterable[str] | pathlib.Path | Iterable[pathlib.Path], emit_log_record: bool = True) -> list[str]

   list files.

   :param path: glob pattern or glob pattern list
   :param emit_log_record: if True, emit a log (debug) record

   :return: a list of filenames

   This function do not raise an error if no file matching the glob pattern
   is encountered. The only consequence is that an empty list is returned.


.. py:function:: mkdir(path: str | pathlib.Path, mode: int = 493, quiet: bool = False) -> None

   Create a directory.

   :param path: path to create. If intermediate directories do not exist
       the procedure create them
   :param mode: default is 0755
   :param quiet: whether a log record should be emitted when creating the
       directory
   :raise FSError: if an error occurs

   This function behaves quite like mkdir -p command shell. So if the
   directory already exist no error is raised.


.. py:function:: mv(source: str | pathlib.Path | Iterable[str] | Iterable[pathlib.Path], target: str | pathlib.Path) -> None

   Move files.

   :param source: a glob pattern, a sequence/iterator of glob patterns, a path,
       or a sequence/iterator of paths
   :param target: target file or directory. If the source resolves as
       several files then target should be a directory

   :raise FSError: if an error occurs


.. py:function:: rm(path: str | pathlib.Path | Iterable[str] | Iterable[pathlib.Path], recursive: bool = False, glob: bool = True) -> None

   Remove files.

   :param path: a glob pattern, a sequence/iterator of glob patterns, a path,
       or a sequence/iterator of paths
   :param recursive: if True do a recursive deletion. Default is False
   :param glob: if True globbing pattern expansion is used

   :raise FSError: if an error occurs

   Note that the function will not raise an error is there are no file to
   delete.


.. py:function:: splitall(path: str | pathlib.Path) -> tuple[str, Ellipsis]

   Split a path into a list of path components.

   :param path: path to split
   :return: a list of path components


.. py:data:: VCS_IGNORE_LIST
   :value: ('RCS', 'SCCS', 'CVS', 'CVS.adm', 'RCSLOG', '.svn', '.git', '.hg', '.bzr', '.cvsignore',...


.. py:function:: sync_tree(source: str | pathlib.Path, target: str | pathlib.Path, ignore: str | collections.abc.Sequence[str] | None = None, file_list: list[str] | None = None, delete: bool = True, preserve_timestamps: bool = True, delete_ignore: bool = False) -> tuple[list[str], list[str]]

   Synchronize the files and directories between two directories.

   :param source: the directory from where the files and directories
       need to be copied
   :param target: the target directory
   :param ignore: glob pattern or list of files or directories to ignore,
       if the name starts with `/` then only the path is taken into
       account from the root of the source (or target) directory.
       If the ignore value contains a glob pattern, it is taken in account
       only if it doesn't contain a /, since for now the filtering
       is not segmented by '/'.
   :param file_list: list of files to synchronize, if empty synchronize all
       files. Note that if file in the list is a directory then the complete
       content of that directory is included. Note also that ignore list
       takes precedence other file_list.
   :param delete: if True, remove files from target if they do not exist
       in source
   :param preserve_timestamps: if True preserve original timestamps.
       If False updated files get their timestamps set to current time.
   :param delete_ignore: if True files that are explicitely ignored
       are deleted. Note delete should be set to True in that case.


.. py:function:: extension(path: str | pathlib.Path) -> str

   Return the extension of a given filename.

   Contrary to os.path.splitext which returns .gz, the function will return
   .tar.gz if the file is FILENAME.tar.gz.

   :param path: a path
   :return: an extension


