summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChristoph Junghans <christoph.junghans@gmail.com>2017-10-02 23:56:43 -0600
committerTodd Gamblin <tgamblin@llnl.gov>2017-10-02 22:56:43 -0700
commitd22ee8f9930daa9b9d9362eccc9758fe2b5f36ae (patch)
tree9f96c667664d4490f6110f163da16beec872ea27 /lib
parent35085fdae2038977ff7a2cdff90cebd92c557172 (diff)
downloadspack-d22ee8f9930daa9b9d9362eccc9758fe2b5f36ae.tar.gz
spack-d22ee8f9930daa9b9d9362eccc9758fe2b5f36ae.tar.bz2
spack-d22ee8f9930daa9b9d9362eccc9758fe2b5f36ae.tar.xz
spack-d22ee8f9930daa9b9d9362eccc9758fe2b5f36ae.zip
patch: add workdir option (#5501)
* patch: add working_dir option * added documentation
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/docs/packaging_guide.rst30
-rw-r--r--lib/spack/spack/directives.py6
-rw-r--r--lib/spack/spack/patch.py21
3 files changed, 46 insertions, 11 deletions
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index 57eafde2dc..4a977205db 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -1304,6 +1304,36 @@ It's generally easier to just structure your patch file so that it
applies cleanly with ``-p1``, but if you're using a patch you didn't
create yourself, ``level`` can be handy.
+"""""""""""""""
+``working_dir``
+"""""""""""""""
+
+This tells spack where to run the ``patch`` command. By default,
+the working directory is the source path of the stage (``.``).
+However, sometimes patches are made with respect to a subdirectory
+and this is where the working directory comes in handy. Internally,
+the working directory is given to ``patch`` via the ``-d`` option.
+Let's take the example patch from above and assume for some reason,
+it can only be downloaded in the following form:
+
+.. code-block:: diff
+ :linenos:
+
+ --- a/romio/adio/ad_lustre/ad_lustre_rwcontig.c 2013-12-10 12:05:44.806417000 -0800
+ +++ b/romio/adio/ad_lustre/ad_lustre_rwcontig.c 2013-12-10 11:53:03.295622000 -0800
+ @@ -8,7 +8,7 @@
+ * Copyright (C) 2008 Sun Microsystems, Lustre group
+ \*/
+
+ -#define _XOPEN_SOURCE 600
+ +//#define _XOPEN_SOURCE 600
+ #include <stdlib.h>
+ #include <malloc.h>
+ #include "ad_lustre.h"
+
+Hence, the patch needs to applied in the ``src/mpi`` subdirectory, and the
+``working_dir='src/mpi'`` option would exactly do that.
+
^^^^^^^^^^^^^^^^^^^^^
Patch functions
^^^^^^^^^^^^^^^^^^^^^
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index cf12b16dd6..e294ac15d1 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -410,7 +410,7 @@ def provides(*specs, **kwargs):
@directive('patches')
-def patch(url_or_filename, level=1, when=None, **kwargs):
+def patch(url_or_filename, level=1, when=None, working_dir=".", **kwargs):
"""Packages can declare patches to apply to source. You can
optionally provide a when spec to indicate that a particular
patch should only be applied when the package's spec meets
@@ -421,6 +421,7 @@ def patch(url_or_filename, level=1, when=None, **kwargs):
level (int): patch level (as in the patch shell command)
when (Spec): optional anonymous spec that specifies when to apply
the patch
+ working_dir (str): dir to change to before applying
Keyword Args:
sha256 (str): sha256 sum of the patch, used to verify the patch
@@ -437,7 +438,8 @@ def patch(url_or_filename, level=1, when=None, **kwargs):
# patch to the existing list.
cur_patches = pkg_or_dep.patches.setdefault(when_spec, [])
cur_patches.append(
- Patch.create(pkg_or_dep, url_or_filename, level, **kwargs))
+ Patch.create(pkg_or_dep, url_or_filename, level,
+ working_dir, **kwargs))
return _execute_patch
diff --git a/lib/spack/spack/patch.py b/lib/spack/spack/patch.py
index 2f52fbdc9f..028f98f3a1 100644
--- a/lib/spack/spack/patch.py
+++ b/lib/spack/spack/patch.py
@@ -56,7 +56,7 @@ class Patch(object):
"""
@staticmethod
- def create(pkg, path_or_url, level=1, **kwargs):
+ def create(pkg, path_or_url, level=1, working_dir=".", **kwargs):
"""
Factory method that creates an instance of some class derived from
Patch
@@ -65,23 +65,25 @@ class Patch(object):
pkg: package that needs to be patched
path_or_url: path or url where the patch is found
level: patch level (default 1)
+ working_dir (str): dir to change to before applying (default '.')
Returns:
instance of some Patch class
"""
# Check if we are dealing with a URL
if '://' in path_or_url:
- return UrlPatch(path_or_url, level, **kwargs)
+ return UrlPatch(path_or_url, level, working_dir, **kwargs)
# Assume patches are stored in the repository
- return FilePatch(pkg, path_or_url, level)
+ return FilePatch(pkg, path_or_url, level, working_dir)
- def __init__(self, path_or_url, level):
+ def __init__(self, path_or_url, level, working_dir):
# Check on level (must be an integer > 0)
if not isinstance(level, int) or not level >= 0:
raise ValueError("Patch level needs to be a non-negative integer.")
# Attributes shared by all patch subclasses
self.path_or_url = path_or_url
self.level = level
+ self.working_dir = working_dir
# self.path needs to be computed by derived classes
# before a call to apply
self.path = None
@@ -99,13 +101,14 @@ class Patch(object):
patch = which("patch", required=True)
with working_dir(stage.source_path):
# Use -N to allow the same patches to be applied multiple times.
- patch('-s', '-p', str(self.level), '-i', self.path)
+ patch('-s', '-p', str(self.level), '-i', self.path,
+ "-d", self.working_dir)
class FilePatch(Patch):
"""Describes a patch that is retrieved from a file in the repository"""
- def __init__(self, pkg, path_or_url, level):
- super(FilePatch, self).__init__(path_or_url, level)
+ def __init__(self, pkg, path_or_url, level, working_dir):
+ super(FilePatch, self).__init__(path_or_url, level, working_dir)
pkg_dir = os.path.dirname(absolute_path_for_package(pkg))
self.path = os.path.join(pkg_dir, path_or_url)
@@ -123,8 +126,8 @@ class FilePatch(Patch):
class UrlPatch(Patch):
"""Describes a patch that is retrieved from a URL"""
- def __init__(self, path_or_url, level, **kwargs):
- super(UrlPatch, self).__init__(path_or_url, level)
+ def __init__(self, path_or_url, level, working_dir, **kwargs):
+ super(UrlPatch, self).__init__(path_or_url, level, working_dir)
self.url = path_or_url
self.archive_sha256 = None