summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rr.build20
-rwxr-xr-xbuild.sh2
-rw-r--r--quickbuild/.build.json17
-rw-r--r--quickbuild/build.php39
-rw-r--r--quickbuild/docker/Dockerfile8
-rw-r--r--quickbuild/docker/compile.sh9
-rw-r--r--quickbuild/main.go14
-rw-r--r--quickbuild/src/Builder.php237
-rw-r--r--service/static/config.go2
9 files changed, 346 insertions, 2 deletions
diff --git a/.rr.build b/.rr.build
new file mode 100644
index 00000000..f5d171f1
--- /dev/null
+++ b/.rr.build
@@ -0,0 +1,20 @@
+{
+ "packages": [
+ "github.com/spiral/roadrunner/service/env",
+ "github.com/spiral/roadrunner/service/http",
+ "github.com/spiral/roadrunner/service/rpc",
+ "github.com/spiral/roadrunner/service/static",
+ "github.com/spiral/php-grpc"
+ ],
+ "commands": [
+ "github.com/spiral/roadrunner/cmd/rr/http",
+ "github.com/spiral/php-grpc/cmd/rr-grpc/grpc"
+ ],
+ "register": [
+ "rr.Container.Register(env.ID, &env.Service{})",
+ "rr.Container.Register(rpc.ID, &rpc.Service{})",
+ "rr.Container.Register(http.ID, &http.Service{})",
+ "rr.Container.Register(static.ID, &static.Service{})",
+ "rr.Container.Register(grpc.ID, &grpc.Service{})"
+ ]
+} \ No newline at end of file
diff --git a/build.sh b/build.sh
index 5772f9f8..36a8f198 100755
--- a/build.sh
+++ b/build.sh
@@ -2,7 +2,7 @@
cd $(dirname "${BASH_SOURCE[0]}")
OD="$(pwd)"
# Pushes application version into the build information.
-RR_VERSION=1.3.0
+RR_VERSION=1.3.1
# Hardcode some values to the core package
LDFLAGS="$LDFLAGS -X github.com/spiral/roadrunner/cmd/rr/cmd.Version=${RR_VERSION}"
diff --git a/quickbuild/.build.json b/quickbuild/.build.json
new file mode 100644
index 00000000..74b83cea
--- /dev/null
+++ b/quickbuild/.build.json
@@ -0,0 +1,17 @@
+{
+ "packages": [
+ "github.com/spiral/roadrunner/service/env",
+ "github.com/spiral/roadrunner/service/http",
+ "github.com/spiral/roadrunner/service/rpc",
+ "github.com/spiral/roadrunner/service/static"
+ ],
+ "commands": [
+ "github.com/spiral/roadrunner/cmd/rr/http"
+ ],
+ "register": [
+ "rr.Container.Register(env.ID, &env.Service{})",
+ "rr.Container.Register(rpc.ID, &rpc.Service{})",
+ "rr.Container.Register(http.ID, &http.Service{})",
+ "rr.Container.Register(static.ID, &static.Service{})"
+ ]
+} \ No newline at end of file
diff --git a/quickbuild/build.php b/quickbuild/build.php
new file mode 100644
index 00000000..63bd1460
--- /dev/null
+++ b/quickbuild/build.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Automatic roadrunner builds.
+ */
+
+use Spiral\RoadRunner\QuickBuild\Builder;
+
+require_once "src/Builder.php";
+
+// load build config
+$version = $argv[1] ?? "quickbuild";
+
+// load build config
+$config = $argv[2] ?? __DIR__ . "/.build.json";
+
+// Greeting!
+Builder::cprintf(
+ "Building <green>RoadRunner</reset> specifically for you (version: <white>%s</reset>)...\n",
+ $version
+);
+
+$builder = Builder::loadConfig($config);
+if ($builder == null) {
+ Builder::cprintf("<red>Unable to load config:</reset> %s\n", $config);
+ return;
+}
+
+$errors = $builder->configErrors();
+if (!empty($errors)) {
+ Builder::cprintf("<yellow>Found configuration errors:</reset>\n");
+ foreach ($errors as $error) {
+ Builder::cprintf("- <red>%s</reset>\n", $error);
+ }
+
+ return;
+}
+
+// Start build
+$builder->build(getcwd(), __DIR__ . '/main.go', 'rr', $version); \ No newline at end of file
diff --git a/quickbuild/docker/Dockerfile b/quickbuild/docker/Dockerfile
new file mode 100644
index 00000000..11fb5abb
--- /dev/null
+++ b/quickbuild/docker/Dockerfile
@@ -0,0 +1,8 @@
+FROM golang:latest
+
+ENV CGO_ENABLED=0
+ENV GO111MODULE=on
+
+WORKDIR /go/src/rr
+
+COPY compile.sh /go/src/rr/ \ No newline at end of file
diff --git a/quickbuild/docker/compile.sh b/quickbuild/docker/compile.sh
new file mode 100644
index 00000000..0c85124f
--- /dev/null
+++ b/quickbuild/docker/compile.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+LDFLAGS="$LDFLAGS -X github.com/spiral/roadrunner/cmd/rr/cmd.Version=${RR_VERSION}"
+LDFLAGS="$LDFLAGS -X github.com/spiral/roadrunner/cmd/rr/cmd.BuildTime=$(date +%FT%T%z)"
+
+# Verify all external modules
+go mod init
+
+# Build the binary
+CGO_ENABLED=0 go build -v -ldflags "$LDFLAGS -extldflags '-static'" -o "rr" \ No newline at end of file
diff --git a/quickbuild/main.go b/quickbuild/main.go
new file mode 100644
index 00000000..a065fe27
--- /dev/null
+++ b/quickbuild/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ "github.com/sirupsen/logrus"
+ rr "github.com/spiral/roadrunner/cmd/rr/cmd"
+ // -packages- //
+ // -commands- //
+)
+
+func main() {
+ // -register- //
+ rr.Logger.Formatter = &logrus.TextFormatter{ForceColors: true}
+ rr.Execute()
+}
diff --git a/quickbuild/src/Builder.php b/quickbuild/src/Builder.php
new file mode 100644
index 00000000..5568d725
--- /dev/null
+++ b/quickbuild/src/Builder.php
@@ -0,0 +1,237 @@
+<?php
+declare(strict_types=1);
+/**
+ * RoadRunner.
+ *
+ * @license MIT
+ * @author Anton Titov (Wolfy-J)
+ */
+
+namespace Spiral\RoadRunner\QuickBuild;
+
+final class Builder
+{
+ const DOCKER = 'spiralscout/rr-build';
+
+ /**
+ * Coloring.
+ *
+ * @var array
+ */
+ protected static $colors = [
+ "reset" => "\e[0m",
+ "white" => "\033[1;38m",
+ "red" => "\033[0;31m",
+ "green" => "\033[0;32m",
+ "yellow" => "\033[1;93m",
+ "gray" => "\033[0;90m"
+ ];
+
+ /** @var array */
+ private $config;
+
+ /**
+ * @param array $config
+ */
+ protected function __construct(array $config)
+ {
+ $this->config = $config;
+ }
+
+ /**
+ * Validate the build configuration.
+ *
+ * @return array
+ */
+ public function configErrors(): array
+ {
+ $errors = [];
+ if (!isset($this->config["commands"])) {
+ $errors[] = "Directive 'commands' missing";
+ }
+
+ if (!isset($this->config["packages"])) {
+ $errors[] = "Directive 'packages' missing";
+ }
+
+ if (!isset($this->config["register"])) {
+ $errors[] = "Directive 'register' missing";
+ }
+
+ return $errors;
+ }
+
+ /**
+ * Build the application.
+ *
+ * @param string $directory
+ * @param string $template
+ * @param string $output
+ * @param string $version
+ */
+ public function build(string $directory, string $template, string $output, string $version)
+ {
+ $filename = $directory . "/main.go";
+ $output = $output . ($this->getOS() == 'windows' ? '.exe' : '');
+
+ // step 1, generate template
+ $this->generate($template, $filename);
+
+ $command = sprintf(
+ 'docker run --rm -v "%s":/mnt -e RR_VERSION=%s -e GOARCH=amd64 -e GOOS=%s %s /bin/bash -c "mv /mnt/main.go main.go; bash compile.sh; cp rr /mnt/%s;"',
+ $directory,
+ $version,
+ $this->getOS(),
+ self::DOCKER,
+ $output
+ );
+
+ self::cprintf("<yellow>%s</reset>\n", $command);
+
+ // run the build
+ $this->run($command, true);
+
+ if (!file_exists($directory . '/' . $output)) {
+ self::cprintf("<red>Build has failed!</reset>");
+ return;
+ }
+
+ self::cprintf("<green>Build complete!</reset>\n");
+ $this->run($directory . '/' . $output, false);
+ }
+
+ /**
+ * @param string $command
+ * @param bool $shadow
+ */
+ protected function run(string $command, bool $shadow = false)
+ {
+ $shadow && self::cprintf("<gray>");
+ passthru($command);
+ $shadow && self::cprintf("</reset>");
+ }
+
+ /**
+ * @param string $template
+ * @param string $filename
+ */
+ protected function generate(string $template, string $filename)
+ {
+ $body = file_get_contents($template);
+
+ $replace = [
+ '// -packages- //' => '"' . join("\"\n\"", $this->config['packages']) . '"',
+ '// -commands- //' => '_ "' . join("\"\n_ \"", $this->config['commands']) . '"',
+ '// -register- //' => join("\n", $this->config['register'])
+ ];
+
+ // compile the template
+ $result = str_replace(array_keys($replace), array_values($replace), $body);
+ file_put_contents($filename, $result);
+ }
+
+ /**
+ * @return string
+ */
+ protected function getOS(): string
+ {
+ $os = strtolower(PHP_OS);
+
+ if (strpos($os, 'win') !== false) {
+ return 'windows';
+ }
+
+ if (strpos($os, 'darwin') !== false) {
+ return 'darwin';
+ }
+
+ return "linux";
+ }
+
+ /**
+ * Create new builder using given config.
+ *
+ * @param string $config
+ * @return Builder|null
+ */
+ public static function loadConfig(string $config): ?Builder
+ {
+ if (!file_exists($config)) {
+ return null;
+ }
+
+ $configData = json_decode(file_get_contents($config), true);
+ if (!is_array($configData)) {
+ return null;
+ }
+
+ return new Builder($configData);
+ }
+
+ /**
+ * Make colored output.
+ *
+ * @param string $format
+ * @param mixed ...$args
+ */
+ public static function cprintf(string $format, ...$args)
+ {
+ if (self::isColorsSupported()) {
+ $format = preg_replace_callback("/<\/?([^>]+)>/", function ($value) {
+ return self::$colors[$value[1]];
+ }, $format);
+ } else {
+ $format = preg_replace("/<[^>]+>/", "", $format);
+ }
+
+ echo sprintf($format, ...$args);
+ }
+
+ /**
+ * @return bool
+ */
+ public static function isWindows(): bool
+ {
+ return \DIRECTORY_SEPARATOR === '\\';
+ }
+
+ /**
+ * Returns true if the STDOUT supports colorization.
+ *
+ * @codeCoverageIgnore
+ * @link https://github.com/symfony/Console/blob/master/Output/StreamOutput.php#L94
+ * @param mixed $stream
+ * @return bool
+ */
+ public static function isColorsSupported($stream = STDOUT): bool
+ {
+ if ('Hyper' === getenv('TERM_PROGRAM')) {
+ return true;
+ }
+
+ try {
+ if (\DIRECTORY_SEPARATOR === '\\') {
+ return (
+ function_exists('sapi_windows_vt100_support')
+ && @sapi_windows_vt100_support($stream)
+ ) || getenv('ANSICON') !== false
+ || getenv('ConEmuANSI') == 'ON'
+ || getenv('TERM') == 'xterm';
+ }
+
+ if (\function_exists('stream_isatty')) {
+ return (bool)@stream_isatty($stream);
+ }
+
+ if (\function_exists('posix_isatty')) {
+ return (bool)@posix_isatty($stream);
+ }
+
+ $stat = @fstat($stream);
+ // Check if formatted mode is S_IFCHR
+ return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
+ } catch (\Throwable $e) {
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/service/static/config.go b/service/static/config.go
index ebc9af2a..eda459a7 100644
--- a/service/static/config.go
+++ b/service/static/config.go
@@ -17,7 +17,7 @@ type Config struct {
// Example: .php, .exe, .bat, .htaccess and etc.
Forbid []string
- // Serve specifies list of exceptions which must always be served by static
+ // Always specifies list of extensions which must always be served by static
// service, even if file not found.
Always []string
}