Skip to content

Commit e62d1dc

Browse files
author
yuzhuang
committed
first commit
1 parent aed20e7 commit e62d1dc

File tree

10 files changed

+322
-2
lines changed

10 files changed

+322
-2
lines changed

.github/workflows/tests.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [master]
6+
7+
pull_request:
8+
branches: [master]
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
tests:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
- name: Setup PHP
20+
uses: shivammathur/setup-php@v2
21+
with:
22+
php-version: 7.4
23+
24+
- name: Validate composer.json and composer.lock
25+
run: composer validate --strict
26+
27+
- name: Cache Composer packages
28+
id: composer-cache
29+
uses: actions/cache@v3
30+
with:
31+
path: vendor
32+
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
33+
restore-keys: |
34+
${{ runner.os }}-php-
35+
- name: Install dependencies
36+
run: composer install --prefer-dist --no-progress
37+
38+
- name: Run test suite
39+
run: composer run-script test

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.idea/*
2+
.idea/codeStyleSettings.xml
3+
.temp/*
4+
composer.lock
5+
/vendor/
6+
coverage.xml
7+
.phpunit.result.cache
8+
.phpunit.cache
9+
/.php-cs-fixer.php
10+
.php-cs-fixer.cache
11+
.temp/coverage.php
12+
*.swp
13+
*.swo
14+
.vscode/
15+
.DS_Store

README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,22 @@
1-
# composer-parser
2-
An parser that can parse php installed packages composer.json file
1+
# ComposerParser
2+
3+
A parser that can parse the composer.json file of installed PHP packages.
4+
5+
## Installation
6+
Require this package with composer:
7+
```bash
8+
composer require xdevor/composer-parser
9+
```
10+
11+
## Usage
12+
13+
1. parse composer.json file of installed PHP packages
14+
```php
15+
Parser::parse('the/package', 'name'); // return name of the package
16+
Parser::parse('the/package', 'not_exist_key'); // return null
17+
Parser::parse('the/package', 'authors.0.name'); // return the first author name
18+
```
19+
20+
## License
21+
22+
ComposerParser is open-sourced software licensed under the [MIT license](LICENSE.md).

composer.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"name": "xdevor/composer-parser",
3+
"description": "A parser that can parse the composer.json file of installed PHP packages.",
4+
"keywords": [
5+
"parser",
6+
"composer",
7+
"packages",
8+
"installed.json"
9+
],
10+
"license": "MIT",
11+
"authors": [
12+
{
13+
"name": "xdevor",
14+
"email": "[email protected]"
15+
}
16+
],
17+
"homepage": "https://github.com/xdevor/composer-parser",
18+
"require": {
19+
"php": "^7.4"
20+
},
21+
"autoload": {
22+
"psr-4": {
23+
"Xdevor\\ComposerParser\\": "src/"
24+
}
25+
},
26+
"autoload-dev": {
27+
"psr-4": {
28+
"Xdevor\\ComposerParser\\Tests\\": "tests/"
29+
},
30+
"files": [
31+
"./src/helpers.php"
32+
]
33+
},
34+
"scripts": {
35+
"test": "./vendor/bin/pest"
36+
},
37+
"config": {
38+
"sort-packages": true,
39+
"allow-plugins": {
40+
"pestphp/pest-plugin": true
41+
}
42+
},
43+
"require-dev": {
44+
"pestphp/pest": "^1.22"
45+
}
46+
}

phpunit.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
>
7+
<testsuites>
8+
<testsuite name="Test Suite">
9+
<directory suffix="Test.php">./tests</directory>
10+
</testsuite>
11+
</testsuites>
12+
<coverage processUncoveredFiles="true">
13+
<include>
14+
<directory suffix=".php">./app</directory>
15+
<directory suffix=".php">./src</directory>
16+
</include>
17+
</coverage>
18+
</phpunit>

src/Concerns/ParseArray.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
namespace Xdevor\ComposerParser\Concerns;
4+
5+
use ArrayAccess;
6+
7+
/**
8+
* The code here is based on/reference to Illuminate\Support/Arr.
9+
*/
10+
trait ParseArray
11+
{
12+
/**
13+
* Get an item from an array using "dot" notation.
14+
*
15+
* @param \ArrayAccess|array $array
16+
* @param string|int|null $key
17+
* @param mixed $default
18+
* @return mixed
19+
*/
20+
public static function get($array, $key, $default = null)
21+
{
22+
if (! static::accessible($array)) {
23+
return value($default);
24+
}
25+
26+
if (is_null($key)) {
27+
return $array;
28+
}
29+
30+
if (static::exists($array, $key)) {
31+
return $array[$key];
32+
}
33+
34+
if (strpos($key, '.') === false) {
35+
return $array[$key] ?? value($default);
36+
}
37+
38+
foreach (explode('.', $key) as $segment) {
39+
if (static::accessible($array) && static::exists($array, $segment)) {
40+
$array = $array[$segment];
41+
} else {
42+
return value($default);
43+
}
44+
}
45+
46+
return $array;
47+
}
48+
49+
/**
50+
* Determine whether the given value is array accessible.
51+
*
52+
* @param mixed $value
53+
* @return bool
54+
*/
55+
public static function accessible($value)
56+
{
57+
return is_array($value) || $value instanceof ArrayAccess;
58+
}
59+
60+
/**
61+
* Determine if the given key exists in the provided array.
62+
*
63+
* @param \ArrayAccess|array $array
64+
* @param string|int $key
65+
* @return bool
66+
*/
67+
public static function exists($array, $key)
68+
{
69+
if ($array instanceof ArrayAccess) {
70+
return $array->offsetExists($key);
71+
}
72+
73+
return array_key_exists($key, $array);
74+
}
75+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Xdevor\ComposerParser\Concerns;
4+
5+
trait ParseInstalledPackages
6+
{
7+
use ParseArray;
8+
9+
/**
10+
* @var string|null path of installed json file
11+
*/
12+
protected $installedJsonPath = null;
13+
14+
public function setInstalledJsonPath(?string $installedJsonPath)
15+
{
16+
$this->installedJsonPath = $installedJsonPath;
17+
}
18+
19+
protected function parsePackageComposer(string $packageName, string $key, $default = null)
20+
{
21+
return self::get($this->packageComposer($packageName), $key, $default);
22+
}
23+
24+
protected function packageComposer(string $templatePackageName): array
25+
{
26+
$packages = $this->installedPackages();
27+
$packageComposer = [];
28+
29+
foreach ($packages as $package) {
30+
if ($package['name'] === $templatePackageName) {
31+
$packageComposer = $package;
32+
}
33+
}
34+
35+
return $packageComposer;
36+
}
37+
38+
protected function installedPackages(): array
39+
{
40+
$packages = [];
41+
$installedJsonPath = $this->installedJsonPath ?? file_exists(__DIR__ . '/../../vendor/composer/installed.json')
42+
? __DIR__ . '/../../vendor/composer/installed.json'
43+
: __DIR__ . '/../../../vendor/composer/installed.json';
44+
45+
if (file_exists($installedJsonPath)) {
46+
$installed = json_decode(file_get_contents($installedJsonPath), true);
47+
$packages = $installed['packages'] ?? $installed;
48+
}
49+
50+
return $packages;
51+
}
52+
}

src/Parser.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Xdevor\ComposerParser;
4+
5+
use Xdevor\ComposerParser\Concerns\ParseInstalledPackages;
6+
7+
class Parser
8+
{
9+
use ParseInstalledPackages;
10+
11+
public function __construct(string $installedJsonPath = null)
12+
{
13+
$this->setInstalledJsonPath($installedJsonPath);
14+
}
15+
16+
public function parse(string $packageName, string $key, $default = null)
17+
{
18+
return $this->parsePackageComposer($packageName, $key, $default);
19+
}
20+
}

src/helpers.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
if (! function_exists('value')) {
4+
/**
5+
* Return the default value of the given value.
6+
*
7+
* @param mixed $value
8+
* @return mixed
9+
*/
10+
function value($value, ...$args)
11+
{
12+
return $value instanceof Closure ? $value(...$args) : $value;
13+
}
14+
}

tests/ParserTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Xdevor\ComposerParser\Parser;
4+
5+
test('It can return correct value if key exist', function () {
6+
$package = 'doctrine/instantiator';
7+
$illuminateSupportName = (new Parser())->parse($package, 'name');
8+
expect($illuminateSupportName)->toBe($package);
9+
});
10+
11+
test('It return default if key not exist', function () {
12+
$package = 'ooo/xxx';
13+
$illuminateSupportName = (new Parser())->parse($package, 'name', null);
14+
expect($illuminateSupportName)->toBe(null);
15+
});
16+
17+
test('It can return correct value if array key exist', function () {
18+
$package = 'doctrine/instantiator';
19+
$illuminateSupportName = (new Parser())->parse($package, 'license.0');
20+
expect($illuminateSupportName)->toBe('MIT');
21+
});

0 commit comments

Comments
 (0)