Skip to content

Commit

Permalink
Merge pull request #1 from netglue/feature/identify-document
Browse files Browse the repository at this point in the history
Add commands for dumping info from a configured repository
  • Loading branch information
gsteel committed Oct 16, 2020
2 parents 57a16d8 + e8285ec commit 0c96bab
Show file tree
Hide file tree
Showing 11 changed files with 439 additions and 9 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@

All notable changes to this project will be documented in this file, in reverse chronological order by release.

## 0.2.0 - 2020-10-16

### Added

- New commands that help with dumping information about the currently configured repository.

### Changed

- Nothing.

### Deprecated

- Nothing.

### Removed

- Nothing.

### Fixed

- Nothing.

## 0.1.4 - 2020-10-16

### Added
Expand Down
70 changes: 62 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,74 @@ $ composer require --dev netglue/prismic-cli
```

The primary installation target for this lib is a [Mezzio](https://github.com/mezzio) app as it has been built to
integrate with the forthcoming [Laminas CLI](https://github.com/laminas/laminas-cli) package. In lieu of Laminas CLI, it
should also play nicely with my own Symfony console bootstrap package at
[netglue/laminas-symfony-console](https://github.com/netglue/laminas-symfony-console). During installation you should be
prompted to inject the config provider if installing as part of a Mezzio app.
integrate with the [Laminas CLI](https://github.com/laminas/laminas-cli) package.

Neither the Laminas, nor my own Symfony Console integration packages are required by this lib.
During installation you should be prompted to inject the config provider(s) if installing as part of a Mezzio app.

`laminas/laminas-cli` is not required by this lib, so you'll need to require it too if that's what you want.

There's nothing to stop you from using this tool 'stand-alone' - the `./example/example.php` should point you in the
right direction for this.
right direction for this. It's also worth inspecting that example so everything makes sense.

### Building Document Model JSON Files

At the moment, the tool has one command, `primo:build` which can generate JSON files from PHP sources that you can copy
The command `primo:build`, given some configuration, generates JSON files from PHP sources that you can copy
and paste into [Prismic.io's](https://prismic.io) custom type editor.

Assuming that you are using a DI container that returns application-wide config as an array using `config` as a service id,
You can drop configuration similar to this in order to have the tool build your types upon invocation.

```php
<?php
return [
'primo' => [
'cli' => [
'builder' => [
'source' => __DIR__ . '/../directory/where/plain-php-files-are',
'dist' => __DIR__ . '/../where-you-want-the-json-files-to-go',
],
],
'types' => [
[
'id' => 'some-type',
'name' => 'My Document Type',
'repeatable' => true,
],
],
],
];
```

The lib currently lacks documentation and a decent test suite but there is an annotated example in `./example`. When it comes to
configuring as part of a Mezzio app, please examine `./src/ConfigProvider.php` for more information.

This lib is not a replacement for JS cli tooling provided by Prismic…
### Commands that Query a Repository

Theres also some commands for getting information from a repository. These commands are opt-in. During installation there's a config
provider called `ApiToolsConfigProvider` which you can skip if you don't want these tools available.

All of the commands require a configured Api Client, using [`netglue/prismic-client`](https://github.com/netglue/prismic-client).

The above mentioned config provider sets up its own factory for the api client, skipping a cache implementation as it's likely that
if you are using the tools, you don't want stale information.

Configure the repository somewhere with information similar to:
```php
return [
'prismic' => [
'api' => 'https://your-repo.cdn.prismic.io/api/v2',
'token' => null, // Or 'string-access-token'
],
];
```

#### Currently Available Commands

- `primo:info` - Without arguments, provides information about the repository itself
- `primo:info <document-id>` - Shows information about a specific document
- `primo:list` - Lists the types available in the configured repository
- `primo:list <type>` - Lists documents and id's of a specific type

You can try out these commands on the test repo used for the Prismic/Mezzio integration lib we wrote at [`netglue/primo`](https://github.com/netglue/primo) by running `./example/api-queries.php`

_Note: This lib is not a replacement for JS cli tooling provided by Prismic…_
9 changes: 8 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@
"require": {
"php": ">=7.3",
"ext-json": "*",
"netglue/prismic-client": "^0.4.2",
"psr/container": "^1.0",
"symfony/console": "^5.1"
},
"require-dev": {
"ext-curl": "*",
"doctrine/coding-standard": "^8.0",
"laminas/laminas-diactoros": "^2.4",
"php-http/curl-client": "^2.1",
"phpunit/phpunit": "^9.2",
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "^3.5"
},
"extra": {
"laminas": {
"config-provider": "Primo\\Cli\\ConfigProvider"
"config-provider": [
"Primo\\Cli\\ConfigProvider",
"Primo\\Cli\\ApiToolsConfigProvider"
]
}
},
"scripts": {
Expand Down
18 changes: 18 additions & 0 deletions example/api-queries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use Primo\Cli\Console\InfoCommand;
use Primo\Cli\Console\ListCommand;
use Prismic\Api;
use Symfony\Component\Console\Application;

require __DIR__ . '/../vendor/autoload.php';

$api = Api::get('https://primo.prismic.io/api/v2');

$application = new Application('Repository Info Commands Example');
$application->add(new InfoCommand($api));
$application->add(new ListCommand($api));

return $application->run();
43 changes: 43 additions & 0 deletions src/ApiToolsConfigProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Primo\Cli;

final class ApiToolsConfigProvider
{
/** @return mixed */
public function __invoke(): array
{
return [
'dependencies' => $this->dependencies(),
'console' => [
'commands' => $this->commands(),
],
'laminas-cli' => [
'commands' => $this->commands(),
],
];
}

/** @return mixed[] */
private function dependencies(): array
{
return [
'factories' => [
'PrimoCliApiInstance' => Container\PrismicApiClientFactory::class,
Console\InfoCommand::class => Console\Container\InfoCommandFactory::class,
Console\ListCommand::class => Console\Container\ListCommandFactory::class,
],
];
}

/** @return string[] */
private function commands(): array
{
return [
Console\InfoCommand::DEFAULT_NAME => Console\InfoCommand::class,
Console\ListCommand::DEFAULT_NAME => Console\ListCommand::class,
];
}
}
16 changes: 16 additions & 0 deletions src/Console/Container/InfoCommandFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Primo\Cli\Console\Container;

use Primo\Cli\Console\InfoCommand;
use Psr\Container\ContainerInterface;

final class InfoCommandFactory
{
public function __invoke(ContainerInterface $container): InfoCommand
{
return new InfoCommand($container->get('PrimoCliApiInstance'));
}
}
16 changes: 16 additions & 0 deletions src/Console/Container/ListCommandFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Primo\Cli\Console\Container;

use Primo\Cli\Console\ListCommand;
use Psr\Container\ContainerInterface;

final class ListCommandFactory
{
public function __invoke(ContainerInterface $container): ListCommand
{
return new ListCommand($container->get('PrimoCliApiInstance'));
}
}
121 changes: 121 additions & 0 deletions src/Console/InfoCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

declare(strict_types=1);

namespace Primo\Cli\Console;

use Prismic\ApiClient;
use Prismic\Document;
use Prismic\Value\Bookmark;
use Prismic\Value\Language;
use Prismic\Value\Type;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

use function array_map;
use function implode;
use function sprintf;

use const PHP_EOL;

final class InfoCommand extends Command
{
public const DEFAULT_NAME = 'primo:info';

/** @var ApiClient */
private $apiClient;

public function __construct(ApiClient $apiClient, string $name = self::DEFAULT_NAME)
{
$this->apiClient = $apiClient;
parent::__construct($name);
}

protected function configure(): void
{
$this->setDescription(
'This command shows information about a specific document when given its unique identifier, '
. 'or, with no arguments provides information about the repository.'
);
$this->addArgument(
'id',
InputArgument::OPTIONAL,
'The unique id of the document'
);
}

public function execute(InputInterface $input, OutputInterface $output): int
{
$style = new SymfonyStyle($input, $output);
$id = $input->getArgument('id');
if (empty($id)) {
$this->showApiInfo($style);

return 0;
}

$document = $this->apiClient->findById($id);
if (! $document) {
$style->warning(sprintf(
'A document could not be found with the id "%s" in the repository "%s"',
$id,
$this->apiClient->host()
));

return 0;
}

$this->showDocumentInfo($style, $document);

return 0;
}

private function showDocumentInfo(SymfonyStyle $style, Document $document): void
{
$style->title(sprintf('Document Information: %s', $document->id()));

$style->table([], [
['ID:', $document->id()],
['UID:', $document->uid() ?: '<none>'],
['Type:', $document->type()],
['Created At:', $document->firstPublished()->format('l jS F Y H:i:s')],
['Modified At:', $document->lastPublished()->format('l jS F Y H:i:s')],
['Language:', $document->lang()],
['Tags:', $document->tags() === [] ? '<none>' : implode(', ', $document->tags())],
]);
}

private function showApiInfo(SymfonyStyle $style): void
{
$style->title(sprintf('Repository Information: %s', $this->apiClient->host()));
$style->table([], [
['Repository Host:', $this->apiClient->host()],
['Master Ref:', $this->apiClient->ref()->ref()],
[
'Document Types:',
implode(PHP_EOL, array_map(static function (Type $type): string {
return sprintf('%s ("%s")', $type->id(), $type->name());
}, $this->apiClient->data()->types())),
],
[
'Tags:',
implode(', ', $this->apiClient->data()->tags()),
],
[
'Languages:',
implode(PHP_EOL, array_map(static function (Language $language): string {
return $language->name();
}, $this->apiClient->data()->languages())),
],
[
'Bookmarks:',
implode(PHP_EOL, array_map(static function (Bookmark $bookmark): string {
return sprintf('%s (%s)', $bookmark->name(), $bookmark->documentId());
}, $this->apiClient->data()->bookmarks())),
],
]);
}
}
Loading

0 comments on commit 0c96bab

Please sign in to comment.