Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add method for compiling code in a branch #188

Merged
merged 7 commits into from
Aug 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ 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`_).
* Add `gpu_specter`_ to known packages (PR `#189`_).

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

3.2.5 (2022-01-20)
------------------
Expand Down
17 changes: 17 additions & 0 deletions doc/desiInstall.rst
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,23 @@ 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`` exists, :command:`desiInstall` will run this
script, supplying the Python executable path as a single command-line argument.
The script itself is intended to be a thin wrapper on *e.g.*::

#!/bin/bash
py=$1
${py} setup.py build_ext --inplace


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

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

Expand Down
28 changes: 28 additions & 0 deletions py/desiutil/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,33 @@ 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:
current_dir = os.getcwd()
self.log.debug("os.chdir('%s')", self.install_dir)
os.chdir(self.install_dir)
proc = Popen([compile_script, sys.executable], universal_newlines=True,
stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
status = proc.returncode
self.log.debug(out)
self.log.debug("os.chdir('%s')", current_dir)
os.chdir(current_dir)
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 @@ -1027,6 +1054,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
37 changes: 37 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,42 @@ def test_get_extra(self, mock_popen, mock_exists):
self.assertLog(-1, message)
self.assertEqual(str(cm.exception), message)

@patch('os.chdir')
@patch('os.path.exists')
@patch('desiutil.install.Popen')
def test_compile_branch(self, mock_popen, mock_exists, mock_chdir):
"""Test compiling code in certain cases.
"""
current_dir = getcwd()
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_chdir.assert_has_calls([call(self.desiInstall.install_dir),
call(current_dir)])
mock_exists.assert_has_calls([call(join(self.desiInstall.install_dir, 'etc', 'fiberassign_compile.sh'))])
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