170 lines
5.2 KiB
PHP
Executable File
170 lines
5.2 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
if (! class_exists(ZipArchive::class)) {
|
|
echo 'This script requires zip PHP extension.' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
function checkRequiredFiles(string $pluginRootDir): void
|
|
{
|
|
if (! is_file(sprintf('%s/manifest.json', $pluginRootDir))) {
|
|
echo sprintf('Manifest file not found in "%s".', $pluginRootDir) . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
if (! is_file(sprintf('%s/main.php', $pluginRootDir))) {
|
|
echo sprintf('WARNING: Plugin does not have required main.php file in "%s".', $pluginRootDir) . PHP_EOL;
|
|
}
|
|
}
|
|
|
|
function getPluginRootDir(?string $rootDir): string
|
|
{
|
|
if ($rootDir === null) {
|
|
$rootDir = realpath(__DIR__ . '/..'); // Assuming bin/pack-plugin-custom, so root is one level up
|
|
echo sprintf('Plugin root dir not given, trying to find automatically: "%s"', $rootDir) . PHP_EOL;
|
|
} else {
|
|
if (! is_dir($rootDir)) {
|
|
echo 'Given directory does not exist.' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
$rootDir = realpath($rootDir);
|
|
}
|
|
return $rootDir;
|
|
}
|
|
|
|
function getPluginInfo(string $pluginRootDir): array
|
|
{
|
|
$manifestContent = file_get_contents($pluginRootDir . '/manifest.json');
|
|
if ($manifestContent === false) {
|
|
echo 'Could not read manifest.json.' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
$manifest = json_decode($manifestContent, true, 512, JSON_BIGINT_AS_STRING);
|
|
$error = json_last_error();
|
|
if ($error !== JSON_ERROR_NONE) {
|
|
echo sprintf('Could not decode manifest: "%s"', $error) . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
$name = $manifest['information']['name'] ?? null;
|
|
if ($name === null) {
|
|
echo 'Could not get plugin\'s name from manifest.' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
if (! preg_match('~^[a-z0-9_-]+$~', $name)) {
|
|
echo 'Plugin\'s name contains invalid characters. Valid characters are: a-z, 0-9, _ (underscore) and - (hyphen).' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
$version = $manifest['information']['version'] ?? '0.0.0';
|
|
|
|
return ['name' => $name, 'version' => $version];
|
|
}
|
|
|
|
$pluginRootDir = getPluginRootDir($argv[1] ?? null);
|
|
checkRequiredFiles($pluginRootDir);
|
|
$pluginInfo = getPluginInfo($pluginRootDir);
|
|
$pluginName = $pluginInfo['name'];
|
|
$pluginVersion = $pluginInfo['version'];
|
|
|
|
// Custom: Add version to zip name
|
|
$zipName = sprintf('%s-%s.zip', $pluginName, $pluginVersion);
|
|
|
|
// Create the zip in the plugin root directory logic
|
|
// If structure matches UBNT repo (src separate), put it one level up.
|
|
// But commonly specific plugins are just the root.
|
|
// The original script checks for README.md in parent and src dir to decide if it's in a mono-repo.
|
|
// We will simplify and default to current dir, but keep the check just in case.
|
|
|
|
if (file_exists(sprintf('%s/../README.md', $pluginRootDir)) && is_dir(sprintf('%s/../src', $pluginRootDir))) {
|
|
$zipPath = sprintf('%s/../%s', $pluginRootDir, $zipName);
|
|
} else {
|
|
$zipPath = sprintf('%s/%s', $pluginRootDir, $zipName);
|
|
}
|
|
|
|
// Delete old ZIP archive.
|
|
if (file_exists($zipPath)) {
|
|
unlink($zipPath);
|
|
}
|
|
|
|
// Install composer dependencies.
|
|
echo 'Installing composer dependencies...' . PHP_EOL;
|
|
shell_exec('composer install --classmap-authoritative --no-dev --no-interaction --quiet');
|
|
|
|
// Create the ZIP archive.
|
|
$zip = new ZipArchive();
|
|
|
|
if ($zip->open($zipPath, ZipArchive::CREATE) !== true) {
|
|
echo 'Can\'t open zip file.' . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
$files = new CallbackFilterIterator(
|
|
new \RecursiveIteratorIterator(
|
|
new \RecursiveDirectoryIterator($pluginRootDir, \RecursiveDirectoryIterator::SKIP_DOTS)
|
|
),
|
|
function (SplFileInfo $fileInfo) {
|
|
return $fileInfo->isFile();
|
|
}
|
|
);
|
|
|
|
$ignoredFiles = [
|
|
'ucrm.json',
|
|
'.ucrm-plugin-running',
|
|
'.ucrm-plugin-execution-requested',
|
|
$zipName,
|
|
'.DS_Store', // Added DS_Store
|
|
];
|
|
|
|
// Add wildcard support for ignored files if needed, but for now simple check
|
|
$ignoredDirectories = [
|
|
'.git/',
|
|
'.idea/',
|
|
'vendor/bin/', // Don't include binaries in the zip if not needed, or at least this script
|
|
'bin/', // Don't include this script itself if we don't want to distributed it (optional)
|
|
];
|
|
|
|
// We probably want to include vendor/bin/pack-plugin (original) if it was there,
|
|
// but we definitely want to exclude .git.
|
|
|
|
/** @var SplFileInfo $fileInfo */
|
|
foreach ($files as $fileInfo) {
|
|
// Get relative path
|
|
$filename = substr($fileInfo->getPathname(), strlen($pluginRootDir) + 1);
|
|
// Fix slashes for zip
|
|
$filename = str_replace('\\', '/', $filename);
|
|
|
|
if (in_array(basename($filename), $ignoredFiles, true)) {
|
|
// Simple check for filename
|
|
continue;
|
|
}
|
|
|
|
// Check ignored files by full relative path
|
|
if (in_array($filename, $ignoredFiles, true)) {
|
|
continue;
|
|
}
|
|
|
|
foreach ($ignoredDirectories as $ignoredDirectory) {
|
|
if (strpos($filename, $ignoredDirectory) === 0) {
|
|
continue 2;
|
|
}
|
|
}
|
|
|
|
// Exclude the script itself if it's inside the root
|
|
if (realpath($fileInfo->getPathname()) === realpath(__FILE__)) {
|
|
continue;
|
|
}
|
|
|
|
if (! $zip->addFile($fileInfo->getPathname(), $filename)) {
|
|
echo sprintf('Unable to add file "%s".', $filename) . PHP_EOL;
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
$zip->close();
|
|
|
|
echo sprintf('Created plugin ZIP archive: "%s"', realpath($zipPath)) . PHP_EOL;
|