From 01eba56e64fde9d8bf8732a3a82d6369d70589b2 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Fri, 1 Sep 2017 02:06:03 +0200 Subject: Patch directive allows non-archives (#5197) - Don't expand downloaded patch file if it is not gzipped/tar'd/zipped/etc. --- lib/spack/spack/directives.py | 11 +++++ lib/spack/spack/patch.py | 5 +- lib/spack/spack/test/data/patch/bar.txt | 1 + lib/spack/spack/test/data/patch/foo.tgz | Bin 0 -> 116 bytes lib/spack/spack/test/patch.py | 84 ++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 lib/spack/spack/test/data/patch/bar.txt create mode 100644 lib/spack/spack/test/data/patch/foo.tgz create mode 100644 lib/spack/spack/test/patch.py (limited to 'lib') diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py index 2a99e171a0..7b9a3aa953 100644 --- a/lib/spack/spack/directives.py +++ b/lib/spack/spack/directives.py @@ -357,6 +357,17 @@ def patch(url_or_filename, level=1, when=None, **kwargs): optionally provide a when spec to indicate that a particular patch should only be applied when the package's spec meets certain conditions (e.g. a particular version). + + Args: + url_or_filename (str): url or filename of the patch + level (int): patch level (as in the patch shell command) + when (Spec): optional anonymous spec that specifies when to apply + the patch + **kwargs: the following list of keywords is supported + + - md5 (str): md5 sum of the patch (used to verify the file + if it comes from a url) + """ def _execute(pkg): constraint = pkg.name if when is None else when diff --git a/lib/spack/spack/patch.py b/lib/spack/spack/patch.py index c970f4dfdc..5742f312ce 100644 --- a/lib/spack/spack/patch.py +++ b/lib/spack/spack/patch.py @@ -131,7 +131,10 @@ class UrlPatch(Patch): patch_stage.fetch() patch_stage.check() patch_stage.cache_local() - patch_stage.expand_archive() + + if spack.util.compression.allowed_archive(self.url): + patch_stage.expand_archive() + self.path = os.path.abspath( os.listdir(patch_stage.path).pop() ) diff --git a/lib/spack/spack/test/data/patch/bar.txt b/lib/spack/spack/test/data/patch/bar.txt new file mode 100644 index 0000000000..ba578e48b1 --- /dev/null +++ b/lib/spack/spack/test/data/patch/bar.txt @@ -0,0 +1 @@ +BAR diff --git a/lib/spack/spack/test/data/patch/foo.tgz b/lib/spack/spack/test/data/patch/foo.tgz new file mode 100644 index 0000000000..73f598ac25 Binary files /dev/null and b/lib/spack/spack/test/data/patch/foo.tgz differ diff --git a/lib/spack/spack/test/patch.py b/lib/spack/spack/test/patch.py new file mode 100644 index 0000000000..7976956748 --- /dev/null +++ b/lib/spack/spack/test/patch.py @@ -0,0 +1,84 @@ +############################################################################## +# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the NOTICE and LICENSE files for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## + +import os.path + +import pytest +import sys + +import spack +import spack.util.compression +import spack.stage + + +@pytest.fixture() +def mock_apply(monkeypatch): + """Monkeypatches ``Patch.apply`` to test only the additional behavior of + derived classes. + """ + + m = sys.modules['spack.patch'] + + def check_expand(self, *args, **kwargs): + # Check tarball expansion + if spack.util.compression.allowed_archive(self.url): + file = os.path.join(self.path, 'foo.txt') + assert os.path.exists(file) + + # Check tarball fetching + dirname = os.path.dirname(self.path) + basename = os.path.basename(self.url) + tarball = os.path.join(dirname, basename) + assert os.path.exists(tarball) + + monkeypatch.setattr(m.Patch, 'apply', check_expand) + + +@pytest.fixture() +def mock_stage(tmpdir, monkeypatch): + + monkeypatch.setattr(spack, 'stage_path', str(tmpdir)) + + class MockStage(object): + def __init__(self): + self.mirror_path = str(tmpdir) + + return MockStage() + + +data_path = os.path.join(spack.test_path, 'data', 'patch') + + +@pytest.mark.usefixtures('mock_apply') +@pytest.mark.parametrize('filename,md5', [ + (os.path.join(data_path, 'foo.tgz'), 'bff717ca9cbbb293bdf188e44c540758'), + (os.path.join(data_path, 'bar.txt'), 'f98bf6f12e995a053b7647b10d937912') +]) +def test_url_patch_expansion(mock_stage, filename, md5): + + m = sys.modules['spack.patch'] + url = 'file://' + filename + patch = m.Patch.create(None, url, 0, md5=md5) + patch.apply(mock_stage) -- cgit v1.2.3-70-g09d2