后端Web框架【免费下载链接】fountain一个用于服务器应用开发的综合工具库。 - 零配置文件 - 环境变量和命令行参数配置 - 约定优于配置 - 深刻利用仓颉语言特性 - 只需要开发动态链接库fboot负责加载、初始化并运行 - 覆盖服务器应用开发的各种场景项目地址https://gitcode.com/Cangjie-SIG/fountain点击查看免费下载本文面向已经用仓颉 SDK 1.0.x fountain 1.0.x 跑起来的老项目。核心目标只有一个在不换技术栈、不重写业务的前提下把项目的 fountain 依赖版本升级到「与当前 fboot 同版」并完成「环境 → 依赖 → 包名 → API → 配置 → 验证」的完整升级闭环。读完本文你将掌握三条升级信号识别、按模块依赖的新式cjpm.toml写法、migrate_fountain_imports.py机械替换 import 的用法、新旧 API 硬差异核对表以及三平台启动脚本的对齐要点能独立完成一次可回退、可交付的版本升级。一、升级总览这是哪类任务风险在哪里旧版本项目升级技能工作流 I与「技术栈转换」「仓颉项目改造」等工作的本质区别在于这里不做架构重写只做版本对齐。升级对象是「已经跑起来的老项目」产出默认是同一个项目就地升级保留 git 历史只有用户明确要求时才重建骨架、在新目录产出。值得注意的是版本升级属于高风险改动交付门禁TDD / 全量回归 / 冒烟 / 提交 / 建 tag需要按 交付全流程规范 执行其中第 4 节专门强调「高风险改动做针对性回归」——依赖升级、公共 API 变更、配置语义变化都要逐个覆盖受影响模块与调用方本流程正是这类改动的典型代表。整体执行顺序是硬性的不能打乱环境对齐 → 现状评估 → 依赖与骨架升级 → 代码适配import → 编译驱动 → 配置与脚本升级 → 回归 冒烟 交付跳过前两步直接改代码会得到一堆假错误详见本文第八节常见问题。二、先决判断三条信号任一命中即走本流程动手之前先确认项目是否真的属于「旧版本」形态。对照下表任意一条命中就进入本升级流程信号1.0.x 时代升级前当前升级目标根 cjpm.toml 的 fountain 依赖fountain {path ../}或fountain {git ..., branch master}聚合根一包fountain::f_mvc fboot 版本等按模块依赖模块 cjpm.toml 的cjc-version1.0.4SDK 1.0.x1.2.0以目标版本仓库 / fboot 新建模板为准源码 importimport fountain.mvc.*聚合根、import f_mvc.*扁平模块名import fountain::f_mvc.*补充判据启动脚本只有一个boot.sh、库搜索路径后插详见第六节根目录没有.modules说明当时中心仓发布尚未出现。从 1.1.x / 1.2.x 起步的项目流程相同、差异更小也走本流程只是逐条核对的差异点更少。三、第 1 步环境对齐先做否则后面全是假错误升级前的环境准备是整个流程的地基分为三步安装 / 配置当前 fboot工作流 Afboot version拿到目标版本号x.y.z—— 这个版本号同时是「待写入的依赖版本」和「后续查询文档的版本」。需要注意fboot version是查询命令输出形如fountain(x.y.z)而fboot version x.y.z [...]才是升版 / 打 tag 的管理命令两者千万别混用。换 SDK / stdx老项目模块写的是cjc-version 1.0.4当前 fountain 模块是1.2.0见仓库根 cjpm.toml 的[package]段。用旧 SDK 编译会在依赖解析 / 语法上先失败。需要把本机 SDK 与 stdx 切到与 fboot 匹配的版本版本号以目标版本仓库的各cjpm.toml与fboot module新建模块模板写出的值为准并配好CANGJIE_STDX_PATH/CANGJIE_STDX_DYNAMIC_PATH—— 因为[target]段的path-option要用到它们。验收fboot version正常cjc -v显示新 SDK此时先不要动项目。环境细节平台选择、fboot 安装、动态库搜索顺序等参见 环境准备与 fboot 安装。其中的高频坑值得提前知晓~/.bashrc里 cangjie 环境把安装目录的libs/fboot放进了LD_LIBRARY_PATH且位置在应用自身产物目录之前而这些.so没有 SONAME运行时会按名字取搜索路径里第一个同名库——这是后面「undefined symbol」类报错的主要来源。四、第 2 步现状评估只读先出清单再动手升级前先做只读盘点把后续要用的信息全部记录下来。这是整个流程的输入清单缺失会导致升级过程反复返工维度看什么记录什么后续要用依赖形态根 cjpm.toml[dependencies]老写法聚合根 path/git、第三方依赖清单、members模块清单各模块 cjpm.tomlcjc-version、output-type必须仍是dynamic、version代码范围import fountain.*/import f_*的去重模块名升级后要声明的fountain::f_xxx直接依赖清单配置清单boot.sh的export与fboot build参数老配置项名后面逐个核对是否仍存在第三方依赖驱动 / 字符集等老写法git 依赖居多与新写法的对照见第五节 4.3测试*_test.cj的位置与写法迁移范围Test/TestCase/Assert写法不变推荐用以下命令快速完成盘点fboot version grep -n fountain cjpm.toml # 依赖形态 grep -rn import fountain\.\|import f_ --include*.cj . # 旧 import 形态哪几个模块 grep -n export boot.sh # 老配置项清单第 2 行命令的产出——去重后的模块名列表——将直接决定升级后[dependencies]里要声明哪些fountain::f_xxx。五、第 3 步依赖与骨架升级5.1 推荐就地升级保留 git 历史动手前确认git status干净并按用户项目规范开分支如feature/upgrade-1.3。根 cjpm.toml的改造删掉聚合根依赖fountain {path/git}改为按模块声明第 4 节记录的模块fountain::f_mvc fboot 版本只列直接使用的传递依赖交给 cjpm 自动解析.modules的[detention]段模块不能版本依赖。[workspace] version保持members保持[profile.build] incremental true保留[target.*]段对齐bin-dependencies.path-option要同时含${CANGJIE_STDX_DYNAMIC_PATH}与${CANGJIE_STDX_PATH}旧产物通常只写了前者。对照仓库根 cjpm.toml 的[target.x86_64-unknown-linux-gnu.bin-dependencies]即可看到当前规范形态。模块 cjpm.tomlcjc-version改成当前值version同步output-type dynamic不动不要在模块里写依赖。可以参考 fdemo/user/cjpm.toml 的模块形态只有[package]段没有[dependencies]——workspace 根声明的依赖对所有成员可见。对照模板再动手在临时目录跑一次fboot workspace tmpfboot module tmpmod拿它生成的 cjpm.toml 逐段对照自己的项目避免漏项。产物样例包括 workspace 根的f_base/f_version依赖注入、[target]段补齐等见 workspace / 模块 / 依赖产物样例与校验。该文档还给出了依赖的四种写法升级后应优先采用中心仓版本依赖[dependencies] # 1) 中心仓版本依赖默认选择 fountain::f_mvc 1.3.16 # 2) 本地路径依赖fountain 源码在本地、或模块未发布时 fountain::f_mvc {path ../fountain/f_mvc} # 3) git 依赖引用仓库 fountain {git https://gitcode.com/Cangjie-SIG/fountain.git, branch master} # 4) 带属性的第三方依赖output-type 等 postgres_driver {version 0.0.3, output-typedynamic}5.2 可选重建骨架与用户确认后项目结构混乱、或用户想顺带对齐fdemo分层时才走这条路径fboot workspace 新目录→fboot module 名→ 源码git mv搬入与新项目搭建工作流 H 的搬移步骤一致。除用户明确要求默认不做——重建会打散 git 历史、放大改动面。六、第 4 步代码适配编译驱动逐条修代码适配是本流程工作量最大的一步原则是先用脚本消掉大部分机械错误再靠编译错误逐个击破 API 差异。6.1 第一步机械替换 import 包名用脚本别手改仓库提供了专门的迁移脚本 migrate_fountain_imports.py用法python skill-root/scripts/migrate_fountain_imports.py 项目根 # 预演只报告 python skill-root/scripts/migrate_fountain_imports.py 项目根 --apply # 落盘脚本覆盖两种老写法与宏包子包依据是两版的 shim 声明旧src/mvc/mvc.cj是package fountain.mvcpublic import f_mvc.*新版是package fountain::fountain.mvcpublic import fountain::f_mvc.*可对照仓库 src/mvc/mvc.cj 验证老写法1.0.x新写法依据src/seg/seg.cjimport fountain.mvc.*import fountain::f_mvc.*旧package fountain.mvcpublic import f_mvc.*→ 新package fountain::fountain.mvcpublic import fountain::f_mvc.*import fountain.mvc.macros.*import fountain::f_mvc.macros.*同上macro package子包import f_mvc.*旧扁平模块名import fountain::f_mvc.*旧f_mvc/src/*.cj是package f_mvc新是package fountain::f_mvcimport fountain.data.macros.*import fountain::f_data.macros.*src/data/macros/macros.cj脚本的工程细节值得了解便于判断它能否处理你的项目默认 dry-run只报告将改写的行、不改文件确认后加--apply落盘落盘前应确保git status干净便于git diff复核、git checkout --回退只改import行通过IMPORT_RE正则匹配import [修饰符] 模块.子包…[.*]支持public/protected/internal/private修饰符前缀两类命中import fountain.seg...走「聚合根」改写AGGREGATE字典把seg映射到模块名如mvc → f_mvcimport f_模块...走「扁平模块名」改写MODULES集合覆盖当前全部库模块两类人工确认项未识别的fountain.*/f_*import会提示、非 import 行里出现的fountain.seg完全限定引用如fountain.orm.DatabasePool会被列进「需人工确认」清单——这类引用脚本不改要人工处理跳过target、.git、.build-logs、node_modules等目录跳过非 UTF-8 文本支持 UTF-8 BOM。落盘后复验grep -rn import fountain\.\|import f_ --include*.cj . # 应无输出这次替换单独一个提交便于整体回退。6.2 第二步fboot build逐条修编译错误两版对照查证fboot build # 从第一个错误开始修改完再跑滚动推进 python skill-root/scripts/fountain_lookup.py --version 老项目在用版本 search 关键词 --module f_mvc # 旧版行为 python skill-root/scripts/fountain_lookup.py --version 目标版本 search 关键词 --module f_mvc # 新版行为这里有几个关键的版本查证方法论老版本号怎么取读老项目所依赖的 fountain 源码里f_version/src/FountainVersion.cj的Version常量老项目的 fountain 依赖正是指向该源码的 path / git 依赖例如1.0.48。1.0.x 的 tag 名与版本标记不总相等实测release-1.0.49~release-1.0.54的FountainVersion标记都还是1.0.48。查旧版时出现⚠ 版本不一致先分辨若是「tag 名 ≠ 标记」属常态内容以切到的 tag 为准若是真切错了版本按提示重切。--version X.Y.Z只切技能目录下的文档副本同一副本先后切两版即完成对照不动任何项目源码输出头部有版本标注。语法 / 关键字 / stdx 问题要加载cangjie-coding与cangjie-doc-lookup技能查证不要凭记忆猜 API。6.3 已知硬差异先按表核对再用两版对照确认细节以下差异表是老 → 新升级中最常踩中的 API 变化建议先在代码里按表核对再用两版对照工具确认细节差异老 → 新证据包名 / importfountain.mvc.*/f_mvc.*→fountain::f_mvc.*第 6.1 节用脚本AOP 参数对象InvocationFuncInfoclass→struct值类型、不可变、每层调用一个实例f_aspect/src/QualifiedFuncInfo.cj、f_aspect/README.md连接池DatabasePool老代码里是fountain.orm.wrap.DatabasePool迁到fountain::f_dbpoolf_orm.wrap.DatabasePool变成重导出init(driver, ds)已删除init(driver, options!)改为显式传 urlConnectionException归属 f_dbpoolf_dbpool/README.md、f_orm/src/wrap/DatabasePool.cj、f_orm/README.md第三方依赖写法charset4cj {git ...}→ 中心仓版本依赖cangjie_tpc::charset4cj 1.0.5opengauss 旧 git 驱动 → 示例改用postgres_driver {version 0.0.3, output-type dynamic}根 cjpm.toml、fdemo/cjpm.toml 注释新模块可用可选换用f_rpc/f_protocol/f_codec/f_dbpool/f_store/f_uring/f_health/f_bloom/f_crypto/f_egraphfountain_lookup.py modules选型见 模块索引与选型fboot 子命令新增pub/randhex/shutdown等fboot version是查询fboot version x.y.z [...]才是升版 / 打 tagf_app/README.md 第 3 节聚合根 import老聚合根import fountain.*系不再作为新代码路线新版聚合根叫fountain::fountain.*只作过渡shim冻结不演进停在旧模块集合没有 f_codec / f_rpc / f_dbpool / f_store / f_uring 等src/ 目录对比 1.0.54 与当前的 shim 集合其中连接池迁移值得展开说明见 f_dbpool/README.mdDatabasePool/PooledConnection从fountain::f_orm.wrap迁出到独立的fountain::f_dbpool模块只依赖f_base、f_log、f_pool不读任何配置项——池参数与连接串一律由调用方显式给出f_orm依赖f_dbpool并在f_orm/src/wrap/DatabasePool.cj通过public import fountain::f_dbpool.DatabasePool重导出因此fountain::f_orm.wrap.DatabasePool这个写法仍然可用且与fountain::f_dbpool.DatabasePool是同一个类型原init(driver: Driver, ds: Datasource)12 个参数取自ORMConfig的orm_databasePool*配置项已删除f_orm的NamedDatasource自己读ORMConfig后调用新构造器其它调用方按同样办法显式传参原init(driver: Driver, options!)改为构造器 3url显式传入不再从ORMConfig.getUrl取抛出的ConnectionException是fountain::f_dbpool.ConnectionException直接继承f_base.BaseException与fountain::f_orm.exception.ConnectionException是两个独立声明捕获连接池异常要用前者。AOP 参数对象变化同样有源码依据老版本的InvocationFuncInfo是class新版本在 f_aspect/src/QualifiedFuncInfo.cj 中定义为public struct——值类型、不可变、按值传递每次调用各一个实例因此并发调用之间不可能共享同一个参数槽。6.4 测试适配Test/TestCase/Assert来自std.unitteststd.unittest.testmacro写法不变用例随包迁移即可cjpm test跑模块用例fboot test [PATH] --dylibPattern...跑应用整体以PATH/test/cjpm.toml覆盖后 build run缺--dylibPattern会抛BootException详见 f_app/README.md老项目若把测试放在业务包里保持原位置即可别顺手重构。七、第 5 步配置与启动脚本升级老项目通常只有 Linux 版boot.sh需要按 启动脚本生成指南 生成 / 对齐三平台脚本模板取自 fdemo 与frpcdemo。老脚本 → 新脚本的必改点点老脚本新脚本库搜索路径LD_LIBRARY_PATH$LD_LIBRARY_PATH:$(find ...)后插工程自己的release/*子目录前插否则命中安装目录旧副本 ⇒undefined symbol平台只有 Linux 版boot.sh/boot-macos.sh/boot-win-gitbash.sh三份同步编译期配置靠环境变量fboot build --keyvalue嵌入产物运行期exports()保留Windows无--keyvalue传参、cygpath -w转 stdx 路径库路径前插的完整写法可以参考 fdemo/boot.sh 的exports()先用find $target_path/release -name lib*.so -printf %h\n扫出工程自己的全部库目录含从中心仓拉来、产物在target/名字/release/嵌套目录里的驱动再export LD_LIBRARY_PATH$extra_libs$LD_LIBRARY_PATH。fdemo 脚本里的注释记录了真实踩坑安装目录libs/fboot下的.so没有 SONAME链接器按文件名先找到旧副本表现为「新符号明明在自建库里有却报 undefined symbol」。三平台的关键差异详见 启动脚本生成指南 第 3 节Linux/WSL动态库搜索变量是LD_LIBRARY_PATH前置find可用-printf %h\n、grep -P可用macOS用DYLD_FALLBACK_LIBRARY_PATHSIP 会剥掉DYLD_LIBRARY_PATHBSD find 无-printf用find -type d、grep -EWindows git-bash库搜索变量是PATH前置stdx 目录也要进 PATH配置用拼--keyvalue参数传fboot run值里不要套引号stdx 路径用cygpath -w转 Windows 形式cjpm是原生进程只认 Windows 路径编译后若库分散在release/*/cp release/*/*.dll release/libs/后统一进 PATH日志文件名不能用:MSYS 会换成私用区字符改用-。配置项逐个核对是本节的核心动作清单来自老boot.sh的export包括orm_*含orm_useThirdPartyPool/orm_noPool/orm_useStdPool/orm_databasePool*、mvc_*、logger_*、切面配置。是否存在、默认值、生效方式一律以目标版本的模块 README 为准——旧项可能被删除或改语义。比如 fdemo/boot.sh 里的orm_databasePoolMaxWaiting默认 30000 毫秒池耗尽且调用方用无限等待取连接时的等待上限配 0 表示真无限等待就是新增项老项目里没有而不确定保留意义的项写进升级报告交给用户不要凭老注释沿用。fdemo的三份脚本还是「运行期exports() 编译期--keyvalue」两种配置载体的对照样本Linux/macOS 版在build()里用export传连接串与密钥或注释掉的fboot build $target_path环境变量写法Windows 版则全部拼成args$args --xxxyyy传给fboot build $target_path $args。注意敏感信息连接串 / 密钥只在build编译期嵌入或运行期环境变量提供不要写死在脚本里。八、第 6 步回归 冒烟 交付针对性回归第 6.3 / 第 7 节列出的老版本行为变化逐条核对每项都要有用例或手工验证再跑全量回归cjpm test/fboot test。回归失败先修实现再改用例与用户确认后。冒烟./boot.sh build→./boot.sh run长驻进程交给用户或后台跑关键路径HTTPcurl/ RPC 调一次 日志无异常堆栈。交付按 交付全流程规范 第 6 / 7 节提交与建 tag。提交粒度要细便于回退与 review依赖与 cjpm.toml 一处、机械 import 重写一处、API / 配置适配按模块各一处。升级报告给用户旧 → 新对照表依赖 / 包名 / API / 配置项 / 脚本 行为变化 未适配项 启动方式。交付门禁的完整要求提交前fboot build通过 单元测试全绿 全量回归通过 冒烟通过tag 前置条件为本轮提交已推送、工作区干净、测试全部通过附注 tag 必须-a都在 交付全流程规范 中有详细说明。九、常见问题FAQ只改版本号能跑吗不能。顺序必须是「环境 → 依赖与 cjpm.toml → import 包名 → 编译驱动修 API → 配置与脚本」跳过前两步会得到一堆假错误。聚合根依赖还能留吗fountain {path ../}配import fountain::fountain.mvc.*在本地仍可用但 shim 冻结、没有新模块、也不随模块演进 ⇒ 新代码统一用按模块依赖fountain::f_*fountain::f_*import。这一点从仓库 src/ 的 shim 集合可以印证当前 shim 只覆盖app/aspect/base/bean/collection等旧模块集合没有f_codec/f_rpc/f_dbpool/f_store/f_uring等新模块。cjc-version报不匹配SDK 没换到位回到第三节第 1 步。错误太多不要慌先完成 6.1 的机械替换能把大部分 import 错误一次消掉再逐模块fboot build编译错误定位流程加载cangjie-coding技能。老项目自带启动脚本一坨 export先把「库路径前插 三平台 编译期参数」三件事做对配置项是否保留按第七节核对别整段照搬。不要顺手重构升级提交里只放升级相关的改动包名、API、配置业务逻辑的改进另开分支 / 另开提交。十、升级后项目形态速览对照示例升级完成后的标准形态可以直接对照仓库现成样例确认根 cjpm.toml[dependencies]全部是fountain::f_xxx按模块声明可参考仓库根 cjpm.toml 的完整形态含cangjie_tpc::charset4cj 1.0.5这类中心仓第三方依赖[package]段cjc-version 1.2.0[target.*.bin-dependencies]的path-option同时含两个 stdx 路径变量模块 cjpm.tomloutput-type dynamic、cjc-version与version对齐参考 fdemo/user/cjpm.tomlimport全部fountain::f_xxx.*形态启动脚本三平台齐全、库路径前插、配置按模块 README 核对过fountain 依赖版本 当前 fboot 版本以f_version/src/FountainVersion.cj的Version常量与fboot version输出为准当前仓库标记为1.3.16见 f_version/src/FountainVersion.cj。至此一次完整的「SDK 1.0.x fountain 1.0.x → 与当前 fboot 同版」升级闭环就完成了老项目从聚合根一包的旧世界平滑迁入按模块依赖、包名统一、配置语义清晰的新世界且全程保留 git 历史、可分步回退。赞分享后端Web框架【免费下载链接】fountain一个用于服务器应用开发的综合工具库。 - 零配置文件 - 环境变量和命令行参数配置 - 约定优于配置 - 深刻利用仓颉语言特性 - 只需要开发动态链接库fboot负责加载、初始化并运行 - 覆盖服务器应用开发的各种场景项目地址https://gitcode.com/Cangjie-SIG/fountain点击查看免费下载相关推荐PyTorch Image Models版本升级从0.6.x到1.0迁移指南PyTorch Image Models版本升级从0.6.x到1.0迁移指南 PyTorch Image Modelstimm 作为深度学习领域最受人工智能计算机视觉深度学习预训练为什么选择OpenSpeedTest安全设计、轻量级与跨平台优势详解为什么选择OpenSpeedTest安全设计、轻量级与跨平台优势详解 OpenSpeedTest是一款由OpenSpeedTest™开发的免费开源HTML5网网络前端CLIP 图文零样本匹配10 分钟跑出第一个结果CLIP 图文零样本匹配10 分钟跑出第一个结果 把一张照片和几句候选描述交给 CLIP它直接告诉你哪句最贴切全程不用训练——这就是常说的CLIP 零样人工智能基础模型大模型多模态计算机视觉上一篇最完整指南用WinFsp打造Git集成文件系统下一篇OpenKore完整指南免费开源RO客户端自动化工具终极教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考