base_binary.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. __package__ = "abx.archivebox"
  2. from typing import Dict, List
  3. from typing_extensions import Self
  4. from pydantic import Field, InstanceOf, validate_call
  5. from pydantic_pkgr import (
  6. Binary,
  7. BinProvider,
  8. BinProviderName,
  9. ProviderLookupDict,
  10. AptProvider,
  11. BrewProvider,
  12. EnvProvider,
  13. )
  14. from archivebox.config import CONSTANTS
  15. import abx
  16. from .base_hook import BaseHook, HookType
  17. class BaseBinProvider(BaseHook, BinProvider):
  18. hook_type: HookType = "BINPROVIDER"
  19. # def on_get_abspath(self, bin_name: BinName, **context) -> Optional[HostBinPath]:
  20. # Class = super()
  21. # get_abspath_func = lambda: Class.on_get_abspath(bin_name, **context)
  22. # # return cache.get_or_set(f'bin:abspath:{bin_name}', get_abspath_func)
  23. # return get_abspath_func()
  24. # def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, **context) -> SemVer | None:
  25. # Class = super()
  26. # get_version_func = lambda: Class.on_get_version(bin_name, abspath, **context)
  27. # # return cache.get_or_set(f'bin:version:{bin_name}:{abspath}', get_version_func)
  28. # return get_version_func()
  29. # TODO: add install/load/load_or_install methods as abx.hookimpl methods
  30. @property
  31. def admin_url(self) -> str:
  32. # e.g. /admin/environment/binproviders/NpmBinProvider/ TODO
  33. return "/admin/environment/binaries/"
  34. @abx.hookimpl
  35. def get_BINPROVIDERS(self):
  36. return [self]
  37. class BaseBinary(BaseHook, Binary):
  38. hook_type: HookType = "BINARY"
  39. binproviders_supported: List[InstanceOf[BinProvider]] = Field(default_factory=list, alias="binproviders")
  40. provider_overrides: Dict[BinProviderName, ProviderLookupDict] = Field(default_factory=dict, alias="overrides")
  41. @staticmethod
  42. def symlink_to_lib(binary, bin_dir=None) -> None:
  43. bin_dir = bin_dir or CONSTANTS.LIB_BIN_DIR
  44. if not (binary.abspath and binary.abspath.exists()):
  45. return
  46. try:
  47. bin_dir.mkdir(parents=True, exist_ok=True)
  48. symlink = bin_dir / binary.name
  49. symlink.unlink(missing_ok=True)
  50. symlink.symlink_to(binary.abspath)
  51. except Exception as err:
  52. # print('[red]:caution: Failed to symlink binary into ./lib/bin folder[/red]', err)
  53. pass
  54. @validate_call
  55. def load(self, **kwargs) -> Self:
  56. binary = super().load(**kwargs)
  57. self.symlink_to_lib(binary=binary, bin_dir=CONSTANTS.LIB_BIN_DIR)
  58. return binary
  59. @validate_call
  60. def install(self, **kwargs) -> Self:
  61. binary = super().install(**kwargs)
  62. self.symlink_to_lib(binary=binary, bin_dir=CONSTANTS.LIB_BIN_DIR)
  63. return binary
  64. @validate_call
  65. def load_or_install(self, **kwargs) -> Self:
  66. binary = super().load_or_install(**kwargs)
  67. self.symlink_to_lib(binary=binary, bin_dir=CONSTANTS.LIB_BIN_DIR)
  68. return binary
  69. @property
  70. def admin_url(self) -> str:
  71. # e.g. /admin/environment/config/LdapConfig/
  72. return f"/admin/environment/binaries/{self.name}/"
  73. @abx.hookimpl
  74. def get_BINARIES(self):
  75. return [self]
  76. class AptBinProvider(AptProvider, BaseBinProvider):
  77. name: BinProviderName = "apt"
  78. class BrewBinProvider(BrewProvider, BaseBinProvider):
  79. name: BinProviderName = "brew"
  80. class EnvBinProvider(EnvProvider, BaseBinProvider):
  81. name: BinProviderName = "env"
  82. apt = AptBinProvider()
  83. brew = BrewBinProvider()
  84. env = EnvBinProvider()