def main(args): import argparse parser = argparse.ArgumentParser( description='Update build defintions to include all GLSL files.', prog=args[0]) add_common_args(parser) update(parser.parse_args(args[1:]))
def main(args): parser = argparse.ArgumentParser( description='Generate an ZIP distribution.', prog=args[0]) parser.add_argument( 'build_dir', help='The build directory (defaults to CWD)', default=Path(os.getcwd()), type=Path, nargs='?', ) parser.add_argument( 'output', help='The output file path', type=Path, ) add_common_args(parser) args = parser.parse_args(args[1:]) with temp_install(args.build_dir) as install_dir, ZipFile( str(args.output), "w", ZIP_DEFLATED) as zfile: for path in install_dir.glob('**/*'): if not path.is_dir(): rel = str(path.relative_to(install_dir)) print("Adding file {}".format(rel)) zfile.write(str(path), rel) print("Generated package {}".format(str(args.output)))
def main(args): import argparse parser = argparse.ArgumentParser( description='Perform all automated routine maintenance tasks.', prog=args[0]) add_common_args(parser) pargs = parser.parse_args(args[1:]) scripts = pargs.rootdir / 'scripts' / 'upkeep' tasks = ( ['fixup-source-files', 'check-rng-usage'], 'update-glsl-sources', ) with ThreadPoolExecutor() as ex: def do_task(task): if isinstance(task, str): print('[upkeep] begin task', task) subprocess.check_call([scripts / f'{task}.py'] + args[1:]) print('[upkeep] task', task, 'done') else: for t in task: do_task(t) tuple(ex.map(do_task, tasks))
def main(args): import argparse parser = argparse.ArgumentParser(description='Update build defintions to include all GLSL files.', prog=args[0]) add_common_args(parser) args = parser.parse_args(args[1:]) for shaders_root in (args.rootdir / 'resources').glob('*/shader'): update(args, shaders_root)
def main(args): parser = argparse.ArgumentParser(description='Generate an NSIS installer for Windows.', prog=args[0]) parser.add_argument('build_dir', help='The build directory (defaults to CWD)', default=Path(os.getcwd()), type=Path, nargs='?', ) parser.add_argument('script_template', help='The NSIS script template', type=Path, ) add_configure_args(parser) add_common_args(parser) args = parser.parse_args(args[1:]) args.variables = dict(args.variables) with args.script_template.open('r') as infile: template = infile.read() with temp_install(args.build_dir) as install_dir: glob = tuple(install_dir.glob('**/*')) files = sorted((PureWindowsPath(p.relative_to(install_dir)) for p in glob if not p.is_dir()), reverse=True) dirs = sorted((PureWindowsPath(p.relative_to(install_dir)) for p in glob if p.is_dir()), reverse=True) indent = ' ' * 4 instdir = '$INSTDIR' uninstall_files = ('\n'+indent).join('Delete "{}\\{}"'.format(instdir, path) for path in files) uninstall_dirs = ('\n'+indent).join('RMDir "{}\\{}"'.format(instdir, path) for path in dirs) uninstall_commands = indent + ('\n\n'+indent).join((uninstall_files, uninstall_dirs)) print(uninstall_commands) args.variables.update({ 'INSTALL_DIR': str(install_dir), 'UNINSTALL_COMMANDS': uninstall_commands, 'INSTALL_OPTIONS_INI': str(Path(args.rootdir) / 'scripts' / 'NSIS.InstallOptions.ini') }) script = configure(template, args.variables, prefix='@', suffix='@', args=args ) nsis_cmd = shlex.split('makensis -V3 -NOCD -INPUTCHARSET UTF8 -WX -') with subprocess.Popen(nsis_cmd, stdin=subprocess.PIPE, cwd=str(args.build_dir)) as proc: proc.stdin.write(script.encode('utf-8')) if proc.returncode != 0: raise MakeNSISError(proc.returncode)
def main(args): import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) parser = argparse.ArgumentParser(description='Generate a distribution archive.', prog=args[0]) parser.add_argument('build_dir', help='the build directory (defaults to CWD)', default=Path(os.getcwd()), type=Path, nargs='?', ) parser.add_argument('output', help='the output file path', type=Path, ) parser.add_argument('--format', help='the archive format', default='zip', choices=sorted(map(lambda x: x[0], shutil.get_archive_formats())), ) parser.add_argument('--prefix', help='add a common prefix to all files and directories in the archive', default=None, ) add_common_args(parser) args = parser.parse_args(args[1:]) if args.prefix is not None: p = PurePosixPath(args.prefix) if p.is_absolute() or p.is_reserved() or '..' in p.parts: raise ValueError('Bad prefix: {}'.format(args.prefix)) args.prefix = str(p) if args.prefix == '.': args.prefix = None with temp_install(args.build_dir) as install_dir: if args.prefix is not None: os.chdir(str(install_dir.parent)) install_dir.rename(install_dir.parent / args.prefix) archive = shutil.make_archive(str(args.output), args.format, '.', str(args.prefix)) else: archive = shutil.make_archive(str(args.output), args.format, str(install_dir)) archive = Path(archive) archive.rename(args.output) print("Generated distribution archive {}".format(str(args.output)))
def main(args): import argparse parser = argparse.ArgumentParser(description='Fix-up all C sources and headers - add/update copyright header, include guards, etc.', prog=args[0]) add_common_args(parser) pargs = parser.parse_args(args[1:]) j = Janitor(pargs.rootdir / 'src') with ThreadPoolExecutor() as ex: tuple(ex.map(j.do_maintenance, j.iter_files()))
def main(args): import argparse parser = argparse.ArgumentParser( description='Update build defintions to include all GLSL files.', prog=args[0]) add_common_args(parser) args = parser.parse_args(args[1:]) for shaders_root in (args.rootdir / 'resources').glob('*/shader'): update(args, shaders_root)
def main(args): import argparse parser = argparse.ArgumentParser( description= 'Fix-up all C sources and headers - add/update copyright header, include guards, etc.', prog=args[0]) add_common_args(parser) pargs = parser.parse_args(args[1:]) j = Janitor(pargs.rootdir / 'src') with ThreadPoolExecutor() as ex: tuple(ex.map(j.do_maintenance, j.iter_files()))
def main(args): import argparse parser = argparse.ArgumentParser(description='Perform all automated routine maintenance tasks.', prog=args[0]) add_common_args(parser) pargs = parser.parse_args(args[1:]) scripts = pargs.rootdir / 'scripts' / 'upkeep' tasks = ( 'fixup-source-files', 'update-glsl-sources', ) with ThreadPoolExecutor() as ex: tuple(ex.map(lambda task: subprocess.check_call([scripts / f'{task}.py'] + args[1:]), tasks))
def main(args): import argparse parser = argparse.ArgumentParser(description='Package game assets.', prog=args[0]) parser.add_argument('directory', type=DirPathType, help='the source package directory') parser.add_argument('output', type=Path, help='the output archive path') add_common_args(parser, depfile=True) args = parser.parse_args(args[1:]) pack(args)
def main(args): import argparse parser = argparse.ArgumentParser( description='Update build defintions to include all GLSL files.', prog=args[0]) add_common_args(parser) args = parser.parse_args(args[1:]) with (args.builddir / 'compile_commands.json').open() as f: compile_commands = json.load(f) with ThreadPoolExecutor() as ex: tuple( ex.map(lambda c: find_suspicious_callsites(preprocess(c)), compile_commands))
def main(args): import argparse parser = argparse.ArgumentParser( description='Check source code for suspicious RNG API usage.', prog=args[0]) add_common_args(parser) args = parser.parse_args(args[1:]) with (args.builddir / 'compile_commands.json').open() as f: compile_commands = json.load(f) with ThreadPoolExecutor() as ex: tuple( ex.map(lambda c: find_suspicious_callsites(preprocess(c)), compile_commands))
def main(args): parser = argparse.ArgumentParser( description='Generate a reusable gaussian blur shader.', prog=args[0]) def kernsize(v): v = int(v) if not v & 1: raise ValueError('Kernel size must be an odd integer') return v parser.add_argument( 'kernel_size', help='size of the 1D convolution kernel, must be odd', type=kernsize, ) parser.add_argument( 'sigma', help='standard deviation value for the probability density function', type=float, ) parser.add_argument( 'name', help= 'name of the shader, defaults to blurX, where X is the kernel size', type=str, default=None, nargs='?', ) add_common_args(parser) args = parser.parse_args() if args.name is None: args.name = f'blur{args.kernel_size}' shaders = args.rootdir / 'resources' / 'shader' blurs = shaders / 'lib' / 'blur' blurs.mkdir(parents=True, exist_ok=True) update_text_file(blurs / f'{args.name}.glslh', gen_lib_shader(args)) update_text_file(shaders / f'{args.name}.frag.glsl', gen_fragment_shader(args)) update_text_file(shaders / f'{args.name}.prog', gen_meta(args))
def main(args): import argparse parser = argparse.ArgumentParser(description='Package game assets.', prog=args[0]) parser.add_argument('directory', type=DirPathType, help='the source package directory' ) parser.add_argument('output', type=Path, help='the output archive path' ) add_common_args(parser, depfile=True) args = parser.parse_args(args[1:]) pack(args)
def main(args): import argparse parser = argparse.ArgumentParser( description='Perform all automated routine maintenance tasks.', prog=args[0]) add_common_args(parser) pargs = parser.parse_args(args[1:]) scripts = pargs.rootdir / 'scripts' / 'upkeep' tasks = ( 'fixup-source-files', 'update-glsl-sources', ) with ThreadPoolExecutor() as ex: tuple( ex.map( lambda task: subprocess.check_call([scripts / f'{task}.py'] + args[1:]), tasks))
def main(args): parser = argparse.ArgumentParser(description='Generate a reusable gaussian blur shader.', prog=args[0]) def kernsize(v): v = int(v) if not v & 1: raise ValueError('Kernel size must be an odd integer') return v parser.add_argument('kernel_size', help='size of the 1D convolution kernel, must be odd', type=kernsize, ) parser.add_argument('sigma', help='standard deviation value for the probability density function', type=float, ) parser.add_argument('name', help='name of the shader, defaults to blurX, where X is the kernel size', type=str, default=None, nargs='?', ) add_common_args(parser) args = parser.parse_args() if args.name is None: args.name = f'blur{args.kernel_size}' shaders = args.rootdir / 'resources' / 'shader' blurs = shaders / 'lib' / 'blur' blurs.mkdir(parents=True, exist_ok=True) update_text_file(blurs / f'{args.name}.glslh', gen_lib_shader(args)) update_text_file(shaders / f'{args.name}.frag.glsl', gen_fragment_shader(args)) update_text_file(shaders / f'{args.name}.prog', gen_meta(args))
def main(args): parser = argparse.ArgumentParser( description='Generate an NSIS installer for Windows.', prog=args[0]) parser.add_argument( 'build_dir', help='The build directory (defaults to CWD)', default=Path(os.getcwd()), type=Path, nargs='?', ) parser.add_argument( 'script_template', help='The NSIS script template', type=Path, ) add_configure_args(parser) add_common_args(parser) args = parser.parse_args(args[1:]) args.variables = dict(args.variables) with args.script_template.open('r') as infile: template = infile.read() with temp_install(args.build_dir) as install_dir: glob = tuple(install_dir.glob('**/*')) files = sorted((PureWindowsPath(p.relative_to(install_dir)) for p in glob if not p.is_dir()), reverse=True) dirs = sorted((PureWindowsPath(p.relative_to(install_dir)) for p in glob if p.is_dir()), reverse=True) indent = ' ' * 4 instdir = '$INSTDIR' uninstall_files = ('\n' + indent).join( 'Delete "{}\\{}"'.format(instdir, path) for path in files) uninstall_dirs = ('\n' + indent).join( 'RMDir "{}\\{}"'.format(instdir, path) for path in dirs) uninstall_commands = ('\n\n' + indent).join( (uninstall_files, uninstall_dirs)) print(uninstall_commands) args.variables.update({ 'INSTALL_DIR': str(install_dir), 'UNINSTALL_COMMANDS': uninstall_commands, 'INSTALL_OPTIONS_INI': str(Path(args.rootdir) / 'scripts' / 'NSIS.InstallOptions.ini') }) script = configure(template, args.variables, prefix='@', suffix='@', args=args) nsis_cmd = shlex.split('makensis -V4 -NOCD -INPUTCHARSET UTF8 -WX -') with subprocess.Popen(nsis_cmd, stdin=subprocess.PIPE, cwd=str(args.build_dir)) as proc: proc.stdin.write(script.encode('utf-8')) if proc.returncode != 0: raise MakeNSISError(proc.returncode)
def main(args): parser = argparse.ArgumentParser(description='Regenerate a Meson build directory, attempting to preserve build options.', prog=args[0]) parser.add_argument('build_dir', default=Path.cwd(), type=Path, nargs='?', help='the build directory (defaults to CWD)', ) parser.add_argument('dest_build_dir', default=None, type=Path, nargs='?', help='the destination directory (defaults to same as build_dir)', ) parser.add_argument('--meson', default=['meson'], type=shlex.split, help='override the Meson executable (useful for wrappers)', ) parser.add_argument('meson_args', default=[], nargs='*', help='additional arguments for Meson', ) add_common_args(parser) args = parser.parse_args(args[1:]) if args.dest_build_dir is None: args.dest_build_dir = args.build_dir with in_dir(args.build_dir): try: build_options = meson_introspect('--buildoptions') except subprocess.SubprocessError: print("Warning: meson introspect failed, retrieving options from saved_options.json. This may not be up to date.", file=sys.stderr) with open('saved_options.json') as infile: build_options = json.loads(infile.read()) regen_cmdline = args.meson + [ str(args.rootdir.resolve(strict=True)), str(args.dest_build_dir.resolve(strict=False)), ] meson_options = set(re.findall(r'\[--([\w-]+)\s+.*?\]', subprocess.check_output(args.meson + ['--help']).decode('utf8'), re.A)) def opt_str_value(opt, value): if isinstance(value, bool): # Meson <= 0.43.0 bug return str(value).lower() if opt == 'install_umask': return '%04o' % int(value) return str(value) for opt in build_options: name = opt['name'] value = opt_str_value(name, opt['value']) if name in meson_options: regen_cmdline.append('--{}={}'.format(name, value)) regen_cmdline += args.meson_args args.dest_build_dir.mkdir(parents=True, exist_ok=True) with in_dir(args.dest_build_dir): obj = { 'command': regen_cmdline, 'build_options': build_options, } with Path('imported_options.json').open('w') as outfile: json.dump(obj, outfile, ensure_ascii=False, indent=4, sort_keys=True, ) meson_dir = Path('meson-private') meson_dir_bak = meson_dir.with_name(meson_dir.name + '.bak') if meson_dir.is_dir(): shutil.rmtree(meson_dir_bak, ignore_errors=True) meson_dir.rename(meson_dir_bak) print('+', regen_cmdline) subprocess.check_call(regen_cmdline) for opt in build_options: name = opt['name'] value = opt_str_value(name, opt['value']) cmdline = args.meson + ['configure', '-D{}={}'.format(name, value)] print('+', cmdline) subprocess.call(cmdline) print('') print("Regeneration done. This process is not 100% reliable; you may want to check the output of 'meson configure'")
def main(args): parser = argparse.ArgumentParser( description= 'Regenerate a Meson build directory, attempting to preserve build options.', prog=args[0]) parser.add_argument( 'build_dir', default=Path.cwd(), type=Path, nargs='?', help='the build directory (defaults to CWD)', ) parser.add_argument( 'dest_build_dir', default=None, type=Path, nargs='?', help='the destination directory (defaults to same as build_dir)', ) parser.add_argument( '--meson', default=['meson'], type=shlex.split, help='override the Meson executable (useful for wrappers)', ) parser.add_argument( 'meson_args', default=[], nargs='*', help='additional arguments for Meson', ) add_common_args(parser) args = parser.parse_args(args[1:]) if args.dest_build_dir is None: args.dest_build_dir = args.build_dir with in_dir(args.build_dir): try: build_options = meson_introspect('--buildoptions') except subprocess.SubprocessError: print( "Warning: meson introspect failed, retrieving options from saved_options.json. This may not be up to date.", file=sys.stderr) with open('saved_options.json') as infile: build_options = json.loads(infile.read()) regen_cmdline = args.meson + [ str(args.rootdir.resolve(strict=True)), str(args.dest_build_dir.resolve(strict=False)), ] meson_options = set( re.findall( r'\[--([\w-]+)\s+.*?\]', subprocess.check_output(args.meson + ['--help']).decode('utf8'), re.A)) def opt_str_value(opt, value): if isinstance(value, bool): # Meson <= 0.43.0 bug return str(value).lower() if opt == 'install_umask': return '%04o' % int(value) return str(value) for opt in build_options: name = opt['name'] value = opt_str_value(name, opt['value']) if name in meson_options: regen_cmdline.append('--{}={}'.format(name, value)) regen_cmdline += args.meson_args args.dest_build_dir.mkdir(parents=True, exist_ok=True) with in_dir(args.dest_build_dir): obj = { 'command': regen_cmdline, 'build_options': build_options, } with Path('imported_options.json').open('w') as outfile: json.dump( obj, outfile, ensure_ascii=False, indent=4, sort_keys=True, ) meson_dir = Path('meson-private') meson_dir_bak = meson_dir.with_name(meson_dir.name + '.bak') if meson_dir.is_dir(): shutil.rmtree(meson_dir_bak, ignore_errors=True) meson_dir.rename(meson_dir_bak) print('+', regen_cmdline) subprocess.check_call(regen_cmdline) for opt in build_options: name = opt['name'] value = opt_str_value(name, opt['value']) cmdline = args.meson + ['configure', '-D{}={}'.format(name, value)] print('+', cmdline) subprocess.call(cmdline) print('') print( "Regeneration done. This process is not 100% reliable; you may want to check the output of 'meson configure'" )