(source_path: Path, plugins_dir: Path, target_path: Path)
| 222 | |
| 223 | |
| 224 | def _copy_local_plugin(source_path: Path, plugins_dir: Path, target_path: Path) -> None: |
| 225 | temp_target = plugins_dir / f".{target_path.name}.tmp-{uuid.uuid4().hex}" |
| 226 | try: |
| 227 | shutil.copytree(source_path, temp_target, ignore=LOCAL_PLUGIN_COPY_IGNORE) |
| 228 | temp_target.rename(target_path) |
| 229 | except FileExistsError: |
| 230 | raise click.ClickException( |
| 231 | f"Plugin {target_path.name} already exists" |
| 232 | ) from None |
| 233 | except Exception: |
| 234 | raise |
| 235 | finally: |
| 236 | if temp_target.exists() or temp_target.is_symlink(): |
| 237 | _cleanup_local_plugin_target(temp_target) |
| 238 | |
| 239 | |
| 240 | def install_local_plugin( |
no test coverage detected