Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

143 linhas
4.9KB

  1. import multiprocessing
  2. import shutil
  3. import os
  4. from pathlib import Path
  5. import copy
  6. from typing import Optional, TypeVar, Iterable
  7. from . import paths, proc, toolchain as tc_mod
  8. from dds_ci.util import Pathish
  9. T = TypeVar('T')
  10. class DDSWrapper:
  11. """
  12. Wraps a 'dds' executable with some convenience APIs that invoke various
  13. 'dds' subcommands.
  14. """
  15. def __init__(self,
  16. path: Path,
  17. *,
  18. repo_dir: Optional[Pathish] = None,
  19. pkg_db_path: Optional[Pathish] = None,
  20. default_cwd: Optional[Pathish] = None) -> None:
  21. self.path = path
  22. self.repo_dir = Path(repo_dir or (paths.PREBUILT_DIR / 'ci-repo'))
  23. self.pkg_db_path = Path(pkg_db_path or (self.repo_dir.parent / 'ci-catalog.db'))
  24. self.default_cwd = default_cwd or Path.cwd()
  25. def clone(self: T) -> T:
  26. return copy.deepcopy(self)
  27. @property
  28. def pkg_db_path_arg(self) -> str:
  29. """The arguments for --catalog"""
  30. return f'--pkg-db-path={self.pkg_db_path}'
  31. @property
  32. def cache_dir_arg(self) -> str:
  33. """The arguments for --repo-dir"""
  34. return f'--pkg-cache-dir={self.repo_dir}'
  35. def set_repo_scratch(self, path: Pathish) -> None:
  36. self.repo_dir = Path(path) / 'data'
  37. self.pkg_db_path = Path(path) / 'pkgs.db'
  38. def clean(self, *, build_dir: Optional[Path] = None, repo: bool = True, pkg_db: bool = True) -> None:
  39. """
  40. Clean out prior executable output, including repos, pkg_db, and
  41. the build results at 'build_dir', if given.
  42. """
  43. if build_dir and build_dir.exists():
  44. shutil.rmtree(build_dir)
  45. if repo and self.repo_dir.exists():
  46. shutil.rmtree(self.repo_dir)
  47. if pkg_db and self.pkg_db_path.exists():
  48. self.pkg_db_path.unlink()
  49. def run(self, args: proc.CommandLine, *, cwd: Optional[Pathish] = None, timeout: Optional[int] = None) -> None:
  50. """Execute the 'dds' executable with the given arguments"""
  51. env = os.environ.copy()
  52. env['DDS_NO_ADD_INITIAL_REPO'] = '1'
  53. proc.check_run([self.path, args], cwd=cwd or self.default_cwd, env=env, timeout=timeout)
  54. def pkg_get(self, what: str) -> None:
  55. self.run(['pkg', 'get', self.pkg_db_path_arg, what])
  56. def repo_add(self, url: str) -> None:
  57. self.run(['pkg', 'repo', 'add', self.pkg_db_path_arg, url])
  58. def repo_remove(self, name: str) -> None:
  59. self.run(['pkg', 'repo', 'remove', self.pkg_db_path_arg, name])
  60. def repo_import(self, sdist: Path) -> None:
  61. self.run(['repo', self.cache_dir_arg, 'import', sdist])
  62. def pkg_import(self, filepath: Pathish) -> None:
  63. self.run(['pkg', 'import', filepath, self.cache_dir_arg])
  64. def build(self,
  65. *,
  66. root: Path,
  67. toolchain: Optional[Path] = None,
  68. build_root: Optional[Path] = None,
  69. jobs: Optional[int] = None,
  70. tweaks_dir: Optional[Path] = None,
  71. more_args: Optional[proc.CommandLine] = None,
  72. timeout: Optional[int] = None) -> None:
  73. """
  74. Run 'dds build' with the given arguments.
  75. :param toolchain: The toolchain to use for the build.
  76. :param root: The root project directory.
  77. :param build_root: The root directory where the output will be written.
  78. :param jobs: The number of jobs to use. Default is CPU-count + 2
  79. """
  80. toolchain = toolchain or tc_mod.get_default_audit_toolchain()
  81. jobs = jobs or multiprocessing.cpu_count() + 2
  82. self.run(
  83. [
  84. 'build',
  85. f'--toolchain={toolchain}',
  86. self.cache_dir_arg,
  87. self.pkg_db_path_arg,
  88. f'--jobs={jobs}',
  89. f'--project={root}',
  90. f'--out={build_root}',
  91. f'--tweaks-dir={tweaks_dir}' if tweaks_dir else (),
  92. more_args or (),
  93. ],
  94. timeout=timeout,
  95. )
  96. def compile_file(self,
  97. paths: Iterable[Pathish],
  98. *,
  99. toolchain: Optional[Pathish] = None,
  100. project_dir: Pathish,
  101. out: Optional[Pathish] = None) -> None:
  102. """
  103. Run 'dds compile-file' for the given paths.
  104. """
  105. toolchain = toolchain or tc_mod.get_default_audit_toolchain()
  106. self.run([
  107. 'compile-file',
  108. self.pkg_db_path_arg,
  109. self.cache_dir_arg,
  110. paths,
  111. f'--toolchain={toolchain}',
  112. f'--project={project_dir}',
  113. f'--out={out}',
  114. ])
  115. def build_deps(self, args: proc.CommandLine, *, toolchain: Optional[Path] = None) -> None:
  116. toolchain = toolchain or tc_mod.get_default_audit_toolchain()
  117. self.run([
  118. 'build-deps',
  119. f'--toolchain={toolchain}',
  120. self.pkg_db_path_arg,
  121. self.cache_dir_arg,
  122. args,
  123. ])