aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/modules/fs.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2022-02-28 14:25:10 -0800
committerEli Schwartz <eschwartz93@gmail.com>2022-08-18 16:53:36 -0400
commit991baf56e99d96bbe3f2841f4b7c283e36ff1c89 (patch)
tree8dc698ed09beee43e75251d4f3cb52562ab0eaec /mesonbuild/modules/fs.py
parentf93886192eeeeaf93608e310f2bf061b56c2e4ad (diff)
downloadmeson-991baf56e99d96bbe3f2841f4b7c283e36ff1c89.zip
meson-991baf56e99d96bbe3f2841f4b7c283e36ff1c89.tar.gz
meson-991baf56e99d96bbe3f2841f4b7c283e36ff1c89.tar.bz2
modules/fs: Replace configure_file(copy:) with fs.copyfile
`configure_file` is both an extremely complicated implementation, and a strange place for copying. It's a bit of a historical artifact, since the fs module didn't yet exist. It makes more sense to move this to the fs module and deprecate this `configure_file` version. This new version works at build time rather than configure time, which has the disadvantage it can't be passed to `run_command`, but with the advantage that changes to the input don't require a full reconfigure.
Diffstat (limited to 'mesonbuild/modules/fs.py')
-rw-r--r--mesonbuild/modules/fs.py65
1 files changed, 60 insertions, 5 deletions
diff --git a/mesonbuild/modules/fs.py b/mesonbuild/modules/fs.py
index f0e3f4c..7e3c75a 100644
--- a/mesonbuild/modules/fs.py
+++ b/mesonbuild/modules/fs.py
@@ -12,24 +12,28 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import typing as T
+from __future__ import annotations
+from pathlib import Path, PurePath, PureWindowsPath
import hashlib
import os
-from pathlib import Path, PurePath, PureWindowsPath
+import typing as T
+from . import ExtensionModule, ModuleReturnValue, ModuleInfo
from .. import mlog
-from . import ExtensionModule, ModuleInfo
+from ..build import CustomTarget, InvalidArguments
+from ..interpreter.type_checking import INSTALL_KW, INSTALL_MODE_KW, INSTALL_TAG_KW, NoneType
+from ..interpreterbase import FeatureNew, KwargInfo, typed_kwargs, typed_pos_args, noKwargs
from ..mesonlib import (
File,
MesonException,
+ has_path_sep,
path_is_in_root,
)
-from ..interpreterbase import FeatureNew, KwargInfo, typed_kwargs, typed_pos_args, noKwargs
if T.TYPE_CHECKING:
from . import ModuleState
from ..interpreter import Interpreter
- from ..mesonlib import FileOrString
+ from ..mesonlib import FileOrString, FileMode
from typing_extensions import TypedDict
@@ -38,6 +42,15 @@ if T.TYPE_CHECKING:
encoding: str
+ class CopyKw(TypedDict):
+
+ """Kwargs for fs.copy"""
+
+ install: bool
+ install_dir: T.Optional[str]
+ install_mode: FileMode
+ install_tag: T.Optional[str]
+
class FSModule(ExtensionModule):
@@ -61,6 +74,7 @@ class FSModule(ExtensionModule):
'name': self.name,
'stem': self.stem,
'read': self.read,
+ 'copyfile': self.copyfile,
})
def _absolute_dir(self, state: 'ModuleState', arg: 'FileOrString') -> Path:
@@ -255,6 +269,47 @@ class FSModule(ExtensionModule):
self.interpreter.add_build_def_file(path)
return data
+ @FeatureNew('fs.copyfile', '0.64.0')
+ @typed_pos_args('fs.copyfile', (File, str), optargs=[str])
+ @typed_kwargs(
+ 'fs.copyfile',
+ INSTALL_KW,
+ INSTALL_MODE_KW,
+ INSTALL_TAG_KW,
+ KwargInfo('install_dir', (str, NoneType)),
+ )
+ def copyfile(self, state: ModuleState, args: T.Tuple[FileOrString, T.Optional[str]],
+ kwargs: CopyKw) -> ModuleReturnValue:
+ """Copy a file into the build directory at build time."""
+ if kwargs['install'] and not kwargs['install_dir']:
+ raise InvalidArguments('"install_dir" must be specified when "install" is true')
+
+ src = self.interpreter.source_strings_to_files([args[0]])[0]
+
+ # The input is allowed to have path separators, but the output may not,
+ # so use the basename for the default case
+ dest = args[1] if args[1] else os.path.basename(src.fname)
+ if has_path_sep(dest):
+ raise InvalidArguments('Destination path may not have path separators')
+
+ ct = CustomTarget(
+ dest,
+ state.subdir,
+ state.subproject,
+ state.environment,
+ state.environment.get_build_command() + ['--internal', 'copy', '@INPUT@', '@OUTPUT@'],
+ [src],
+ [dest],
+ build_by_default=True,
+ install=kwargs['install'],
+ install_dir=kwargs['install_dir'],
+ install_mode=kwargs['install_mode'],
+ install_tag=kwargs['install_tag'],
+ backend=state.backend,
+ )
+
+ return ModuleReturnValue(ct, [ct])
+
def initialize(*args: T.Any, **kwargs: T.Any) -> FSModule:
return FSModule(*args, **kwargs)