This commit is contained in:
Bozhidar 2024-09-10 18:14:49 +03:00
parent 9ecdde0957
commit 733f6ca2eb
9 changed files with 346 additions and 0 deletions

View file

@ -0,0 +1,116 @@
<?php
namespace Modules\Customer\App\Filament\Resources;
use App\GitClient;
use App\Models\GitRepository;
use Faker\Provider\Text;
use Modules\Customer\App\Filament\Resources\GitRepositoryResource\Pages;
use Modules\Customer\App\Filament\Resources\GitRepositoryResource\RelationManagers;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class GitRepositoryResource extends Resource
{
protected static ?string $model = GitRepository::class;
protected static ?string $navigationIcon = 'phyre-git';
protected static ?string $navigationGroup = 'Hosting';
public static function form(Form $form): Form
{
$branches = [];
$tags = [];
return $form
->schema([
Forms\Components\TextInput::make('url')
->label('URL')
->required()
->columnSpanFull()
->live()
->afterStateUpdated(function ($state, Forms\Set $set) use (&$branches, &$tags) {
$state = trim($state);
$repoDetails = GitClient::getRepoDetailsByUrl($state);
if ($repoDetails['name']) {
$set('name', $repoDetails['owner'] .'/'. $repoDetails['name']);
$branches = $repoDetails['branches'];
$tags = $repoDetails['tags'];
}
})
->placeholder('Enter the URL of the repository'),
Forms\Components\TextInput::make('name')
->label('Name')
->required()
->columnSpanFull()
->placeholder('Enter the name of the repository'),
Forms\Components\Select::make('branch')
->label('Branch')
->required()
->options($branches)
->live()
->columnSpanFull()
->placeholder('Enter the branch of the repository'),
Forms\Components\Select::make('tag')
->label('Tag')
->live()
->options($tags)
->columnSpanFull()
->placeholder('Enter the tag of the repository'),
Forms\Components\TextInput::make('dir')
->label('Directory')
->columnSpanFull()
->required()
->placeholder('Enter the directory of the repository'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
//
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListGitRepositories::route('/'),
'create' => Pages\CreateGitRepository::route('/create'),
'edit' => Pages\EditGitRepository::route('/{record}/edit'),
];
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Modules\Customer\App\Filament\Resources\GitRepositoryResource\Pages;
use Modules\Customer\App\Filament\Resources\GitRepositoryResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateGitRepository extends CreateRecord
{
protected static string $resource = GitRepositoryResource::class;
protected static ?string $navigationLabel = 'Clone Git Repository';
public function getTitle(): string
{
return 'Clone Git Repository';
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Modules\Customer\App\Filament\Resources\GitRepositoryResource\Pages;
use Modules\Customer\App\Filament\Resources\GitRepositoryResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditGitRepository extends EditRecord
{
protected static string $resource = GitRepositoryResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Modules\Customer\App\Filament\Resources\GitRepositoryResource\Pages;
use Modules\Customer\App\Filament\Resources\GitRepositoryResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListGitRepositories extends ListRecords
{
protected static string $resource = GitRepositoryResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

100
web/app/GitClient.php Normal file
View file

@ -0,0 +1,100 @@
<?php
namespace App;
class GitClient
{
public static function parseGitUrl($url)
{
$name = '';
$owner = '';
$provider = '';
// first type is: git@github.com:microweber-dev/panel.git
// second type is: https://github.com/microweber-dev/panel.git
// third type is: https://github.com/microweber-dev/panel
// fourth type is: http://gitlab.com/microweber-dev/panel.git
if (str_contains($url, ':') && str_contains($url, 'git@')) {
$urlExploded = explode(':', $url);
$provider = $urlExploded[0];
$provider = str_replace('git@', '', $provider);
$urlExploded = explode('/', $urlExploded[1]);
$owner = $urlExploded[0];
$name = str_replace('.git', '', $urlExploded[1]);
} else if (str_contains($url, '.git')) {
$parsedUrl = parse_url($url);
$provider = $parsedUrl['host'];
$urlExploded = explode('/', $parsedUrl['path']);
$owner = $urlExploded[1];
$name = str_replace('.git', '', $urlExploded[2]);
} else {
$parsedUrl = parse_url($url);
$provider = $parsedUrl['host'];
$urlExploded = explode('/', $parsedUrl['path']);
$owner = $urlExploded[1];
$name = $urlExploded[2];
}
return [
'name' => $name,
'owner' => $owner,
'provider' => $provider
];
}
public static function getRepoDetailsByUrl($url)
{
shell_exec('GIT_TERMINAL_PROMPT=0');
$outputBranches = shell_exec('git ls-remote --heads '.$url);
$outputTags = shell_exec('git ls-remote --tags '.$url);
$branches = [];
$tags = [];
$gitUrl = self::parseGitUrl($url);
foreach (explode("\n", $outputBranches) as $line) {
if (empty($line)) {
continue;
}
$parts = explode("\t", $line);
$branch = str_replace('refs/heads/', '', $parts[1]);
$branches[$branch] = $branch;
}
foreach (explode("\n", $outputTags) as $line) {
if (empty($line)) {
continue;
}
$parts = explode("\t", $line);
$tag = str_replace('refs/tags/', '', $parts[1]);
$tags[$tag] = $tag;
}
$output = [
'branches' => $branches,
'tags' => $tags,
'name' => $gitUrl['name'],
'owner' => $gitUrl['owner'],
'provider' => $gitUrl['provider']
];
return $output;
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class GitRepository extends Model
{
use HasFactory;
protected $fillable = [
'name',
'url',
'branch',
'last_commit_hash',
'last_commit_message',
'last_commit_date',
'status',
'status_message',
'dir',
'domain_id',
];
}

View file

@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('git_repositories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('url');
$table->string('branch');
$table->string('last_commit_hash')->nullable();
$table->string('last_commit_message')->nullable();
$table->timestamp('last_commit_date')->nullable();
$table->string('status')->nullable();
$table->string('status_message')->nullable();
$table->string('dir')->nullable();
$table->unsignedBigInteger('domain_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('git_repositories');
}
};

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<path fill="currentColor" d="M2.6 10.59L8.38 4.8l1.69 1.7c-.24.85.15 1.78.93 2.23v5.54c-.6.34-1 .99-1 1.73a2 2 0 0 0 2 2a2 2 0 0 0 2-2c0-.74-.4-1.39-1-1.73V9.41l2.07 2.09c-.07.15-.07.32-.07.5a2 2 0 0 0 2 2a2 2 0 0 0 2-2a2 2 0 0 0-2-2c-.18 0-.35 0-.5.07L13.93 7.5a1.98 1.98 0 0 0-1.15-2.34c-.43-.16-.88-.2-1.28-.09L9.8 3.38l.79-.78c.78-.79 2.04-.79 2.82 0l7.99 7.99c.79.78.79 2.04 0 2.82l-7.99 7.99c-.78.79-2.04.79-2.82 0L2.6 13.41c-.79-.78-.79-2.04 0-2.82" />
</svg>

After

Width:  |  Height:  |  Size: 553 B

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<path fill="currentColor" d="M2.6 10.59L8.38 4.8l1.69 1.7c-.24.85.15 1.78.93 2.23v5.54c-.6.34-1 .99-1 1.73a2 2 0 0 0 2 2a2 2 0 0 0 2-2c0-.74-.4-1.39-1-1.73V9.41l2.07 2.09c-.07.15-.07.32-.07.5a2 2 0 0 0 2 2a2 2 0 0 0 2-2a2 2 0 0 0-2-2c-.18 0-.35 0-.5.07L13.93 7.5a1.98 1.98 0 0 0-1.15-2.34c-.43-.16-.88-.2-1.28-.09L9.8 3.38l.79-.78c.78-.79 2.04-.79 2.82 0l7.99 7.99c.79.78.79 2.04 0 2.82l-7.99 7.99c-.78.79-2.04.79-2.82 0L2.6 13.41c-.79-.78-.79-2.04 0-2.82" />
</svg>

After

Width:  |  Height:  |  Size: 553 B