Skip to content
Merged
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
4 changes: 3 additions & 1 deletion src/Highlighter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use ReflectionClass;
use Tempest\Highlight\Languages\Base\Injections\GutterInjection;
use Tempest\Highlight\Languages\Bash\BashLanguage;
use Tempest\Highlight\Languages\Blade\BladeLanguage;
use Tempest\Highlight\Languages\Css\CssLanguage;
use Tempest\Highlight\Languages\Diff\DiffLanguage;
Expand Down Expand Up @@ -51,7 +52,8 @@ final class Highlighter

public function __construct(private readonly Theme $theme = new CssTheme())
{
$this->addLanguage(new BladeLanguage())
$this->addLanguage(new BashLanguage())
->addLanguage(new BladeLanguage())
->addLanguage(new CssLanguage())
->addLanguage(new DiffLanguage())
->addLanguage(new DocCommentLanguage())
Expand Down
72 changes: 72 additions & 0 deletions src/Languages/Bash/BashLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash;

use Override;
use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\Bash\Patterns\BashBuiltinPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashCommentPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashFlagPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashKeywordPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashNumberPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashOperatorPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashShebangPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashVariablePattern;
use Tempest\Highlight\Languages\Php\Patterns\DoubleQuoteValuePattern;
use Tempest\Highlight\Languages\Php\Patterns\SingleQuoteValuePattern;

class BashLanguage extends BaseLanguage
{
public function getName(): string
{
return 'bash';
}

#[Override]
public function getAliases(): array
{
return ['sh', 'shell'];
}

#[Override]
public function getInjections(): array
{
return [
...parent::getInjections(),
];
}

#[Override]
public function getPatterns(): array
{
return [
...parent::getPatterns(),

// COMMENTS
new BashShebangPattern(),
new BashCommentPattern(),

// VALUES
new SingleQuoteValuePattern(),
new DoubleQuoteValuePattern(),

// KEYWORDS
new BashKeywordPattern(),
new BashBuiltinPattern(),

// VARIABLES
new BashVariablePattern(),

// OPERATORS
new BashOperatorPattern(),

// NUMBERS
new BashNumberPattern(),

// FLAGS
new BashFlagPattern(),
];
}
}
33 changes: 33 additions & 0 deletions src/Languages/Bash/Patterns/BashBuiltinPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

final readonly class BashBuiltinPattern implements Pattern
{
use IsPattern;

public function __construct(private array $builtins = [
'echo', 'printf', 'cd', 'pwd', 'test', 'eval', 'exec',
'set', 'read', 'exit',
])
{
}

public function getPattern(): string
{
$builtins = implode('|', $this->builtins);

return "\b(?<match>(?:{$builtins}))\b";
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

#[PatternTest(input: '# this is a comment', output: '# this is a comment')]
final readonly class BashCommentPattern implements Pattern
{
use IsPattern;

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

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

#[PatternTest(input: 'ls -la', output: '-la')]
#[PatternTest(input: 'grep --color=auto', output: '--color')]
final readonly class BashFlagPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>--?[a-zA-Z][\w-]*)';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

final readonly class BashKeywordPattern implements Pattern
{
use IsPattern;

public function __construct(private array $keywords = [
'if', 'then', 'else', 'elif', 'fi', 'for', 'while', 'do', 'done',
'case', 'esac', 'function', 'return', 'in', 'select', 'until',
'break', 'continue', 'declare', 'local', 'export', 'readonly',
'unset', 'shift', 'trap', 'source',
])
{
}

public function getPattern(): string
{
$keywords = implode('|', $this->keywords);

return "\b(?<match>(?:{$keywords}))\b";
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

#[PatternTest(input: 'exit 0', output: '0')]
final readonly class BashNumberPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '\b(?<match>\d+)\b';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

#[PatternTest(input: 'cmd1 | cmd2', output: '|')]
#[PatternTest(input: 'cmd1 && cmd2', output: '&&')]
final readonly class BashOperatorPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\|\||&&|>>|<<|;;|[|><;])';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

#[PatternTest(input: '#!/bin/bash', output: '#!/bin/bash')]
#[PatternTest(input: '#!/usr/bin/env bash', output: '#!/usr/bin/env bash')]
final readonly class BashShebangPattern implements Pattern
{
use IsPattern;

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

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Bash\Patterns;

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

#[PatternTest(input: 'echo $HOME', output: '$HOME')]
#[PatternTest(input: 'echo ${PATH}', output: '${PATH}')]
final readonly class BashVariablePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\$\{[^}]+\}|\$[a-zA-Z_]\w*|\$[\d@?#!\$\-\*])';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VARIABLE;
}
}
60 changes: 60 additions & 0 deletions tests/Bench/Fixtures/bash.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash

# Configuration
MAX_RETRIES=3
LOG_FILE="/var/log/deploy.log"

# Function to check service health
check_health() {
local url=$1
local timeout=${2:-5}

if curl --silent --fail --max-time "$timeout" "$url" > /dev/null 2>&1; then
echo "Service is healthy"
return 0
else
echo "Service is not responding" >> "$LOG_FILE"
return 1
fi
}

# Deploy with retries
deploy() {
local attempt=1

while [ $attempt -le $MAX_RETRIES ]; do
echo "Deployment attempt $attempt of $MAX_RETRIES"

if docker-compose up -d --build 2>&1 | tee -a "$LOG_FILE"; then
echo "Deployment successful"
break
fi

attempt=$((attempt + 1))
sleep 5
done

if [ $attempt -gt $MAX_RETRIES ]; then
echo "Deployment failed after $MAX_RETRIES attempts" >&2
exit 1
fi
}

# Parse arguments
case "$1" in
start)
deploy
;;
status)
check_health "http://localhost:8080/health"
;;
*)
echo "Usage: $0 {start|status}"
exit 1
;;
esac

for service in web api worker; do
printf "Checking %s...\n" "$service"
systemctl is-active --quiet "$service" && echo "OK" || echo "FAILED"
done
Loading
Loading