238 lines
6.9 KiB
Python
238 lines
6.9 KiB
Python
import os
|
|
import shutil
|
|
from command import Command
|
|
from config import Config
|
|
from cache import Cache
|
|
from seed import Seed
|
|
from target import Target
|
|
from env import Environment
|
|
from platform import Platform
|
|
from colorama import Fore, Style
|
|
|
|
|
|
class SetCommand(Command):
|
|
def __init__(self):
|
|
super().__init__(
|
|
name='set',
|
|
description='Set a configuration key value.')
|
|
|
|
|
|
def run(self, args):
|
|
key = args.get_positional(0)
|
|
value = args.get_positional(1)
|
|
|
|
if key is None or value is None:
|
|
print('usage: meadow set <key> <value>')
|
|
return -1
|
|
|
|
try:
|
|
value_i = int(value)
|
|
Config.set(key, value_i)
|
|
except:
|
|
Config.set(key, value)
|
|
|
|
return 0
|
|
|
|
|
|
class SeedsCommand(Command):
|
|
def __init__(self):
|
|
super().__init__(
|
|
name='seeds',
|
|
description='List all available seeds.')
|
|
|
|
|
|
def write_dot(self, path):
|
|
f = open(path, mode='w')
|
|
f.write('digraph seeds {\n')
|
|
f.write(' node [shape=Mrecord];\n')
|
|
nodes = {}
|
|
|
|
seeds = Seed.all_seeds()
|
|
targets = Target.all_targets()
|
|
for s in seeds.values():
|
|
if s.name() in nodes:
|
|
continue
|
|
|
|
sname = s.name().replace('-', '_')
|
|
nodes[s.name()] = s
|
|
f.write(' {} [label="{}"];\n'.format(sname, s.name()))
|
|
|
|
for d in s.dependencies().values():
|
|
continue
|
|
|
|
|
|
for t in targets.values():
|
|
if t.name() in nodes:
|
|
continue
|
|
|
|
t.resolve()
|
|
tname = t.name().replace('-', '_')
|
|
nodes[t.name()] = t
|
|
f.write(' {} [label="{}",shape=hexagon];\n'.format(tname, t.name()))
|
|
|
|
for s in seeds.values():
|
|
for k, d in s.dependencies().items():
|
|
if d.name() not in nodes:
|
|
nodes[d.name()] = d
|
|
dname = d.name().replace('-', '_')
|
|
f.write(' {} [label="{}",shape=diamond];\n'.format(dname, d.name()))
|
|
|
|
sname = s.name().replace('-', '_')
|
|
dname = d.name().replace('-', '_')
|
|
|
|
if d.is_resolved():
|
|
f.write(' {} -> {};\n'.format(dname, sname))
|
|
else:
|
|
f.write(' {} -> {}[style=dotted];\n'.format(dname, sname))
|
|
|
|
for t in targets.values():
|
|
for k, d in t.dependencies().items():
|
|
tname = t.name().replace('-', '_')
|
|
dname = d.name().replace('-', '_')
|
|
|
|
if d.is_resolved():
|
|
f.write(' {} -> {};\n'.format(dname, tname))
|
|
else:
|
|
f.write(' {} -> {}[style=dotted];\n'.format(dname, tname))
|
|
|
|
f.write('}\n')
|
|
f.close()
|
|
|
|
|
|
def run(self, args):
|
|
seeds = Seed.all_seeds()
|
|
|
|
dot_path = args.get_named('to-dot-file', 0, 1)
|
|
if dot_path is not None:
|
|
self.write_dot(dot_path)
|
|
return 0
|
|
|
|
for s in seeds.values():
|
|
print('{}'.format(s.name()))
|
|
|
|
|
|
class PlatformsCommand(Command):
|
|
def __init__(self):
|
|
super().__init__(
|
|
name='platforms',
|
|
description='List all available platforms')
|
|
|
|
|
|
def run(self, args):
|
|
print('Supported platforms:')
|
|
|
|
platforms = Platform.all_platforms()
|
|
current_platform = Platform.current_platform()
|
|
|
|
for p in platforms.values():
|
|
if current_platform is not None and p.name() == current_platform.name():
|
|
print(f'* {Fore.GREEN}{p.name()}{Style.RESET_ALL}')
|
|
else:
|
|
print(f' {p.name()}')
|
|
|
|
|
|
class HelpCommand(Command):
|
|
def __init__(self):
|
|
super().__init__(
|
|
name='help',
|
|
description='List all available commands.')
|
|
|
|
|
|
def run(self, args):
|
|
print('Available commands:')
|
|
|
|
commands = Command.all_commands()
|
|
max_len = 0
|
|
|
|
for c in commands.values():
|
|
if len(c.name()) > max_len:
|
|
max_len = len(c.name())
|
|
|
|
max_len += 5
|
|
for c in commands.values():
|
|
print(' ', end='')
|
|
print(c.name(), end='')
|
|
|
|
for i in range(len(c.name()), max_len):
|
|
print(' ', end='')
|
|
|
|
print(c.description())
|
|
|
|
|
|
class BuildCommand(Command):
|
|
def __init__(self):
|
|
super().__init__(
|
|
name='build',
|
|
description='Build the currently selected target.')
|
|
|
|
|
|
def run(self, args):
|
|
verbose = args.get_named('verbose', 0, 0)
|
|
|
|
current_target = Target.current_target()
|
|
if current_target is None:
|
|
print(f'{Fore.RED}Err:{Style.RESET_ALL} no build target has been set. Use `meadow set target.name <...>` to specify which target to build')
|
|
return -1
|
|
|
|
current_platform = Platform.current_platform()
|
|
if current_platform is None:
|
|
print(f'{Fore.RED}Err:{Style.RESET_ALL} no target platform has been set. Use `meadow set target.platform <...>` to specify which platform to target')
|
|
return -1
|
|
|
|
components = current_target.resolve()
|
|
|
|
for c in components:
|
|
build_system = None
|
|
if isinstance(c, Seed):
|
|
build_system = c.build_system()
|
|
build_system.check_out_of_date()
|
|
|
|
for c in components:
|
|
build_system = None
|
|
if isinstance(c, Seed):
|
|
build_system = c.build_system()
|
|
|
|
if build_system is not None:
|
|
out_of_date = \
|
|
build_system.is_configuration_out_of_date() \
|
|
or build_system.is_build_out_of_date()
|
|
|
|
if out_of_date:
|
|
print(f'{Fore.GREEN}>>>{Style.RESET_ALL} Building {c.name()}')
|
|
|
|
if build_system.is_configuration_out_of_date():
|
|
print(f'{Fore.CYAN} >>{Style.RESET_ALL} Configuring build...')
|
|
build_system.configure(verbose=verbose)
|
|
|
|
if out_of_date:
|
|
print(f'{Fore.CYAN} >>{Style.RESET_ALL} Building...')
|
|
build_system.build(verbose=verbose)
|
|
print(f'{Fore.CYAN} >>{Style.RESET_ALL} Installing...')
|
|
build_system.install(verbose=verbose)
|
|
|
|
print(f'{Style.BRIGHT}{Fore.GREEN}>>> Build Complete!{Style.RESET_ALL}')
|
|
|
|
|
|
class CleanCommand(Command):
|
|
def __init__(self):
|
|
super().__init__(
|
|
name='clean',
|
|
description='Delete all build-related files.')
|
|
|
|
|
|
def run(self, args):
|
|
build_dir = Environment.build_root()
|
|
|
|
for i in os.listdir(build_dir):
|
|
if i.startswith('meadow') and ('cache' not in i):
|
|
continue
|
|
|
|
ipath = os.path.join(build_dir, i)
|
|
if os.path.isdir(ipath):
|
|
shutil.rmtree(ipath)
|
|
else:
|
|
os.remove(ipath)
|
|
|
|
Cache.reset()
|
|
return 0
|