PackageClass.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. namespace DistributeHelper;
  3. error_reporting(E_ALL & ~E_NOTICE);
  4. include "Utility.php";
  5. class PackageClass
  6. {
  7. private static $config = null; //全局配置信息
  8. private static $app = null; //当前安装包composer.json
  9. //当所有包都安装完毕后
  10. public static function postUpdate($vendorDir,$rootPkg,$vendorPkgs)
  11. {
  12. //初始化
  13. if(! self::initialize($vendorDir)){
  14. self::setProgressFailed('INITIALIZE_FAILED');
  15. return false;
  16. }
  17. //分发模式
  18. if( self::$config['distribute-mode'] == 'install'){
  19. self::install($vendorDir,$rootPkg,$vendorPkgs);
  20. }
  21. else{
  22. self::upgrade($vendorDir,$rootPkg,$vendorPkgs);
  23. }
  24. return true;
  25. }
  26. private static function install($vendorDir,$rootPkg,$vendorPkgs){
  27. //依赖库都已下载,默认先给个进度
  28. self::setProgressStep1(100);
  29. //逐个依赖仓库操作
  30. self::postUpdateVendorPkgs($vendorDir,$vendorPkgs);
  31. //顶层仓库操作
  32. self::postUpdateRootPkg($vendorDir,$rootPkg);
  33. //全部操作完毕
  34. self::setProgressOK(true);
  35. }
  36. private static function upgrade($vendorDir,$rootPkg,$vendorPkgs){
  37. //依赖库都已下载,默认先给个进度
  38. self::setProgressStep1(100);
  39. //逐个依赖仓库操作
  40. self::postUpdateVendorPkgs($vendorDir,$vendorPkgs);
  41. //顶层仓库操作
  42. self::postUpdateRootPkg($vendorDir,$rootPkg);
  43. //全部操作完毕
  44. self::setProgressOK(true);
  45. }
  46. /*
  47. private static function createModuleIni($vendorDir,$vendorPkgs)
  48. {
  49. //[MODULE]节点内容
  50. $content = '[MODULE]' . PHP_EOL;
  51. foreach($vendorPkgs as $i=>$pkg){
  52. if( in_array($pkg->getName(),['a/distribute-helper']) )
  53. continue;
  54. $cfgPath = pathJoin($vendorDir,$pkg->getName(),'composer.json');
  55. $data = json_decode(file_get_contents($cfgPath), true);
  56. $moduleName = $data["distribute-helper"]["module-name"];
  57. if(!$moduleName){
  58. logError('bad format. no module-name node exists.',$cfgPath);
  59. return false;
  60. }
  61. $content .= $moduleName . '=' . $pkg->getName() . ',' . $pkg->getPrettyVersion() . PHP_EOL;
  62. }
  63. //[CONFIG]节点内容
  64. //获取包信息
  65. $repoDir = dirname($vendorDir);
  66. $packageInfo = self::getPackageInfo($vendorDir,$repoDir,$pkg);
  67. $moduleConfig = $packageInfo['helper']['module-config'] ? : array();
  68. $content = '[CONFIG]' . PHP_EOL;
  69. foreach($moduleConfig as $i=>$cfg){
  70. $content .= $cfg['name'] . '=' . $cfg['value'] . PHP_EOL;
  71. }
  72. //保存文件
  73. file_put_contents(MODULEINI_PATH,$content);
  74. return true;
  75. }*/
  76. private static function postUpdateVendorPkgs($vendorDir,$vendorPkgs)
  77. {
  78. $count = count($vendorPkgs);
  79. foreach($vendorPkgs as $i=>$pkg){
  80. //获取包信息
  81. $repoDir = pathJoin($vendorDir,$pkg->getName());
  82. $packageInfo = self::getPackageInfo($vendorDir,$repoDir,$pkg);
  83. //获取当前包的module文件
  84. self::fetchModuleFiles($packageInfo);
  85. self::setProgressStep2($count,$i,1);
  86. //获取当前包的common文件
  87. self::fetchCommonFiles($packageInfo);
  88. self::setProgressStep2($count,$i,2);
  89. //拷贝当前包的config文件
  90. //self::copyConfigFiles($packageInfo);
  91. self::setProgressStep2($count,$i,3);
  92. }
  93. }
  94. private static function postUpdateRootPkg($vendorDir,$pkg)
  95. {
  96. //获取包信息
  97. $repoDir = dirname($vendorDir);
  98. $packageInfo = self::getPackageInfo($vendorDir,$repoDir,$pkg);
  99. //注册全局路径
  100. self::copyCopyFiles($packageInfo);
  101. //注册全局路径
  102. self::registerPath($packageInfo);
  103. //注册自启动程序
  104. self::registerAutorun($packageInfo);
  105. }
  106. //初始化
  107. private static function initialize($vendorDir)
  108. {
  109. //创建.distribute目录
  110. $distributeDir = pathJoin(dirname($vendorDir),'.distribute');
  111. if( !file_exists($distributeDir) ){
  112. createDirectory($distributeDir);
  113. }
  114. //设置日志文件路径
  115. if(! defined('LOG_PATH')){
  116. $logPath = pathJoin($distributeDir,'log.txt');
  117. define('LOG_PATH',$logPath);
  118. if(file_exists($logPath))
  119. unlink($logPath);
  120. }
  121. //设置进度文件路径
  122. if(! defined('PROGRESS_PATH')){
  123. $progressPath = pathJoin($distributeDir,'progress.txt');
  124. define('PROGRESS_PATH',$progressPath);
  125. if(file_exists($progressPath))
  126. unlink($progressPath);
  127. }
  128. //创建module目录
  129. $moduleDir = pathJoin(dirname($vendorDir),'module');
  130. if( !file_exists($moduleDir) ){
  131. createDirectory($moduleDir);
  132. }
  133. //解析安装包信息
  134. $composerJson = pathJoin(dirname($vendorDir),'composer.json');
  135. self::$app = json_decode(file_get_contents($composerJson), true);
  136. if(! self::$app ){
  137. logError("failed to decode " . $composerJson);
  138. return false;
  139. }
  140. //获取部署配置信息
  141. $cfgPath = pathJoin($distributeDir,'config.json');
  142. if(! file_exists($cfgPath) ){
  143. logInfo(".distribute/config.json file not exists,use default config. ");
  144. self::$config = defaultConfig();
  145. }
  146. else{
  147. self::$config = loadConfig($cfgPath);
  148. if(!self::$config){
  149. logError("Failed to load distribute config",$cfgPath);
  150. return false;
  151. }
  152. logInfo("succeeded to decode config file -- .distribute/config.json");
  153. }
  154. return true;
  155. }
  156. private static function setProgressStep1($percent)
  157. {
  158. $progress = 0.1 * $percent;
  159. file_put_contents(PROGRESS_PATH,strval($progress));
  160. }
  161. private static function setProgressStep2($total,$index,$step)
  162. {
  163. $index = $index + $step/3.0;
  164. $progress = 10 + intval(90.0 * $index / $total);
  165. file_put_contents(PROGRESS_PATH,strval($progress));
  166. }
  167. private static function setProgressFailed($msg)
  168. {
  169. file_put_contents(PROGRESS_PATH,"FAIL:" . $msg);
  170. }
  171. private static function setProgressOK($restart)
  172. {
  173. if($restart){
  174. file_put_contents(PROGRESS_PATH,"OK:NEED_RESTART");
  175. }
  176. else{
  177. file_put_contents(PROGRESS_PATH,"OK:NO_RESTART");
  178. }
  179. }
  180. //获取包相关信息
  181. private static function getPackageInfo($vendorDir,$repoDir,$pkg)
  182. {
  183. $config = self::$config;
  184. $app = self::$app;
  185. $repoName = $pkg->getName();
  186. $module_alias = $app["distribute-root"]["module-alias"];
  187. $cfgPath = pathJoin($repoDir,'composer.json');
  188. $data = json_decode(file_get_contents($cfgPath), true);
  189. $moduleName = $module_alias[$repoName] ? : $repoName;
  190. //获取安装目录
  191. $rootDir = dirname($vendorDir);
  192. $commonDir = pathJoin($rootDir,'common');
  193. $configDir = pathJoin($rootDir,'config',$moduleName);
  194. $moduleDir = pathJoin($rootDir,'module',$moduleName);
  195. //获取缓存目录
  196. $cacheDir = pathJoin($config['cache-dir'],str_replace('/','-',$pkg->getName()));
  197. //返回包的相关信息
  198. return array(
  199. "repoName" => $repoName,
  200. "version" => $pkg->getPrettyVersion(),
  201. "rootDir" => $rootDir,
  202. "cacheDir" => $cacheDir,
  203. "toolDir" => $config['tool-dir'],
  204. "ossHost" => $config['oss-host'],
  205. "moduleName" => $moduleName,
  206. "commonDir" => $commonDir,
  207. "configDir" => $configDir,
  208. "moduleDir" => $moduleDir,
  209. "helper" => $data["distribute-helper"],
  210. );
  211. }
  212. //下载包module文件
  213. private static function fetchModuleFiles($packageInfo)
  214. {
  215. $toolDir = $packageInfo['toolDir'];
  216. $cacheDir = $packageInfo['cacheDir'];
  217. $repoName = $packageInfo['repoName'];
  218. $version = $packageInfo['version'];
  219. $moduleDir = $packageInfo['moduleDir'];
  220. $ossHost = $packageInfo['ossHost'];
  221. $moduleFiles = $packageInfo['helper']['module-files'] ? : array();
  222. foreach($moduleFiles as $fileInfo){
  223. $fileName = $fileInfo['name'];
  224. //下载文件到缓存区
  225. $filePath = downloadToDir($toolDir,$ossHost,$repoName,$fileName,$cacheDir);
  226. if(! $filePath ){
  227. logError($repoName,"fetch module file failed",$fileName);
  228. return false;
  229. }
  230. logInfo("succeeded to fetch module file --",$repoName,$fileName);
  231. // 解压文件
  232. if( isZipFile($fileName) ){
  233. if(! unzipFile($toolDir,$filePath,$moduleDir)) {
  234. logError($repoName,"unzip module file failed",$fileName);
  235. return false;
  236. }
  237. }
  238. }
  239. return true;
  240. }
  241. //下载包common文件
  242. private static function fetchCommonFiles($packageInfo)
  243. {
  244. $toolDir = $packageInfo['toolDir'];
  245. $cacheDir = $packageInfo['cacheDir'];
  246. $repoName = $packageInfo['repoName'];
  247. $version = $packageInfo['version'];
  248. $commonDir = $packageInfo['commonDir'];
  249. $ossHost = $packageInfo['ossHost'];
  250. $commonFiles = $packageInfo['helper']['common-files']? : array();
  251. foreach($commonFiles as $fileInfo){
  252. $fileName = $fileInfo['name'];
  253. $target = $fileInfo['target'];
  254. //下载文件到缓存区
  255. $filePath = downloadToDir($toolDir,$ossHost,$repoName,$fileName,$cacheDir);
  256. if(! $filePath ){
  257. logError($repoName,"fetch common file failed",$fileName);
  258. return false;
  259. }
  260. logInfo("succeeded to fetch common file --",$repoName,$fileName);
  261. // 解压文件
  262. if( isZipFile($fileName) ){
  263. $targetDir = pathJoin($commonDir,$target);
  264. if(! unzipFile($toolDir,$filePath,$targetDir)) {
  265. logError($repoName,"unzip common file failed",$fileName);
  266. return false;
  267. }
  268. }
  269. }
  270. return true;
  271. }
  272. //拷贝config文件
  273. /*
  274. private static function copyConfigFiles($packageInfo)
  275. {
  276. $cacheDir = $packageInfo['cacheDir'];
  277. $repoName = $packageInfo['repoName'];
  278. $version = $packageInfo['version'];
  279. $configDir = $packageInfo['configDir'];
  280. $moduleDir = $packageInfo['moduleDir'];
  281. $configFiles = $packageInfo['helper']['config-files'] ? : array();
  282. foreach($configFiles as $fileInfo){
  283. $fileName = $fileInfo['name'];
  284. $targetName = $fileInfo['target'];
  285. $filePath = pathJoin($moduleDir,$fileName);
  286. if(! file_exists($filePath) ){
  287. logError($repoName,"config file not exists",$filePath);
  288. return false;
  289. }
  290. if(!$fileInfo['override'] && file_exists($targetPath)){
  291. logInfo($repoName,"skip copy config file",$targetPath);
  292. }
  293. $targetPath = pathJoin($configDir,$targetName);
  294. fileCopy($filePath,$targetPath);
  295. }
  296. return true;
  297. }*/
  298. //拷贝copy-files文件
  299. private static function copyCopyFiles($packageInfo)
  300. {
  301. $cacheDir = $packageInfo['cacheDir'];
  302. $repoName = $packageInfo['repoName'];
  303. $version = $packageInfo['version'];
  304. $rootDir = $packageInfo['rootDir'];
  305. $copyFiles = $packageInfo['helper']['copy-files'] ? : array();
  306. foreach($copyFiles as $fileInfo){
  307. $fileName = $fileInfo['name'];
  308. $targetName = $fileInfo['target'];
  309. $filePath = pathJoin($rootDir,$fileName);
  310. if(! file_exists($filePath) ){
  311. logError($repoName,"file not exists",$filePath);
  312. return false;
  313. }
  314. if(!$fileInfo['override'] && file_exists($targetPath)){
  315. logInfo($repoName,"skip copy file",$targetPath);
  316. }
  317. $targetPath = pathJoin($rootDir,$targetName);
  318. logInfo($repoName,"copy file ",$fileName," -> ",$targetName);
  319. fileCopy($filePath,$targetPath);
  320. }
  321. return true;
  322. }
  323. private static function registerPath($packageInfo)
  324. {
  325. }
  326. private static function registerAutorun($packageInfo)
  327. {
  328. }
  329. }