Files

220 lines
5.7 KiB
Python

import os
import sys
import tomli
from dependency import *
from cmake import CMakeBuildSystem
from publish import Publish
from build import UnknownBuildSystemError
from env import Environment
from source_only import SourceOnlyBuildSystem
from generic import GenericBuildSystem
all_seeds = {}
class SeedParseError(Exception):
pass
class Seed(DependencyItem):
def all_seeds():
return all_seeds
def get(name):
if name in all_seeds:
return all_seeds[name]
return None
def load_file(self, path):
with open(path, mode='rb') as f:
self.__data = tomli.load(f)
def __init_dependencies(self):
self.__dependencies = {}
if 'dependency' not in self.__data:
return
dependency = self.__data['dependency']
if 'seeds' in dependency:
seeds = dependency['seeds']
self.__dependencies = {}
for s in seeds:
self.__dependencies[s] = SeedDependency(parent=self.name(), name=s)
def __init_build_system(self):
self.__build_system = None
if 'build' not in self.__data:
return
build = self.__data['build']
if 'build_system' not in build:
return
source_dir = os.path.dirname(self.__seed_path)
bin_dir = os.path.join(Environment.build_root(), self.name())
install = self.__data.get('install', None)
if 'source_dir' in build:
source_dir = build['source_dir']
match build['build_system']:
case 'none':
self.__build_system = None
case 'cmake':
self.__build_system = CMakeBuildSystem(
parent=self,
name=self.name(),
source_dir=source_dir,
bin_dir=bin_dir,
install=install,
data=build)
case 'source-only':
self.__build_system = SourceOnlyBuildSystem(
parent=self,
name=self.name(),
source_dir=source_dir,
bin_dir=bin_dir,
install=install,
data=build)
case 'generic':
self.__build_system = GenericBuildSystem(
parent=self,
name=self.name(),
source_dir=source_dir,
bin_dir=bin_dir,
install=install,
data=build)
case _:
raise UnknownBuildSystemError(
'Seed {} has unrecognised build system "{}"'.format(self.name(), build['build_system']))
def __init_publish(self):
install_path = Environment.system_root()
if 'build' in self.__data and 'build_for' in self.__data['build']:
build_for = self.__data['build']['build_for']
if build_for == 'host':
install_path = Environment.native_root()
self.__publish = None
if 'publish' not in self.__data:
return
self.__publish = Publish(install_path=install_path, data=self.__data['publish'])
def add_dependency(self, name, dep):
self.__dependencies[name] = dep
def collect_dependencies(self, **kwargs):
ctx = None
if 'ctx' in kwargs:
ctx = kwargs['ctx']
else:
ctx = {}
for k, d in self.__dependencies.items():
if k in ctx:
continue
ctx[d.name()] = d.target()
if isinstance(d.target(), Seed):
d.target().collect_dependencies(ctx=ctx)
return list(ctx.values())
def __init__(self, **kwargs):
super().__init__()
if not 'path' in kwargs:
return
self.__seed_path = kwargs['path']
self.load_file(kwargs['path'])
self.__init_dependencies()
self.__init_build_system()
self.__init_publish()
def seed_path(self):
return self.__seed_path
def name(self):
if not 'seed' in self.__data:
return None
s = self.__data['seed']
if 'name' in s:
return s['name']
return None
def type(self):
if not 'seed' in self.__data:
return None
s = self.__data['seed']
if 'type' in s:
return s['type']
return 'component'
def dependencies(self):
return self.__dependencies
def publish(self):
return self.__publish
def install(self):
return self.__data.get('install', None)
def should_include_standard_dependencies(self):
if 'dependency' not in self.__data:
return True
s = self.__data['dependency']
if 'no_standard_dependencies' in s:
return not s['no_standard_dependencies']
return True
def build_system(self):
return self.__build_system
def scan_directory(paths):
for p in paths:
for root, dirs, files in os.walk(p):
for f in files:
if not f.endswith('.seed'):
continue
seed_path = os.path.join(root, f)
seed = None
try:
seed = Seed(path=seed_path)
except tomli.TOMLDecodeError as e:
raise SeedParseError('Err: Failed to parse seed file {}: {}'.format(seed_path, e))
all_seeds[seed.name()] = seed
def resolve_all():
for s in all_seeds.values():
deps = s.dependencies()
for k, v in deps.items():
v.resolve()