import sys from ninja_syntax import Writer import os def scan_assets(build_root): print(f'[spacetime] Scanning {build_root}/assets/src for assets') assets = [] for entry in os.scandir(f'{build_root}/assets/src'): if entry.is_file() and entry.name.endswith('.ink.svg'): assets.append(f'{build_root}/assets/src/{entry.name}') print(f'[spacetime] Found {len(assets)} assets') return assets default_asset_size = 512 asset_override = { 'earth.ink.svg': 2048 } def gen_inkscape_rules_for_asset_size(size, writer): writer.rule(f'inkscape_{size}px_full', f'inkscape -w {size * 1} -h {size * 1} $in -o $out') writer.rule(f'inkscape_{size}px_375', f'inkscape -w {int(size * 0.375)} -h {int(size * 0.375)} $in -o $out') writer.rule(f'inkscape_{size}px_125', f'inkscape -w {int(size * 0.125)} -h {int(size * 0.125)} $in -o $out') def gen_inkscape_rules_for_asset_sizes(writer): gen_inkscape_rules_for_asset_size(default_asset_size, writer) for override in asset_override: gen_inkscape_rules_for_asset_size(asset_override[override], writer) def asset_size(asset): if asset.split('/')[-1] in asset_override: return asset_override[asset.split('/')[-1]] else: return default_asset_size def gen_inkscape_rules_for_asset(root, asset, writer, files_375, files_full, files_125): in_file = asset out_file_name = asset.split('.')[0].split('/')[-1] out_full = f'{root}/assets/final/full/{out_file_name}.png' files_full.append(out_full) rule_full = f'inkscape_{asset_size(asset)}px_full' out_375 = f'{root}/assets/final/375/{out_file_name}.png' files_375.append(out_375) rule_375 = f'inkscape_{asset_size(asset)}px_375' out_125 = f'{root}/assets/final/125/{out_file_name}.png' files_125.append(out_125) rule_125 = f'inkscape_{asset_size(asset)}px_125' writer.build([out_full], rule_full, [in_file]) writer.build([out_375], rule_375, [in_file]) writer.build([out_125], rule_125, [in_file]) def gen_rules_for_client(root, env, writer): if env == 'dev': writer.rule('cargo-client', 'wasm-pack build --target web client', depfile=f'{root}/target/wasm32-unknown-unknown/release/starkingdoms_client.d', pool='console') elif env == 'prod': writer.rule('cargo-client', 'wasm-pack build --target web client --no-default-features --features textures-fast', depfile=f'{root}/target/wasm32-unknown-unknown/release/starkingdoms_client.d', pool='console') writer.build( [ f'{root}/client/pkg/.gitignore', f'{root}/client/pkg/package.json', f'{root}/client/pkg/starkingdoms_client.d.ts', f'{root}/client/pkg/starkingdoms_client.js', f'{root}/client/pkg/starkingdoms_client_bg.wasm', f'{root}/client/pkg/starkingdoms_client_bg.wasm.d.ts', f'{root}/target/wasm32-unknown-unknown/release/starkingdoms_client.wasm' ], 'cargo-client', [ f'{root}/assets/dist/spritesheet-125', f'{root}/assets/dist/spritesheet-125.png', f'{root}/assets/dist/spritesheet-125.ron', f'{root}/assets/dist/spritesheet-375', f'{root}/assets/dist/spritesheet-375.png', f'{root}/assets/dist/spritesheet-375.ron', f'{root}/assets/dist/spritesheet-full', f'{root}/assets/dist/spritesheet-full.png', f'{root}/assets/dist/spritesheet-full.ron', ] ) writer.rule('client-copy-file', f'cp -r {root}/client/pkg {root}/web/dist') writer.build( [ f'{root}/web/dist/.gitignore', f'{root}/web/dist/package.json', f'{root}/web/dist/starkingdoms_client.d.ts', f'{root}/web/dist/starkingdoms_client.js', f'{root}/web/dist/starkingdoms_client_bg.wasm', f'{root}/web/dist/starkingdoms_client_bg.wasm.d.ts' ], 'client-copy-file', [ f'{root}/client/pkg/.gitignore', f'{root}/client/pkg/package.json', f'{root}/client/pkg/starkingdoms_client.d.ts', f'{root}/client/pkg/starkingdoms_client.js', f'{root}/client/pkg/starkingdoms_client_bg.wasm', f'{root}/client/pkg/starkingdoms_client_bg.wasm.d.ts', ], ) writer.build(['client'], 'phony', [f'{root}/web/dist/starkingdoms_client.js']) def gen_rules_for_server(root, env, writer): if env == 'dev': out_dir = 'debug' writer.rule('cargo-server', 'cargo build --bin starkingdoms-server', depfile=f'{root}/target/debug/starkingdoms-server.d', pool='console') elif env == 'prod': out_dir = 'release' writer.rule('cargo-server', 'cargo build --bin starkingdoms-server --release', depfile=f'{root}/target/release/starkingdoms-server.d', pool='console') writer.build([f'{root}/target/{out_dir}/starkingdoms-server'], 'cargo-server', ['server/Cargo.toml']) writer.build(['server'], 'phony', [f'{root}/target/{out_dir}/starkingdoms-server']) def gen_inkscape(root, assets, writer, files_375, files_full, files_125): gen_inkscape_rules_for_asset_sizes(writer) for asset in assets: gen_inkscape_rules_for_asset(root, asset, writer, files_375, files_full, files_125) def gen_packers(root, writer, files_375, files_full, files_125): # sheep pack assets/final/full/*.png -f amethyst_named -o assets/dist/spritesheet-full writer.rule(f'pack', 'sheep pack -f amethyst_named -o $out $in && touch $out') writer.build(f'{root}/assets/dist/spritesheet-full', 'pack', inputs=files_full, implicit_outputs=[f'{root}/assets/dist/spritesheet-full.png', f'{root}/assets/dist/spritesheet-full.ron']) writer.build(f'asset-full', 'phony', inputs=[f'{root}/assets/dist/spritesheet-full']) writer.build(f'{root}/assets/dist/spritesheet-375', 'pack', inputs=files_375, implicit_outputs=[f'{root}/assets/dist/spritesheet-375.png', f'{root}/assets/dist/spritesheet-375.ron']) writer.build(f'asset-375', 'phony', inputs=[f'{root}/assets/dist/spritesheet-375']) writer.build(f'{root}/assets/dist/spritesheet-125', 'pack', inputs=files_125, implicit_outputs=[f'{root}/assets/dist/spritesheet-125.png', f'{root}/assets/dist/spritesheet-125.ron']) writer.build(f'asset-125', 'phony', inputs=[f'{root}/assets/dist/spritesheet-125']) writer.build(f'asset', 'phony', inputs=[f'{root}/assets/dist/spritesheet-full', f'{root}/assets/dist/spritesheet-375', f'{root}/assets/dist/spritesheet-125']) def generate_assets_build_command(root, assets, writer): files_full = [] files_375 = [] files_125 = [] gen_inkscape(root, assets, writer, files_375, files_full, files_125) gen_packers(root, writer, files_375, files_full, files_125) def main(): target = sys.argv[1] env = sys.argv[2] root = sys.argv[3] print(f'[spacetime] Configuring ninja for PRIMARY_TARGET={target} with ENV={env}, BUILDROOT={root}') with open(f'{root}/build.ninja', 'w') as f: writer = Writer(f) writer.comment('Generated by spacetime.py') writer.comment('Do not manually edit this file') if env == 'prod' or target == 'asset': assets = scan_assets(root) generate_assets_build_command(root, assets, writer) if target == 'client': gen_rules_for_client(root, env, writer) elif target == 'server': gen_rules_for_server(root, env, writer) print(f'[spacetime] Configured build') if __name__ == "__main__": main()