Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions src/Languages/Dockerfile/DockerfileLanguage.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

use Override;
use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\Dockerfile\Patterns\CommentPattern;
use Tempest\Highlight\Languages\Dockerfile\Patterns\DoubleQuoteValuePattern;
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;
use Tempest\Highlight\Languages\Dockerfile\Patterns\SingleQuoteValuePattern;

class DockerfileLanguage extends BaseLanguage
{
Expand Down Expand Up @@ -54,6 +57,9 @@ public function getPatterns(): array
new ImageAliasKeywordPattern(),
new ImageAliasNamePattern(),
new ImageTagPattern(),
new SingleQuoteValuePattern(),
new DoubleQuoteValuePattern(),
new CommentPattern(),
];
}
}
27 changes: 27 additions & 0 deletions src/Languages/Dockerfile/Patterns/CommentPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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\TokenType;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '# Hello world!', output: '# Hello world!')]
final class CommentPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '/(?<match>\#.*)/';
}

public function getTokenType(): TokenType
{
return TokenTypeEnum::COMMENT;
}
}
27 changes: 27 additions & 0 deletions src/Languages/Dockerfile/Patterns/DoubleQuoteValuePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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: 'RUN ["php"]', output: '"php"')]
#[PatternTest(input: 'RUN ["php", "test.php"]', output: ['"php"', '"test.php"'])]
final readonly class DoubleQuoteValuePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>"(\\\"|.)*?")';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VALUE;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Dockerfile/Patterns/SingleQuoteValuePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?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: "RUN ['php']", output: "'php'")]
final readonly class SingleQuoteValuePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return "(?<match>'(\\\'|.)*?')";
}

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

declare(strict_types=1);

namespace Languages\Dockerfile;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Tempest\Highlight\Highlighter;

class DockerfileLanguageTest extends TestCase
{
#[DataProvider('provide_highlight_cases')]
public function test_highlight(string $content, string $expected): void
{
$highlighter = new Highlighter();

$this->assertSame(
$expected,
$highlighter->parse($content, 'dockerfile'),
);
}

public static function provide_highlight_cases(): iterable
{
return [
['FROM python:3.13', '<span class="hl-keyword">FROM</span> <span class="hl-value">python</span>:<span class="hl-value">3.13</span>'],
['FROM php AS stage-one', '<span class="hl-keyword">FROM</span> <span class="hl-value">php</span> <span class="hl-keyword">AS</span> <span class="hl-value">stage-one</span>'],
['WORKDIR /usr/local/app', '<span class="hl-keyword">WORKDIR</span> /usr/local/app'],
['CMD ["node", "./src/index.js"]', '<span class="hl-keyword">CMD</span> [<span class="hl-value">&quot;node&quot;</span>, <span class="hl-value">&quot;./src/index.js&quot;</span>]'],
["CMD ['php', 'index.php']", '<span class="hl-keyword">CMD</span> [<span class="hl-value">\'php\'</span>, <span class="hl-value">\'index.php\'</span>]'],
['# This is a comment', '<span class="hl-comment"># This is a comment</span>'],
];
}
}
18 changes: 18 additions & 0 deletions tests/targets/dockerfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
```dockerfile
FROM python:3.13
WORKDIR /usr/local/app

# Install the application dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Copy in the source code
COPY src ./src
EXPOSE 8080

# Setup an app user so the container doesn't run as the root user
RUN useradd app
USER app

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
```