App: Miscellaneous fixes and improvements based on AI code analysis #44
2 changed files with 40 additions and 21 deletions
|
|
@ -114,7 +114,7 @@ class App(Base):
|
|||
if pretty:
|
||||
return self.__pretty_topdir
|
||||
return self.__topdir
|
||||
for d in [self.__projs_root, '/opt']:
|
||||
for d in [self.__projs_root, self.___opt_root]:
|
||||
ret = d + '/' + name
|
||||
if os.path.exists(ret):
|
||||
return ret
|
||||
|
|
@ -126,10 +126,14 @@ class App(Base):
|
|||
def __find_dir(
|
||||
self,
|
||||
name: str,
|
||||
search_subdirs: list[str] = [],
|
||||
search_absdirs: list[str] = [],
|
||||
search_subdirs: list[str] | None = None,
|
||||
search_absdirs: list[str] | None = None,
|
||||
pretty: bool = True,
|
||||
) -> str | None:
|
||||
if search_subdirs is None:
|
||||
search_subdirs = []
|
||||
if search_absdirs is None:
|
||||
search_absdirs = []
|
||||
|
||||
def __format_relpath(path: str):
|
||||
if path.startswith('./'):
|
||||
|
|
@ -181,16 +185,18 @@ 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:
|
||||
def __get_project_conf(self, project: str) -> ProjectConf | None:
|
||||
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)
|
||||
try:
|
||||
return self.__read_project_conf(pd)
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
|
||||
def __get_project_refs_cached(
|
||||
self, buf, visited, spec, section, key, add_self, scope, names_only
|
||||
|
|
@ -272,8 +278,6 @@ class App(Base):
|
|||
add_self = False,
|
||||
names_only = True,
|
||||
)
|
||||
if deps is None:
|
||||
continue
|
||||
graph[project] = set(deps)
|
||||
for dep in deps:
|
||||
self.__read_dep_graph([dep], sections, graph)
|
||||
|
|
@ -313,22 +317,25 @@ class App(Base):
|
|||
temp.remove(project)
|
||||
return None
|
||||
|
||||
def __find_circular_deps(self, projects: list[str], flavours: list[str]) -> bool:
|
||||
def __find_circular_deps(self, projects: list[str],
|
||||
flavours: list[str]) -> list[str]:
|
||||
graph: Graph = {}
|
||||
ret: list[str] = []
|
||||
self.__read_dep_graph(projects, flavours, graph)
|
||||
unvisited = list(graph.keys())
|
||||
temp: set[str] = set()
|
||||
flipped = self.__flip_dep_graph(graph)
|
||||
while unvisited:
|
||||
project = unvisited[0]
|
||||
log(DEBUG, 'Checking circular dependency of', project)
|
||||
last = self.__find_circular_deps_recursive(
|
||||
project, self.__flip_dep_graph(graph), unvisited, temp, ret
|
||||
project, flipped, unvisited, temp, ret
|
||||
)
|
||||
if last is not None:
|
||||
log(DEBUG, f'Found circular dependency below {project}, last is {last}')
|
||||
return True
|
||||
return False
|
||||
ret.append(last)
|
||||
return ret
|
||||
return []
|
||||
|
||||
def __init__(self, distro: Distro | None = None) -> None:
|
||||
|
||||
|
|
@ -347,6 +354,7 @@ class App(Base):
|
|||
# -- Members with default values
|
||||
self.__topdir_fmt = 'absolute'
|
||||
self.__projs_root = pwd.getpwuid(os.getuid()).pw_dir + '/local/src/jw.dev/proj'
|
||||
self.___opt_root = '/opt'
|
||||
self.__pretty_projs_root = None
|
||||
|
||||
async def __init_async(self) -> None:
|
||||
|
|
@ -489,8 +497,8 @@ class App(Base):
|
|||
def find_dir(
|
||||
self,
|
||||
name: str,
|
||||
search_subdirs: list[str] = [],
|
||||
search_absdirs: list[str] = [],
|
||||
search_subdirs: list[str] | None = None,
|
||||
search_absdirs: list[str] | None = None,
|
||||
pretty: bool = True,
|
||||
throw: bool = False,
|
||||
) -> str | None:
|
||||
|
|
@ -541,13 +549,15 @@ class App(Base):
|
|||
try:
|
||||
with open(version_path) as fd:
|
||||
ret = fd.read().replace('\n', '').replace('-dev', '')
|
||||
fd.close()
|
||||
return ret
|
||||
except EnvironmentError:
|
||||
log(DEBUG, f'Ignoring unreadable file "{version_path}"')
|
||||
continue
|
||||
raise Exception(f'No version file found for project "{project}"')
|
||||
ret = self.__get_project_conf(project).get_str_or_none(section, key)
|
||||
proj_conf = self.__get_project_conf(project)
|
||||
if proj_conf is None:
|
||||
return None
|
||||
ret = proj_conf.get_str_or_none(section, key)
|
||||
log(
|
||||
DEBUG,
|
||||
'Lookup %s -> %s / [%s%s] -> "%s"' %
|
||||
|
|
@ -574,7 +584,10 @@ class App(Base):
|
|||
for key in keys:
|
||||
vals = self.get_value(p, section, key)
|
||||
if vals:
|
||||
ret += [val.strip() for val in vals.split(',')]
|
||||
for val in vals.split(','):
|
||||
stripped = val.strip()
|
||||
if stripped:
|
||||
ret.append(stripped)
|
||||
return list(dict.fromkeys(ret)) # Remove duplicates, keep ordering
|
||||
|
||||
def get_project_refs(
|
||||
|
|
@ -624,5 +637,5 @@ class App(Base):
|
|||
return ', '.join(intersection)
|
||||
return None
|
||||
|
||||
def find_circular_deps(self, projects: list[str], flavours: list[str]) -> bool:
|
||||
def find_circular_deps(self, projects: list[str], flavours: list[str]) -> list[str]:
|
||||
return self.__find_circular_deps(projects, flavours)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ....lib.log import NOTICE, log
|
||||
from .Cmd import Cmd, Parent
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
|
@ -22,8 +23,13 @@ class CmdDep(Cmd): # export
|
|||
parser.add_argument('-f', '--flavour', nargs = '?', default = 'build')
|
||||
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
if self.app.find_circular_deps(args.module, args.flavour):
|
||||
log(NOTICE, f'Found circular dependency in flavour {args.flavour}')
|
||||
cycle = self.app.find_circular_deps(args.module, args.flavour)
|
||||
if cycle:
|
||||
log(
|
||||
NOTICE,
|
||||
f'Found circular dependency in flavour {args.flavour}: '
|
||||
' -> '.join(cycle)
|
||||
)
|
||||
exit(1)
|
||||
log(
|
||||
NOTICE,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue