Skip to content

feat(validators-hook): created new package with validation offering #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 2, 2023
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
2 changes: 2 additions & 0 deletions .github/workflows/php-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
php-version: ['7.4', '8.0', '8.1', '8.2']
project-dir:
- hooks/OpenTelemetry
- hooks/DDTrace
- hooks/Validators
- providers/Flagd
- providers/Split
- providers/CloudBees
Expand Down
2 changes: 2 additions & 0 deletions .gitsplit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ splits:
target: "https://${GH_TOKEN}@github.com/open-feature-php/otel-hook.git"
- prefix: "hooks/DDTrace"
target: "https://${GH_TOKEN}@github.com/open-feature-php/dd-trace-hook.git"
- prefix: "hooks/Validators"
target: "https://${GH_TOKEN}@github.com/open-feature-php/validators-hook.git"
- prefix: "providers/Flagd"
target: "https://${GH_TOKEN}@github.com/open-feature-php/flagd-provider.git"
- prefix: "providers/Split"
Expand Down
18 changes: 18 additions & 0 deletions hooks/Validators/.github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
on:
push:
branches:
- main

name: Run Release Please
jobs:
release-please:
runs-on: ubuntu-latest

# Release-please creates a PR that tracks all changes
steps:
- uses: google-github-actions/release-please-action@v3
id: release
with:
command: manifest
token: ${{secrets.GITHUB_TOKEN}}
default-branch: main
3 changes: 3 additions & 0 deletions hooks/Validators/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/composer.lock
/vendor
/build
3 changes: 3 additions & 0 deletions hooks/Validators/.release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.0.1"
}
67 changes: 67 additions & 0 deletions hooks/Validators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# OpenFeature Validator Hooks

[![a](https://img.shields.io/badge/slack-%40cncf%2Fopenfeature-brightgreen?style=flat&logo=slack)](https://cloud-native.slack.com/archives/C0344AANLA1)
[![Latest Stable Version](http://poser.pugx.org/open-feature/validators-hook/v)](https://packagist.org/packages/open-feature/validators-hook)
[![Total Downloads](http://poser.pugx.org/open-feature/validators-hook/downloads)](https://packagist.org/packages/open-feature/validators-hook)
![PHP 7.4+](https://img.shields.io/badge/php->=7.4-blue.svg)
[![License](http://poser.pugx.org/open-feature/validators-hook/license)](https://packagist.org/packages/open-feature/validators-hook)

## Overview

Validator Hook constructs that provide means to execute validation against resolved feature flag values.

This package also builds on various PSRs (PHP Standards Recommendations) such as the Logger interfaces (PSR-3) and the Basic and Extended Coding Standards (PSR-1 and PSR-12).

## Installation

```
$ composer require open-feature/validators-hook // installs the latest version
```

## Usage

The following validator hook constructs are available, but more are being worked on over time:

- `RegexpValidatorHoook`


```php
use OpenFeature\Hooks\Validators\RegexpValidatorHook;

$alphanumericValidator = new RegexpValidatorHook('/^[A-Za-z0-9]+$/');
$hexadecimalValidator = new RegexpValidatorHook('/^[0-9a-f]+$/');
$asciiValidator = new RegexpValidatorHook('/^[ -~]$/');

// hooks can be applied to the global API, clients, providers, and resolution invocations

// all feature flag resolutions will use this validator
$api = OpenFeatureAPI::getInstance();
$api->addHooks($asciiValidator);

// invocations from this client will use this validator also
$client = $api->getClient('example');
$client->setHooks([$alphanumericValidator]);

// this specific invocation will use this validator also
$client->resolveBooleanValue('test-flag', 'deadbeef', null, new EvaluationOptions([$hexadecimalValidator]));
```

For more examples, see the [examples](./examples/).

## Development

### PHP Versioning

This library targets PHP version 7.4 and newer. As long as you have any compatible version of PHP on your system you should be able to utilize the OpenFeature SDK.

This package also has a `.tool-versions` file for use with PHP version managers like `asdf`.

### Installation and Dependencies

Install dependencies with `composer install`. `composer install` will update the `composer.lock` with the most recent compatible versions.

We value having as few runtime dependencies as possible. The addition of any dependencies requires careful consideration and review.

### Testing

Run tests with `composer run test`.
133 changes: 133 additions & 0 deletions hooks/Validators/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
{
"name": "open-feature/validators-hook",
"description": "A validator hooks package for OpenFeature",
"license": "Apache-2.0",
"type": "library",
"keywords": [
"featureflags",
"featureflagging",
"openfeature",
"validator",
"hook"
],
"authors": [
{
"name": "OpenFeature PHP Maintainers",
"homepage": "https://github.com/orgs/open-feature/teams/php-maintainer"
},
{
"name": "open-feature/php-sdk-contrib Contributors",
"homepage": "https://github.com/open-feature/php-sdk-contrib/graphs/contributors"
}
],
"require": {
"php": "^7.4 || ^8",
"open-feature/sdk": "^1.2.0"
},
"require-dev": {
"ergebnis/composer-normalize": "^2.25",
"friendsofphp/php-cs-fixer": "^3.13",
"hamcrest/hamcrest-php": "^2.0",
"mdwheele/zalgo": "^0.3.1",
"mikey179/vfsstream": "v1.6.11",
"mockery/mockery": "^1.5",
"phan/phan": "^5.4",
"php-parallel-lint/php-console-highlighter": "^1.0",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "~1.9.0",
"phpstan/phpstan-mockery": "^1.0",
"phpstan/phpstan-phpunit": "^1.1",
"psalm/plugin-mockery": "^0.9.1",
"psalm/plugin-phpunit": "^0.18.0",
"ramsey/coding-standard": "^2.0.3",
"ramsey/composer-repl": "^1.4",
"ramsey/conventional-commits": "^1.3",
"roave/security-advisories": "dev-latest",
"spatie/phpunit-snapshot-assertions": "^4.2",
"vimeo/psalm": "~4.30.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"OpenFeature\\Hooks\\Validators\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"OpenFeature\\Hooks\\Validators\\Test\\": "tests"
}
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"ergebnis/composer-normalize": true,
"captainhook/plugin-composer": true,
"ramsey/composer-repl": true
},
"sort-packages": true
},
"extra": {
"captainhook": {
"force-install": false
}
},
"scripts": {
"dev:analyze": [
"@dev:analyze:phpstan",
"@dev:analyze:psalm"
],
"dev:analyze:phpstan": "phpstan analyse --ansi --debug --memory-limit=512M",
"dev:analyze:psalm": "psalm",
"dev:build:clean": "git clean -fX build/",
"dev:lint": [
"@dev:lint:syntax",
"@dev:lint:style"
],
"dev:lint:fix": "phpcbf",
"dev:lint:style": "phpcs --colors",
"dev:lint:syntax": "parallel-lint --colors src/ tests/",
"dev:test": [
"@dev:lint",
"@dev:analyze",
"@dev:test:unit",
"@dev:test:integration"
],
"dev:test:coverage:ci": "phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml",
"dev:test:coverage:html": "phpunit --colors=always --coverage-html build/coverage/coverage-html/",
"dev:test:unit": [
"@dev:test:unit:setup",
"phpunit --colors=always --testdox --testsuite=unit",
"@dev:test:unit:teardown"
],
"dev:test:unit:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on",
"dev:test:unit:setup": "echo 'Setup for unit tests...'",
"dev:test:unit:teardown": "echo 'Tore down for unit tests...'",
"dev:test:integration": [
"@dev:test:integration:setup",
"phpunit --colors=always --testdox --testsuite=integration",
"@dev:test:integration:teardown"
],
"dev:test:integration:debug": "phpunit --colors=always --testdox -d xdebug.profiler_enable=on",
"dev:test:integration:setup": "echo 'Setup for integration tests...'",
"dev:test:integration:teardown": "echo 'Tore down integration tests...'",
"test": "@dev:test"
},
"scripts-descriptions": {
"dev:analyze": "Runs all static analysis checks.",
"dev:analyze:phpstan": "Runs the PHPStan static analyzer.",
"dev:analyze:psalm": "Runs the Psalm static analyzer.",
"dev:build:clean": "Cleans the build/ directory.",
"dev:lint": "Runs all linting checks.",
"dev:lint:fix": "Auto-fixes coding standards issues, if possible.",
"dev:lint:style": "Checks for coding standards issues.",
"dev:lint:syntax": "Checks for syntax errors.",
"dev:test": "Runs linting, static analysis, and unit tests.",
"dev:test:coverage:ci": "Runs unit tests and generates CI coverage reports.",
"dev:test:coverage:html": "Runs unit tests and generates HTML coverage report.",
"dev:test:unit": "Runs unit tests.",
"test": "Runs linting, static analysis, and unit tests."
}
}
2 changes: 2 additions & 0 deletions hooks/Validators/examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/*/vendor
/*/composer.lock
3 changes: 3 additions & 0 deletions hooks/Validators/examples/ExampleRegexpValidators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# OpenFeature Validators Hook example

This example provides an example of using the validators hooks for OpenFeature.
27 changes: 27 additions & 0 deletions hooks/Validators/examples/ExampleRegexpValidators/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "open-feature/validators-hook-example",
"description": "An example of using the validator hooks for OpenFeature",
"type": "project",
"license": "Apache-2.0",
"authors": [
{
"name": "Tom Carrio",
"email": "[email protected]"
}
],
"require": {
"open-feature/sdk": "^1.2.0",
"open-feature/validators-hook": "dev-main"
},
"repositories": [
{
"type": "path",
"url": "../../",
"options": {
"versions": {
"open-feature/validators-hook": "dev-main"
}
}
}
]
}
31 changes: 31 additions & 0 deletions hooks/Validators/examples/ExampleRegexpValidators/src/main.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Examples\OpenFeature\Http;

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

use OpenFeature\Hooks\Validators\Regexp\RegexpValidatorHook;
use OpenFeature\OpenFeatureAPI;


// retrieve the OpenFeatureAPI instance
$api = OpenFeatureAPI::getInstance();

// retrieve an OpenFeatureClient
$client = $api->getClient('split-example', '1.0');

// create some example hook validators

$alphanumericValidator = new RegexpValidatorHook('/^[A-Za-z0-9]+$/');
$hexadecimalValidator = new RegexpValidatorHook('/^[0-9a-f]+$/');
$asciiValidator = new RegexpValidatorHook('/^[ -~]$/');

$client->setHooks([
$alphanumericValidator,
$hexadecimalValidator,
$asciiValidator
]);

$flagValue = $client->getBooleanDetails('dev.openfeature.example_flag', true, null, null);
28 changes: 28 additions & 0 deletions hooks/Validators/phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">

<arg name="extensions" value="php"/>
<arg name="colors"/>
<arg value="sp"/>

<file>./src</file>
<file>./tests</file>

<exclude-pattern>*/tests/fixtures/*</exclude-pattern>
<exclude-pattern>*/tests/*/fixtures/*</exclude-pattern>

<rule ref="Ramsey">
<exclude name="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming"/>
<exclude name="SlevomatCodingStandard.Classes.SuperfluousErrorNaming"/>
<exclude name="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming"/>
<exclude name="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming"/>
<exclude name="SlevomatCodingStandard.Classes.SuperfluousTraitNaming"/>

<exclude name="Generic.Files.LineLength.TooLong"/>
<exclude name="Generic.Commenting.Todo.TaskFound"/>

<!-- Ignore this for PHP 7.4 -->
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint"/>
</rule>

</ruleset>
9 changes: 9 additions & 0 deletions hooks/Validators/phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
parameters:
tmpDir: ./build/cache/phpstan
level: max
paths:
- ./src
- ./tests
excludePaths:
- */tests/fixtures/*
- */tests/*/fixtures/*
28 changes: 28 additions & 0 deletions hooks/Validators/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="./vendor/autoload.php"
cacheResultFile="./build/cache/phpunit.result.cache"
colors="true"
verbose="true">

<testsuites>
<testsuite name="unit">
<directory>./tests/unit</directory>
</testsuite>
<testsuite name="integration">
<directory>./tests/integration</directory>
</testsuite>
</testsuites>

<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>

<php>
<ini name="date.timezone" value="UTC"/>
</php>

</phpunit>
2 changes: 2 additions & 0 deletions hooks/Validators/psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.9.5@0cfe565d0afbcd31eadcc281b9017b5692911661"/>
Loading