diff --git a/config/pre-built.json b/config/pre-built.json
new file mode 100644
index 00000000..8b5811e2
--- /dev/null
+++ b/config/pre-built.json
@@ -0,0 +1,5 @@
+{
+ "repo": "static-php/static-php-cli-hosted",
+ "match-pattern": "{name}-{arch}-{os}.tgz",
+ "pack-config": {}
+}
\ No newline at end of file
diff --git a/src/SPC/ConsoleApplication.php b/src/SPC/ConsoleApplication.php
index 1131ef12..f0a357fc 100644
--- a/src/SPC/ConsoleApplication.php
+++ b/src/SPC/ConsoleApplication.php
@@ -8,7 +8,9 @@ use SPC\command\BuildCliCommand;
use SPC\command\BuildLibsCommand;
use SPC\command\DeleteDownloadCommand;
use SPC\command\dev\AllExtCommand;
+use SPC\command\dev\ExtVerCommand;
use SPC\command\dev\GenerateExtDocCommand;
+use SPC\command\dev\LibVerCommand;
use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand;
@@ -48,6 +50,8 @@ final class ConsoleApplication extends Application
// Dev commands
new AllExtCommand(),
new PhpVerCommand(),
+ new LibVerCommand(),
+ new ExtVerCommand(),
new SortConfigCommand(),
new GenerateExtDocCommand(),
]
diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php
index 4f4a72f8..de529165 100644
--- a/src/SPC/builder/BuilderBase.php
+++ b/src/SPC/builder/BuilderBase.php
@@ -161,7 +161,7 @@ abstract class BuilderBase
* @throws WrongUsageException
* @internal
*/
- public function proveExts(array $extensions): void
+ public function proveExts(array $extensions, bool $skip_check_deps = false): void
{
CustomExt::loadCustomExt();
$this->emitPatchPoint('before-php-extract');
@@ -181,6 +181,10 @@ abstract class BuilderBase
$this->addExt($ext);
}
+ if ($skip_check_deps) {
+ return;
+ }
+
foreach ($this->exts as $ext) {
$ext->checkDependency();
}
diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php
index 562db372..ff280a15 100644
--- a/src/SPC/builder/Extension.php
+++ b/src/SPC/builder/Extension.php
@@ -228,6 +228,16 @@ class Extension
// do nothing, just throw wrong usage exception if not valid
}
+ /**
+ * Get current extension version
+ *
+ * @return null|string Version string or null
+ */
+ public function getExtVersion(): ?string
+ {
+ return null;
+ }
+
/**
* @throws RuntimeException
*/
diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php
index ef6ea79d..fb0a4591 100644
--- a/src/SPC/builder/LibraryBase.php
+++ b/src/SPC/builder/LibraryBase.php
@@ -182,6 +182,16 @@ abstract class LibraryBase
// do nothing, just throw wrong usage exception if not valid
}
+ /**
+ * Get current lib version
+ *
+ * @return null|string Version string or null
+ */
+ public function getLibVersion(): ?string
+ {
+ return null;
+ }
+
/**
* Get current builder object.
*/
diff --git a/src/SPC/builder/extension/swoole.php b/src/SPC/builder/extension/swoole.php
index 1e892ee5..e95969e3 100644
--- a/src/SPC/builder/extension/swoole.php
+++ b/src/SPC/builder/extension/swoole.php
@@ -10,6 +10,18 @@ use SPC\util\CustomExt;
#[CustomExt('swoole')]
class swoole extends Extension
{
+ public function getExtVersion(): ?string
+ {
+ // Get version from source directory
+ $file = SOURCE_PATH . '/php-src/ext/swoole/include/swoole_version.h';
+ // Match #define SWOOLE_VERSION "5.1.3"
+ $pattern = '/#define SWOOLE_VERSION "(.+)"/';
+ if (preg_match($pattern, file_get_contents($file), $matches)) {
+ return $matches[1];
+ }
+ return null;
+ }
+
public function getUnixConfigureArg(): string
{
// enable swoole
diff --git a/src/SPC/command/dev/ExtVerCommand.php b/src/SPC/command/dev/ExtVerCommand.php
new file mode 100644
index 00000000..0f08fa9a
--- /dev/null
+++ b/src/SPC/command/dev/ExtVerCommand.php
@@ -0,0 +1,51 @@
+addArgument('extension', InputArgument::REQUIRED, 'The library name');
+ }
+
+ public function initialize(InputInterface $input, OutputInterface $output): void
+ {
+ $this->no_motd = true;
+ parent::initialize($input, $output);
+ }
+
+ public function handle(): int
+ {
+ // Get lib object
+ $builder = BuilderProvider::makeBuilderByInput($this->input);
+
+ $ext_conf = Config::getExt($this->getArgument('extension'));
+ $builder->proveExts([$this->getArgument('extension')], true);
+
+ // Check whether lib is extracted
+ // if (!is_dir(SOURCE_PATH . '/' . $this->getArgument('library'))) {
+ // $this->output->writeln("Library {$this->getArgument('library')} is not extracted");
+ // return static::FAILURE;
+ // }
+
+ $version = $builder->getExt($this->getArgument('extension'))->getExtVersion();
+ if ($version === null) {
+ $this->output->writeln("Failed to get version of extension {$this->getArgument('extension')}");
+ return static::FAILURE;
+ }
+ $this->output->writeln("{$version}");
+ return static::SUCCESS;
+ }
+}
diff --git a/src/SPC/command/dev/LibVerCommand.php b/src/SPC/command/dev/LibVerCommand.php
new file mode 100644
index 00000000..717fd155
--- /dev/null
+++ b/src/SPC/command/dev/LibVerCommand.php
@@ -0,0 +1,60 @@
+addArgument('library', InputArgument::REQUIRED, 'The library name');
+ }
+
+ public function initialize(InputInterface $input, OutputInterface $output): void
+ {
+ $this->no_motd = true;
+ parent::initialize($input, $output);
+ }
+
+ public function handle(): int
+ {
+ // Get lib object
+ $builder = BuilderProvider::makeBuilderByInput($this->input);
+ $builder->setLibsOnly();
+
+ // check lib name exist in lib.json
+ try {
+ Config::getLib($this->getArgument('library'));
+ } catch (WrongUsageException $e) {
+ $this->output->writeln("Library {$this->getArgument('library')} is not supported yet");
+ return static::FAILURE;
+ }
+
+ $builder->proveLibs([$this->getArgument('library')]);
+
+ // Check whether lib is extracted
+ if (!is_dir(SOURCE_PATH . '/' . $this->getArgument('library'))) {
+ $this->output->writeln("Library {$this->getArgument('library')} is not extracted");
+ return static::FAILURE;
+ }
+
+ $version = $builder->getLib($this->getArgument('library'))->getLibVersion();
+ if ($version === null) {
+ $this->output->writeln("Failed to get version of library {$this->getArgument('library')}");
+ return static::FAILURE;
+ }
+ $this->output->writeln("{$version}");
+ return static::SUCCESS;
+ }
+}