devsuite/cds/CDSPackager.php
2024-05-27 00:44:14 -04:00

171 lines
4.5 KiB
PHP

<?php
namespace Crispage\DevSuite;
defined("ROOT") or die();
use \Crispage\ApplicationConfig;
use \Crispage\Utils\FileUtils;
class CDSPackager {
public DevSuite $cds;
public \Crispage $app;
public readonly string $pkgpath;
public function __construct(DevSuite $cds) {
$this->cds = $cds;
$this->app = $cds->app;
$this->pkgpath = ROOT . ApplicationConfig::get("cds.package_path");
if (!file_exists($this->pkgpath)) {
mkdir($this->pkgpath);
mkdir("$this->pkgpath/build");
mkdir("$this->pkgpath/archive");
}
}
public function getPath(string $package): string {
return "$this->pkgpath/build/$package";
}
public function initDirectory(string $package): void {
$path = $this->getPath($package);
if (file_exists($path)) FileUtils::emptyDirectory($path);
else mkdir($path);
mkdir("$path/_crispage");
mkdir("$path/user");
}
public function createInfoFile(
string $package, array $info, array $pdata, array $exts, array $files, bool $dplugins = true
): void {
$path = $this->getPath($package) . "/_crispage/package.ini";
$info["type"] = "package";
$info["package"] = $info["id"];
$info["classname"] = $info["id"];
$einfo = [];
$edata = [];
$pdata["contents"] = $files;
if ($dplugins) $pdata["plugins"] = [];
foreach ($exts as $ext) {
$einfo[$ext->id] = [
"id" => $ext->id,
"version" => $ext->version,
"package" => $ext->package,
"classname" => $ext->classname,
"type" => $ext->type
];
$edata[$ext->id] = $ext->data;
if ($dplugins && $ext->type == "plugin")
$pdata["plugins"][] = $ext->id;
}
IniWriter::write($path, [
"ExtensionInfo" => $info,
"PackageData" => $pdata,
"Extensions" => $einfo,
"ExtensionData" => $edata
]);
}
public function copyDefaultScripts(string $package): int {
$path = $this->getPath($package) . "/_crispage/scripts";
mkdir($path);
return FileUtils::copyDirectory(ROOT . "/cds/static/defaultscripts", $path);
}
public function copyCodeDirectory(string $package, string $dir): int {
$from = ROOT . $dir;
if (!file_exists($from)) return 0;
$to = $this->getPath($package) . "/user/" . basename($dir);
return FileUtils::copyDirectory($from, $to);
}
public function copyFiles(string $package, string $path): int {
$from = ROOT . $path;
$to = $this->getPath($package) . $path;
if (!file_exists($from)) return 0;
if (is_dir($from)) {
@mkdir(dirname($to), 0777, true);
return FileUtils::copyDirectory($from, $to);
}
else {
copy($from, $to);
return 1;
}
}
public function buildPackage(
string $package, array $info, array $pdata, array $exts,
array $cdirs, array $files, bool $dscripts = true, bool $dplugins = true
): string {
$info["id"] = $package;
$this->cds->log("Building package $package", "Packager");
$this->cds->log(
sprintf(
"Including %d extensions, %d code directories, %d additional files",
count($exts), count($cdirs), count($files)
)
);
$this->cds->log("Initializing package directory...");
$this->initDirectory($package);
$this->cds->log("Creating info file...");
$this->createInfoFile($package, $info, $pdata, $exts, $files, $dplugins);
if ($dscripts) {
$this->cds->log("Copying default scripts...");
$this->copyDefaultScripts($package);
}
$this->cds->log("Copying code directories...");
$count = 0;
foreach ($cdirs as $dir) {
$this->cds->log(">>> $dir");
$count += $this->copyCodeDirectory($package, $dir);
}
$this->cds->log("Copied $count files");
$this->cds->log("Copying additional files...");
$count = 0;
foreach ($files as $path) {
$this->cds->log(">>> $path");
$count += $this->copyFiles($package, $path);
}
$this->cds->log("Copied $count files");
return $this->getPath($package);
}
public function targzPackage(string $package): ?string {
$this->cds->log("Creating package archive for $package", "Packager");
$path = $this->getPath($package);
$info = @parse_ini_file("$path/_crispage/package.ini", true, INI_SCANNER_TYPED);
$id = ($info) ? ($info["Package"]["id"] ?? $package) : $package;
$version = ($info) ? ($info["Package"]["version"] ?? "0.0.0") : "0.0.0";
$arcname = "{$id}_$version.tar.gz";
$arcpath = "$this->pkgpath/archive/$arcname";
try {
$arc = new \PharData($arcpath);
$arc->buildFromDirectory($path);
$this->cds->log("Archive $arcname created");
return $arcpath;
}
catch (\Exception $e) {
$this->cds->log("Failed to create archive:\n$e");
return null;
}
}
}
?>