Skip to content

Commit

Permalink
Merge 4ccdccb into 5362733
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverba137 committed Aug 18, 2022
2 parents 5362733 + 4ccdccb commit e32bd3c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ Change Log
* :command:`desiInstall` uses desihub location of simqso fork (commit e963344_).
* Allow :command:`desiInstall` to remove permission-locked directories;
suppress certain :command:`pip` warnings (PR `#185`_).
* Allow :command:`desiInstall` to compile code in certain branch installs (PR `#188`_).

.. _e963344: https://github.com/desihub/desiutil/commit/e963344cd072255174187d2bd6da72d085745abd
.. _`#185`: https://github.com/desihub/desiutil/pull/185
.. _`#188`: https://github.com/desihub/desiutil/pull/188

3.2.5 (2022-01-20)
------------------
Expand Down
14 changes: 14 additions & 0 deletions doc/desiInstall.rst
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,20 @@ not bundled with the code. The script should download data *directly* to
with :command:`desiInstall` and unit tests. Note that here are other, better ways to
install and manipulate data that is bundled *with* a Python package.

Compile in Branch Installs
--------------------------

In a few cases (fiberassign_, specex_) code needs to be compiled even when
installing a branch. If :command:`desiInstall` detects a branch install *and*
the script ``etc/product_compile.sh``, :command:`desiInstall` will run this
script, supplying the Python executable path as a single command-line arguement.
The script itself is intended to be a thin wrapper on *e.g.*::

python setup.py build_ext --inplace

.. _fiberassign: https://github.com/desihub/fiberassign
.. _specex: https://github.com/desihub/specex

Fix Permissions
---------------

Expand Down
23 changes: 23 additions & 0 deletions py/desiutil/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,28 @@ def get_extra(self):
raise DesiInstallException(message)
return

def compile_branch(self):
"""Certain packages need C/C++ code compiled even for a branch install.
"""
if self.is_branch:
compile_script = os.path.join(self.install_dir, 'etc',
'{0}_compile.sh'.format(self.baseproduct))
if os.path.exists(compile_script):
self.log.debug("Detected compile script: %s.", compile_script)
if self.options.test:
self.log.debug('Test Mode. Skipping compile script.')
else:
proc = Popen([compile_script, sys.executable], universal_newlines=True,
stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
status = proc.returncode
self.log.debug(out)
if status != 0 and len(err) > 0:
message = "Error compiling code: {0}".format(err)
self.log.critical(message)
raise DesiInstallException(message)
return

def verify_bootstrap(self):
"""Make sure that desiutil/desiInstall was installed with
an explicit Python executable path.
Expand Down Expand Up @@ -1026,6 +1048,7 @@ def run(self): # pragma: no cover
self.prepare_environment()
self.install()
self.get_extra()
self.compile_branch()
self.verify_bootstrap()
self.permissions()
except DesiInstallException:
Expand Down
34 changes: 34 additions & 0 deletions py/desiutil/test/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
"""Test desiutil.install.
"""
import sys
import unittest
from unittest.mock import patch, call, MagicMock, mock_open
from os import chdir, environ, getcwd, mkdir, remove, rmdir
Expand Down Expand Up @@ -507,6 +508,39 @@ def test_get_extra(self, mock_popen, mock_exists):
self.assertLog(-1, message)
self.assertEqual(str(cm.exception), message)

@patch('os.path.exists')
@patch('desiutil.install.Popen')
def test_compile_branch(self, mock_popen, mock_exists):
"""Test compiling code in certain cases.
"""
options = self.desiInstall.get_options(['fiberassign', 'branches/main'])
self.desiInstall.baseproduct = 'fiberassign'
self.desiInstall.is_branch = True
self.desiInstall.install_dir = join(self.data_dir, 'fiberassign')
mock_exists.return_value = True
mock_proc = mock_popen()
mock_proc.returncode = 0
mock_proc.communicate.return_value = ('out', 'err')
self.desiInstall.compile_branch()
# mock_exists.assert_called_once_with(join(self.desiInstall.install_dir, 'etc', 'fiberassign_compile.sh'),
# sys.executable)
mock_popen.assert_has_calls([call([join(self.desiInstall.install_dir, 'etc', 'fiberassign_compile.sh'), sys.executable],
stderr=-1, stdout=-1, universal_newlines=True)], any_order=True)
mock_popen.reset_mock()
self.desiInstall.options.test = True
self.desiInstall.compile_branch()
self.assertLog(-1, 'Test Mode. Skipping compile script.')
mock_popen.reset_mock()
self.desiInstall.options.test = False
mock_proc = mock_popen()
mock_proc.returncode = 1
mock_proc.communicate.return_value = ('out', 'err')
with self.assertRaises(DesiInstallException) as cm:
self.desiInstall.compile_branch()
message = "Error compiling code: err"
self.assertLog(-1, message)
self.assertEqual(str(cm.exception), message)

def test_verify_bootstrap(self):
"""Test proper installation of the desiInstall executable.
"""
Expand Down

0 comments on commit e32bd3c

Please sign in to comment.