Skip to content

Commit

Permalink
Introduce PluginSource, PluginSourceGit, PluginSourceLocal
Browse files Browse the repository at this point in the history
- they'll be used to install or update plugins
- the idea is to support both raw directories and git repos from local media
- and of course support for git remote repositories
- PluginSources are expected to be configured by UI
  • Loading branch information
zas authored and phw committed Sep 24, 2024
1 parent 2916828 commit 41eb0da
Showing 1 changed file with 57 additions and 26 deletions.
83 changes: 57 additions & 26 deletions picard/plugin3/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,57 @@ def transfer_progress(self, stats):
print(f'{stats.indexed_objects}/{stats.total_objects}')


class PluginSourceSyncError(Exception):
pass


class PluginSource:
"""Abstract class for plugin sources"""

def sync(self, target_directory: str):
raise NotImplementedError


class PluginSourceGit(PluginSource):
"""Plugin is stored in a git repository, local or remote"""
def __init__(self, url: str, ref: str = None):
super().__init__()
# Note: url can be a local directory
self.url = url
self.ref = ref or 'main'

def sync(self, target_directory: str):
if os.path.isdir(target_directory):
print(f'{target_directory} exists, fetch changes')
repo = pygit2.Repository(target_directory)
for remote in repo.remotes:
remote.fetch(callbacks=GitRemoteCallbacks())
else:
print(f'Cloning {self.url} to {target_directory}')
repo = pygit2.clone_repository(self.url, target_directory, callbacks=GitRemoteCallbacks())
print(list(repo.references))
print(list(repo.branches))
print(list(repo.remotes))

if self.ref:
commit = repo.revparse_single(self.ref)
else:
commit = repo.revparse_single('HEAD')

print(commit)
print(commit.message)
# hard reset to passed ref or HEAD
repo.reset(commit.id, pygit2.enums.ResetMode.HARD)


class PluginSourceLocal(PluginSource):
"""Plugin is stored in a local directory, but is not a git repo"""

def sync(self, target_directory: str):
# TODO: copy tree to plugin directory (?)
pass


class Plugin:
local_path: str = None
remote_url: str = None
Expand All @@ -52,34 +103,14 @@ def __init__(self, plugins_dir: str, plugin_name: str):
self.module_name = f'picard.plugins.{self.plugin_name}'
self.local_path = os.path.join(self.plugins_dir, self.plugin_name)

def sync(self, url: str = None, ref: str = None):
def sync(self, plugin_source: PluginSource = None):
"""Sync plugin source
Use remote url or local path, and sets the repository to ref
"""
if url:
self.remote_url = url
if os.path.isdir(self.local_path):
print(f'{self.local_path} exists, fetch changes')
repo = pygit2.Repository(self.local_path)
for remote in repo.remotes:
remote.fetch(callbacks=GitRemoteCallbacks())
else:
print(f'Cloning {url} to {self.local_path}')
repo = pygit2.clone_repository(url, self.local_path, callbacks=GitRemoteCallbacks())

print(list(repo.references))
print(list(repo.branches))
print(list(repo.remotes))

if ref:
commit = repo.revparse_single(ref)
else:
commit = repo.revparse_single('HEAD')

print(commit)
print(commit.message)
# hard reset to passed ref or HEAD
repo.reset(commit.id, pygit2.enums.ResetMode.HARD)
if plugin_source:
try:
plugin_source.sync(self.local_path)
except Exception as e:
raise PluginSourceSyncError(e)

def read_manifest(self):
"""Reads metadata for the plugin from the plugin's MANIFEST.toml
Expand Down

0 comments on commit 41eb0da

Please sign in to comment.