当前位置: 首页 > news >正文

hyperf Rector + PHPStan 升级自动化工具开源完整流程(从 0 到持续维护)====写一个开源项目全流程

一套能直接开源落地的 Hyperf Rector + PHPStan 升级自动化工具方案,覆盖 从0搭建 ->自动升级 ->CI 门禁 ->持续维护,并给可用代码骨架。 ---1)目标定义(MVP) 先把这4件事做扎实:1. 一键执行升级流程:dry-run ->rector fix ->phpstan ->tests2. 内置 Hyperf 常见升级规则(比如注解到属性、类型补全)3. 提供可复用 CLI 命令(方便接入任意 Hyperf 项目)4. CI 自动验证,失败即阻断 ---2)推荐仓库结构 hyperf-upgrade-automation/ ├─ bin/ │ └─ hyperf-upgrade ├─ config/ │ ├─ rector.php │ └─ phpstan.neon.dist ├─ src/ │ ├─ Command/ │ │ └─ UpgradeCommand.php │ ├─ Pipeline/ │ │ ├─ UpgradePipeline.php │ │ └─ Step/ │ │ ├─ RectorDryRunStep.php │ │ ├─ RectorApplyStep.php │ │ ├─ PhpStanStep.php │ │ └─ TestStep.php │ ├─ Rector/ │ │ └─ Rule/ │ │ └─ HyperfInjectToPropertyAttributeRector.php │ └─ Report/ │ └─ JsonReportWriter.php ├─ stubs/ │ ├─ rector.php.stub │ └─ phpstan.neon.stub ├─ tests/ ├─ .github/workflows/ci.yml ├─ .github/workflows/release.yml ├─ composer.json ├─ README.md ├─ SECURITY.md └─ LICENSE ---3)0初始化mkdirhyperf-upgrade-automationcdhyperf-upgrade-automationcomposerinitcomposerrequire rector/rector phpstan/phpstan symfony/console symfony/processcomposerrequire--devphpunit/phpunit friendsofphp/php-cs-fixer ---4)核心配置(直接可用)4.1config/rector.php<?php declare(strict_types=1);use Rector\Config\RectorConfig;use Rector\Set\ValueObject\SetList;use HyperfUpgradeAutomation\Rector\Rule\HyperfInjectToPropertyAttributeRector;returnRectorConfig::configure()->withPaths([__DIR__.'/../app', __DIR__.'/../src', __DIR__.'/../config',])->withImportNames(removeUnusedImports:true)->withPhpSets(php82:true)->withSets([SetList::CODE_QUALITY, SetList::DEAD_CODE, SetList::TYPE_DECLARATION,])->withRules([HyperfInjectToPropertyAttributeRector::class,]);4.2config/phpstan.neon.dist includes: - vendor/phpstan/phpstan/conf/bleedingEdge.neon parameters: level:7paths: - app - src tmpDir: runtime/phpstan treatPhpDocTypesAsCertain:falsecheckMissingIterableValueType:truereportUnmatchedIgnoredErrors:true---5)自定义 Rector 规则(Hyperf 升级关键) 示例:把旧注释 @Inject 迁移为 PHP8属性#[Inject](基础版)。src/Rector/Rule/HyperfInjectToPropertyAttributeRector.php<?php declare(strict_types=1);namespace HyperfUpgradeAutomation\Rector\Rule;use PhpParser\Node;use PhpParser\Node\Stmt\Property;use Rector\Rector\AbstractRector;use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;use PhpParser\Node\Attribute;use PhpParser\Node\AttributeGroup;use PhpParser\Node\Name;final class HyperfInjectToPropertyAttributeRector extends AbstractRector{publicfunctiongetRuleDefinition(): RuleDefinition{returnnew RuleDefinition('Convert @Inject annotation to #[Inject] attribute on properties',[]);}publicfunctiongetNodeTypes(): array{return[Property::class];}publicfunctionrefactor(Node$node): ?Node{if(!$nodeinstanceof Property){returnnull;}$doc=$node->getDocComment();if(!$doc){returnnull;}$docText=$doc->getText();if(strpos($docText,'@Inject')===false){returnnull;}foreach($node->attrGroups as$group){foreach($group->attrs as$attr){if($this->isName($attr->name,'Inject')||$this->isName($attr->name,'Hyperf\\Di\\Annotation\\Inject')){returnnull;}}}$node->attrGroups[]=new AttributeGroup([new Attribute(new Name('Hyperf\\Di\\Annotation\\Inject')),]);$cleaned=preg_replace('/\s*\*\s*@Inject.*\R?/','',$docText)??$docText;if(trim(str_replace(['/**','*/','*'],'',$cleaned))===''){$node->setDocComment(null);}else{$node->setDocComment(new\PhpParser\Comment\Doc($cleaned));}return$node;}}---6)升级流水线命令(一次跑完)6.1主命令 src/Command/UpgradeCommand.php<?php declare(strict_types=1);namespace HyperfUpgradeAutomation\Command;use HyperfUpgradeAutomation\Pipeline\UpgradePipeline;use Symfony\Component\Console\Attribute\AsCommand;use Symfony\Component\Console\Command\Command;use Symfony\Component\Console\Input\InputInterface;use Symfony\Component\Console\Input\InputOption;use Symfony\Component\Console\Output\OutputInterface;#[AsCommand(name: 'upgrade:run', description: 'Run Hyperf upgrade automation pipeline')]final class UpgradeCommand extends Command{publicfunction__construct(private UpgradePipeline$pipeline){parent::__construct();}protectedfunctionconfigure(): void{$this->addOption('dry-run', null, InputOption::VALUE_NONE,'Only run checks, no apply');$this->addOption('project-root', null, InputOption::VALUE_REQUIRED,'Target project root', getcwd());}protectedfunctionexecute(InputInterface$input, OutputInterface$output): int{$dryRun=(bool)$input->getOption('dry-run');$root=(string)$input->getOption('project-root');return$this->pipeline->run($root,$dryRun,$output);}}6.2Pipeline(核心编排) src/Pipeline/UpgradePipeline.php<?php declare(strict_types=1);namespace HyperfUpgradeAutomation\Pipeline;use Symfony\Component\Console\Output\OutputInterface;use Symfony\Component\Process\Process;final class UpgradePipeline{publicfunctionrun(string$root, bool$dryRun, OutputInterface$output): int{$steps=$dryRun?[['Rector dry-run',['vendor/bin/rector','process','--config=config/rector.php','--dry-run']],['PHPStan',['vendor/bin/phpstan','analyse','-c','config/phpstan.neon.dist']],['Tests',['vendor/bin/phpunit']],]:[['Rector apply',['vendor/bin/rector','process','--config=config/rector.php']],['PHPStan',['vendor/bin/phpstan','analyse','-c','config/phpstan.neon.dist']],['Tests',['vendor/bin/phpunit']],];foreach($stepsas[$name,$cmd]){$output->writeln("<info>==> {$name}</info>");$p=new Process($cmd,$root, null, null,1800);$p->setTty(false);$p->run(function($type,$buffer)use($output){$output->write($buffer);});if(!$p->isSuccessful()){$output->writeln("<error>Step failed: {$name}</error>");return1;}}$output->writeln('<info>Upgrade pipeline completed.</info>');return0;}}6.3CLI 入口 bin/hyperf-upgrade#!/usr/bin/env php<?php declare(strict_types=1);use Symfony\Component\Console\Application;use HyperfUpgradeAutomation\Command\UpgradeCommand;use HyperfUpgradeAutomation\Pipeline\UpgradePipeline;require __DIR__.'/../vendor/autoload.php';$app=new Application('hyperf-upgrade-automation','0.1.0');$app->add(new UpgradeCommand(new UpgradePipeline()));$app->setDefaultCommand('upgrade:run',true);$app->run();---7)在目标 Hyperf 项目怎么用 目标项目 composer.json 加脚本:{"scripts":{"upgrade:dry":"php vendor/bin/hyperf-upgrade --dry-run --project-root=.","upgrade:apply":"php vendor/bin/hyperf-upgrade --project-root=.","qa":["vendor/bin/phpstan analyse -c config/phpstan.neon.dist","vendor/bin/phpunit"]}}---8)CI 门禁(必须) .github/workflows/ci.yml name: ci on: pull_request: push: branches:[main]jobs: upgrade-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version:"8.2"- run:composerinstall--no-interaction --prefer-dist - name: Upgrade dry run run: php bin/hyperf-upgrade --dry-run --project-root=. - name: PHPStan strict run: vendor/bin/phpstan analyse-cconfig/phpstan.neon.dist - name: Unit tests run: vendor/bin/phpunit ---9)开源发布完整流程1. LICENSE 用 MIT 或 Apache-2.02. README 必须包含: - 快速开始(3 分钟跑通) - 支持的 Hyperf/PHP 版本矩阵 - 已实现规则清单 - 升级失败回滚方式(建议gitclean branch)3. SECURITY.md 给漏洞提交流程4. 打首版 Tag:v0.1.05. GitHub Release 写明 Breaking Changes6. 接 Packagist 发布(包名示例 acme/hyperf-upgrade-automation) ---10)持续维护策略(重点) - v0.1:基础流水线 +3~5 条 Hyperf 规则 - v0.2:按 Hyperf 版本分规则集(8.x,9.x) - v0.3:自动生成升级报告(改动文件、规则命中次数) - v1.0:稳定规则 API + 插件机制(外部团队可扩展规则) 建议每次发布都带这三类内容:1. 新增规则2. 规则修复3. 已知误改场景与规避方法 ---11)最容易踩坑的地方1. Rector 直接 apply 到主分支(必须先在独立分支跑)2. PHPStan level 一次拉满导致噪音过大(先6/7 再逐步升)3. 忽略基线文件长期不清理(会掩盖真实问题)4. 自定义规则没做测试,误改业务代码5. 升级只看语法,不跑集成测试 --- 这套骨架直接能做开源首版:先发布 upgrade:run + rector/phpstan 默认配置 + 一条 Hyperf 自定义 Rector 规则 + CI 门禁,就已经有实际生产价值。
http://www.jsqmd.com/news/701951/

相关文章:

  • 2024机器学习工程师薪资趋势与技能溢价分析
  • 实测Qwen2.5-Coder-1.5B:自动生成Python代码效果展示
  • 机器学习预测区间:原理与Python实战
  • 边缘AI模型部署实战:telanflow/mps框架解析与性能优化
  • hyperf 安全基线工具箱开源完整流程(从 0 到持续维护)===写一个开源项目全流程
  • nli-MiniLM2-L6-H768效果展示:630MB模型精准识别蕴含/矛盾/中立关系
  • 如何在Windows上解锁苹果触控板的原生级体验?mac-precision-touchpad驱动完全指南
  • YOLOv8鹰眼检测数据导出教程:如何保存检测结果?
  • Java的java.lang.ModuleLayer层次结构与模块隔离在复杂应用中的组织
  • 朴素贝叶斯算法原理与实战应用指南
  • 构建混合特征机器学习流水线:TF-IDF与LLM嵌入的工程实践
  • 2026 必报!未来 5 年 “钱景” 最好的 4 个专业,缺口大、薪资高、不内卷
  • ECOC多分类方法:原理、实现与优化策略
  • 如何提交网站到谷歌网站收录? Shopify卖家必看:解决产品页不收录难题 | 零代码指南
  • 灵感画廊部署案例:树莓派5+eGPU边缘端轻量级艺术终端可行性验证
  • DeepSeek-R1-Distill-Qwen-7B在工业质检中的创新应用
  • 从零构建AI智能体:LangChain与LangGraph实战指南
  • BERT模型解析与应用:从原理到实践优化
  • 模力方舟:中国AI开源平台的自主创新之路
  • 2026屋面水平生命线品牌标杆名录:水平生命线标准、钢缆垂直生命线系统、国标垂直生命线、国标水平生命线、垂直生命线品牌选择指南 - 优质品牌商家
  • Intv_ai_mk11模型微调入门:使用自有数据提升垂直领域表现
  • QQ音乐资源解析工具:解锁音乐世界的技术利器
  • 神经网络过拟合防治:噪声注入原理与实践指南
  • ChatArena多智能体对话框架:从核心原理到实战应用
  • 新手挖洞必看!7 个合法变现渠道,从 0 到 1 轻松赚第一桶金
  • 三步打造个人知识库:如何用MOOC离线下载工具永久保存优质课程资源
  • Phi-3.5-mini-instruct C语言编程助手:指针与内存管理详解
  • Dev Container连接慢到崩溃?揭秘VSCode 2026新增“Lazy Attach”机制与预加载缓存策略(附benchmark对比图)
  • Java应用性能监控利器MyPerf4J:无侵入方法级监控实战指南
  • 2026壳寡糖厂家筛选指南:壳寡糖产品/壳寡糖企业/壳寡糖公司/壳寡糖厂家/壳寡糖排名/壳寡糖推荐/壳聚糖产品/选择指南 - 优质品牌商家