Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Dockerfile highlighting support #135

Merged
merged 5 commits into from
Aug 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
49 changes: 49 additions & 0 deletions src/Languages/Dockerfile/DockerfileLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?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';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be dockerfile? Maybe add docker as an alias as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought as you regarding the alias. And ChatGPT would also describe it this way, so I think dockerfile and docker will be enough.

}

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',
);
}
}
Loading