diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2023-09-04 08:49:39 -0400 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 2023-09-05 09:05:24 +0530 |
commit | fe9af72684f85d709ce45096534aa51854a6da9b (patch) | |
tree | 0b41f1df5e985a9943bc7f3d321f47786a7e9291 | |
parent | f07476a89677f5c87a62b6756b76a0e8ebc4bceb (diff) | |
download | meson-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.md | 6 | ||||
-rw-r--r-- | docs/markdown/snippets/meson_home.md | 7 | ||||
-rw-r--r-- | mesonbuild/wrap/wrap.py | 14 | ||||
-rw-r--r-- | test cases/unit/116 meson package cache dir/cache_dir/bar/meson.build | 1 | ||||
-rw-r--r-- | test cases/unit/116 meson package cache dir/cache_dir/foo.zip | bin | 0 -> 373 bytes | |||
-rw-r--r-- | test cases/unit/116 meson package cache dir/meson.build | 4 | ||||
-rw-r--r-- | test cases/unit/116 meson package cache dir/subprojects/bar.wrap | 3 | ||||
-rw-r--r-- | test cases/unit/116 meson package cache dir/subprojects/foo.wrap | 5 | ||||
-rw-r--r-- | unittests/platformagnostictests.py | 10 |
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 Binary files differnew file mode 100644 index 0000000..91bc36a --- /dev/null +++ b/test cases/unit/116 meson package cache dir/cache_dir/foo.zip 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')}) |