patch: add workdir option (#5501)
* patch: add working_dir option * added documentation
This commit is contained in:
parent
35085fdae2
commit
d22ee8f993
@ -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
|
applies cleanly with ``-p1``, but if you're using a patch you didn't
|
||||||
create yourself, ``level`` can be handy.
|
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
|
Patch functions
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -410,7 +410,7 @@ def _execute_provides(pkg):
|
|||||||
|
|
||||||
|
|
||||||
@directive('patches')
|
@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
|
"""Packages can declare patches to apply to source. You can
|
||||||
optionally provide a when spec to indicate that a particular
|
optionally provide a when spec to indicate that a particular
|
||||||
patch should only be applied when the package's spec meets
|
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)
|
level (int): patch level (as in the patch shell command)
|
||||||
when (Spec): optional anonymous spec that specifies when to apply
|
when (Spec): optional anonymous spec that specifies when to apply
|
||||||
the patch
|
the patch
|
||||||
|
working_dir (str): dir to change to before applying
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
sha256 (str): sha256 sum of the patch, used to verify the patch
|
sha256 (str): sha256 sum of the patch, used to verify the patch
|
||||||
@ -437,7 +438,8 @@ def _execute_patch(pkg_or_dep):
|
|||||||
# patch to the existing list.
|
# patch to the existing list.
|
||||||
cur_patches = pkg_or_dep.patches.setdefault(when_spec, [])
|
cur_patches = pkg_or_dep.patches.setdefault(when_spec, [])
|
||||||
cur_patches.append(
|
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
|
return _execute_patch
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class Patch(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@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
|
Factory method that creates an instance of some class derived from
|
||||||
Patch
|
Patch
|
||||||
@ -65,23 +65,25 @@ def create(pkg, path_or_url, level=1, **kwargs):
|
|||||||
pkg: package that needs to be patched
|
pkg: package that needs to be patched
|
||||||
path_or_url: path or url where the patch is found
|
path_or_url: path or url where the patch is found
|
||||||
level: patch level (default 1)
|
level: patch level (default 1)
|
||||||
|
working_dir (str): dir to change to before applying (default '.')
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
instance of some Patch class
|
instance of some Patch class
|
||||||
"""
|
"""
|
||||||
# Check if we are dealing with a URL
|
# Check if we are dealing with a URL
|
||||||
if '://' in path_or_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
|
# 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)
|
# Check on level (must be an integer > 0)
|
||||||
if not isinstance(level, int) or not level >= 0:
|
if not isinstance(level, int) or not level >= 0:
|
||||||
raise ValueError("Patch level needs to be a non-negative integer.")
|
raise ValueError("Patch level needs to be a non-negative integer.")
|
||||||
# Attributes shared by all patch subclasses
|
# Attributes shared by all patch subclasses
|
||||||
self.path_or_url = path_or_url
|
self.path_or_url = path_or_url
|
||||||
self.level = level
|
self.level = level
|
||||||
|
self.working_dir = working_dir
|
||||||
# self.path needs to be computed by derived classes
|
# self.path needs to be computed by derived classes
|
||||||
# before a call to apply
|
# before a call to apply
|
||||||
self.path = None
|
self.path = None
|
||||||
@ -99,13 +101,14 @@ def apply(self, stage):
|
|||||||
patch = which("patch", required=True)
|
patch = which("patch", required=True)
|
||||||
with working_dir(stage.source_path):
|
with working_dir(stage.source_path):
|
||||||
# Use -N to allow the same patches to be applied multiple times.
|
# 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):
|
class FilePatch(Patch):
|
||||||
"""Describes a patch that is retrieved from a file in the repository"""
|
"""Describes a patch that is retrieved from a file in the repository"""
|
||||||
def __init__(self, pkg, path_or_url, level):
|
def __init__(self, pkg, path_or_url, level, working_dir):
|
||||||
super(FilePatch, self).__init__(path_or_url, level)
|
super(FilePatch, self).__init__(path_or_url, level, working_dir)
|
||||||
|
|
||||||
pkg_dir = os.path.dirname(absolute_path_for_package(pkg))
|
pkg_dir = os.path.dirname(absolute_path_for_package(pkg))
|
||||||
self.path = os.path.join(pkg_dir, path_or_url)
|
self.path = os.path.join(pkg_dir, path_or_url)
|
||||||
@ -123,8 +126,8 @@ def sha256(self):
|
|||||||
|
|
||||||
class UrlPatch(Patch):
|
class UrlPatch(Patch):
|
||||||
"""Describes a patch that is retrieved from a URL"""
|
"""Describes a patch that is retrieved from a URL"""
|
||||||
def __init__(self, path_or_url, level, **kwargs):
|
def __init__(self, path_or_url, level, working_dir, **kwargs):
|
||||||
super(UrlPatch, self).__init__(path_or_url, level)
|
super(UrlPatch, self).__init__(path_or_url, level, working_dir)
|
||||||
self.url = path_or_url
|
self.url = path_or_url
|
||||||
|
|
||||||
self.archive_sha256 = None
|
self.archive_sha256 = None
|
||||||
|
Loading…
Reference in New Issue
Block a user