def METHOD_NAME(
    self, options: List[str] = [], exclude: List[str] = [],
    force_trailing_slash: bool = False
) -> None:
    """
    Sync data from source to target using the rsync protocol
    :param list options: rsync options
    :param list exclude: file patterns to exclude
    :param bool force_trailing_slash: add '/' to source_dir if not present
    A speciality of the rsync tool is that it behaves differently
    if the given source_dir ends with a '/' or not. If it ends
    with a slash the data structure below will be synced to the
    target_dir. If it does not end with a slash the source_dir
    and its contents are synced to the target_dir. For example
    .. code:: bash
        source
          └── some_data
        1. $ rsync -a source target
        target
          └── source
                └── some_data
        2. $ rsync -a source/ target
        target
          └── some_data
    The parameter force_trailing_slash can be used to make
    sure rsync behaves like shown in the second case. If
    set to true a '/' is appended to the given source_dir
    if not already present
    """
    if force_trailing_slash and not self.source_dir.endswith(os.sep):
        self.source_dir += os.sep
    target_entry_permissions = None
    exclude_options = []
    rsync_options = []
    if options:
        rsync_options = options
    if not self.target_supports_extended_attributes():
        warn_me = False
        if '--xattrs' in rsync_options:
            rsync_options.remove('--xattrs')
            warn_me = True
        if '--acls' in rsync_options:
            rsync_options.remove('--acls')
            warn_me = True
        if warn_me:
            log.warning(
                'Extended attributes not supported for target: %s',
                self.target_dir
            )
    if exclude:
        for item in exclude:
            exclude_options.append('--exclude')
            exclude_options.append(
                '/' + item
            )
    if os.path.exists(self.target_dir):
        target_entry_permissions = os.stat(self.target_dir)[ST_MODE]
    Command.run(
        ['rsync'] + rsync_options + exclude_options + [
            self.source_dir, self.target_dir
        ]
    )
    if target_entry_permissions:
        # rsync applies the permissions of the source directory
        # also to the target directory which is unwanted because
        # only permissions of the files and directories from the
        # source directory and its contents should be transfered
        # but not from the source directory itself. Therefore
        # the permission bits of the target directory before the
        # sync are applied back after sync to ensure they have
        # not changed
        os.chmod(self.target_dir, target_entry_permissions)