Skip to content

Commit

Permalink
✨ Add the clear command
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamim committed May 15, 2024
1 parent ca5fd28 commit 7bafdc3
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/gcm/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from .clear import Clear
from .disable import Disable
from .enable import Enable
from .stats import Stats

COMMANDS = [Enable(), Disable(), Stats()]
COMMANDS = [
Enable(),
Disable(),
Clear(),
Stats(),
]
58 changes: 58 additions & 0 deletions src/gcm/commands/clear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import subprocess

import click

from ..utils import warn
from .base import PACKAGE_NAME, Command, ccache_dir_env
from .exit_codes import (
CCACHE_BINARY_NOT_FOUND,
OK,
PERMISSION_DENIED,
UNKNOWN_ERROR,
)


def clear_stats(package: str, keep_stats: bool) -> int:
args = ['ccache', '-C']
if not keep_stats:
args.append('-z')

try:
result = subprocess.run(
args,
stderr=subprocess.PIPE,
env=ccache_dir_env(package),
text=True,
)
except FileNotFoundError:
warn('Unable to clear ccache data due to missing ccache binary')
return CCACHE_BINARY_NOT_FOUND

if result.returncode:
click.echo(f'\n{result.stderr}', nl=False, err=True)
if 'Permission denied' in result.stderr:
warn('Unable to clear ccache data due to a lack of permissions')
return PERMISSION_DENIED

warn('Unknown error, please submit a bug report!')
return UNKNOWN_ERROR

return OK


class Clear(Command):
"""Clear ccache data for a package."""

INVOKE_MESSAGE = f'Clearing ccache data for {PACKAGE_NAME}'

params = [
click.Option(
['-k', '--keep-stats'],
is_flag=True,
help='Keep statistics counters.',
)
]

@staticmethod
def callback(package: str, keep_stats: bool) -> int: # type: ignore[override]
return clear_stats(package, keep_stats)
2 changes: 2 additions & 0 deletions src/gcm/commands/exit_codes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
UNKNOWN_ERROR = -1
OK = 0
AMBIGUOUS_PACKAGE_NAME = 1
PACKAGE_NOT_FOUND = 2
CCACHE_BINARY_NOT_FOUND = 3
PERMISSION_DENIED = 4
93 changes: 93 additions & 0 deletions tests/commands/test_clear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import subprocess
from unittest.mock import patch

import pytest
from click.testing import CliRunner

from gcm.commands.base import ccache_dir_env
from gcm.commands.clear import Clear
from gcm.commands.exit_codes import (
CCACHE_BINARY_NOT_FOUND,
OK,
PERMISSION_DENIED,
UNKNOWN_ERROR,
)

from ..base import ABORTED, DONE

OUTPUT = 'Clearing ccache data for \x1b[32m\x1b[1mapp-misc/foo\x1b[0m\n{}{}\n'


@pytest.mark.parametrize(
'args,run_args',
(
(['foo'], ['ccache', '-C', '-z']),
(['foo', '-k'], ['ccache', '-C']),
(['foo', '--keep-stats'], ['ccache', '-C']),
),
)
@patch('subprocess.run')
def test_clear_ok(run, args, run_args):
run.return_value.returncode = 0

result = CliRunner().invoke(Clear(), args, color=True)

package = 'app-misc/foo'
run.assert_called_once_with(
run_args,
env=ccache_dir_env(package),
stderr=subprocess.PIPE,
text=True,
)
assert result.exit_code == OK
assert result.output == OUTPUT.format('', DONE)


@patch('subprocess.run', side_effect=FileNotFoundError)
def test_clear_no_ccache(run):
result = CliRunner().invoke(Clear(), ['foo'], color=True)

run.accert_called_once()
assert result.exit_code == CCACHE_BINARY_NOT_FOUND
assert result.output == OUTPUT.format(
'\x1b[33mUnable to clear ccache data '
'due to missing ccache binary\x1b[0m\n',
ABORTED,
)


@patch('subprocess.run')
def test_clear_permission_denied(run):
stderr = 'ccache: error: Permission denied\n'

run.return_value.returncode = 1
run.return_value.stderr = stderr

result = CliRunner().invoke(Clear(), ['foo'], color=True)

run.accert_called_once()
assert result.exit_code == PERMISSION_DENIED
assert result.output == OUTPUT.format(
f'\n{stderr}'
'\x1b[33mUnable to clear ccache data '
'due to a lack of permissions\x1b[0m\n',
ABORTED,
)


@patch('subprocess.run')
def test_clear_unknown_error(run):
stderr = 'ccache: error: Something went wrong\n'

run.return_value.returncode = 1
run.return_value.stderr = stderr

result = CliRunner().invoke(Clear(), ['foo'], color=True)

run.accert_called_once()
assert result.exit_code == UNKNOWN_ERROR
assert result.output == OUTPUT.format(
f'\n{stderr}'
'\x1b[33mUnknown error, please submit a bug report!\x1b[0m\n',
ABORTED,
)

0 comments on commit 7bafdc3

Please sign in to comment.