diff --git a/src/python/jw/pkg/App.py b/src/python/jw/pkg/App.py index ccba3931..d55ab50e 100644 --- a/src/python/jw/pkg/App.py +++ b/src/python/jw/pkg/App.py @@ -16,6 +16,7 @@ from typing import TYPE_CHECKING from .lib.App import App as Base from .lib.Distro import Distro from .lib.log import DEBUG, ERR, log +from .lib.ProjectConf import ProjectConf if TYPE_CHECKING: import argparse @@ -180,6 +181,17 @@ class App(Base): return ret return None + @cache + def __read_project_conf(self, project_dir: str) -> ProjectConf: + return ProjectConf.read(project_dir + '/make/project.conf') + + @cache + def __get_project_conf(self, project: str) -> ProjectConf: + pd = self.__proj_dir(project, False) + if pd is None: + raise Exception(f'Failed to find directory of project {project}') + return self.__read_project_conf(pd) + def __get_project_refs_cached( self, buf, visited, spec, section, key, add_self, scope, names_only ): @@ -405,9 +417,11 @@ class App(Base): self.___pretty_topdir = self.__format_topdir(self.___topdir, args.topdir_format) self.__topdir_fmt = args.topdir_format if self.___topdir is not None: - self.__top_name = self.read_value( - self.___topdir + '/make/project.conf', 'build', 'name' - ) + try: + conf = self.__read_project_conf(self.__topdir) + self.__top_name = conf.get_str_or_none('build', 'name') + except FileNotFoundError: + pass if not self.__top_name: self.__top_name = re.sub( '-[0-9.-]*$', @@ -529,66 +543,13 @@ class App(Base): file.close() return ret.rstrip() - @cache - def read_value(self, path: str, section: str, key: str) -> str | None: - - def scan_section(f, key: str) -> str | None: - if key is None: - ret = '' - for line in f: - if len(line) and line[0] == '[': - break - ret += line - return ret if len(ret) else None - lines: list[str] = [] - cont_line = '' - for line in f: - if len(line) and line[0] == '[': - break - cont_line += line.rstrip() - if len(cont_line) and cont_line[-1] == '\\': - cont_line = cont_line[0:-1] - continue - lines.append(cont_line) - cont_line = '' - rx = re.compile(r'^\s*' + key + r'\s*=\s*(.*)\s*$') - for line in lines: - # log(DEBUG, ' looking for "%s" in line="%s"' % (key, line)) - m = re.search(rx, line) - if m is not None: - return m.group(1) - return None - - def scan_section_debug(f, key: str) -> str | None: - ret = scan_section(f, key) - # log(DEBUG, ' returning', rr) - return ret - - try: - # log(DEBUG, 'looking for {}::[{}].{}'.format(path, section, key)) - # TODO: Parse - with open(path, 'r') as f: - if not len(section): - return scan_section(f, key) - pat = '[' + section + ']' - for line in f: - if line.rstrip() == pat: - return scan_section(f, key) - return None - except Exception: - log(DEBUG, f'Not found: {path}') - # TODO: handle this special case cleaner somewhere up the stack - if section == 'build' and key == 'libname': - return 'none' - return None - @cache def get_value(self, project: str, section: str, key: str) -> str | None: ret: str | None - proj_dir = self.__proj_dir(project, pretty = False) - if proj_dir is None: - raise Exception(f"Can't get project directory for {project}") if section == 'version': + proj_dir = self.__proj_dir(project, pretty = False) + if proj_dir is None: + raise Exception(f"Can't get project directory for {project}") proj_version_dirs = [proj_dir] if proj_dir != self.___topdir: proj_version_dirs.append('/usr/share/doc/packages/' + project) @@ -603,8 +564,7 @@ class App(Base): log(DEBUG, f'Ignoring unreadable file "{version_path}"') continue raise Exception(f'No version file found for project "{project}"') - path = proj_dir + '/make/project.conf' - ret = self.read_value(path, section, key) + ret = self.__get_project_conf(project).get_str_or_none(section, key) log( DEBUG, 'Lookup %s -> %s / [%s%s] -> "%s"' %