aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Wrap-dependency-system-manual.md33
-rw-r--r--docs/markdown/snippets/diff_files.md6
-rwxr-xr-xmesonbuild/msubprojects.py1
-rw-r--r--mesonbuild/wrap/wrap.py37
-rw-r--r--test cases/common/153 wrap file should not failed/meson.build7
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch33
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch21
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch21
-rw-r--r--test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap14
9 files changed, 172 insertions, 1 deletions
diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md
index eb5de1b..314cd1f 100644
--- a/docs/markdown/Wrap-dependency-system-manual.md
+++ b/docs/markdown/Wrap-dependency-system-manual.md
@@ -84,6 +84,8 @@ previously reserved to `wrap-file`:
- `patch_directory` - *Since 0.55.0* Overlay directory, alternative to `patch_filename` in the case
files are local instead of a downloaded archive. The directory must be placed in
`subprojects/packagefiles`.
+- `diff_files` - *Since 0.63.0* Comma-separated list of local diff files (see
+ [Diff files](#diff-files) below).
### Specific to wrap-file
- `source_url` - download url to retrieve the wrap-file source archive
@@ -147,6 +149,37 @@ wrap-file mode. When using wrap-git, the repository must contain all
Meson build definitions. Since *0.55.0* Meson build patches are
supported for any wrap modes, including wrap-git.
+## Diff files
+
+*Since: 0.63.0*
+
+You can also provide local patch files in `diff` format. For historic reasons,
+they are referred to as "diff files", since the "patch" name is already used for
+overlay archives.
+
+The diff files are described by the `diff_files` property (a comma-separated
+list), and must be available locally in the `subprojects/packagefiles`
+directory.
+
+Meson will apply the diff files after extracting or cloning the project, and
+after applying the overlay archive (`patch_*`). For this feature, the `patch` or
+`git` command-line tool must be available.
+
+The diff files will be applied with `-p1`, i.e. treating the first path
+component as a prefix to be stripped. This is the default for diffs produced by
+Git.
+
+```ini
+[wrap-file]
+directory = libfoobar-1.0
+
+source_url = https://example.com/foobar-1.0.tar.gz
+source_filename = foobar-1.0.tar.gz
+source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663
+
+diff_files = libfoobar-1.0/0001.patch, libfoobar-1.0/0002.patch
+```
+
## `provide` section
*Since *0.55.0*
diff --git a/docs/markdown/snippets/diff_files.md b/docs/markdown/snippets/diff_files.md
new file mode 100644
index 0000000..3f425a2
--- /dev/null
+++ b/docs/markdown/snippets/diff_files.md
@@ -0,0 +1,6 @@
+## Diff files for wraps
+
+Wrap files can now define `diff_files`, a list of local patch files in `diff`
+format. Meson will apply the diff files after extracting or cloning the project,
+and after applying the overlay archive (`patch_*`). For this feature, the
+`patch` or `git` command-line tool must be available.
diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py
index 455b6e7..8a58d7d 100755
--- a/mesonbuild/msubprojects.py
+++ b/mesonbuild/msubprojects.py
@@ -205,6 +205,7 @@ class Runner:
self.git_stash()
self.git_output(['reset', '--hard', 'FETCH_HEAD'])
self.wrap_resolver.apply_patch()
+ self.wrap_resolver.apply_diff_files()
except GitException as e:
self.log(' -> Could not reset', mlog.bold(self.repo_dir), 'to', mlog.bold(revision))
self.log(mlog.red(e.output))
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index f544122..00ef9a0 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -33,7 +33,7 @@ import textwrap
from pathlib import Path
from . import WrapMode
from .. import coredata
-from ..mesonlib import quiet_git, GIT, ProgressBar, MesonException, windows_proof_rmtree
+from ..mesonlib import quiet_git, GIT, ProgressBar, MesonException, windows_proof_rmtree, Popen_safe
from ..interpreterbase import FeatureNew
from ..interpreterbase import SubProject
from .. import mesonlib
@@ -55,6 +55,8 @@ WHITELIST_SUBDOMAIN = 'wrapdb.mesonbuild.com'
ALL_TYPES = ['file', 'git', 'hg', 'svn']
+PATCH = shutil.which('patch')
+
def whitelist_wrapdb(urlstr: str) -> urllib.parse.ParseResult:
""" raises WrapException if not whitelisted subdomain """
url = urllib.parse.urlparse(urlstr)
@@ -116,6 +118,7 @@ class PackageDefinition:
self.values = {} # type: T.Dict[str, str]
self.provided_deps = {} # type: T.Dict[str, T.Optional[str]]
self.provided_programs = [] # type: T.List[str]
+ self.diff_files = [] # type: T.List[Path]
self.basename = os.path.basename(fname)
self.has_wrap = self.basename.endswith('.wrap')
self.name = self.basename[:-5] if self.has_wrap else self.basename
@@ -177,6 +180,15 @@ class PackageDefinition:
raise WrapException(f'{self.wrap_section!r} is not a valid first section in {self.basename}')
self.type = self.wrap_section[5:]
self.values = dict(config[self.wrap_section])
+ if 'diff_files' in self.values:
+ FeatureNew('Wrap files with diff_files', '0.63.0').use(self.subproject)
+ for s in self.values['diff_files'].split(','):
+ path = Path(s.strip())
+ if path.is_absolute():
+ raise WrapException('diff_files paths cannot be absolute')
+ if '..' in path.parts:
+ raise WrapException('diff_files paths cannot contain ".."')
+ self.diff_files.append(path)
def parse_provide_section(self, config: configparser.ConfigParser) -> None:
if config.has_section('provide'):
@@ -366,6 +378,7 @@ class Resolver:
raise WrapException(f'Unknown wrap type {self.wrap.type!r}')
try:
self.apply_patch()
+ self.apply_diff_files()
except Exception:
windows_proof_rmtree(self.dirname)
raise
@@ -628,6 +641,28 @@ class Resolver:
raise WrapException(f'patch directory does not exist: {patch_dir}')
self.copy_tree(src_dir, self.dirname)
+ def apply_diff_files(self) -> None:
+ for filename in self.wrap.diff_files:
+ mlog.log(f'Applying diff file "{filename}"')
+ path = Path(self.wrap.filesdir) / filename
+ if not path.exists():
+ raise WrapException(f'Diff file "{path}" does not exist')
+ if PATCH:
+ cmd = [PATCH, '-f', '-p1', '-i', str(path)]
+ elif GIT:
+ # If the `patch` command is not available, fall back to `git
+ # apply`. The `--work-tree` is necessary in case we're inside a
+ # Git repository: by default, Git will try to apply the patch to
+ # the repository root.
+ cmd = [GIT, '--work-tree', '.', 'apply', '-p1', str(path)]
+ else:
+ raise WrapException('Missing "patch" or "git" commands to apply diff files')
+
+ p, out, _ = Popen_safe(cmd, cwd=self.dirname, stderr=subprocess.STDOUT)
+ if p.returncode != 0:
+ mlog.log(out.strip())
+ raise WrapException(f'Failed to apply diff file "{filename}"')
+
def copy_tree(self, root_src_dir: str, root_dst_dir: str) -> None:
"""
Copy directory tree. Overwrites also read only files.
diff --git a/test cases/common/153 wrap file should not failed/meson.build b/test cases/common/153 wrap file should not failed/meson.build
index 48d1068..5448502 100644
--- a/test cases/common/153 wrap file should not failed/meson.build
+++ b/test cases/common/153 wrap file should not failed/meson.build
@@ -2,6 +2,10 @@ project('mainproj', 'c',
default_options : ['wrap_mode=nodownload'],
)
+if not find_program('patch', required : false).found() and not find_program('git', required : false).found()
+ error('MESON_SKIP_TEST: patch/git not found.')
+endif
+
subproject('zlib')
foo = subproject('foo')
bar = subproject('bar')
@@ -14,3 +18,6 @@ executable('grabprog2', files('src/subprojects/foo/prog2.c'))
subdir('src')
subproject('patchdir')
+
+exe = subproject('patchfile').get_variable('foo_exe')
+test('test_foo', exe)
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch
new file mode 100644
index 0000000..a29fb6c
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-foo-to-executable.patch
@@ -0,0 +1,33 @@
+From b79f6cc4a096f6c2888f73b947b652491885896a Mon Sep 17 00:00:00 2001
+From: Xavier Claessens <xavier.claessens@collabora.com>
+Date: Fri, 30 Nov 2018 14:13:47 -0500
+Subject: [PATCH] Change foo to executable
+
+---
+ foo.c | 4 ++++
+ meson.build | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/foo.c b/foo.c
+index 54f9119..468f033 100644
+--- a/foo.c
++++ b/foo.c
+@@ -1,3 +1,7 @@
+ int dummy_func(void) {
+ return 44;
+ }
++
++int main(void) {
++ return dummy_func() == 44 ? 0 : 1;
++}
+diff --git a/meson.build b/meson.build
+index 318e81d..4a281d9 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1,2 +1,2 @@
+ project('static lib patchdir', 'c')
+-libfoo = static_library('foo', 'foo.c')
++foo_exe = executable('foo', 'foo.c')
+--
+2.17.1
+
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch
new file mode 100644
index 0000000..49cf1e9
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0001-Change-return-value-to-43.patch
@@ -0,0 +1,21 @@
+From 7001dcc738e5ae7dfa8af20ed582b9a985804f72 Mon Sep 17 00:00:00 2001
+From: Xavier Claessens <xavier.claessens@collabora.com>
+Date: Fri, 30 Nov 2018 10:15:33 -0500
+Subject: [PATCH 1/2] Change return value to 43
+
+---
+ foo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/foo.c b/foo.c
+index 019f2ba..e4577b8 100644
+--- a/foo.c
++++ b/foo.c
+@@ -1,3 +1,3 @@
+ int dummy_func(void) {
+- return 42;
++ return 43;
+ }
+--
+2.17.1
+
diff --git a/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch
new file mode 100644
index 0000000..4794cea
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/packagefiles/patchfile/0002-Change-return-value-to-44.patch
@@ -0,0 +1,21 @@
+From c2da2e490b09f2e251c7f4ef7c1240acee215fec Mon Sep 17 00:00:00 2001
+From: Xavier Claessens <xavier.claessens@collabora.com>
+Date: Fri, 30 Nov 2018 10:15:47 -0500
+Subject: [PATCH 2/2] Change return value to 44
+
+---
+ foo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/foo.c b/foo.c
+index e4577b8..54f9119 100644
+--- a/foo.c
++++ b/foo.c
+@@ -1,3 +1,3 @@
+ int dummy_func(void) {
+- return 43;
++ return 44;
+ }
+--
+2.17.1
+
diff --git a/test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap b/test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap
new file mode 100644
index 0000000..3d446fe
--- /dev/null
+++ b/test cases/common/153 wrap file should not failed/subprojects/patchfile.wrap
@@ -0,0 +1,14 @@
+[wrap-file]
+directory = foo-1.0-patchfile
+
+source_url = http://something.invalid
+source_filename = foo-1.0.tar.xz
+source_hash = 9ed8f67d75e43d3be161efb6eddf30dd01995a958ca83951ea64234bac8908c1
+lead_directory_missing = true
+
+patch_directory = foo-1.0
+
+diff_files =
+ patchfile/0001-Change-return-value-to-43.patch,
+ patchfile/0002-Change-return-value-to-44.patch,
+ patchfile/0001-Change-foo-to-executable.patch