--- /dev/null
+/nbproject/
+build/replicator.key
+*~
+tmp*
+*.tmp
+public/phars/*
+!public/phars/.gitkeep
+build/*
+!build/.gitkeep
+vendor
--- /dev/null
+# Replicator
+
+Packages latest PECL releases with [pharext](https://github.com/m6w6/pharext)
--- /dev/null
+#!/usr/bin/php
+<?php
+
+ini_set("display_errors", 0);
+ini_set("log_errors", 1);
+
+$procs = [];
+
+function check(&$procs) {
+ foreach ($procs as $dir => list($prc, $fds, $pkg)) {
+ $status = proc_get_status($prc);
+ if (!$status["running"]) {
+ array_map("fclose", $fds);
+ proc_close($prc);
+ if (!$status["exitcode"]) {
+ printf("%s\t%s\n", $pkg, $dir);
+ }
+ unset($procs[$dir]);
+ }
+ }
+ return count($procs);
+}
+
+while (!feof(STDIN)) {
+ if (strlen($line = rtrim(fgets(STDIN)))) {
+ if (list($pkg, $ver, $tgz) = explode("\t", $line)) {
+ $dir = basename($tgz, ".tgz");
+ $ext = sprintf("%s/../public/phars/%s/%s-%s.ext.phar", __DIR__, $pkg, $pkg, $ver);
+
+ if (!is_file($ext)) {
+ $prc = proc_open("tar -xf $tgz --transform='s#^package\\(2\\)\\{0,1\\}\\.xml$#$dir/package.xml#' 2>&1", [
+ ["pipe","r"],STDERR
+ ], $fds, __DIR__."/../build");
+ $procs[$dir] = [$prc, $fds, $pkg];
+ }
+ check($procs);
+ }
+ }
+}
+
+while (check($procs)) {
+ usleep(1000);
+}
--- /dev/null
+#!/usr/bin/php
+<?php
+
+ini_set("display_errors", 0);
+ini_set("log_errors", 1);
+
+use http\Url;
+use http\Client;
+use http\Client\Request;
+
+$procs = [];
+$client = new Client;
+$client->setOptions([
+ "timetout" => 60,
+ "connecttimeout" => 6
+]);
+
+while (!feof(STDIN)) {
+ if (strlen($url = rtrim(fgets(STDIN)))) {
+ $url = new Url($url, null, 0);
+ $ver = basename($url->path);
+ $pkg = basename(dirname($url->path));
+ $skp = sprintf("%s/../build/%s-%s.skip", __DIR__, $pkg, $ver);
+ $tgz = sprintf("%s/../build/%s-%s.tgz", __DIR__, $pkg, $ver);
+ $ext = sprintf("%s/../public/phars/%s/%s-%s.ext.phar", __DIR__, $pkg, $pkg, $ver);
+
+ if (is_file($skp)) {
+ // skip
+ } elseif (is_file($tgz) || is_file($ext)) {
+ printf("%s\t%s\t%s\n", $pkg, $ver, $tgz);
+ } else {
+ $client->enqueue(new Request("GET", $url), function($res) use($tgz, $pkg, $ver) {
+ $res->getBody()->toStream(fopen($tgz, "w"));
+ printf("%s\t%s\t%s\n", $pkg, $ver, $tgz);
+ return true;
+ });
+ }
+ }
+}
+
+while (count($client)) {
+ try {
+ $client->send();
+ } catch (Exception $e) {
+ error_log($e->getMessage());
+ }
+}
--- /dev/null
+#!/usr/bin/php
+<?php
+
+ini_set("display_errors", 0);
+ini_set("log_errors", 1);
+
+if (($sxe = simplexml_load_file("http://pecl.php.net/feeds/latest.rss"))) {
+ foreach ($sxe->item as $item) {
+ printf("%s\n", $item->link);
+ }
+}
--- /dev/null
+#!/usr/bin/php
+<?php
+
+ini_set("display_errors", 0);
+ini_set("log_errors", 1);
+
+$procs = [];
+
+function check(&$procs) {
+ foreach ($procs as $dir => list($prc, $fds, $pkg, $src, $dst)) {
+ $status = proc_get_status($prc);
+ if (!$status["running"]) {
+ array_map("fclose", $fds);
+ proc_close($prc);
+ if ($status["exitcode"] || !is_file("$dst/$dir.ext.phar")) {
+ touch("$src.skip");
+ } else {
+ printf("%s\t%s.ext.phar\n", $pkg, $dir);
+ }
+ system("rm -r $src.tgz $src");
+ unset($procs[$dir]);
+ }
+ }
+ return count($procs);
+}
+
+while (!feof(STDIN)) {
+ if (strlen($line = rtrim(fgets(STDIN)))) {
+ if (list($pkg, $dir) = explode("\t", $line)) {
+ $src = __DIR__."/../build/$dir";
+ $dst = __DIR__."/../public/phars/$pkg";
+
+ if (!is_dir($dst) && !mkdir($dst, 0777, true)) {
+ continue;
+ }
+
+ $prc = proc_open(__DIR__."/../vendor/bin/pharext -qps $src -zZd $dst 2>&1", [
+ ["pipe","r"],STDERR
+ ], $fds
+ );
+ $procs[$dir] = [$prc, $fds, $pkg, $src, $dst];
+ check($procs);
+ }
+ }
+}
+
+while (check($procs)) {
+ usleep(1000);
+}
--- /dev/null
+{
+ "require": {
+ "m6w6/pharext": "~2.0",
+ "concisecss/concise.css": "~2.1"
+ }
+}
--- /dev/null
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "2ababbd1d8bcdc4e489021e43199b3ee",
+ "packages": [
+ {
+ "name": "concisecss/concise.css",
+ "version": "v2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ConciseCSS/concise.css.git",
+ "reference": "1e093f3c26b13e08d1cb1836088fa0752db0af31"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ConciseCSS/concise.css/zipball/1e093f3c26b13e08d1cb1836088fa0752db0af31",
+ "reference": "1e093f3c26b13e08d1cb1836088fa0752db0af31",
+ "shasum": ""
+ },
+ "replace": {
+ "concisecss/concise.css": "self.version"
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Keenan Payne",
+ "email": "contact@keenanpayne.com"
+ }
+ ],
+ "description": "A lightweight front-end framework that provides functionality without the bloat.",
+ "homepage": "http://concisecss.com",
+ "keywords": [
+ "JS",
+ "css",
+ "framework",
+ "front-end",
+ "mobile-first",
+ "responsive",
+ "sass",
+ "scss",
+ "web"
+ ],
+ "time": "2015-02-17 06:23:04"
+ },
+ {
+ "name": "m6w6/pharext",
+ "version": "v2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/m6w6/pharext.git",
+ "reference": "e3ff870fe1f8a3b3eb8f55eea68f6f61d99e640c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/m6w6/pharext/zipball/e3ff870fe1f8a3b3eb8f55eea68f6f61d99e640c",
+ "reference": "e3ff870fe1f8a3b3eb8f55eea68f6f61d99e640c",
+ "shasum": ""
+ },
+ "bin": [
+ "bin/pharext",
+ "bin/pharext.pubkey"
+ ],
+ "type": "project",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "description": "Package PHP extensions as self-installing PHARs",
+ "keywords": [
+ "ext",
+ "extension",
+ "install",
+ "package",
+ "phar"
+ ],
+ "time": "2015-03-10 10:38:16"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
--- /dev/null
+../vendor/concisecss/concise.css/dist
\ No newline at end of file
--- /dev/null
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Replicator</title>
+ <link rel="stylesheet" href="concise/css/concise.min.css">
+ <link href='//fonts.googleapis.com/css?family=Droid+Sans' rel='stylesheet' type='text/css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <style>
+ body {
+ }
+ .header {
+ background: rgba(0,128,196,0.5);
+ padding: 1em 0;
+ }
+ .header h1 {
+ font-weight: bold;
+ }
+ .header h1 a {
+ text-decoration: none;
+ }
+ .header h1 big {
+ color: #fdfdfd;
+ text-shadow: grey 0 0 .1em;
+ }
+ .header h1 small {
+ color: #666;
+ text-shadow: white 0 0 .2em;
+ }
+ li {
+ list-style-type: circle;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="header">
+ <header>
+ <h1 class="container">
+ <a href="?"><big>Replicator</big></a><br>
+ <small>Replicating PECL releases as pharext packages since 2015</small>
+ </h1>
+ </header>
+ </div>
+ <div class="container">
+ <?php $packages = array_map("basename", glob("phars/*")); ?>
+
+ <?php if ($_SERVER["QUERY_STRING"] && in_array($_SERVER["QUERY_STRING"], $packages, true)) : ?>
+
+ <h2><?= $package = $_SERVER["QUERY_STRING"]; ?></h2>
+ <table class="table table-full">
+ <thead>
+ <tr>
+ <th class="text-left">Package</th>
+ <th class="text-left">Date</th>
+ <th class="text-right">Size</th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php foreach (array_reverse(glob("phars/$package/*.ext.phar*")) as $phar) : ?>
+ <tr>
+ <td class="text-left"><a href="<?= htmlspecialchars($phar) ?>"
+ ><?= htmlspecialchars(basename($phar)) ?></a>
+ </td>
+ <td class="text-left">
+ <?php
+
+ $time = time();
+ $dsec = 86400;
+ $lmod = filemtime($phar);
+ $days = [1 => "today", "yesterday"];
+ do {
+ for ($i = 1; $i < 7; ++$i) {
+ if ($lmod > $time - $dsec * $i) {
+ switch ($i) {
+ case 1:
+ echo "today";
+ break 3;
+ case 2:
+ echo "yesterday";
+ break 3;
+ default:
+ echo "$i days ago";
+ break 3;
+ }
+ }
+ }
+ echo date("Y-m-d", $lmod);
+ } while (false);
+
+ ?>
+ </td>
+ <td class="text-right">
+ <?php
+
+ $u = ["Bytes", "KB", "MB"];
+ $s = filesize($phar);
+ $l = floor(log10($s));
+ printf("%1.1F %s\n", $s/pow(10,$l-($l%3)), $u[$l/3]);
+
+ ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </tbody>
+ </table>
+ <?php else: ?>
+
+ <h2>Available Packages</h2>
+ <ul class="list-inline">
+ <?php foreach (array_map("htmlspecialchars", $packages) as $index => $package) : ?>
+ <?php $next = strtolower($package{0}); ?>
+ <?php if (isset($prev) && $next != $prev) : ?>
+
+ </ul>
+ <ul class="list-inline">
+ <?php endif; ?>
+
+ <li><a href="?<?= $package ?>"><?= $package ?></a></li>
+ <?php $prev = $next; ?>
+ <?php endforeach; ?>
+
+ </ul>
+ <?php endif; ?>
+
+ </div>
+ </body>
+</html>