diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index d717485e8a1e..d62943fdde4c 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1968,8 +1968,8 @@ def func_vcs_tag(self, node: mparser.BaseNode, args: T.List['TYPE_var'], kwargs: vcs = mesonlib.detect_vcs(source_dir) if vcs: mlog.log('Found {} repository at {}'.format(vcs['name'], vcs['wc_dir'])) - vcs_cmd = vcs['get_rev'].split() - regex_selector = vcs['rev_regex'] + vcs_cmd = vcs.get_rev + regex_selector = vcs.rev_regex else: vcs_cmd = [' '] # executing this cmd will fail in vcstagger.py and force to use the fallback string # vcstagger.py parameters: infile, outfile, fallback, source_dir, replace_string, regex_selector, command... diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index dc327373a759..cdd8e1956570 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -30,6 +30,7 @@ if T.TYPE_CHECKING: from typing_extensions import Literal, Protocol + from typing import TypedDict from .._typing import ImmutableListProtocol from ..build import ConfigurationData @@ -756,40 +757,61 @@ def windows_detect_native_arch() -> str: raise EnvironmentException('Unable to detect native OS architecture') return arch -def detect_vcs(source_dir: T.Union[str, Path]) -> T.Optional[T.Dict[str, str]]: +class VcsData: + def __init__(self, *, + name:str = '', + cmd:str = '', + repo_dir:str = '', + get_rev: 'T.List[str]' = [''], + rev_regex:str = '', + dep:str = '', + wc_dir:'T.Optional[str]' = None): + self.name:str = name + self.cmd:str = cmd + self.repo_dir:str = repo_dir + self.get_rev: 'T.List[str]' = get_rev + self.rev_regex: str = rev_regex + self.dep: str = dep + self.wc_dir: 'T.Optional[str]' = wc_dir + +def detect_vcs(source_dir: T.Union[str, Path]) -> 'VcsData': vcs_systems = [ - { - 'name': 'git', - 'cmd': 'git', - 'repo_dir': '.git', - 'get_rev': 'git describe --dirty=+ --always', - 'rev_regex': '(.*)', - 'dep': '.git/logs/HEAD' - }, - { - 'name': 'mercurial', - 'cmd': 'hg', - 'repo_dir': '.hg', - 'get_rev': 'hg id -i', - 'rev_regex': '(.*)', - 'dep': '.hg/dirstate' - }, - { - 'name': 'subversion', - 'cmd': 'svn', - 'repo_dir': '.svn', - 'get_rev': 'svn info', - 'rev_regex': 'Revision: (.*)', - 'dep': '.svn/wc.db' - }, - { - 'name': 'bazaar', - 'cmd': 'bzr', - 'repo_dir': '.bzr', - 'get_rev': 'bzr revno', - 'rev_regex': '(.*)', - 'dep': '.bzr' - }, + VcsData( + name = 'git', + cmd =' git', + repo_dir = '.git', + get_rev = ['git', 'describe', '--dirty=+', '--always'], + rev_regex = '(.*)', + dep = '.git/logs/HEAD', + wc_dir = None, + ), + VcsData( + name = 'mercurial', + cmd = 'hg', + repo_dir = '.hg', + get_rev = ['hg', 'id', '-i'], + rev_regex = '(.*)', + dep= '.hg/dirstate', + wc_dir=None, + ), + VcsData( + name = 'subversion', + cmd = 'svn', + repo_dir = '.svn', + get_rev = ['svn', 'info'], + rev_regex = 'Revision: (.*)', + dep = '.svn/wc.db', + wc_dir = None, + ), + VcsData( + name = 'bazaar', + cmd = 'bzr', + repo_dir = '.bzr', + get_rev = ['bzr', 'revno'], + rev_regex = '(.*)', + dep = '.bzr', + wc_dir = None, + ), ] if isinstance(source_dir, str): source_dir = Path(source_dir) @@ -800,8 +822,10 @@ def detect_vcs(source_dir: T.Union[str, Path]) -> T.Optional[T.Dict[str, str]]: parent_paths_and_self.appendleft(source_dir) for curdir in parent_paths_and_self: for vcs in vcs_systems: - if Path.is_dir(curdir.joinpath(vcs['repo_dir'])) and shutil.which(vcs['cmd']): - vcs['wc_dir'] = str(curdir) + repodir = vcs.repo_dir + cmd = vcs.cmd + if curdir.joinpath(repodir).is_dir() and shutil.which(cmd): + vcs.wc_dir = str(curdir) return vcs return None