diff --git a/build_differ.py b/build_differ.py index 0c6ab53..c3e4f6d 100644 --- a/build_differ.py +++ b/build_differ.py @@ -1,3 +1,4 @@ +import asyncio import subprocess import os import tarfile @@ -9,34 +10,50 @@ def get_version(): Extracts the version from the specified __about__.py file. """ about = {} - with open('./src/python_redlines/__about__.py') as f: + with open("./src/python_redlines/__about__.py") as f: exec(f.read(), about) - return about['__version__'] + return about["__version__"] -def run_command(command): +async def run_command(command): """ Runs a shell command and prints its output. """ - process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - for line in process.stdout: + process = await asyncio.create_subprocess_exec( + *command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + async for line in process.stdout: print(line.decode().strip()) + await process.wait() -def compress_files(source_dir, target_file): + +def _compress_tar(source_dir, target_file): + with tarfile.open(target_file, "w:gz") as tar: + tar.add(source_dir, arcname=os.path.basename(source_dir)) + + +def _compress_zip(source_dir, target_file): + with zipfile.ZipFile(target_file, "w", zipfile.ZIP_DEFLATED) as zipf: + for root, dirs, files in os.walk(source_dir): + for file in files: + zipf.write( + os.path.join(root, file), + os.path.relpath( + os.path.join(root, file), os.path.join(source_dir, "..") + ), + ) + + +async def compress_files(source_dir, target_file): """ Compresses files in the specified directory into a tar.gz or zip file. """ - if target_file.endswith('.tar.gz'): - with tarfile.open(target_file, "w:gz") as tar: - tar.add(source_dir, arcname=os.path.basename(source_dir)) - elif target_file.endswith('.zip'): - with zipfile.ZipFile(target_file, 'w', zipfile.ZIP_DEFLATED) as zipf: - for root, dirs, files in os.walk(source_dir): - for file in files: - zipf.write(os.path.join(root, file), - os.path.relpath(os.path.join(root, file), - os.path.join(source_dir, '..'))) + loop = asyncio.get_event_loop() + if target_file.endswith(".tar.gz"): + await loop.run_in_executor(None, _compress_tar, source_dir, target_file) + elif target_file.endswith(".zip"): + await loop.run_in_executor(None, _compress_zip, source_dir, target_file) def cleanup_old_builds(dist_dir, current_version): @@ -44,61 +61,66 @@ def cleanup_old_builds(dist_dir, current_version): Deletes any build files ending in .zip or .tar.gz in the dist_dir with a different version tag. """ for file in os.listdir(dist_dir): - if not file.endswith((f'{current_version}.zip', f'{current_version}.tar.gz', '.gitignore')): + if not file.endswith( + (f"{current_version}.zip", f"{current_version}.tar.gz", ".gitignore") + ): file_path = os.path.join(dist_dir, file) os.remove(file_path) print(f"Deleted old build file: {file}") -def main(): +async def main(): version = get_version() print(f"Version: {version}") dist_dir = "./src/python_redlines/dist/" - # Build for Linux x64 - print("Building for Linux x64...") - run_command('dotnet publish ./csproj -c Release -r linux-x64 --self-contained') - - # Build for Linux ARM64 - print("Building for Linux ARM64...") - run_command('dotnet publish ./csproj -c Release -r linux-arm64 --self-contained') - - # Build for Windows x64 - print("Building for Windows x64...") - run_command('dotnet publish ./csproj -c Release -r win-x64 --self-contained') - - # Build for Windows ARM64 - print("Building for Windows ARM64...") - run_command('dotnet publish ./csproj -c Release -r win-arm64 --self-contained') - - # Build for macOS x64 - print("Building for macOS x64...") - run_command('dotnet publish ./csproj -c Release -r osx-x64 --self-contained') - - # Build for macOS ARM64 - print("Building for macOS ARM64...") - run_command('dotnet publish ./csproj -c Release -r osx-arm64 --self-contained') - - # Compress the Linux x64 build - linux_x64_build_dir = './csproj/bin/Release/net8.0/linux-x64' - compress_files(linux_x64_build_dir, f"{dist_dir}/linux-x64-{version}.tar.gz") - - # Compress the Linux ARM64 build - linux_arm64_build_dir = './csproj/bin/Release/net8.0/linux-arm64' - compress_files(linux_arm64_build_dir, f"{dist_dir}/linux-arm64-{version}.tar.gz") - - # Compress the Windows x64 build - windows_build_dir = './csproj/bin/Release/net8.0/win-x64' - compress_files(windows_build_dir, f"{dist_dir}/win-x64-{version}.zip") - - # Compress the macOS x64 build - macos_x64_build_dir = './csproj/bin/Release/net8.0/osx-x64' - compress_files(macos_x64_build_dir, f"{dist_dir}/osx-x64-{version}.tar.gz") - - # Compress the macOS ARM64 build - macos_arm64_build_dir = './csproj/bin/Release/net8.0/osx-arm64' - compress_files(macos_arm64_build_dir, f"{dist_dir}/osx-arm64-{version}.tar.gz") + await run_command(["dotnet", "restore", "./csproj"]) + + run_commands = [ + ["dotnet", "publish", "./csproj", "-c", "Release", "-r", "linux-x64", "--self-contained", "--no-restore"], + ["dotnet", "publish", "./csproj", "-c", "Release", "-r", "linux-arm64", "--self-contained", "--no-restore"], + ["dotnet", "publish", "./csproj", "-c", "Release", "-r", "win-x64", "--self-contained", "--no-restore"], + ["dotnet", "publish", "./csproj", "-c", "Release", "-r", "win-arm64", "--self-contained", "--no-restore"], + ["dotnet", "publish", "./csproj", "-c", "Release", "-r", "osx-x64", "--self-contained", "--no-restore"], + ["dotnet", "publish", "./csproj", "-c", "Release", "-r", "osx-arm64", "--self-contained", "--no-restore"], + ] + + await asyncio.gather(*[run_command(command) for command in run_commands]) + + compression_inputs = [ + ( + "./csproj/bin/Release/net8.0/linux-x64", + f"{dist_dir}/linux-x64-{version}.tar.gz", + ), + ( + "./csproj/bin/Release/net8.0/linux-arm64", + f"{dist_dir}/linux-arm64-{version}.tar.gz", + ), + ( + "./csproj/bin/Release/net8.0/win-x64", + f"{dist_dir}/win-x64-{version}.zip", + ), + ( + "./csproj/bin/Release/net8.0/win-arm64", + f"{dist_dir}/win-arm64-{version}.zip", + ), + ( + "./csproj/bin/Release/net8.0/osx-x64", + f"{dist_dir}/osx-x64-{version}.tar.gz", + ), + ( + "./csproj/bin/Release/net8.0/osx-arm64", + f"{dist_dir}/osx-arm64-{version}.tar.gz", + ), + ] + + await asyncio.gather( + *[ + compress_files(source_dir, target_file) + for source_dir, target_file in compression_inputs + ] + ) cleanup_old_builds(dist_dir, version) @@ -106,4 +128,4 @@ def main(): if __name__ == "__main__": - main() + asyncio.run(main()) diff --git a/csproj/redlines.csproj b/csproj/redlines.csproj index 8b2abdd..0e354c2 100644 --- a/csproj/redlines.csproj +++ b/csproj/redlines.csproj @@ -5,6 +5,7 @@ net8.0 enable enable + win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64