Skip to content

Commit 2e73bee

Browse files
Continuous integration pipeline
Implemented a CI pipeline with Github Actions, code style linting, type checking and unit testing.
1 parent b688124 commit 2e73bee

38 files changed

+1172
-272
lines changed

.github/workflows/pr.yml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
name: "Review PR"
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
8+
# This job ensures the coding standard is followed
9+
coding-standards:
10+
name: "Coding Standards"
11+
runs-on: ${{ matrix.operating-system }}
12+
strategy:
13+
matrix:
14+
php-version:
15+
- "7.4"
16+
operating-system:
17+
- "ubuntu-latest"
18+
steps:
19+
- name: "Checkout Code"
20+
uses: "actions/checkout@v2"
21+
- name: "Install PHP"
22+
uses: "shivammathur/setup-php@v2"
23+
with:
24+
coverage: "pcov"
25+
php-version: "${{ matrix.php-version }}"
26+
ini-values: memory_limit=-1
27+
tools: composer:v2
28+
- name: "Use Cache"
29+
uses: "actions/cache@v2"
30+
with:
31+
path: |
32+
~/.composer/cache
33+
vendor
34+
key: "php-${{ matrix.php-version }}-locked"
35+
restore-keys: "php-${{ matrix.php-version }}-locked"
36+
- name: "Install locked dependencies"
37+
run: "composer install --no-interaction --no-progress --no-suggest"
38+
- name: "Coding Standard"
39+
run: "vendor/bin/php-cs-fixer fix --dry-run -vvv"
40+
41+
type-analysis:
42+
name: "Type Coverage"
43+
runs-on: ${{ matrix.operating-system }}
44+
strategy:
45+
matrix:
46+
php-version:
47+
- "7.4"
48+
operating-system:
49+
- "ubuntu-latest"
50+
steps:
51+
- name: "Checkout Code"
52+
uses: "actions/checkout@v2"
53+
- name: "Install PHP"
54+
uses: "shivammathur/setup-php@v2"
55+
with:
56+
coverage: "pcov"
57+
php-version: "${{ matrix.php-version }}"
58+
ini-values: memory_limit=-1
59+
tools: composer:v2
60+
- name: "Use Cache"
61+
uses: "actions/cache@v2"
62+
with:
63+
path: |
64+
~/.composer/cache
65+
vendor
66+
key: "php-${{ matrix.php-version }}-locked"
67+
restore-keys: "php-${{ matrix.php-version }}-locked"
68+
- name: "Install locked dependencies"
69+
run: "composer install --no-interaction --no-progress --no-suggest"
70+
- name: "Run Psalm"
71+
run: "vendor/bin/psalm --output-format=github --shepherd --stats"
72+
73+
unit-test:
74+
name: "Unit Testing"
75+
runs-on: ${{ matrix.operating-system }}
76+
strategy:
77+
matrix:
78+
dependencies:
79+
- "locked"
80+
- "highest"
81+
php-version:
82+
- "7.4"
83+
- "8.0"
84+
operating-system:
85+
- "ubuntu-latest"
86+
steps:
87+
- name: "Checkout Code"
88+
uses: "actions/checkout@v2"
89+
- name: "Install PHP"
90+
uses: "shivammathur/setup-php@v2"
91+
with:
92+
coverage: "pcov"
93+
php-version: "${{ matrix.php-version }}"
94+
ini-values: memory_limit=-1
95+
tools: composer:v2
96+
- name: "Use Cache"
97+
uses: "actions/cache@v2"
98+
with:
99+
path: |
100+
~/.composer/cache
101+
vendor
102+
key: "php-${{ matrix.php-version }}-locked"
103+
restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}"
104+
- name: "Install lowest dependencies"
105+
if: ${{ matrix.dependencies == 'lowest' }}
106+
run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest --ignore-platform-reqs"
107+
- name: "Install highest dependencies"
108+
if: ${{ matrix.dependencies == 'highest' }}
109+
run: "composer update --no-interaction --no-progress --no-suggest --ignore-platform-reqs"
110+
- name: "Install locked dependencies"
111+
if: ${{ matrix.dependencies == 'locked' }}
112+
run: "composer install --no-interaction --no-progress --no-suggest --ignore-platform-reqs"
113+
- name: "Run PHPUnit"
114+
run: "vendor/bin/phpunit --testdox --coverage-text"

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.phpunit.result.cache
22
composer.lock
3-
vendor
3+
vendor
4+
.php_cs.cache

.php_cs.dist

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
$header = <<<EOF
4+
This file is part of the https://github.com/mnavarrocarter/php-fetch project.
5+
(c) Matías Navarro-Carter <[email protected]>
6+
For the full copyright and license information, please view the LICENSE
7+
file that was distributed with this source code.
8+
EOF;
9+
10+
return PhpCsFixer\Config::create()
11+
->setRules([
12+
'@Symfony' => true,
13+
'array_syntax' => ['syntax' => 'short'],
14+
'phpdoc_no_empty_return' => true,
15+
'header_comment' => ['header' => $header],
16+
'yoda_style' => [
17+
'equal' => false,
18+
'identical' => false,
19+
'less_and_greater' => false,
20+
'always_move_variable' => true
21+
],
22+
])
23+
->setFinder(
24+
PhpCsFixer\Finder::create()
25+
->in(__DIR__.'/src')
26+
)
27+
;

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Matías Navarro Carter
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ PHP Fetch
33

44
A simple, type-safe, zero dependency port of the javascript `fetch` WebApi for PHP.
55

6+
7+
<h3 align="center">
8+
<img style="alignment: center" src="https://media0.giphy.com/media/xlYKItjhiDsY/giphy.gif?cid=ecf05e474io66b5jt2mrufubg3otjzq26qgtqd0cb0w71fiu&rid=giphy.gif"/>
9+
</h3>
10+
611
> NOTE: This library is in `< 1.0.0` version and as per the Semantic Versioning Spec, breaking
712
> changes might occur in minor releases before reaching `1.0.0`. Specify your constraints
813
> carefully.
@@ -62,6 +67,27 @@ At the moment, the only options supported are:
6267
- `body`: The request body. It can be a `resource`, a `string` or `null`.
6368
- `headers`: An associative array of header names and values.
6469

70+
### Getting response information
71+
72+
You can get all the information you need from the response using
73+
the available api.
74+
75+
```php
76+
<?php
77+
78+
use function MNC\Http\fetch;
79+
80+
$response = fetch('https://mnavarro.dev');
81+
82+
echo $response->status()->protocolVersion(); // 1.1
83+
echo $response->status()->code(); // 200
84+
echo $response->status()->reasonPhrase(); // OK
85+
echo $response->headers()->has('content-type'); // true
86+
echo $response->headers()->contains('content-type', 'html'); // true
87+
echo $response->headers()->get('content-type'); // text/html;charset=utf-8
88+
echo $response->body()->read(''); // Outputs some bytes from the response body
89+
```
90+
6591
### Exception Handling
6692

6793
A call to `fetch` can throw two exceptions, which are properly documented.
@@ -123,8 +149,8 @@ when we provide helpers like these in our apis.
123149
This library provides an approach a bit more safe. If the response headers contain the
124150
`application/json` content type, the `MNC\Http\Io\Reader` object of the body is internally
125151
decorated with a `MNC\Http\Encoding\Json` object. This object implements both the
126-
`JsonReader` and `JsonDecoder` interfaces, plus the normal `Reader` interface,
127-
and you can check for those interfaces to conveniently handle json payloads safely.
152+
`Reader` and `JsonDecoder` interfaces. Checking for the former is the safest way of
153+
handling json payloads:
128154

129155
```php
130156
<?php
@@ -385,8 +411,12 @@ So, the simplicity of this library is more than enough for most of my applicatio
385411
Again, this is not a defect of HTTP clients per se. A client that has many features will
386412
have a lot of code and dependencies. The question is whether you need those features for
387413
your use case or not. In my experience, most of the time I don't need them, and I
388-
always ended up doing simple HTTP requests with PHP streams. I built this library so
389-
I don't have to do that anymore.
414+
always end up doing simple HTTP requests with PHP streams. I built this library so
415+
I don't have to do that anymore for simple use cases.
416+
417+
Again, if your use case is more complex, you might want to consider using a more feature
418+
rich HTTP client. [Symfony Panther](https://github.com/symfony/panther) is my go-to
419+
recommendation for web scraping, for example.
390420

391421
### No HTTP client is just a function
392422

composer.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,21 @@
2525
"php": ">=7.4",
2626
"ext-json": "*"
2727
},
28+
"scripts": {
29+
"lint": "php-cs-fixer fix",
30+
"pr": [
31+
"php-cs-fixer fix --dry-run -vvv",
32+
"psalm --stats",
33+
"phpunit --testdox --coverage-text"
34+
]
35+
},
2836
"require-dev": {
2937
"phpunit/phpunit": "^9.4",
30-
"symfony/var-dumper": "^5.1"
38+
"symfony/var-dumper": "^5.1",
39+
"vimeo/psalm": "^4.1",
40+
"amphp/http-server": "^2.1",
41+
"amphp/http-server-static-content": "^1.0",
42+
"mnavarrocarter/amp-http-router": "^0.1.0",
43+
"friendsofphp/php-cs-fixer": "^2.16"
3144
}
3245
}

examples/class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static function authenticate(string $token): FetchApiClient
4343

4444
$body = $response->body();
4545
if ($body instanceof JsonDecoder) {
46-
return $body->parseJson();
46+
return $body->decode();
4747
}
4848
return null;
4949
};

examples/composition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
$body = $response->body();
2020
if ($body instanceof JsonDecoder) {
21-
return $body->parseJson();
21+
return $body->decode();
2222
}
2323
return null;
2424
};

examples/info.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use function MNC\Http\fetch;
4+
5+
require_once __DIR__ . '/../vendor/autoload.php';
6+
7+
$response = fetch('https://mnavarro.dev');
8+
9+
echo $response->status()->protocolVersion(); // 1.1
10+
echo $response->status()->code(); // 200
11+
echo $response->status()->reasonPhrase(); // OK
12+
echo $response->headers()->has('content-type'); // true
13+
echo $response->headers()->contains('content-type', 'html'); // true
14+
echo $response->headers()->get('content-type'); // text/html;charset=utf-8
15+
echo $response->body()->read(); // Outputs some bytes from the response body

examples/json.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
$body = $response->body();
1515

1616
if ($body instanceof JsonDecoder) {
17-
var_dump($body->parseJson()); // Dumps the json as an array
17+
var_dump($body->decode()); // Dumps the json as an array
1818
}

0 commit comments

Comments
 (0)