Skip to content

Commit

Permalink
✨ GitHubTextualPath
Browse files Browse the repository at this point in the history
  • Loading branch information
juftin committed Mar 12, 2024
1 parent 73fab41 commit 8aa06d8
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 34 deletions.
10 changes: 5 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from typing import Any, Dict, List

import pytest
from upath import UPath

from tests.helpers import Screenshotter
from textual_universal_directorytree.alternate_paths import GitHubPath


@pytest.fixture
Expand All @@ -28,13 +28,13 @@ def screenshot_dir(repo_dir: pathlib.Path) -> pathlib.Path:


@pytest.fixture
def github_release_path() -> GitHubPath:
def github_release_path() -> UPath:
"""
Return the path to the GitHub Release
"""
release = "v1.0.0"
uri = f"github://juftin:textual-universal-directorytree@{release}"
return GitHubPath(uri)
return UPath(uri)


@pytest.fixture(scope="module")
Expand All @@ -56,13 +56,13 @@ def vcr_config() -> Dict[str, List[Any]]:


@pytest.fixture
def screenshotter(github_release_path: GitHubPath) -> Screenshotter:
def screenshotter(github_release_path: UPath) -> Screenshotter:
"""
Return a Screenshotter
Parameters
----------
github_release_path : GitHubPath
github_release_path : UPath
The path to the GitHub Release
Returns
Expand Down
30 changes: 30 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
Test utils
"""

from textual_universal_directorytree import UPath
from textual_universal_directorytree.alternate_paths import (
GitHubTextualPath,
S3TextualPath,
)
from textual_universal_directorytree.utils import is_local_path, is_remote_path


def test_is_local_path() -> None:
"""
Test is_local_path + is_remote_path
"""
local_tests_dir = UPath("tests")
assert is_local_path(local_tests_dir) is True
assert is_remote_path(local_tests_dir) is False
local_dot_dir = UPath(".")
assert is_local_path(local_dot_dir) is True
assert is_remote_path(local_dot_dir) is False
github_path = UPath("github://juftin:textual-universal-directorytree@main")
assert is_local_path(github_path) is False
assert is_remote_path(github_path) is True
assert isinstance(github_path, GitHubTextualPath)
s3_path = UPath("s3://bucket/key")
assert is_local_path(s3_path) is False
assert is_remote_path(s3_path) is True
assert isinstance(s3_path, S3TextualPath)
14 changes: 12 additions & 2 deletions textual_universal_directorytree/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@
Textual Universal Directory Tree
"""

from textual_universal_directorytree.alternate_paths import GitHubPath, S3TextualPath
from upath import UPath, registry

from textual_universal_directorytree.alternate_paths import (
GitHubTextualPath,
S3TextualPath,
)
from textual_universal_directorytree.universal_directory_tree import (
UniversalDirectoryTree,
)
from textual_universal_directorytree.utils import is_local_path, is_remote_path

registry.register_implementation(protocol="github", cls=GitHubTextualPath, clobber=True)
registry.register_implementation(protocol="s3", cls=S3TextualPath, clobber=True)
registry.register_implementation(protocol="s3a", cls=S3TextualPath, clobber=True)

__all__ = [
"UniversalDirectoryTree",
"is_local_path",
"is_remote_path",
"GitHubPath",
"GitHubTextualPath",
"S3TextualPath",
"UPath",
]
27 changes: 15 additions & 12 deletions textual_universal_directorytree/alternate_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,39 @@

from __future__ import annotations

from os import getenv
import os
from typing import Any

from upath.implementations.cloud import S3Path
from upath.implementations.github import GitHubPath as UGitHubPath
from upath.implementations.github import GitHubPath


class GitHubPath(UGitHubPath):
class GitHubTextualPath(GitHubPath):
"""
GitHubPath
UPath implementation for GitHub to be compatible with
the Directory Tree
UPath implementation for GitHub to be compatible with the Directory Tree
"""

def __init__(
self, *args: Any, protocol: str | None = None, **storage_options: Any
) -> None:
@classmethod
def _transform_init_args(
cls,
args: tuple[str | os.PathLike[Any], ...],
protocol: str,
storage_options: dict[str, Any],
) -> tuple[tuple[str | os.PathLike[Any], ...], str, dict[str, Any]]:
"""
Initialize the GitHubPath with GitHub Token Authentication
"""
if "token" not in storage_options:
token = getenv("GITHUB_TOKEN")
token = os.getenv("GITHUB_TOKEN")
if token is not None:
storage_options.update({"username": "Bearer", "token": token})
handled_args = args
if "sha" not in storage_options:
handled_url = self.handle_github_url(args[0])
handled_url = cls.handle_github_url(args[0])
handled_args = (handled_url, *args[1:])
super().__init__(*handled_args, protocol=protocol, **storage_options)
return handled_args, protocol, storage_options

def __str__(self) -> str:
"""
Expand Down Expand Up @@ -70,7 +73,7 @@ def handle_github_url(cls, url: str | GitHubPath) -> str:
else:
msg = f"Invalid GitHub URL: {url}"
raise ValueError(msg)
token = getenv("GITHUB_TOKEN")
token = os.getenv("GITHUB_TOKEN")
auth = {"auth": ("Bearer", token)} if token is not None else {}
resp = requests.get(
f"https://api.github.com/repos/{org}/{repo}",
Expand Down
8 changes: 1 addition & 7 deletions textual_universal_directorytree/universal_directory_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
"""

from textual.widgets import DirectoryTree
from upath import UPath, registry

from textual_universal_directorytree.alternate_paths import GitHubPath, S3TextualPath

registry.register_implementation(protocol="github", cls=GitHubPath, clobber=True)
registry.register_implementation(protocol="s3", cls=S3TextualPath, clobber=True)
registry.register_implementation(protocol="s3a", cls=S3TextualPath, clobber=True)
from upath import UPath


class UniversalDirectoryTree(DirectoryTree):
Expand Down
16 changes: 8 additions & 8 deletions textual_universal_directorytree/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

import pathlib

from upath.core import _FSSpecAccessor
from upath import UPath
from upath.implementations.local import LocalPath


def is_remote_path(path: pathlib.Path) -> bool:
def is_local_path(path: pathlib.Path) -> bool:
"""
Check if the path is a remote path
Check if the path is a local path
"""
accessor = getattr(path, "_accessor", None)
return isinstance(accessor, _FSSpecAccessor)
return isinstance(path, LocalPath)


def is_local_path(path: pathlib.Path) -> bool:
def is_remote_path(path: UPath) -> bool:
"""
Check if the path is a local path
Check if the path is a remote path
"""
return not is_remote_path(path)
return not is_local_path(path)

0 comments on commit 8aa06d8

Please sign in to comment.