Skip to content

Commit

Permalink
Merge branch 'main' into comments_in_workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
falkoschindler committed Oct 26, 2023
2 parents 3e44cdc + 2340268 commit 74d7f4d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 19 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,20 @@ Positional arguments:
Options:

- `--target-root TARGET_ROOT`
subfolder on target to synchronize to
subfolder on target to synchronize to (default: "")
- `--target-port TARGET_PORT`
SSH port on target
SSH port on target (default: 22)
- `--on-change ON_CHANGE`
command to be executed on remote host after any file change
command to be executed on remote host after any file change (default: None)
- `--mutex-interval MUTEX_INTERVAL`
interval in which mutex is updated
interval in which mutex is updated (default: 10 seconds)

### Notes

- We suggest you have some auto-reloading in place on the (slow) target machine, like [NiceGUI](https://nicegui.io).
- Only one user per target host should run LiveSync at a time. Therefore LiveSync provides a mutex mechanism.
- By default `.git/` folders are not synchronized.
- All files and directories from the `.gitignore` of any source directory are also excluded from synchronization.
- You can create a `.syncignore` file in any source directory to skip additional files and directories from syncing.
- If a `.syncignore` file doesn't exist, it is automatically created containing `.git/`, `__pycache__/`, `.DS_Store`, `*.tmp`, and `.env`.
- If you pass a VSCode workspace file as `source`, LiveSync will synchronize each directory listed in the `folders` section.

## Installation
Expand Down
19 changes: 7 additions & 12 deletions livesync/folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import watchfiles

KWONLY_SLOTS = {'kw_only': True, 'slots': True} if sys.version_info >= (3, 10) else {}
DEFAULT_IGNORES = ['.git/', '__pycache__/', '.DS_Store', '*.tmp', '.env']


def run_subprocess(command: str, *, quiet: bool = False) -> None:
Expand Down Expand Up @@ -36,7 +37,7 @@ def __init__(self, local_dir: Path, target: Target) -> None:

# from https://stackoverflow.com/a/22090594/3419103
match_pattern = pathspec.patterns.gitwildmatch.GitWildMatchPattern
self._ignore_spec = pathspec.PathSpec.from_lines(match_pattern, self.get_excludes())
self._ignore_spec = pathspec.PathSpec.from_lines(match_pattern, self.get_ignores())

self._stop_watching = asyncio.Event()

Expand All @@ -48,17 +49,11 @@ def target_path(self) -> Path:
def ssh_path(self) -> str:
return f'{self.target.host}:{self.target_path}'

def get_excludes(self) -> List[str]:
return ['.git/', '__pycache__/', '.DS_Store', '*.tmp', '.env'] + \
self._parse_ignore_file(self.local_path / '.syncignore') + \
self._parse_ignore_file(self.local_path / '.gitignore')

@staticmethod
def _parse_ignore_file(path: Path) -> List[str]:
def get_ignores(self) -> List[str]:
path = self.local_path / '.syncignore'
if not path.is_file():
return []
with path.open() as f:
return [line.strip() for line in f.readlines() if not line.startswith('#')]
path.write_text('\n'.join(DEFAULT_IGNORES))
return [line.strip() for line in path.read_text().splitlines() if not line.startswith('#')]

def get_summary(self) -> str:
summary = f'{self.local_path} --> {self.ssh_path}\n'
Expand Down Expand Up @@ -90,7 +85,7 @@ def stop_watching(self) -> None:
def sync(self, post_sync_command: Optional[str] = None) -> None:
args = '--prune-empty-dirs --delete -avz --checksum --no-t'
# args += ' --mkdirs' # INFO: this option is not available in rsync < 3.2.3
args += ''.join(f' --exclude="{e}"' for e in self.get_excludes())
args += ''.join(f' --exclude="{e}"' for e in self.get_ignores())
args += f' -e "ssh -p {self.target.port}"'
run_subprocess(f'rsync {args} {self.local_path}/ {self.ssh_path}/', quiet=True)
if post_sync_command:
Expand Down
4 changes: 3 additions & 1 deletion livesync/livesync.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ def git_summary(folders: List[Folder]) -> str:


async def async_main() -> None:
parser = argparse.ArgumentParser(description='Repeatedly synchronize local directories with remote machine')
parser = argparse.ArgumentParser(
description='Repeatedly synchronize local directories with remote machine',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('source', type=str, help='local source folder or VSCode workspace file')
parser.add_argument('--target-root', type=str, default='', help='subfolder on target to synchronize to')
parser.add_argument('--target-port', type=int, default=22, help='SSH port on target')
Expand Down
2 changes: 2 additions & 0 deletions tests/test_syncing_with_git_summary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set -e
# create source folder
mkdir -p /root/my_project
echo 'file content' > /root/my_project/file.txt
echo '.syncignore' > /root/my_project/.gitignore

# create git repository
cd /root/my_project
Expand All @@ -13,6 +14,7 @@ git config --global user.email "[email protected]"
git config --global user.name "Zauberzeug"
git init
git add file.txt
git add .gitignore
git commit -m 'initial commit'

# livesync should create the target file
Expand Down

0 comments on commit 74d7f4d

Please sign in to comment.