Skip to content

Commit 63907da

Browse files
authored
Add CLI for flush/invalidate/list (#36)
2 parents 2a3c665 + 0827bfd commit 63907da

5 files changed

Lines changed: 197 additions & 0 deletions

File tree

src/Commands/Flush.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Thoughtco\StatamicCacheTracker\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Thoughtco\StatamicCacheTracker\Facades\Tracker;
7+
8+
class Flush extends Command
9+
{
10+
protected $signature = 'cache-tracker:flush';
11+
12+
protected $description = 'Flush all tracked URLs from the cache tracker';
13+
14+
public function handle()
15+
{
16+
$count = count(Tracker::all());
17+
18+
Tracker::flush();
19+
20+
$this->info("Flushed {$count} tracked URL(s).");
21+
}
22+
}

src/Commands/Invalidate.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Thoughtco\StatamicCacheTracker\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Thoughtco\StatamicCacheTracker\Facades\Tracker;
7+
8+
class Invalidate extends Command
9+
{
10+
protected $signature = 'cache-tracker:invalidate {url : The URL to remove from the cache tracker}';
11+
12+
protected $description = 'Remove a URL from the cache tracker and invalidate it from the static cache';
13+
14+
public function handle()
15+
{
16+
$url = $this->argument('url');
17+
18+
if (! Tracker::has($url)) {
19+
$this->warn("URL not found in tracker: {$url}");
20+
21+
return 1;
22+
}
23+
24+
Tracker::remove($url);
25+
26+
$this->info("Invalidated: {$url}");
27+
}
28+
}

src/Commands/ListUrls.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Thoughtco\StatamicCacheTracker\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Thoughtco\StatamicCacheTracker\Facades\Tracker;
7+
8+
class ListUrls extends Command
9+
{
10+
protected $signature = 'cache-tracker:list {--url= : Filter by URL (supports * wildcard)}';
11+
12+
protected $description = 'List all tracked URLs and their cache tags';
13+
14+
public function handle()
15+
{
16+
$all = collect(Tracker::all());
17+
18+
if ($filter = $this->option('url')) {
19+
$prefix = rtrim($filter, '*');
20+
$all = $all->filter(fn ($data) => str_starts_with($data['url'], $prefix));
21+
}
22+
23+
if ($all->isEmpty()) {
24+
$this->info('No tracked URLs found.');
25+
26+
return;
27+
}
28+
29+
$this->table(
30+
['URL', 'Tags'],
31+
$all->map(fn ($data) => [$data['url'], implode(', ', $data['tags'])])->values()
32+
);
33+
34+
$this->info("Total: {$all->count()} URL(s)");
35+
}
36+
}

src/ServiceProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99

1010
class ServiceProvider extends AddonServiceProvider
1111
{
12+
protected $commands = [
13+
Commands\Flush::class,
14+
Commands\Invalidate::class,
15+
Commands\ListUrls::class,
16+
];
17+
1218
protected $actions = [
1319
Actions\ClearCache::class,
1420
Actions\ViewCacheTags::class,

tests/Unit/CommandsTest.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
namespace Thoughtco\StatamicCacheTracker\Tests\Unit;
4+
5+
use PHPUnit\Framework\Attributes\Test;
6+
use Thoughtco\StatamicCacheTracker\Facades\Tracker;
7+
use Thoughtco\StatamicCacheTracker\Tests\TestCase;
8+
9+
class CommandsTest extends TestCase
10+
{
11+
#[Test]
12+
public function flush_command_clears_all_tracked_urls()
13+
{
14+
Tracker::add('/page1', ['products:1']);
15+
Tracker::add('/page2', ['products:2']);
16+
17+
$this->assertCount(2, Tracker::all());
18+
19+
$this->artisan('cache-tracker:flush')
20+
->expectsOutput('Flushed 2 tracked URL(s).')
21+
->assertExitCode(0);
22+
23+
$this->assertCount(0, Tracker::all());
24+
}
25+
26+
#[Test]
27+
public function flush_command_reports_zero_when_nothing_tracked()
28+
{
29+
$this->artisan('cache-tracker:flush')
30+
->expectsOutput('Flushed 0 tracked URL(s).')
31+
->assertExitCode(0);
32+
}
33+
34+
#[Test]
35+
public function invalidate_command_removes_url()
36+
{
37+
Tracker::add('/page1', ['products:1']);
38+
Tracker::add('/page2', ['products:2']);
39+
40+
$this->artisan('cache-tracker:invalidate', ['url' => '/page1'])
41+
->expectsOutput('Invalidated: /page1')
42+
->assertExitCode(0);
43+
44+
$this->assertCount(1, Tracker::all());
45+
$this->assertNull(Tracker::get('/page1'));
46+
$this->assertNotNull(Tracker::get('/page2'));
47+
}
48+
49+
#[Test]
50+
public function invalidate_command_warns_when_url_not_found()
51+
{
52+
$this->artisan('cache-tracker:invalidate', ['url' => '/not-tracked'])
53+
->expectsOutput('URL not found in tracker: /not-tracked')
54+
->assertExitCode(1);
55+
}
56+
57+
#[Test]
58+
public function list_command_shows_all_tracked_urls()
59+
{
60+
Tracker::add('/page1', ['products:1', 'category:electronics']);
61+
Tracker::add('/page2', ['products:2']);
62+
63+
$this->artisan('cache-tracker:list')
64+
->expectsTable(['URL', 'Tags'], [
65+
['/page1', 'products:1, category:electronics'],
66+
['/page2', 'products:2'],
67+
])
68+
->expectsOutput('Total: 2 URL(s)')
69+
->assertExitCode(0);
70+
}
71+
72+
#[Test]
73+
public function list_command_shows_message_when_nothing_tracked()
74+
{
75+
$this->artisan('cache-tracker:list')
76+
->expectsOutput('No tracked URLs found.')
77+
->assertExitCode(0);
78+
}
79+
80+
#[Test]
81+
public function list_command_filters_by_url_prefix()
82+
{
83+
Tracker::add('/blog/post-1', ['entries:1']);
84+
Tracker::add('/blog/post-2', ['entries:2']);
85+
Tracker::add('/about', ['entries:3']);
86+
87+
$this->artisan('cache-tracker:list', ['--url' => '/blog/*'])
88+
->expectsTable(['URL', 'Tags'], [
89+
['/blog/post-1', 'entries:1'],
90+
['/blog/post-2', 'entries:2'],
91+
])
92+
->expectsOutput('Total: 2 URL(s)')
93+
->assertExitCode(0);
94+
}
95+
96+
#[Test]
97+
public function list_command_filter_returns_no_results_message()
98+
{
99+
Tracker::add('/page1', ['products:1']);
100+
101+
$this->artisan('cache-tracker:list', ['--url' => '/blog/*'])
102+
->expectsOutput('No tracked URLs found.')
103+
->assertExitCode(0);
104+
}
105+
}

0 commit comments

Comments
 (0)