134 lines
3.5 KiB
Python
Executable File
134 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
"""
|
|
Measure sizes of a list of files.
|
|
|
|
This produces the format for use in <https://github.com/benchmark-action/github-action-benchmark>.
|
|
|
|
Use the script:
|
|
python3 scripts/ci/count_bytes.py --help
|
|
|
|
python3 scripts/ci/count_bytes.py \
|
|
"Wasm":crates/viewer/re_web_viewer_server/web_viewer/re_viewer_bg.wasm
|
|
|
|
python3 scripts/ci/count_bytes.py --format=github \
|
|
"Wasm":crates/viewer/re_web_viewer_server/web_viewer/re_viewer_bg.wasm
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os.path
|
|
import sys
|
|
from enum import Enum
|
|
from typing import Any
|
|
|
|
|
|
def get_unit(size: float) -> str:
|
|
UNITS = ["B", "kiB", "MiB", "GiB", "TiB"]
|
|
|
|
unit_index = 0
|
|
while size > 1024:
|
|
size /= 1024
|
|
unit_index += 1
|
|
|
|
return UNITS[unit_index]
|
|
|
|
|
|
DIVISORS = {
|
|
"B": 1,
|
|
"kiB": 1024,
|
|
"MiB": 1024 * 1024,
|
|
"GiB": 1024 * 1024 * 1024,
|
|
"TiB": 1024 * 1024 * 1024 * 1024,
|
|
}
|
|
|
|
|
|
def get_divisor(unit: str) -> int:
|
|
return DIVISORS[unit]
|
|
|
|
|
|
def render_table_dict(data: list[dict[str, str]]) -> str:
|
|
keys = data[0].keys()
|
|
column_widths = [max(len(key), *(len(str(row[key])) for row in data)) for key in keys]
|
|
separator = "|" + "|".join("-" * (width + 2) for width in column_widths)
|
|
header_row = "|".join(f" {key.center(width)} " for key, width in zip(keys, column_widths, strict=False))
|
|
|
|
table = f"|{header_row}|\n{separator}|\n"
|
|
for row in data:
|
|
row_str = "|".join(
|
|
f" {str(row.get(key, '')).ljust(width)} " for key, width in zip(keys, column_widths, strict=False)
|
|
)
|
|
table += f"|{row_str}|\n"
|
|
|
|
return table
|
|
|
|
|
|
def render_table_rows(rows: list[Any], headers: list[str]) -> str:
|
|
column_widths = [max(len(str(item)) for item in col) for col in zip(*([tuple(headers), *rows]), strict=False)]
|
|
separator = "|" + "|".join("-" * (width + 2) for width in column_widths)
|
|
header_row = "|".join(f" {header.center(width)} " for header, width in zip(headers, column_widths, strict=False))
|
|
|
|
table = f"|{header_row}|\n{separator}|\n"
|
|
for row in rows:
|
|
row_str = "|".join(f" {str(item).ljust(width)} " for item, width in zip(row, column_widths, strict=False))
|
|
table += f"|{row_str}|\n"
|
|
|
|
return table
|
|
|
|
|
|
class Format(Enum):
|
|
JSON = "json"
|
|
GITHUB = "github"
|
|
|
|
def render(self, data: list[dict[str, str]]) -> str:
|
|
if self is Format.JSON:
|
|
return json.dumps(data)
|
|
if self is Format.GITHUB:
|
|
return render_table_dict(data)
|
|
|
|
|
|
def measure(files: list[str], format: Format) -> None:
|
|
output: list[dict[str, str]] = []
|
|
for arg in files:
|
|
parts = arg.split(":")
|
|
name = parts[0]
|
|
file = parts[1]
|
|
size = os.path.getsize(file)
|
|
unit = parts[2] if len(parts) > 2 else get_unit(size)
|
|
div = get_divisor(unit)
|
|
|
|
output.append({
|
|
"name": name,
|
|
"value": str(round(size / div, 2)),
|
|
"unit": unit,
|
|
})
|
|
|
|
sys.stdout.write(format.render(output))
|
|
sys.stdout.flush()
|
|
|
|
|
|
def percentage(value: str) -> int:
|
|
value = value.replace("%", "")
|
|
return int(value)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Generate a PR summary page")
|
|
parser.add_argument(
|
|
"--format",
|
|
type=Format,
|
|
choices=list(Format),
|
|
default=Format.JSON,
|
|
help="Format to render",
|
|
)
|
|
parser.add_argument("files", nargs="*", help="Entries to measure. Format: name:path[:unit]")
|
|
|
|
args = parser.parse_args()
|
|
measure(args.files, args.format)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|