Fixed manually promoting wrap files with a full path, e.g.
`meson wrap promote subprojects/s1/subprojects/projname.wrap`,
which resulted in an error before (new test added:
`./run_unittests.py AllPlatformTests.test_subproject_promotion_wrap`).
Additionally, running promote with an invalid subproject path now fails
properly. Before, it just silently did nothing (added to test:
`./run_unittests.py AllPlatformTests.test_subproject_promotion`).
This can be useful to make sure that a project builds when
its fallbacks are used on systems where external dependencies
satisfy the version requirements, or to easily hack on the sources
of a dependency for which a fallback exists.
The '+' and 'U' cases should not happen normally because we don't run
any git commands if the subproject directory exists and contains
a meson build file. However, if the user accidentally messed up the
subproject checkout to a version that had no build files, we would
error out with an assertion.
According to Python documentation[1] dirname and basename
are defined as follows:
os.path.dirname() = os.path.split()[0]
os.path.basename() = os.path.split()[1]
For the purpose of better readability split() is replaced
by appropriate function if only one part of returned tuple
is used.
[1]: https://docs.python.org/3/library/os.path.html#os.path.split
Using wrap mechanism in enterprise environment,
Some package is very large, example, sdk package from
BSP vendor.
so:
- open file in the output directory with a temporary name
- download a chunk, update hash calculation, write chunk to file
- when finished close file and check the hash
- if hash is incorrect, delete temp file and raise error
- if hash is correct, atomically rename temp file to final file
fix issue: #2358
fix shutil.unpack_archive() failure when the
destination files already exists and is read-only.
Example: all files in opensource package live555
is `-r--r--r--`, if some file in patch archive try to
patch original files of live555, shutil.unpack_archive
will raise `[Errno 13] Permission denied`
This also adds a "# noqa: F401" comment on an unused "import lzma",
which we are using it in a try/except block that is being used to
check if the lzma module is importable; of course it is unused.
v2: This turned out to be a little tricky.
mesonbuild/modules/__init__.py had the "unused" import:
from ..interpreterbase import permittedKwargs, noKwargs
However, that meant that the various modules could do things like:
from . import noKwargs # "." is "mesonbuild.modules"
Which breaks when you remove __init__.py's "unused" import. I
could have tagged that import with "# noqa: F401", but instead I
chose to have each of the module import directly from
"..interpreterbase" instead of ".".
Meson has a common pattern of using 'if len(foo) == 0:' or
'if len(foo) != 0:', however, this is a common anti-pattern in python.
Instead tests for emptiness/non-emptiness should be done with a simple
'if foo:' or 'if not foo:'
Consider the following:
>>> import timeit
>>> timeit.timeit('if len([]) == 0: pass')
0.10730923599840025
>>> timeit.timeit('if not []: pass')
0.030033907998586074
>>> timeit.timeit('if len(['a', 'b', 'c', 'd']) == 0: pass')
0.1154778649979562
>>> timeit.timeit("if not ['a', 'b', 'c', 'd']: pass")
0.08259823200205574
>>> timeit.timeit('if len("") == 0: pass')
0.089759664999292
>>> timeit.timeit('if not "": pass')
0.02340641999762738
>>> timeit.timeit('if len("foo") == 0: pass')
0.08848102600313723
>>> timeit.timeit('if not "foo": pass')
0.04032287199879647
And for the one additional case of 'if len(foo.strip()) == 0', which can
be replaced with 'if not foo.isspace()'
>>> timeit.timeit('if len(" ".strip()) == 0: pass')
0.15294511600222904
>>> timeit.timeit('if " ".isspace(): pass')
0.09413968399894657
>>> timeit.timeit('if len(" abc".strip()) == 0: pass')
0.2023209120015963
>>> timeit.timeit('if " abc".isspace(): pass')
0.09571301700270851
In other words, it's always a win to not use len(), when you don't
actually want to check the length.
Using Meson from outside a git repo results in an error when trying to
resolve submodule subprojects. Running git from inside subproject root
should be enough to fix it.
Partially fixes#1679
Signed-off-by: Ernestas Kulik <ernestas.kulik@gmail.com>
After an initial checkout, submodules aren’t initialized and thus trying
to update them fails.
Partially fixes#1679
Signed-off-by: Ernestas Kulik <ernestas.kulik@gmail.com>
Special wrap modes:
nofallback: Don't download wraps for dependency() fallbacks
nodownload: Don't download wraps for all subproject() calls
Subprojects are used for two purposes:
1. To download and build dependencies by using .wrap files if they
are not provided by the system. This is usually expressed via
dependency(..., fallback: ...).
2. To download and build 'copylibs' which are meant to be used by
copying into your project. This is always done with an explicit
subproject() call.
--wrap-mode=nofallback will never do (1)
--wrap-mode=nodownload will do neither (1) nor (2)
If you are building from a release tarball, you should be able to
safely use 'nodownload' since upstream is expected to ship all
required sources with the tarball.
If you are building from a git repository, you will want to use
'nofallback' so that any 'copylib' wraps will be download as
subprojects.
Note that these options do not affect subprojects that are git
submodules since those are only usable in git repositories, and you
almost always want to download them.
This will benefit projects such as GNOME Recipes that prefer using
submodules over wraps because it's easier to maintain since git is
aware of it, and because it integrates with their existing
workflow. Without this, these projects have to manually initialize
the submodules which is completely unnecessary.
Closes https://github.com/mesonbuild/meson/issues/1449
Also use a pathlib.Path object for the checks since it does I/O only
once and is much more efficient anyway. Path objects are available
since Python 3.4, so this is fine.
Also did a bit of cleanup.
interpreter.py: There’s a catch all except clause at the line 1928, it didn’t give the user any information whatsoever about the exception it caught. Now it at least print it to the log as a warning.