aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2023-09-04 08:49:39 -0400
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2023-09-05 09:05:24 +0530
commitfe9af72684f85d709ce45096534aa51854a6da9b (patch)
tree0b41f1df5e985a9943bc7f3d321f47786a7e9291
parentf07476a89677f5c87a62b6756b76a0e8ebc4bceb (diff)
downloadmeson-fe9af72684f85d709ce45096534aa51854a6da9b.zip
meson-fe9af72684f85d709ce45096534aa51854a6da9b.tar.gz
meson-fe9af72684f85d709ce45096534aa51854a6da9b.tar.bz2
wrap: Use MESON_PACKAGE_CACHE_DIR as default packagecache path
Allow packagecache to contain already extracted directory to match what some distro does with Cargo source packages in /usr/share/cargo/registry. Note that there is no need to lock the cache directory because we download into a temporary name and atomically rename afterward. It means we could be downloading the same file twice, but at least integrity is guaranteed. Fixes: #12211
-rw-r--r--docs/markdown/Wrap-dependency-system-manual.md6
-rw-r--r--docs/markdown/snippets/meson_home.md7
-rw-r--r--mesonbuild/wrap/wrap.py14
-rw-r--r--test cases/unit/116 meson package cache dir/cache_dir/bar/meson.build1
-rw-r--r--test cases/unit/116 meson package cache dir/cache_dir/foo.zipbin0 -> 373 bytes
-rw-r--r--test cases/unit/116 meson package cache dir/meson.build4
-rw-r--r--test cases/unit/116 meson package cache dir/subprojects/bar.wrap3
-rw-r--r--test cases/unit/116 meson package cache dir/subprojects/foo.wrap5
-rw-r--r--unittests/platformagnostictests.py10
9 files changed, 48 insertions, 2 deletions
diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md
index c8b91d5..3aeea14 100644
--- a/docs/markdown/Wrap-dependency-system-manual.md
+++ b/docs/markdown/Wrap-dependency-system-manual.md
@@ -109,6 +109,12 @@ project's `subprojects/packagecache` directory, it will be used instead
of downloading the file, even if `--wrap-mode` option is set to
`nodownload`. The file's hash will be checked.
+Since *1.3.0* if the `MESON_PACKAGE_CACHE_DIR` environment variable is set, it is used instead of
+the project's `subprojects/packagecache`. This allows sharing the cache across multiple
+projects. In addition it can contain an already extracted source tree as long as it
+has the same directory name as the `directory` field in the wrap file. In that
+case, the directory will be copied into `subprojects/` before applying patches.
+
### Specific to VCS-based wraps
- `url` - name of the wrap-git repository to clone. Required.
- `revision` - name of the revision to checkout. Must be either: a
diff --git a/docs/markdown/snippets/meson_home.md b/docs/markdown/snippets/meson_home.md
new file mode 100644
index 0000000..2d656fc
--- /dev/null
+++ b/docs/markdown/snippets/meson_home.md
@@ -0,0 +1,7 @@
+## New environment variable `MESON_PACKAGE_CACHE_DIR`
+
+If the `MESON_PACKAGE_CACHE_DIR` environment variable is set, it is used instead of the
+project's `subprojects/packagecache`. This allows sharing the cache across multiple
+projects. In addition it can contain an already extracted source tree as long as it
+has the same directory name as the `directory` field in the wrap file. In that
+case, the directory will be copied into `subprojects/` before applying patches.
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index c857050..941da3d 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -289,7 +289,7 @@ class Resolver:
def __post_init__(self) -> None:
self.subdir_root = os.path.join(self.source_dir, self.subdir)
- self.cachedir = os.path.join(self.subdir_root, 'packagecache')
+ self.cachedir = os.environ.get('MESON_PACKAGE_CACHE_DIR') or os.path.join(self.subdir_root, 'packagecache')
self.wraps: T.Dict[str, PackageDefinition] = {}
self.netrc: T.Optional[netrc] = None
self.provided_deps: T.Dict[str, PackageDefinition] = {}
@@ -462,7 +462,17 @@ class Resolver:
if not os.path.isdir(self.dirname):
raise WrapException('Path already exists but is not a directory')
else:
- if self.wrap.type == 'file':
+ # Check first if we have the extracted directory in our cache. This can
+ # happen for example when MESON_PACKAGE_CACHE_DIR=/usr/share/cargo/registry
+ # on distros that ships Rust source code.
+ # TODO: We don't currently clone git repositories into the cache
+ # directory, but we should to avoid cloning multiple times the same
+ # repository. In that case, we could do something smarter than
+ # copy_tree() here.
+ cached_directory = os.path.join(self.cachedir, self.directory)
+ if os.path.isdir(cached_directory):
+ self.copy_tree(cached_directory, self.dirname)
+ elif self.wrap.type == 'file':
self.get_file()
else:
self.check_can_download()
diff --git a/test cases/unit/116 meson package cache dir/cache_dir/bar/meson.build b/test cases/unit/116 meson package cache dir/cache_dir/bar/meson.build
new file mode 100644
index 0000000..dca36f6
--- /dev/null
+++ b/test cases/unit/116 meson package cache dir/cache_dir/bar/meson.build
@@ -0,0 +1 @@
+project('bar')
diff --git a/test cases/unit/116 meson package cache dir/cache_dir/foo.zip b/test cases/unit/116 meson package cache dir/cache_dir/foo.zip
new file mode 100644
index 0000000..91bc36a
--- /dev/null
+++ b/test cases/unit/116 meson package cache dir/cache_dir/foo.zip
Binary files differ
diff --git a/test cases/unit/116 meson package cache dir/meson.build b/test cases/unit/116 meson package cache dir/meson.build
new file mode 100644
index 0000000..2057bba
--- /dev/null
+++ b/test cases/unit/116 meson package cache dir/meson.build
@@ -0,0 +1,4 @@
+project('meson package cache dir')
+
+subproject('foo')
+subproject('bar')
diff --git a/test cases/unit/116 meson package cache dir/subprojects/bar.wrap b/test cases/unit/116 meson package cache dir/subprojects/bar.wrap
new file mode 100644
index 0000000..3ec5834
--- /dev/null
+++ b/test cases/unit/116 meson package cache dir/subprojects/bar.wrap
@@ -0,0 +1,3 @@
+[wrap-file]
+directory = bar
+
diff --git a/test cases/unit/116 meson package cache dir/subprojects/foo.wrap b/test cases/unit/116 meson package cache dir/subprojects/foo.wrap
new file mode 100644
index 0000000..b7dd41d
--- /dev/null
+++ b/test cases/unit/116 meson package cache dir/subprojects/foo.wrap
@@ -0,0 +1,5 @@
+[wrap-file]
+directory = foo
+source_url = http://server.invalid/foo.zip
+source_filename = foo.zip
+source_hash = c5dd7e8fca93045f736c83700686722b0fbc20b7dc4597b295060684c5b05b72
diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py
index efe3109..92c613d 100644
--- a/unittests/platformagnostictests.py
+++ b/unittests/platformagnostictests.py
@@ -18,6 +18,7 @@ import pickle
import tempfile
import subprocess
import textwrap
+import shutil
from unittest import skipIf, SkipTest
from pathlib import Path
@@ -261,3 +262,12 @@ class PlatformAgnosticTests(BasePlatformTests):
self.assertEqual(data['modules'], expected)
self.assertEqual(data['count'], 68)
+
+ def test_meson_package_cache_dir(self):
+ # Copy testdir into temporary directory to not pollute meson source tree.
+ testdir = os.path.join(self.unit_test_dir, '116 meson package cache dir')
+ srcdir = os.path.join(self.builddir, 'srctree')
+ shutil.copytree(testdir, srcdir)
+ builddir = os.path.join(srcdir, '_build')
+ self.change_builddir(builddir)
+ self.init(srcdir, override_envvars={'MESON_PACKAGE_CACHE_DIR': os.path.join(srcdir, 'cache_dir')})