Skip to content

Commit

Permalink
Create a small CLI application
Browse files Browse the repository at this point in the history
  • Loading branch information
Nyholm committed Dec 20, 2019
1 parent f33cbc1 commit 8c8a35f
Show file tree
Hide file tree
Showing 21 changed files with 611 additions and 224 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/vendor/
composer.lock
composer.lock
.php_cs.cache
147 changes: 147 additions & 0 deletions .phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?xml version="1.0"?>
<ruleset>
<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="80"/>
<arg name="cache" value=".phpcs-cache"/>
<!-- Show sniff names -->
<arg value="s"/>

<file>bref</file>
<file>src</file>
<file>tests</file>
<exclude-pattern>tests/Bridge/Symfony/var</exclude-pattern>
<exclude-pattern>tests/Bridge/Symfony/cache</exclude-pattern>
<exclude-pattern>tests/Bridge/Symfony/logs</exclude-pattern>
<exclude-pattern>tests/Bridge/Laravel/bootstrap/cache</exclude-pattern>

<!-- Import the Doctrine coding standard -->
<rule ref="Doctrine"/>

<!-- Allow long lines -->
<rule ref="Generic.Files.LineLength.TooLong">
<severity>0</severity>
</rule>

<!-- Do not align assignments -->
<rule ref="Generic.Formatting.MultipleStatementAlignment">
<severity>0</severity>
</rule>

<!-- Require specific order of phpDoc annotations with empty newline between specific groups -->
<rule ref="SlevomatCodingStandard.Commenting.DocCommentSpacing">
<properties>
<property name="linesCountBeforeFirstContent" value="0"/>
<property name="linesCountAfterLastContent" value="0"/>
<property name="linesCountBetweenDescriptionAndAnnotations" value="1"/>
<property name="linesCountBetweenAnnotationsGroups" value="1"/>
<property name="annotationsGroups" type="array">
<element value="
@ORM\,
@ODM\,
"/>
<element value="
@param,
@return,
@throws,
"/>
<element value="
@internal,
@deprecated,
@link,
@see,
@uses,
"/>
</property>
</properties>
</rule>

<!-- Do not enforce usage of early exit -->
<rule ref="SlevomatCodingStandard.ControlStructures.EarlyExit">
<severity>0</severity>
</rule>

<!-- Require new instances without parentheses when not passing parameters -->
<rule ref="SlevomatCodingStandard.ControlStructures.NewWithParentheses">
<severity>0</severity>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.NewWithoutParentheses"/>

<!-- Do not require closures not referencing $this be static -->
<rule ref="SlevomatCodingStandard.Functions.StaticClosure">
<severity>0</severity>
</rule>

<!-- Allow using some absolute class name references (except global ones) -->
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly">
<properties>
<property name="allowFallbackGlobalConstants" value="true"/>
<property name="allowFallbackGlobalFunctions" value="true"/>
<property name="allowFullyQualifiedGlobalClasses" value="true"/>
<property name="allowFullyQualifiedGlobalConstants" value="true"/>
<property name="allowFullyQualifiedGlobalFunctions" value="true"/>
<property name="allowFullyQualifiedNameForCollidingClasses" value="true"/>
<property name="allowFullyQualifiedNameForCollidingConstants" value="true"/>
<property name="allowFullyQualifiedNameForCollidingFunctions" value="true"/>
<property name="searchAnnotations" value="true"/>
</properties>
</rule>

<!-- Require presence of declare(strict_types=1) -->
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<properties>
<!-- Inline with the `<?php` opening tag -->
<property name="newlinesCountBetweenOpenTagAndDeclare" value="0"/>
<property name="spacesCountAroundEqualsSign" value="0"/>
<property name="newlinesCountAfterDeclare" value="2"/>
</properties>
</rule>

<!-- Require no space before colon in return types -->
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing">
<properties>
<property name="spacesCountBeforeColon" value="0"/>
</properties>
</rule>

<!-- Do not force arrays with 1 item to be inline -->
<rule ref="Squiz.Arrays.ArrayDeclaration.MultiLineNotAllowed">
<severity>0</severity>
</rule>

<!-- Do not forbid declaring functions -->
<rule ref="Squiz.Functions.GlobalFunction">
<severity>0</severity>
</rule>

<!-- Allow using variables in double quoted strings -->
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
<severity>0</severity>
</rule>

<!-- More lax rules about `array` type-hints (no need to always detail what's in the array) -->
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversablePropertyTypeHintSpecification">
<severity>0</severity>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification">
<severity>0</severity>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification">
<severity>0</severity>
</rule>

<!-- ########################-->
<!-- TESTS -->
<!-- ########################-->

<!-- Allow underscores and non-breakable spaces to be used in tests for readability -->
<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
<exclude-pattern type="relative">tests/*</exclude-pattern>
</rule>

<!-- Do not enforce return types in tests else it crowds the test methods with `: void` -->
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingReturnTypeHint">
<exclude-pattern type="relative">tests/*</exclude-pattern>
</rule>

</ruleset>
5 changes: 5 additions & 0 deletions .prettyci.composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"doctrine/coding-standard": "^5.0"
}
}
20 changes: 20 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
language: php

notifications:
email:
on_success: never

services:
- docker

env:
- LAYER=amqp PHP=72
- LAYER=amqp PHP=73
- LAYER=amqp PHP=74
- LAYER=mecached PHP=72
- LAYER=mecached PHP=73
- LAYER=mecached PHP=74

script:
- cd layer/$LAYER
- docker build --build-arg PHP_VERSION=$PHP .
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
SHELL := /bin/bash
php_versions = 72 73 74
php_versions = 73

docker-images:
PWD=pwd
Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Bref layers
# Bref extra layers

Create small layers with specific PHP extensions. This is useful when you want something "off the shelf".
If you ever need more than one layer you should consider creating your own layer. That is because AWS has
Expand Down
12 changes: 12 additions & 0 deletions bref-extra
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env php
<?php
require __DIR__.'/vendor/autoload.php';

$app = new Bref\Extra\Application();
$app->command('publish', \Bref\Extra\Command\PublishCommand::class)->descriptions('Publish new layers. Create checksums.json');
$app->command('list', \Bref\Extra\Command\ListCommand::class)->descriptions('Create layer.json');
$app->command('help', \Bref\Extra\Command\HelpCommand::class)->descriptions('Prints some help texts.');

$app->setDefaultCommand('help');

$app->run();
1 change: 1 addition & 0 deletions checksums.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
9 changes: 8 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
"require-dev": {
"symfony/process": "^5.0",
"symfony/finder": "^5.0",
"aws/aws-sdk-php": "^3.130"
"aws/aws-sdk-php": "^3.130",
"mnapoli/silly": "^1.7",
"mnapoli/silly-php-di": "^1.2"
},
"autoload-dev": {
"psr-4": {
"Bref\\Extra\\": "src/"
}
},
"license": "MIT",
"authors": [
Expand Down
1 change: 0 additions & 1 deletion export/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
*
!.gitignore
!checksums
6 changes: 0 additions & 6 deletions export/checksums

This file was deleted.

1 change: 1 addition & 0 deletions layers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
45 changes: 45 additions & 0 deletions src/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Bref\Extra;

use Bref\Extra\Aws\LayerProvider;
use Bref\Extra\Aws\LayerPublisher;
use Bref\Extra\Service\RegionProvider;
use Bref\Extra\Command\ListCommand;
use Bref\Extra\Command\PublishCommand;
use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;

class Application extends \Silly\Edition\PhpDi\Application
{
protected function createContainer()
{
$builder = new ContainerBuilder();
$awsId = getenv('AWS_ID');
if (empty($awsId)){
$awsId = 'foobar';
}

$projectDir = dirname(__DIR__);
$localLayers = array_keys(json_decode(file_get_contents($projectDir.'/checksums.json'), true));

$builder->addDefinitions([
'project_dir' => $projectDir,
'aws_id' => $awsId,
'layer_names' => $localLayers,
LayerProvider::class => function (ContainerInterface $c) {
return new LayerProvider($c->get('layer_names'), $c->get('aws_id'));
},
ListCommand::class => function (ContainerInterface $c) {
return new ListCommand($c->get(LayerProvider::class), $c->get(RegionProvider::class), $c->get('project_dir'));
},
PublishCommand::class => function (ContainerInterface $c) {
return new PublishCommand($c->get(LayerPublisher::class), $c->get(RegionProvider::class), $c->get('project_dir'));
},
]);

return $builder->build();
}
}
66 changes: 66 additions & 0 deletions src/Aws/LayerProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Bref\Extra\Aws;

use Aws\Lambda\LambdaClient;
use function GuzzleHttp\Promise\unwrap;

/**
* Fetches layers and details from AWS
*
* @author Tobias Nyholm <[email protected]>
*/
class LayerProvider
{
private $awsId;

/**
* @var array
*/
private $layerNames;

/**
* @param array $layerNames the name of the layers to list.
* @param string $awsId The account id
*/
public function __construct(array $layerNames, string $awsId)
{
$this->awsId = $awsId;
$this->layerNames = $layerNames;
}


public function listLayers(string $selectedRegion): array
{
$lambda = new LambdaClient([
'version' => 'latest',
'region' => $selectedRegion,
]);

$accountId = $this->awsId;
// Run the API calls in parallel (thanks to async)
$promises = array_combine($this->layerNames, array_map(function (string $layerName) use ($lambda, $selectedRegion, $accountId) {
return $lambda->listLayerVersionsAsync([
'LayerName' => "arn:aws:lambda:$selectedRegion:$accountId:layer:$layerName",
'MaxItems' => 1,
]);
}, $this->layerNames));

// Wait on all of the requests to complete. Throws a ConnectException
// if any of the requests fail
$results = \GuzzleHttp\Promise\unwrap($promises);

$layers = [];
foreach ($results as $layerName => $result) {
$versions = $result['LayerVersions'];
$latestVersion = end($versions);
$layers[$layerName] = $latestVersion['Version'];
}

return $layers;
}


}
Loading

0 comments on commit 8c8a35f

Please sign in to comment.