TopN 6 роки тому
батько
коміт
4dc7f634a3

+ 3 - 0
.gitignore

@@ -1,5 +1,8 @@
 /koala/vendor
 /php/midi/vendor
+/php/midi/composer.json
+/php/midi/composer.lock
 /koala/.idea
+/koala/glide.lock
 /koala-libc/.idea
 .idea

+ 1 - 1
composer.json

@@ -3,7 +3,7 @@
   "description": "A PHP Replay Client For Rdebug",
   "keywords": ["php", "rdebug", "koala", "replay", "Real Debugger"],
   "type": "library",
-  "version": "0.0.3",
+  "version": "0.0.4",
   "license": "Apache-2.0",
   "config": {
     "secure-http": false,

+ 5 - 0
doc/midi/Config.md

@@ -74,6 +74,7 @@ php:
     enable-uploader: 1
     uploader-url:
     recommend-dsl-url:
+    sync-module-url:
 ```
 
 ## 配置注解
@@ -269,5 +270,9 @@ rdebug
     - recommend-dsl-url
     
         DiPlugin 私有属性,获取 Nuwa 平台推荐的 Session 的 Url,可以忽略这个选项。
+       
+    - sync-module-url
+    
+        DiPlugin 私有属性,通过这个 Url 同步模块配置。
 
 

+ 5 - 0
doc/midi/Config_en-US.md

@@ -67,6 +67,7 @@ php:
     enable-uploader: 1
     uploader-url:
     recommend-dsl-url:
+    sync-module-url: 
 ```
 
 - `rdebug-dir`
@@ -227,4 +228,8 @@ rdebug
     - recommend-dsl-url
 
         DiPlugin private config.
+        
+    - sync-module-url
+        
+        DiPlugin private config. Use this url to sync module config.
 

BIN
output/bin/midi-diplugin.phar


BIN
output/bin/midi.phar


+ 120 - 1
php/midi/src/DiPlugin/DiConfig.php

@@ -9,6 +9,9 @@ namespace DiPlugin;
 use Midi\Config;
 use Midi\Container;
 use Midi\Exception\Exception;
+use GuzzleHttp\Client;
+use GuzzleHttp\Promise;
+use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Finder\Finder;
 
 /**
@@ -19,11 +22,13 @@ use Symfony\Component\Finder\Finder;
  */
 final class DiConfig
 {
+    const MODULE_CACHE_TIME = 43200;
+    const SYNC_TIMEOUT = 2;
 
     /**
      * Module Information
      *
-     * value will be lazy init by internal
+     * value will be lazy init by internal and update by cloud
      */
     protected static $module = [
 //        'xxx-module-name' => [
@@ -291,6 +296,29 @@ final class DiConfig
     }
 
     /**
+     * @param array $module
+     */
+    public static function updateModule(array $module)
+    {
+        foreach ($module as $name => $configs) {
+            if (isset(self::$module[$name])) {
+                foreach ($configs as $key => $value) {
+                    if ($key === 'uri') {
+                        if (!is_array($value)) {
+                            $value = [$value,];
+                        }
+                        self::$module[$name][$key] = array_unique(self::$module[$name][$key], $value);
+                    } else {
+                        self::$module[$name][$key] = $value;
+                    }
+                }
+            } else {
+                self::$module[$name] = $configs;
+            }
+        }
+    }
+
+    /**
      * copy \DiPlugin\DiConfig to \Midi\Config
      *
      * @param Config $config
@@ -319,4 +347,95 @@ final class DiConfig
 
         return $config;
     }
+
+    /**
+     * Sync Module Config from `sync-module-url`
+     */
+    public static function dailySyncModuleConfig()
+    {
+        $config = self::getMidiConfig();
+        $syncUrl = $config->get('php', 'sync-module-url');
+        if (empty($syncUrl)) {
+            return false;
+        }
+
+        $module = Container::make('dependsDir') . DR . 'module.php';
+        if (file_exists($module) && (time() - filemtime($module)) < self::MODULE_CACHE_TIME) {
+            $config = include $module;
+            if (!empty($config)) {
+                self::updateModule($config);
+                return true;
+            }
+            return false;
+        }
+
+        /** @var OutputInterface $output */
+        $output = Container::make('output');
+        $client = new Client();
+        $res = $client->request('GET', $syncUrl, ['timeout' => self::SYNC_TIMEOUT,]);
+        if ($res->getStatusCode() !== 200) {
+            $output->writeln("Sync module information from $syncUrl fail!", OutputInterface::VERBOSITY_VERBOSE);
+            return false;
+        }
+        try {
+            $resp = \GuzzleHttp\json_decode($res->getBody(), true);
+        } catch (\exception $e) {
+            $output->writeln("Sync module information from $syncUrl, response invalid json!", OutputInterface::VERBOSITY_VERBOSE);
+            return false;
+        }
+
+        /**
+         * {
+         *     'data': [
+         *         {"name": "", 'data': "[{key:..., value:...}, {key:..., value:...,}]"},
+         *     ],
+         *     'errmsg': 'success',
+         *     'errno': 0,
+         *     'total': 10,
+         * }
+         */
+        if (!isset($resp['errno']) || $resp['errno'] !== 0) {
+            $output->writeln("Sync module information from $syncUrl fail, error message: {$resp['errmsg']}!", OutputInterface::VERBOSITY_VERBOSE);
+            return false;
+        }
+
+        $syncConfig = [];
+        if ($resp['total'] > 0) {
+            foreach ($resp['data'] as $row) {
+                $moduleName = $row['name'];
+                try {
+                    $configs = \GuzzleHttp\json_decode($row['data'], true);
+                } catch (\exception $e) {
+                    continue;
+                }
+                $moduleConfig = [];
+                foreach ($configs as $config) {
+                    $key = $config['key'];
+                    $value = $config['value'];
+                    if ($key === 'language' && $value !== 'php') {
+                        continue 2;
+                    }
+                    switch ($key) {
+                        case "deploy":
+                        case "framework":
+                            $moduleConfig[$key] = $value;
+                            break;
+                        case "context":
+                            $moduleConfig['record-host'] = $value;
+                            break;
+                    }
+                }
+                if (count($moduleConfig)) {
+                    $moduleConfig['name'] = $moduleName;
+                    $syncConfig[$moduleName]  = $moduleConfig;
+                }
+            }
+            if (count($syncConfig)) {
+                self::updateModule($syncConfig);
+                file_put_contents($module, '<?php return '.var_export($syncConfig, true ).";\n");
+                return true;
+            }
+        }
+        return false;
+    }
 }

+ 2 - 2
php/midi/src/DiPlugin/Mock/MockDisf.php

@@ -337,7 +337,7 @@ HHHHH;
      */
     protected static function getDisf($increase)
     {
-        $disfConfigFile = Container::make('workingDir') . '/.midi/__disf.json';
+        $disfConfigFile = Container::make('midiWorkingDir') . '/__disf.json';
         FileUtil::createFile($disfConfigFile);
 
         try {
@@ -378,7 +378,7 @@ HHHHH;
         $disf['v_midi'] = Application::getMidiVersion();
         $disf['m_time'] = filemtime(Container::make('workingDir'));
 
-        $disfFile = Container::make('workingDir') . '/.midi/__disf.json';
+        $disfFile = Container::make('midiWorkingDir') . '/__disf.json';
         file_put_contents($disfFile, json_encode($disf, JSON_PRETTY_PRINT));
         Container::make('output')->writeln('<info>Build: <comment>' . $disfFile . '</comment></info>');
     }

+ 3 - 1
php/midi/src/DiPlugin/Plugin.php

@@ -70,6 +70,8 @@ class Plugin implements PluginInterface, EventSubscriberInterface
         Container::bind('DiPluginResDir', function () {
             return Container::make('resDir') . DR . 'diplugin';
         });
+
+        DiConfig::dailySyncModuleConfig();
     }
 
     /**
@@ -203,7 +205,7 @@ class Plugin implements PluginInterface, EventSubscriberInterface
                     // Nuwa framework copy original dist, and replace to local path
                     // Because nuwa coverage data are local path, but dist are deploy path
                     // If not replace, data will be filter by deploy path and get empty coverage data
-                    $midiDist = Container::make('workingDir') . DR . '.midi' . DR . Coverage::DIST;
+                    $midiDist = Container::make('midiWorkingDir') . DR . Coverage::DIST;
                     if (!file_exists($midiDist)) {
                         // if not exist just copy or keep
                         $content = file_get_contents($dist);

+ 1 - 2
php/midi/src/Midi/Command/ReplayerCommand.php

@@ -205,8 +205,7 @@ class ReplayerCommand extends BaseCommand
 
     public static function prepareStaticFiles()
     {
-        $reportDir = Container::make('reportDir');
-        $staticTmpDir = $reportDir . DR . 'static';
+        $staticTmpDir = Container::make('reportDir') . DR . 'static';
         if (!is_dir($staticTmpDir)) {
             $static = Container::make('templateDir') . DR . 'static';
             FileUtil::copyDir($static, $staticTmpDir);

+ 8 - 3
php/midi/src/Midi/Config.php

@@ -12,9 +12,10 @@ use Symfony\Component\Yaml\Yaml;
 class Config
 {
 
-    const MIDI_CONFIG_DIR = '.midi';
+    const MIDI_WORKING_DIR = '.midi';
+    const MIDI_CONFIG_DIR = self::MIDI_WORKING_DIR;
     const MIDI_CONFIG_FILE = 'config.yml';
-    const KOALA_PREPEND_FILE = 'prepend.php';
+    const KOALA_PREPEND_FILE = '_internal_auto_prepend.php';
 
     /**
      * @var array
@@ -130,6 +131,10 @@ class Config
             return $code = '';
         }
 
+        if ($inject === $this->getPrependFile()) {
+            throw new \Error("Filename $inject is internal use only, please change your inject filename");
+        }
+
         if (is_string($inject)) {
             $inject = [$inject,];
         }
@@ -150,6 +155,6 @@ class Config
      */
     public function getPrependFile()
     {
-        return Container::make('mockDir') . DR . self::KOALA_PREPEND_FILE;
+        return Container::make('midiWorkingDir') . DR . self::KOALA_PREPEND_FILE;
     }
 }

+ 3 - 4
php/midi/src/Midi/Console/Application.php

@@ -88,14 +88,13 @@ class Application extends BaseApplication
             return;
         }
 
-        $config = $this->midi->getConfig();
-        $this->registerCustomCommands($config);
-        $this->registerPlugins($config, $input, $output);
-
         Container::bind('app', $this);
         Container::bind('input', $input);
         Container::bind('output', $output);
 
+        $config = $this->midi->getConfig();
+        $this->registerCustomCommands($config);
+        $this->registerPlugins($config, $input, $output);
         $this->isInitialized = true;
     }
 

+ 5 - 6
php/midi/src/Midi/Factory.php

@@ -330,8 +330,10 @@ final class Factory
         self::createDir($rdebugDir);
         Container::bind('rdebugDir', $rdebugDir);
         Container::bind('workingDir', getcwd());
+        Container::bind('midiWorkingDir', function () {
+            return self::createDir(Container::make('workingDir') . DR . Config::MIDI_WORKING_DIR);
+        });
         Container::bind('rootDir', ROOT_PATH . '/');
-
         Container::bind('resDir', ROOT_PATH . '/res');
         Container::bind('templateDir', function () {
             return Container::make('resDir') . '/template/report';
@@ -345,14 +347,14 @@ final class Factory
          *   - res
          *     - replayer
          *     - depends
-         *     - static
          *   - session
-         *   - mock
          *   - log
          *   - upgrade
          *   - report
          *     - coverage
          *     - trace
+         *         - tmp
+         *     - static
          */
         Container::bind('toolResDir', function () use ($rdebugDir) {
             return self::createDir($rdebugDir . DR . 'res');
@@ -366,9 +368,6 @@ final class Factory
         Container::bind('sessionDir', function () use ($rdebugDir) {
             return self::createDir($rdebugDir . DR . 'session');
         });
-        Container::bind('mockDir', function () use ($rdebugDir) {
-            return self::createDir($rdebugDir . DR . 'mock');
-        });
         Container::bind('logDir', function () use ($rdebugDir) {
             return self::createDir($rdebugDir . DR . 'log');
         });

+ 1 - 1
php/midi/version-dev.txt

@@ -1 +1 @@
-0.0.3
+0.0.4

+ 1 - 1
php/midi/version.txt

@@ -1 +1 @@
-0.0.3
+0.0.4