Skip to content

Commit

Permalink
feat: add bench app-cache helper command
Browse files Browse the repository at this point in the history
  • Loading branch information
18alantom committed Jan 19, 2024
1 parent 30f301e commit 42ac015
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# MAC OS
.DS_Store

# VS Code
.vscode/

# Vim Gitignore
## Swap
[._]*.s[a-v][a-z]
Expand Down
2 changes: 2 additions & 0 deletions bench/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def bench_command(bench_path="."):


from bench.commands.utils import (
app_cache_helper,
backup_all_sites,
bench_src,
disable_production,
Expand Down Expand Up @@ -108,6 +109,7 @@ def bench_command(bench_path="."):
bench_command.add_command(bench_src)
bench_command.add_command(find_benches)
bench_command.add_command(migrate_env)
bench_command.add_command(app_cache_helper)

from bench.commands.setup import setup

Expand Down
18 changes: 18 additions & 0 deletions bench/commands/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,21 @@ def migrate_env(python, backup=True):
from bench.utils.bench import migrate_env

migrate_env(python=python, backup=backup)


@click.command("app-cache", help="View or remove items belonging to bench get-app cache")
@click.option("--clear", is_flag=True, default=False, help="Remove all items")
@click.option(
"--remove-app",
default="",
help="Removes all items that match provided app name",
)
@click.option(
"--remove-hash",
default="",
help="Removes all items that matches provided commit-hash",
)
def app_cache_helper(clear=False, remove_app="", remove_hash=""):
from bench.utils.bench import cache_helper

cache_helper(clear, remove_app, remove_hash)
124 changes: 121 additions & 3 deletions bench/utils/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@
import logging
import os
import re
import shutil
import subprocess
import sys
from functools import lru_cache
from glob import glob
from json.decoder import JSONDecodeError
from pathlib import Path

# imports - third party imports
import click

# imports - module imports
import bench
from bench.exceptions import PatchError, ValidationError
from bench.utils import exec_cmd, get_bench_name, get_cmd_output, log, which
from bench.utils import (exec_cmd, get_bench_cache_path, get_bench_name,
get_cmd_output, log, which)

logger = logging.getLogger(bench.PROJECT_NAME)

Expand Down Expand Up @@ -353,13 +356,14 @@ def build_assets(bench_path=".", app=None, using_cached=False):
command = "bench build"
if app:
command += f" --app {app}"

env = {"BENCH_DEVELOPER": "1"}
if using_cached:
env["USING_CACHED"] = "1"

exec_cmd(command, cwd=bench_path, env=env)


def handle_version_upgrade(version_upgrade, bench_path, force, reset, conf):
from bench.utils import log, pause_exec

Expand Down Expand Up @@ -638,3 +642,117 @@ def validate_branch():
)

sys.exit(1)


def cache_helper(clear=False, remove_app="", remove_hash="") -> None:
can_remove = bool(remove_hash or remove_app)
if not clear and not can_remove:
cache_list()
elif can_remove:
cache_remove(remove_app, remove_hash)
elif clear:
cache_clear()
else:
pass # unreachable


def cache_list() -> None:
from datetime import datetime

tot_size = 0
tot_items = 0

printed_header = False
for item in get_bench_cache_path("apps").iterdir():
if item.suffix not in [".tar", ".tgz"]:
continue

stat = item.stat()
size_mb = stat.st_size / 1_000_000
created = datetime.fromtimestamp(stat.st_ctime)
accessed = datetime.fromtimestamp(stat.st_atime)

app = item.name.split("-")[0]
tot_items += 1
tot_size += stat.st_size
compressed = item.suffix == ".tgz"

if not printed_header:
click.echo(
f"{'APP':15} "
f"{'FILE':25} "
f"{'SIZE':>13} "
f"{'COMPRESSED'} "
f"{'CREATED':19} "
f"{'ACCESSED':19} "
)
printed_header = True

click.echo(
f"{app:15} "
f"{item.name:25} "
f"{size_mb:10.3f} MB "
f"{str(compressed):10} "
f"{created:%Y-%m-%d %H:%M:%S} "
f"{accessed:%Y-%m-%d %H:%M:%S} "
)
if tot_items:
click.echo(f"Total size {tot_size / 1_000_000:.3f} MB belonging to {tot_items} items")
else:
click.echo("No cached items")


def cache_remove(app: str = "", hash: str = "") -> None:
rem_items = 0
rem_size = 0
for item in get_bench_cache_path("apps").iterdir():
if not should_remove_item(item, app, hash):
continue

rem_items += 1
rem_size += item.stat().st_size
item.unlink(True)
click.echo(f"Removed {item.name}")

if rem_items:
click.echo(f"Cleared {rem_size / 1_000_000:.3f} MB belonging to {rem_items} items")
else:
click.echo("No items removed")


def should_remove_item(item: Path, app: str, hash: str) -> bool:
if item.suffix not in [".tar", ".tgz"]:
return False

name = item.name
if app and hash and name.startswith(f"{app}-{hash[:10]}."):
return True

if app and name.startswith(f"{app}-"):
return True

if hash and f"-{hash[:10]}." in name:
return True

return False


def cache_clear() -> None:
cache_path = get_bench_cache_path("apps")
tot_items = len(os.listdir(cache_path))
if not tot_items:
click.echo("No cached items")
return

tot_size = get_dir_size(cache_path)
shutil.rmtree(cache_path)

rem_items = tot_items - len(os.listdir(cache_path))
rem_size = tot_size - get_dir_size(cache_path)

if rem_items:
click.echo(f"Cleared {rem_size / 1_000_000:.3f} MB belonging to {rem_items} items")


def get_dir_size(p: Path) -> int:
return sum(i.stat(follow_symlinks=False).st_size for i in p.iterdir())

0 comments on commit 42ac015

Please sign in to comment.