Skip to content

Commit

Permalink
Merge pull request #135 from kburton-dev/add-dockerfile-support
Browse files Browse the repository at this point in the history
Add Dockerfile highlighting support
  • Loading branch information
brendt authored Aug 4, 2024
2 parents ea8bb97 + cd9156b commit 415db5f
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Highlighter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Tempest\Highlight\Languages\Css\CssLanguage;
use Tempest\Highlight\Languages\Diff\DiffLanguage;
use Tempest\Highlight\Languages\DocComment\DocCommentLanguage;
use Tempest\Highlight\Languages\Dockerfile\DockerfileLanguage;
use Tempest\Highlight\Languages\Ellison\EllisonLanguage;
use Tempest\Highlight\Languages\Gdscript\GdscriptLanguage;
use Tempest\Highlight\Languages\Html\HtmlLanguage;
Expand Down Expand Up @@ -43,6 +44,7 @@ public function __construct(
->addLanguage(new CssLanguage())
->addLanguage(new DiffLanguage())
->addLanguage(new DocCommentLanguage())
->addLanguage(new DockerfileLanguage())
->addLanguage(new EllisonLanguage())
->addLanguage(new GdscriptLanguage())
->addLanguage(new HtmlLanguage())
Expand Down
56 changes: 56 additions & 0 deletions src/Languages/Dockerfile/DockerfileLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Dockerfile;

use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageAliasKeywordPattern;
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageAliasNamePattern;
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageNamePattern;
use Tempest\Highlight\Languages\Dockerfile\Patterns\ImageTagPattern;
use Tempest\Highlight\Languages\Dockerfile\Patterns\KeywordPattern;

class DockerfileLanguage extends BaseLanguage
{
public function getName(): string
{
return 'dockerfile';
}

public function getAliases(): array
{
return [
'docker',
];
}

public function getPatterns(): array
{
return [
new KeywordPattern('ADD'),
new KeywordPattern('ARG'),
new KeywordPattern('CMD'),
new KeywordPattern('COPY'),
new KeywordPattern('ENTRYPOINT'),
new KeywordPattern('ENV'),
new KeywordPattern('EXPOSE'),
new KeywordPattern('FROM'),
new KeywordPattern('HEALTHCHECK'),
new KeywordPattern('LABEL'),
new KeywordPattern('MAINTAINER'),
new KeywordPattern('ONBUILD'),
new KeywordPattern('RUN'),
new KeywordPattern('SHELL'),
new KeywordPattern('STOPSIGNAL'),
new KeywordPattern('USER'),
new KeywordPattern('VOLUME'),
new KeywordPattern('WORKDIR'),

new ImageNamePattern(),
new ImageAliasKeywordPattern(),
new ImageAliasNamePattern(),
new ImageTagPattern(),
];
}
}
29 changes: 29 additions & 0 deletions src/Languages/Dockerfile/Patterns/ImageAliasKeywordPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Dockerfile\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'FROM php', output: null)]
#[PatternTest(input: 'FROM php:8.1', output: null)]
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: 'AS')]
#[PatternTest(input: ' FROM php:8.1 AS stage-one ', output: 'AS')]
final readonly class ImageAliasKeywordPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return "/^[\s]*FROM[\s][\S]+[\s](?<match>AS)[\s][\S]+/m";
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::KEYWORD;
}
}
29 changes: 29 additions & 0 deletions src/Languages/Dockerfile/Patterns/ImageAliasNamePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Dockerfile\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'FROM php', output: null)]
#[PatternTest(input: 'FROM php:8.1', output: null)]
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: 'stage-one')]
#[PatternTest(input: ' FROM php:8.1 AS stage-one ', output: 'stage-one')]
final readonly class ImageAliasNamePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return "/^[\s]*FROM[\s][\S]+[\s]AS[\s](?<match>[\S]+)/m";
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VALUE;
}
}
31 changes: 31 additions & 0 deletions src/Languages/Dockerfile/Patterns/ImageNamePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Dockerfile\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'FROM php', output: 'php')]
#[PatternTest(input: ' FROM php', output: 'php')]
#[PatternTest(input: 'FROM php:8.1', output: 'php')]
#[PatternTest(input: 'FROM php/cli:8.1', output: 'php/cli')]
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: 'php')]

final readonly class ImageNamePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return "/^[\s]*FROM[\s](?<match>[\w\/]+)/m";
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VALUE;
}
}
31 changes: 31 additions & 0 deletions src/Languages/Dockerfile/Patterns/ImageTagPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Dockerfile\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'FROM php', output: null)]
#[PatternTest(input: 'FROM php', output: null)]
#[PatternTest(input: 'FROM php:8.1', output: '8.1')]
#[PatternTest(input: 'FROM php/cli:8.1', output: '8.1')]
#[PatternTest(input: 'FROM php:8.1 AS stage-one', output: '8.1')]

final readonly class ImageTagPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return "/^[\s]*FROM[\s][\w\/]+:(?<match>\S+)[\s]?/m";
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VALUE;
}
}
28 changes: 28 additions & 0 deletions src/Languages/Dockerfile/Patterns/KeywordPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Dockerfile\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\Tokens\TokenTypeEnum;

final readonly class KeywordPattern implements Pattern
{
use IsPattern;

public function __construct(private string $keyword)
{
}

public function getPattern(): string
{
return "/^[\s]*(?<match>{$this->keyword})[\s].*/m";
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::KEYWORD;
}
}
44 changes: 44 additions & 0 deletions tests/Languages/Dockerfile/Patterns/KeywordPatternTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Tests\Languages\Dockerfile\Patterns;

use PHPUnit\Framework\TestCase;
use Tempest\Highlight\Languages\Dockerfile\Patterns\KeywordPattern;
use Tempest\Highlight\Tests\TestsPatterns;

class KeywordPatternTest extends TestCase
{
use TestsPatterns;

public function test_pattern()
{
$this->assertMatches(
pattern: new KeywordPattern('FROM'),
content: 'FROM image:tag',
expected: 'FROM',
);

$this->assertMatches(
pattern: new KeywordPattern('FROM'),
content: 'FROM image:tag AS alias',
expected: 'FROM',
);

$this->assertMatches(
pattern: new KeywordPattern('FROM'),
content: ' FROM image:tag AS alias',
expected: 'FROM',
);

$this->assertMatches(
pattern: new KeywordPattern('COPY'),
content: <<<'DOCKERFILE'
FROM image:tag
COPY . /usr/share/nginx/html
DOCKERFILE,
expected: 'COPY',
);
}
}

0 comments on commit 415db5f

Please sign in to comment.