Skip to content

Commit

Permalink
wrap: Add support for applying a list of patch files
Browse files Browse the repository at this point in the history
Co-authored-by: Xavier Claessens <xavier.claessens@collabora.com>
  • Loading branch information
pwmarcz and xclaesse committed Dec 10, 2021
1 parent f45a21a commit 78d7d3b
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 1 deletion.
33 changes: 33 additions & 0 deletions docs/markdown/Wrap-dependency-system-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.61.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
Expand Down Expand Up @@ -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.61.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
Meson build patches.

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 build patches (`patch_*`). For this feature, `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 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-0001.patch, libfoobar-0002.patch
```

## `provide` section

*Since *0.55.0*
Expand Down
33 changes: 32 additions & 1 deletion mesonbuild/wrap/wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from pathlib import Path
from . import WrapMode
from .. import coredata
from ..mesonlib import quiet_git, GIT, ProgressBar, MesonException
from ..mesonlib import quiet_git, GIT, ProgressBar, MesonException, Popen_safe
from ..interpreterbase import FeatureNew
from .. import mesonlib

Expand All @@ -52,6 +52,8 @@

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)
Expand Down Expand Up @@ -98,6 +100,7 @@ def __init__(self, fname: str, subproject: str = ''):
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[str]
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
Expand Down Expand Up @@ -159,6 +162,10 @@ def parse_wrap_section(self, config: configparser.ConfigParser) -> None:
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.61.0').use(self.subproject)
diff_files = [s.strip() for s in self.values['diff_files'].split(',')]
self.diff_files += diff_files

def parse_provide_section(self, config: configparser.ConfigParser) -> None:
if config.has_section('provide'):
Expand Down Expand Up @@ -343,6 +350,7 @@ def resolve(self, packagename: str, method: str) -> str:
else:
raise WrapException(f'Unknown wrap type {self.wrap.type!r}')
self.apply_patch()
self.apply_diff_files()

# A meson.build or CMakeLists.txt file is required in the directory
if method == 'meson' and not os.path.exists(meson_file):
Expand Down Expand Up @@ -587,6 +595,29 @@ def apply_patch(self) -> None:
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 False and 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.
Expand Down
5 changes: 5 additions & 0 deletions test cases/common/153 wrap file should not failed/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ executable('grabprog2', files('src/subprojects/foo/prog2.c'))
subdir('src')

subproject('patchdir')

if find_program('patch', required : false).found() or find_program('git', required : false).found()
exe = subproject('patchfile').get_variable('foo_exe')
test('test_foo', exe)
endif
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 78d7d3b

Please sign in to comment.