Skip to content

Commit

Permalink
fix PATH resolution and abspath resolving after install
Browse files Browse the repository at this point in the history
  • Loading branch information
pirate committed Aug 30, 2024
1 parent e600395 commit 224efe3
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 18 deletions.
29 changes: 13 additions & 16 deletions pydantic_pkgr/binprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def validate_bin_dir(path: Path) -> Path:
def validate_PATH(PATH: str | List[str]) -> str:
paths = PATH.split(':') if isinstance(PATH, str) else list(PATH)
assert all(Path(bin_dir) for bin_dir in paths)
return ':'.join(paths)
return ':'.join(paths).strip(':')

PATHStr = Annotated[str, BeforeValidator(validate_PATH)]

Expand Down Expand Up @@ -295,7 +295,7 @@ class BinProvider(BaseModel):
model_config = ConfigDict(extra='ignore', populate_by_name=True, validate_defaults=True, revalidate_instances='always')
name: BinProviderName = ''

PATH: PATHStr = Field(default='') # e.g. '/opt/homebrew/bin:/opt/archivebox/bin'
PATH: PATHStr = Field(default=str(Path(sys.executable).parent)) # e.g. '/opt/homebrew/bin:/opt/archivebox/bin'
INSTALLER_BIN: BinName = 'env'

abspath_handler: ProviderLookupDict = Field(default={'*': 'self.on_get_abspath'}, exclude=True)
Expand Down Expand Up @@ -368,15 +368,6 @@ def exec(self, bin_name: BinName | HostBinPath, cmd: Iterable[str | Path | int |
cmd = [str(bin_abspath), *(str(arg) for arg in cmd)]
return run(cmd, stdout=PIPE, stderr=PIPE, text=True, cwd=str(cwd), **kwargs)

@field_validator('PATH', mode='after')
@classmethod
def load_PATH(cls, PATH: PATHStr) -> PATHStr:
python_bin_dir = str(Path(sys.executable).parent)

if python_bin_dir not in PATH:
PATH = ':'.join([python_bin_dir, *PATH.split(':')])
return TypeAdapter(PATHStr).validate_python(PATH)

def get_default_handlers(self):
return self.get_handlers_for_bin('*')

Expand Down Expand Up @@ -661,15 +652,16 @@ class NpmProvider(BinProvider):
name: BinProviderName = 'npm'
INSTALLER_BIN: BinName = 'npm'

PATH: PATHStr = ''

@model_validator(mode='after')
def load_PATH_from_npm_prefix(self):
if not self.INSTALLER_BIN_ABSPATH:
return TypeAdapter(PATHStr).validate_python('')

PATH = self.PATH

npm_global_dir = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix', '-g']).stdout.strip() + '/bin' # /opt/homebrew/bin
npm_bin_dirs = {npm_global_dir}
npm_bin_dirs = set()

search_dir = Path(self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix']).stdout.strip())
stop_if_reached = [str(Path('/')), str(Path('~').expanduser().absolute())]
Expand All @@ -683,9 +675,12 @@ def load_PATH_from_npm_prefix(self):
search_dir = search_dir.parent
num_hops += 1

npm_global_dir = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix', '-g']).stdout.strip() + '/bin' # /opt/homebrew/bin
npm_bin_dirs.add(npm_global_dir)

for bin_dir in npm_bin_dirs:
if str(bin_dir) not in PATH:
PATH = ':'.join([str(bin_dir), *PATH.split(':')])
PATH = ':'.join([*PATH.split(':'), str(bin_dir)])
self.PATH = TypeAdapter(PATHStr).validate_python(PATH)
return self

Expand All @@ -707,6 +702,8 @@ def on_install(self, bin_name: str, packages: Optional[InstallArgs]=None, **cont
class AptProvider(BinProvider):
name: BinProviderName = 'apt'
INSTALLER_BIN: BinName = 'apt-get'

PATH: PATHStr = ''

packages_handler: ProviderLookupDict = {
**BinProvider.model_fields['packages_handler'].default,
Expand Down Expand Up @@ -749,7 +746,7 @@ def on_install(self, bin_name: BinName, packages: Optional[InstallArgs]=None, **

apt.packages(
name=f"Ensure {bin_name} is installed",
packages=packages.split(' '),
packages=packages,
update=True,
_sudo=True,
)
Expand Down Expand Up @@ -806,7 +803,7 @@ def on_install(self, bin_name: str, packages: Optional[InstallArgs]=None, **cont
class EnvProvider(BinProvider):
name: BinProviderName = 'env'
INSTALLER_BIN: BinName = 'env'
PATH: PATHStr = Field(default=DEFAULT_ENV_PATH) # add dir containing python to $PATH
PATH: PATHStr = DEFAULT_ENV_PATH # add dir containing python to $PATH

abspath_handler: ProviderLookupDict = {
**BinProvider.model_fields['abspath_handler'].default,
Expand Down
4 changes: 2 additions & 2 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,13 @@ def test_env_provider(self):
def test_pip_provider(self):
pipprovider = PipProvider()
# print(provider.PATH)
binary = Binary(name='wget', binproviders=[pipprovider])
binary = Binary(name='yt-dlp', binproviders=[pipprovider])
self.install_with_binprovider(pipprovider, binary)

def test_npm_provider(self):
npmprovider = NpmProvider()
# print(provider.PATH)
binary = Binary(name='wget', binproviders=[npmprovider])
binary = Binary(name='single-file', binproviders=[npmprovider], overrides={'env': {'packages': lambda: ['single-file-cli']}})
self.install_with_binprovider(npmprovider, binary)

def test_brew_provider(self):
Expand Down

0 comments on commit 224efe3

Please sign in to comment.