Author: Shivam Mathur (shivammathur)
Date: 2024-07-08T00:27:31+05:30
Commit:
https://github.com/php/web-downloads/commit/2dd6a7cc2c19c5ce43d840541ebf6ca5eba55871
Raw diff:
https://github.com/php/web-downloads/commit/2dd6a7cc2c19c5ce43d840541ebf6ca5eba55871.diff
Add routing and Auth
Changed paths:
A .env.example
A .gitignore
A bootstrap.php
A composer.json
A composer.lock
A public/index.php
A routes.php
A src/Auth.php
A src/IndexHandler.php
A src/PeclHandler.php
A src/PhpHandler.php
A src/Router.php
A src/Validator.php
A src/WinlibsHandler.php
A src/scripts/common.sh
A src/scripts/pecl.sh
A src/scripts/php.sh
A src/scripts/winlibs.sh
D src/pecl.sh
D src/php.sh
D src/run.php
D src/winlibs.sh
Diff:
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..e64e685
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,3 @@
+AUTH_TOKEN=
+BUILDS_DIRECTORY=
+SCRIPTS_USER=
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3d5163b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/vendor/
+.env
diff --git a/bootstrap.php b/bootstrap.php
new file mode 100644
index 0000000..54248d2
--- /dev/null
+++ b/bootstrap.php
@@ -0,0 +1,10 @@
+<?php
+
+require_once __DIR__.'/vendor/autoload.php';
+
+use Dotenv\Dotenv;
+
+$dotenv = Dotenv::createImmutable(__DIR__);
+$dotenv->load();
+
+require_once __DIR__.'/routes.php';
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..89846d4
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,16 @@
+{
+ "name": "php/web-downloads",
+ "description": "Scripts for downloads.php.net",
+ "type": "project",
+ "license": "MIT",
+ "autoload": {
+ "psr-4": {
+ "App\\": "src/"
+ }
+ },
+ "require": {
+ "php": "^8.2",
+ "vlucas/phpdotenv": "^5.6",
+ "symfony/process": "^7.1"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..6fc5314
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,542 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at
https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "4e249ba8959f6a2c56b273e97dedc5a5",
+ "packages": [
+ {
+ "name": "graham-campbell/result-type",
+ "version": "v1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GrahamCampbell/Result-Type.git",
+ "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862",
+ "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0",
+ "phpoption/phpoption": "^1.9.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "GrahamCampbell\\ResultType\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "[email protected]",
+ "homepage": "https://github.com/GrahamCampbell"
+ }
+ ],
+ "description": "An Implementation Of The Result Type",
+ "keywords": [
+ "Graham Campbell",
+ "GrahamCampbell",
+ "Result Type",
+ "Result-Type",
+ "result"
+ ],
+ "support": {
+ "issues":
"https://github.com/GrahamCampbell/Result-Type/issues",
+ "source":
"https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-11-12T22:16:48+00:00"
+ },
+ {
+ "name": "phpoption/phpoption",
+ "version": "1.9.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/schmittjoh/php-option.git",
+ "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820",
+ "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": true
+ },
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpOption\\": "src/PhpOption/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Johannes M. Schmitt",
+ "email": "[email protected]",
+ "homepage": "https://github.com/schmittjoh"
+ },
+ {
+ "name": "Graham Campbell",
+ "email": "[email protected]",
+ "homepage": "https://github.com/GrahamCampbell"
+ }
+ ],
+ "description": "Option Type for PHP",
+ "keywords": [
+ "language",
+ "option",
+ "php",
+ "type"
+ ],
+ "support": {
+ "issues": "https://github.com/schmittjoh/php-option/issues",
+ "source": "https://github.com/schmittjoh/php-option/tree/1.9.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/phpoption/phpoption",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-11-12T21:59:55+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.30.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "0424dff1c58f028c451efff2045f5d92410bd540"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
+ "reference": "0424dff1c58f028c451efff2045f5d92410bd540",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source":
"https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-05-31T15:07:36+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.30.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+ "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source":
"https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-06-19T12:30:46+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.30.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
+ "reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+
features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source":
"https://github.com/symfony/polyfill-php80/tree/v1.30.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-05-31T15:07:36+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v7.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "febf90124323a093c7ee06fdb30e765ca3c20028"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/symfony/process/zipball/febf90124323a093c7ee06fdb30e765ca3c20028",
+ "reference": "febf90124323a093c7ee06fdb30e765ca3c20028",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "[email protected]"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Executes commands in sub-processes",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v7.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-05-31T14:57:53+00:00"
+ },
+ {
+ "name": "vlucas/phpdotenv",
+ "version": "v5.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/vlucas/phpdotenv.git",
+ "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url":
"https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4",
+ "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-pcre": "*",
+ "graham-campbell/result-type": "^1.1.2",
+ "php": "^7.2.5 || ^8.0",
+ "phpoption/phpoption": "^1.9.2",
+ "symfony/polyfill-ctype": "^1.24",
+ "symfony/polyfill-mbstring": "^1.24",
+ "symfony/polyfill-php80": "^1.24"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "ext-filter": "*",
+ "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
+ },
+ "suggest": {
+ "ext-filter": "Required to use the boolean validator."
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": true
+ },
+ "branch-alias": {
+ "dev-master": "5.6-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Dotenv\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "[email protected]",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Vance Lucas",
+ "email": "[email protected]",
+ "homepage": "https://github.com/vlucas"
+ }
+ ],
+ "description": "Loads environment variables from `.env` to
`getenv()`, `$_ENV` and `$_SERVER` automagically.",
+ "keywords": [
+ "dotenv",
+ "env",
+ "environment"
+ ],
+ "support": {
+ "issues": "https://github.com/vlucas/phpdotenv/issues",
+ "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url":
"https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-11-12T22:43:29+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "^8.2"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.6.0"
+}
diff --git a/public/index.php b/public/index.php
new file mode 100644
index 0000000..f2fe731
--- /dev/null
+++ b/public/index.php
@@ -0,0 +1,7 @@
+<?php
+
+// Register the Composer autoloader...
+require_once __DIR__.'/../vendor/autoload.php';
+
+// Init
+require_once __DIR__ . '/../bootstrap.php';
diff --git a/routes.php b/routes.php
new file mode 100644
index 0000000..dbd8441
--- /dev/null
+++ b/routes.php
@@ -0,0 +1,11 @@
+<?php
+
+use App\IndexHandler;
+use App\Router;
+
+$router = new Router();
+$router->registerRoute('/', 'GET', IndexHandler::class);
+$router->registerRoute('/pecl', 'POST', PeclHandler::class, true);
+$router->registerRoute('/winlibs', 'POST', WinlibsHandler::class, true);
+$router->registerRoute('/php', 'POST', PhpHandler::class, true);
+$router->handleRequest();
diff --git a/src/Auth.php b/src/Auth.php
new file mode 100644
index 0000000..26dd4b6
--- /dev/null
+++ b/src/Auth.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace App;
+
+class Auth
+{
+ public function authenticate(): bool
+ {
+ $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
+ $authToken = str_replace('Bearer ', '', $authHeader);
+
+ return $authToken === $_ENV['AUTH_TOKEN'];
+ }
+}
diff --git a/src/IndexHandler.php b/src/IndexHandler.php
new file mode 100644
index 0000000..c15db73
--- /dev/null
+++ b/src/IndexHandler.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace App;
+class IndexHandler
+{
+ public function handle(): void
+ {
+ echo 'Welcome!';
+ }
+}
\ No newline at end of file
diff --git a/src/PeclHandler.php b/src/PeclHandler.php
new file mode 100644
index 0000000..0310c1d
--- /dev/null
+++ b/src/PeclHandler.php
@@ -0,0 +1,9 @@
+<?php
+
+class PeclHandler
+{
+
+ public function handle()
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/PhpHandler.php b/src/PhpHandler.php
new file mode 100644
index 0000000..61ffbc3
--- /dev/null
+++ b/src/PhpHandler.php
@@ -0,0 +1,9 @@
+<?php
+
+class PhpHandler
+{
+
+ public function handle()
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Router.php b/src/Router.php
new file mode 100644
index 0000000..7d16d5f
--- /dev/null
+++ b/src/Router.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace App;
+
+class Router
+{
+ private array $routes = [];
+ private Auth $auth;
+
+ public function __construct()
+ {
+ $this->auth = new Auth();
+ }
+
+ public function registerRoute(string $path, string $method, string
$handler, bool $requiresAuth = false): void
+ {
+ $this->routes[$method][$path] = [
+ 'handler' => $handler,
+ 'requiresAuth' => $requiresAuth
+ ];
+ }
+
+ public function handleRequest(): void
+ {
+ $path = $_SERVER['REQUEST_URI'];
+ $method = $_SERVER['REQUEST_METHOD'];
+
+ $allowedMethods = [];
+
+ foreach ($this->routes as $registeredMethod => $paths) {
+ if (isset($paths[$path])) {
+ $allowedMethods[] = $registeredMethod;
+ }
+ }
+
+ if (isset($this->routes[$method][$path])) {
+ $route = $this->routes[$method][$path];
+
+ if ($route['requiresAuth'] && !$this->auth->authenticate()) {
+ http_response_code(401);
+ echo 'Unauthorized';
+ return;
+ }
+
+ $handler = $route['handler'];
+ (new $handler)->handle();
+ } elseif (!empty($allowedMethods)) {
+ http_response_code(405);
+ echo 'Method Not Allowed. Allowed methods: ' . implode(', ',
$allowedMethods);
+ } else {
+ http_response_code(404);
+ echo 'Not Found';
+ }
+ }
+}
diff --git a/src/Validator.php b/src/Validator.php
new file mode 100644
index 0000000..345ac19
--- /dev/null
+++ b/src/Validator.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace App;
+
+class Validator
+{
+ protected array $errors = [];
+
+ public function validate(array $data, array $rules): bool
+ {
+ $this->errors = [];
+
+ foreach ($rules as $field => $ruleString) {
+ $rulesArray = explode('|', $ruleString);
+ foreach ($rulesArray as $rule) {
+ $ruleParts = explode(':', $rule);
+ $ruleName = $ruleParts[0];
+ $ruleValue = $ruleParts[1] ?? null;
+
+ if (!$this->$ruleName($data[$field] ?? null, $ruleValue)) {
+ $this->errors[$field][] = $this->getErrorMessage($field,
$ruleName);
+ }
+ }
+ }
+
+ return empty($this->errors);
+ }
+
+ public function errors(): array
+ {
+ return $this->errors;
+ }
+
+ protected function required($value): bool
+ {
+ return !is_null($value) && $value !== '';
+ }
+
+ protected function url($value): bool
+ {
+ return filter_var($value, FILTER_VALIDATE_URL) !== false;
+ }
+
+ protected function string($value): bool
+ {
+ return is_string($value);
+ }
+
+ protected function getErrorMessage($field, $rule): string
+ {
+ $messages = [
+ 'required' => "The $field field is required.",
+ 'url' => "The $field field must be a valid URL.",
+ 'string' => "The $field field must be a string.",
+ ];
+
+ return $messages[$rule] ?? "The $field field has an invalid value.";
+ }
+}
diff --git a/src/WinlibsHandler.php b/src/WinlibsHandler.php
new file mode 100644
index 0000000..8af13c8
--- /dev/null
+++ b/src/WinlibsHandler.php
@@ -0,0 +1,9 @@
+<?php
+
+class WinlibsHandler
+{
+
+ public function handle()
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/pecl.sh b/src/pecl.sh
deleted file mode 100644
index 544ce32..0000000
--- a/src/pecl.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env bash
-
-# Fetch PECL extension builds
diff --git a/src/run.php b/src/run.php
deleted file mode 100644
index 215a1fb..0000000
--- a/src/run.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-
-// TODO: Implement the run function
\ No newline at end of file
diff --git a/src/scripts/common.sh b/src/scripts/common.sh
new file mode 100644
index 0000000..b9c4c94
--- /dev/null
+++ b/src/scripts/common.sh
@@ -0,0 +1,10 @@
+function fetch_artifact() {
+ local filepath=$1
+ local url=$2
+ local token=$3
+ if [[ "$url" == *api.github.com* ]]; then
+ curl -H "Accept: application/vnd.github+json" -H "Authorization: token
$token" -L -o "$filepath" "$url"
+ else
+ curl -L -o "$filepath" "$url"
+ fi
+}
\ No newline at end of file
diff --git a/src/scripts/pecl.sh b/src/scripts/pecl.sh
new file mode 100644
index 0000000..222a175
--- /dev/null
+++ b/src/scripts/pecl.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+# TODO: Fetch PECL builds
diff --git a/src/php.sh b/src/scripts/php.sh
similarity index 100%
rename from src/php.sh
rename to src/scripts/php.sh
diff --git a/src/winlibs.sh b/src/scripts/winlibs.sh
similarity index 100%
rename from src/winlibs.sh
rename to src/scripts/winlibs.sh