Skip to content

Commit 415db5f

Browse files
authored
Merge pull request #135 from kburton-dev/add-dockerfile-support
Add Dockerfile highlighting support
2 parents ea8bb97 + cd9156b commit 415db5f

File tree

8 files changed

+250
-0
lines changed

8 files changed

+250
-0
lines changed

src/Highlighter.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Tempest\Highlight\Languages\Css\CssLanguage;
1212
use Tempest\Highlight\Languages\Diff\DiffLanguage;
1313
use Tempest\Highlight\Languages\DocComment\DocCommentLanguage;
14+
use Tempest\Highlight\Languages\Dockerfile\DockerfileLanguage;
1415
use Tempest\Highlight\Languages\Ellison\EllisonLanguage;
1516
use Tempest\Highlight\Languages\Gdscript\GdscriptLanguage;
1617
use Tempest\Highlight\Languages\Html\HtmlLanguage;
@@ -43,6 +44,7 @@ public function __construct(
4344
->addLanguage(new CssLanguage())
4445
->addLanguage(new DiffLanguage())
4546
->addLanguage(new DocCommentLanguage())
47+
->addLanguage(new DockerfileLanguage())
4648
->addLanguage(new EllisonLanguage())
4749
->addLanguage(new GdscriptLanguage())
4850
->addLanguage(new HtmlLanguage())
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Languages\Dockerfile;
6+
7+
use Tempest\Highlight\Languages\Base\BaseLanguage;
8+
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageAliasKeywordPattern;
9+
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageAliasNamePattern;
10+
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageNamePattern;
11+
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageTagPattern;
12+
use Tempest\Highlight\Languages\Dockerfile\Patterns\KeywordPattern;
13+
14+
class DockerfileLanguage extends BaseLanguage
15+
{
16+
public function getName(): string
17+
{
18+
return 'dockerfile';
19+
}
20+
21+
public function getAliases(): array
22+
{
23+
return [
24+
'docker',
25+
];
26+
}
27+
28+
public function getPatterns(): array
29+
{
30+
return [
31+
new KeywordPattern('ADD'),
32+
new KeywordPattern('ARG'),
33+
new KeywordPattern('CMD'),
34+
new KeywordPattern('COPY'),
35+
new KeywordPattern('ENTRYPOINT'),
36+
new KeywordPattern('ENV'),
37+
new KeywordPattern('EXPOSE'),
38+
new KeywordPattern('FROM'),
39+
new KeywordPattern('HEALTHCHECK'),
40+
new KeywordPattern('LABEL'),
41+
new KeywordPattern('MAINTAINER'),
42+
new KeywordPattern('ONBUILD'),
43+
new KeywordPattern('RUN'),
44+
new KeywordPattern('SHELL'),
45+
new KeywordPattern('STOPSIGNAL'),
46+
new KeywordPattern('USER'),
47+
new KeywordPattern('VOLUME'),
48+
new KeywordPattern('WORKDIR'),
49+
50+
new ImageNamePattern(),
51+
new ImageAliasKeywordPattern(),
52+
new ImageAliasNamePattern(),
53+
new ImageTagPattern(),
54+
];
55+
}
56+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Languages\Dockerfile\Patterns;
6+
7+
use Tempest\Highlight\IsPattern;
8+
use Tempest\Highlight\Pattern;
9+
use Tempest\Highlight\PatternTest;
10+
use Tempest\Highlight\Tokens\TokenTypeEnum;
11+
12+
#[PatternTest(input: 'FROM php', output: null)]
13+
#[PatternTest(input: 'FROM php:8.1', output: null)]
14+
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: 'AS')]
15+
#[PatternTest(input: ' FROM php:8.1 AS stage-one ', output: 'AS')]
16+
final readonly class ImageAliasKeywordPattern implements Pattern
17+
{
18+
use IsPattern;
19+
20+
public function getPattern(): string
21+
{
22+
return "/^[\s]*FROM[\s][\S]+[\s](?<match>AS)[\s][\S]+/m";
23+
}
24+
25+
public function getTokenType(): TokenTypeEnum
26+
{
27+
return TokenTypeEnum::KEYWORD;
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Languages\Dockerfile\Patterns;
6+
7+
use Tempest\Highlight\IsPattern;
8+
use Tempest\Highlight\Pattern;
9+
use Tempest\Highlight\PatternTest;
10+
use Tempest\Highlight\Tokens\TokenTypeEnum;
11+
12+
#[PatternTest(input: 'FROM php', output: null)]
13+
#[PatternTest(input: 'FROM php:8.1', output: null)]
14+
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: 'stage-one')]
15+
#[PatternTest(input: ' FROM php:8.1 AS stage-one ', output: 'stage-one')]
16+
final readonly class ImageAliasNamePattern implements Pattern
17+
{
18+
use IsPattern;
19+
20+
public function getPattern(): string
21+
{
22+
return "/^[\s]*FROM[\s][\S]+[\s]AS[\s](?<match>[\S]+)/m";
23+
}
24+
25+
public function getTokenType(): TokenTypeEnum
26+
{
27+
return TokenTypeEnum::VALUE;
28+
}
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Languages\Dockerfile\Patterns;
6+
7+
use Tempest\Highlight\IsPattern;
8+
use Tempest\Highlight\Pattern;
9+
use Tempest\Highlight\PatternTest;
10+
use Tempest\Highlight\Tokens\TokenTypeEnum;
11+
12+
#[PatternTest(input: 'FROM php', output: 'php')]
13+
#[PatternTest(input: ' FROM php', output: 'php')]
14+
#[PatternTest(input: 'FROM php:8.1', output: 'php')]
15+
#[PatternTest(input: 'FROM php/cli:8.1', output: 'php/cli')]
16+
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: 'php')]
17+
18+
final readonly class ImageNamePattern implements Pattern
19+
{
20+
use IsPattern;
21+
22+
public function getPattern(): string
23+
{
24+
return "/^[\s]*FROM[\s](?<match>[\w\/]+)/m";
25+
}
26+
27+
public function getTokenType(): TokenTypeEnum
28+
{
29+
return TokenTypeEnum::VALUE;
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Languages\Dockerfile\Patterns;
6+
7+
use Tempest\Highlight\IsPattern;
8+
use Tempest\Highlight\Pattern;
9+
use Tempest\Highlight\PatternTest;
10+
use Tempest\Highlight\Tokens\TokenTypeEnum;
11+
12+
#[PatternTest(input: 'FROM php', output: null)]
13+
#[PatternTest(input: 'FROM php', output: null)]
14+
#[PatternTest(input: 'FROM php:8.1', output: '8.1')]
15+
#[PatternTest(input: 'FROM php/cli:8.1', output: '8.1')]
16+
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: '8.1')]
17+
18+
final readonly class ImageTagPattern implements Pattern
19+
{
20+
use IsPattern;
21+
22+
public function getPattern(): string
23+
{
24+
return "/^[\s]*FROM[\s][\w\/]+:(?<match>\S+)[\s]?/m";
25+
}
26+
27+
public function getTokenType(): TokenTypeEnum
28+
{
29+
return TokenTypeEnum::VALUE;
30+
}
31+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Languages\Dockerfile\Patterns;
6+
7+
use Tempest\Highlight\IsPattern;
8+
use Tempest\Highlight\Pattern;
9+
use Tempest\Highlight\Tokens\TokenTypeEnum;
10+
11+
final readonly class KeywordPattern implements Pattern
12+
{
13+
use IsPattern;
14+
15+
public function __construct(private string $keyword)
16+
{
17+
}
18+
19+
public function getPattern(): string
20+
{
21+
return "/^[\s]*(?<match>{$this->keyword})[\s].*/m";
22+
}
23+
24+
public function getTokenType(): TokenTypeEnum
25+
{
26+
return TokenTypeEnum::KEYWORD;
27+
}
28+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Tests\Languages\Dockerfile\Patterns;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Tempest\Highlight\Languages\Dockerfile\Patterns\KeywordPattern;
9+
use Tempest\Highlight\Tests\TestsPatterns;
10+
11+
class KeywordPatternTest extends TestCase
12+
{
13+
use TestsPatterns;
14+
15+
public function test_pattern()
16+
{
17+
$this->assertMatches(
18+
pattern: new KeywordPattern('FROM'),
19+
content: 'FROM image:tag',
20+
expected: 'FROM',
21+
);
22+
23+
$this->assertMatches(
24+
pattern: new KeywordPattern('FROM'),
25+
content: 'FROM image:tag AS alias',
26+
expected: 'FROM',
27+
);
28+
29+
$this->assertMatches(
30+
pattern: new KeywordPattern('FROM'),
31+
content: ' FROM image:tag AS alias',
32+
expected: 'FROM',
33+
);
34+
35+
$this->assertMatches(
36+
pattern: new KeywordPattern('COPY'),
37+
content: <<<'DOCKERFILE'
38+
FROM image:tag
39+
COPY . /usr/share/nginx/html
40+
DOCKERFILE,
41+
expected: 'COPY',
42+
);
43+
}
44+
}

0 commit comments

Comments
 (0)