Skip to content

Commit

Permalink
Allow config and temp directories to be configured independently.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArclightHub committed Nov 7, 2023
1 parent 26a70c2 commit 8d3ffa5
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 54 deletions.
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# docker-compose up -d && docker logs -f scribe_app_1
FROM ubuntu:jammy
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC

# APT
RUN apt-get -qq update && apt-get install -qq \
make \
curl \
php \
php-curl \
php-xml \
php-sqlite3 \
php-bcmath \
php-curl \
php-gd \
php-imagick \
php-intl \
php-mbstring \
php-pdo \
php-zip \
php-soap \
php-pcov \
git \
p7zip-full

# Composer Install
RUN curl -sS https://getcomposer.org/installer | php && \
mv composer.phar /usr/local/bin/composer
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
install:
composer install

test: install
composer test-ci
9 changes: 5 additions & 4 deletions camel/Camel.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Knuckles\Camel\Output\OutputEndpointData;
use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Tools\Utils;
use Symfony\Component\Yaml\Yaml;


class Camel
{
public static function cacheDir(string $docsName = 'scribe'): string
public static function cacheDir(CacheConfiguration $docsObject): string
{
return ".$docsName/endpoints.cache";
return $docsObject . "/endpoints.cache";
}

public static function camelDir(string $docsName = 'scribe'): string
public static function camelDir(CacheConfiguration $docsObject): string
{
return ".$docsName/endpoints";
return $docsObject . "/endpoints";
}

/**
Expand Down
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Allow devs to run the unit tests in a dockerized environment
# clear && docker-compose up -d && docker logs -f scribe_app_1
version: '3.7'
services:
app:
build:
context: ./
volumes:
- ./:/testing
working_dir: /testing
command: make test
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<file>tests/Unit/ExtractorTest.php</file>
<file>tests/Unit/ExtractorPluginSystemTest.php</file>
<file>tests/Unit/ConfigDifferTest.php</file>
<file>tests/Unit/CacheConfigurationTest.php</file>
</testsuite>
<testsuite name="Unit Tests 2">
<file>tests/Unit/ExtractedEndpointDataTest.php</file>
Expand Down
30 changes: 19 additions & 11 deletions src/Commands/GenerateDocumentation.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Knuckles\Camel\Camel;
use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\GroupedEndpoints\GroupedEndpointsFactory;
use Knuckles\Scribe\Matching\RouteMatcherInterface;
use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
Expand All @@ -24,6 +25,7 @@ class GenerateDocumentation extends Command
{--no-extraction : Skip extraction of route and API info and just transform the YAML and Markdown files into HTML}
{--no-upgrade-check : Skip checking for config file upgrades. Won't make things faster, but can be helpful if the command is buggy}
{--config=scribe : choose which config file to use}
{--cache-directory= : choose which cache directory to use}
";

protected $description = 'Generate API documentation from your Laravel/Dingo routes.';
Expand All @@ -34,7 +36,8 @@ class GenerateDocumentation extends Command

protected bool $forcing;

protected string $configName;
/** @var CacheConfiguration */
protected CacheConfiguration $configObject;

public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFactory $groupedEndpointsFactory): void
{
Expand All @@ -47,9 +50,9 @@ public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFact
}

// Extraction stage - extract endpoint info either from app or existing Camel files (previously extracted data)
$groupedEndpointsInstance = $groupedEndpointsFactory->make($this, $routeMatcher, $this->configName);
$groupedEndpointsInstance = $groupedEndpointsFactory->make($this, $routeMatcher, $this->configObject);
$extractedEndpoints = $groupedEndpointsInstance->get();
$userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($this->configName));
$userDefinedEndpoints = Camel::loadUserDefinedEndpoints(Camel::camelDir($this->configObject));
$groupedEndpoints = $this->mergeUserDefinedEndpoints($extractedEndpoints, $userDefinedEndpoints);

// Output stage
Expand All @@ -61,7 +64,7 @@ public function handle(RouteMatcherInterface $routeMatcher, GroupedEndpointsFact
$this->writeExampleCustomEndpoint();
}

$writer = new Writer($this->docConfig, $this->configName);
$writer = new Writer($this->docConfig, $this->configObject);
$writer->writeDocs($groupedEndpoints);

$this->upgradeConfigFileIfNeeded();
Expand Down Expand Up @@ -98,12 +101,17 @@ public function bootstrap(): void

c::bootstrapOutput($this->output);

$this->configName = $this->option('config');
if (!config($this->configName)) {
throw new \InvalidArgumentException("The specified config (config/{$this->configName}.php) doesn't exist.");
$configName = $this->option('config');
if (!config($configName)) {
throw new \InvalidArgumentException("The specified config (config/{$configName}.php) doesn't exist.");
}

$this->docConfig = new DocumentationConfig(config($this->configName));
$this->configObject = new CacheConfiguration($configName, $configName, true);
if ($this->hasOption('cache-directory') && !empty($this->option('cache-directory'))) {
$this->configObject = new CacheConfiguration($this->option('cache-directory'), $configName, false);
}

$this->docConfig = new DocumentationConfig(config($this->configObject->getScribeConfigFile()));

// Force root URL so it works in Postman collection
$baseUrl = $this->docConfig->get('base_url') ?? config('app.url');
Expand Down Expand Up @@ -146,7 +154,7 @@ protected function mergeUserDefinedEndpoints(array $groupedEndpoints, array $use
protected function writeExampleCustomEndpoint(): void
{
// We add an example to guide users in case they need to add a custom endpoint.
copy(__DIR__ . '/../../resources/example_custom_endpoint.yaml', Camel::camelDir($this->configName) . '/custom.0.yaml');
copy(__DIR__ . '/../../resources/example_custom_endpoint.yaml', Camel::camelDir($this->configObject) . '/custom.0.yaml');
}

protected function upgradeConfigFileIfNeeded(): void
Expand All @@ -155,12 +163,12 @@ protected function upgradeConfigFileIfNeeded(): void

$this->info("Checking for any pending upgrades to your config file...");
try {
if (! $this->laravel['files']->exists($this->laravel->configPath("{$this->configName}.php"))) {
if (! $this->laravel['files']->exists($this->laravel->configPath($this->configObject->getScribeConfigFile() . ".php"))) {
$this->info("No config file to upgrade.");
return;
}

$upgrader = Upgrader::ofConfigFile("config/{$this->configName}.php", __DIR__ . '/../../config/scribe.php')
$upgrader = Upgrader::ofConfigFile("config/" . $this->configObject->getScribeConfigFile() . ".php", __DIR__ . '/../../config/scribe.php')
->dontTouch(
'routes', 'example_languages', 'database_connections_to_transact', 'strategies', 'laravel.middleware',
'postman.overrides', 'openapi.overrides', 'groups', 'examples.models_source'
Expand Down
46 changes: 46 additions & 0 deletions src/Configuration/CacheConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Knuckles\Scribe\Configuration;

/**
* Decouple scribe config file name from the cache directory.
*/
class CacheConfiguration
{
/** @var string */
private string $scribeConfig;

/** @var string */
private string $cacheDir;

/** @var bool */
private bool $isHidden;

/**
* @param string $cacheDir
* @param string $scribeConfig
* @param bool $isHidden
*/
public function __construct(string $cacheDir, string$scribeConfig, bool $isHidden = true)
{
$this->cacheDir = $cacheDir;
$this->scribeConfig = $scribeConfig;
$this->isHidden = $isHidden;
}

/**
* @return string
*/
public function getScribeConfigFile(): string
{
return $this->scribeConfig;
}

/**
* @return string
*/
public function __toString(): string
{
return ($this->isHidden ? '.' : '') . $this->cacheDir;
}
}
5 changes: 3 additions & 2 deletions src/Extracting/ApiDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Knuckles\Scribe\Extracting;

use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
use Knuckles\Scribe\Tools\Utils as u;
use Knuckles\Scribe\Tools\DocumentationConfig;
Expand All @@ -23,9 +24,9 @@ class ApiDetails

private array $lastKnownFileContentHashes = [];

public function __construct(DocumentationConfig $config = null, bool $preserveUserChanges = true, string $docsName = 'scribe')
public function __construct(DocumentationConfig $config = null, bool $preserveUserChanges = true, CacheConfiguration $docsName)

Check failure on line 27 in src/Extracting/ApiDetails.php

View workflow job for this annotation

GitHub Actions / Lint code (PHP 8.1)

Deprecated in PHP 8.0: Required parameter $docsName follows optional parameter $preserveUserChanges.
{
$this->markdownOutputPath = ".{$docsName}"; //.scribe by default
$this->markdownOutputPath = $docsName; //.scribe by default
// If no config is injected, pull from global. Makes testing easier.
$this->config = $config ?: new DocumentationConfig(config($docsName));
$this->baseUrl = $this->config->get('base_url') ?? config('app.url');
Expand Down
12 changes: 8 additions & 4 deletions src/GroupedEndpoints/GroupedEndpointsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
namespace Knuckles\Scribe\GroupedEndpoints;

use Knuckles\Scribe\Commands\GenerateDocumentation;
use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Matching\RouteMatcherInterface;

class GroupedEndpointsFactory
{
public function make(GenerateDocumentation $command, RouteMatcherInterface $routeMatcher, string $docsName = 'scribe'): GroupedEndpointsContract
{
public function make(
GenerateDocumentation $command,
RouteMatcherInterface $routeMatcher,
CacheConfiguration $docsName
): GroupedEndpointsContract {
if ($command->isForcing()) {
return static::fromApp($command, $routeMatcher, false, $docsName);
}
Expand All @@ -24,12 +28,12 @@ public static function fromApp(
GenerateDocumentation $command,
RouteMatcherInterface $routeMatcher,
bool $preserveUserChanges,
string $docsName = 'scribe'
CacheConfiguration $docsName
): GroupedEndpointsFromApp {
return new GroupedEndpointsFromApp($command, $routeMatcher, $preserveUserChanges, $docsName);
}

public static function fromCamelDir(string $docsName = 'scribe'): GroupedEndpointsFromCamelDir
public static function fromCamelDir(CacheConfiguration $docsName): GroupedEndpointsFromCamelDir
{
return new GroupedEndpointsFromCamelDir($docsName);
}
Expand Down
10 changes: 6 additions & 4 deletions src/GroupedEndpoints/GroupedEndpointsFromApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Knuckles\Camel\Extraction\ExtractedEndpointData;
use Knuckles\Camel\Output\OutputEndpointData;
use Knuckles\Scribe\Commands\GenerateDocumentation;
use Knuckles\Scribe\Configuration\CacheConfiguration;
use Knuckles\Scribe\Exceptions\CouldntGetRouteDetails;
use Knuckles\Scribe\Extracting\ApiDetails;
use Knuckles\Scribe\Extracting\Extractor;
Expand All @@ -34,10 +35,11 @@ class GroupedEndpointsFromApp implements GroupedEndpointsContract
public static string $cacheDir;

public function __construct(
private GenerateDocumentation $command, private RouteMatcherInterface $routeMatcher,
private bool $preserveUserChanges = true, protected string $docsName = 'scribe'
)
{
private GenerateDocumentation $command,
private RouteMatcherInterface $routeMatcher,
private bool $preserveUserChanges = true,
protected CacheConfiguration $docsName

Check failure on line 41 in src/GroupedEndpoints/GroupedEndpointsFromApp.php

View workflow job for this annotation

GitHub Actions / Lint code (PHP 8.1)

Deprecated in PHP 8.0: Required parameter $docsName follows optional parameter $preserveUserChanges.
) {
$this->docConfig = $command->getDocConfig();

static::$camelDir = Camel::camelDir($this->docsName);
Expand Down
5 changes: 3 additions & 2 deletions src/GroupedEndpoints/GroupedEndpointsFromCamelDir.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
namespace Knuckles\Scribe\GroupedEndpoints;

use Knuckles\Camel\Camel;
use Knuckles\Scribe\Configuration\CacheConfiguration;

class GroupedEndpointsFromCamelDir implements GroupedEndpointsContract
{
protected string $docsName;
protected CacheConfiguration $docsName;

public function __construct(string $docsName = 'scribe')
public function __construct(CacheConfiguration $docsName)
{
$this->docsName = $docsName;
}
Expand Down
Loading

0 comments on commit 8d3ffa5

Please sign in to comment.