Skip to content

Commit

Permalink
Merge pull request #34 from AllenNeuralDynamics/fix-remove-uv-require…
Browse files Browse the repository at this point in the history
…ment

Defer executable checks to class instantiation
  • Loading branch information
bruno-f-cruz authored Jan 11, 2025
2 parents 6c4edb4 + b2eff13 commit 828066f
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 78 deletions.
2 changes: 1 addition & 1 deletion src/aind_behavior_experiment_launcher/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.3.0"
__version__ = "0.3.1"

import logging
import logging.config
Expand Down
16 changes: 10 additions & 6 deletions src/aind_behavior_experiment_launcher/apps/python_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@

_HAS_UV = shutil.which("uv") is not None

if not _HAS_UV:
logging.error("uv executable not detected.")
raise RuntimeError(
"uv is not installed in this computer. Please install uv. see https://docs.astral.sh/uv/getting-started/installation/"
)


class PythonScriptApp(App):
def __init__(
Expand All @@ -31,6 +25,7 @@ def __init__(
append_python_exe: bool = False,
timeout: Optional[float] = None,
) -> None:
self._validate_uv()
self._script = script
self._project_directory = project_directory
self._timeout = timeout
Expand Down Expand Up @@ -122,3 +117,12 @@ def _add_uv_project_directory(self) -> str:

def _add_uv_optional_toml_dependencies(self) -> str:
return " ".join([f"--extra {dep}" for dep in self._optional_toml_dependencies])

@staticmethod
def _validate_uv() -> bool:
if not _HAS_UV:
logging.error("uv executable not detected.")
raise RuntimeError(
"uv is not installed in this computer. Please install uv. see https://docs.astral.sh/uv/getting-started/installation/"
)
return True
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

DEFAULT_EXTRA_ARGS = "/E /DCOPY:DAT /R:100 /W:3 /tee"

_HAS_ROBOCOPY = shutil.which("robocopy") is not None


class RobocopyService(DataTransfer):
def __init__(
Expand Down Expand Up @@ -82,7 +84,7 @@ def _solve_src_dst_mapping(
return {source: Path(destination)}

def validate(self):
if not shutil.which("robocopy"):
if not _HAS_ROBOCOPY:
logger.error("Robocopy command is not available on this system.")
return False
return True
15 changes: 11 additions & 4 deletions src/aind_behavior_experiment_launcher/launcher/git_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@

logger = logging.getLogger(__name__)

_HAS_GIT = shutil.which("git") is not None

if not _HAS_GIT:
logging.error("git executable not detected.")
raise RuntimeError("git is not installed in this computer. Please install git. https://git-scm.com/downloads")
_HAS_GIT = shutil.which("git") is not None


class GitRepository(Repo):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._validate_git()

def reset_repo(self) -> Self:
self.git.reset("--hard")
Expand Down Expand Up @@ -67,3 +65,12 @@ def try_prompt_full_reset(self, ui_helper: UIHelper, force_reset: bool = False)
logging.info("Full reset of repository and submodules: %s", self.working_dir)
self.full_reset()
return self

@staticmethod
def _validate_git() -> bool:
if not _HAS_GIT:
logging.error("git executable not detected.")
raise RuntimeError(
"git is not installed in this computer. Please install git. https://git-scm.com/downloads"
)
return True
10 changes: 0 additions & 10 deletions tests/test_data_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,6 @@ def test_transfer(self, mock_popen):
mock_popen.return_value = mock_process
self.service.transfer()

@patch("src.aind_behavior_experiment_launcher.data_transfer.robocopy.shutil.which", return_value=None)
def test_validate_fail(self, mock_which):
result = self.service.validate()
self.assertFalse(result)

@patch("src.aind_behavior_experiment_launcher.data_transfer.robocopy.shutil.which", return_value="robocopy")
def test_validate_success(self, mock_which):
result = self.service.validate()
self.assertTrue(result)

def test_solve_src_dst_mapping_single_path(self):
result = self.service._solve_src_dst_mapping(self.source, self.destination)
self.assertEqual(result, {Path(self.source): Path(self.destination)})
Expand Down
Loading

0 comments on commit 828066f

Please sign in to comment.