拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Texture(AsyncDisplayKit)贡献指南:从提 Issue、走 RFC 到提交 Pull Request 的完整协作规范

Texture(AsyncDisplayKit)贡献指南:从提 Issue、走 RFC 到提交 Pull Request 的完整协作规范 移动开发UI组件【免费下载链接】TextureSmooth asynchronous user interfaces for iOS apps.项目地址https://gitcode.com/gh_mirrors/te/Texture点击查看免费下载导读本文基于 Texture 开源仓库的 CONTRIBUTING.md 撰写系统梳理了这个 iOS 异步 UI 框架对外开源协作的完整规范包括问题Issue的提问与上报流程、功能提案的 RFC 流程、Pull Request 的提交流程、语义化版本管理策略以及一套可落地的 Objective-C 编码规范缩进、命名、括号、锁与可空性标注。无论你是想上报一个 bug、提出一个新功能还是直接贡献代码读完本文你都能按照项目官方流程高效参与并让自己的代码风格与 Texture 核心团队保持一致。提问与求助渠道先到 Slack别用 IssueTexture 在文档开篇就明确了求助渠道的分工如果你在使用 Texture 时遇到困难或对用法有疑问请到官方Slack 频道提问请不要通过提交 GitHub Issue 来寻求使用帮助Issue 只用于 bug 跟踪与功能讨论。同时仓库中的 .github/ISSUE_TEMPLATE.md 也呼应了这一点模板顶部同样提示如果你在寻找帮助请考虑加入我们的 slack 频道并建议上报者尽可能包含示例工程或截图、代码片段、Texture 版本号、崩溃时的 backtrace bt all。也就是说一个高质量的 Issue 应当自带可复现的最小工程和足够的诊断信息而不是一句含糊的它不工作了。Core Team谁来审核与合并Texture 有一个Core Team核心团队其职责包括评审并推动社区提交的 RFC Issue作为这些 RFC 的批准人approver推动 Texture 朝着一致的方向演进目标是构建通用的 iOS UI 框架团队成员拥有仓库的合并merge权限。核心团队成员基于技术专长与对社区的贡献被任命。文档中列出的成员包括 Adlai Holler、Garrett Moon、Huy Nguyen、Michael Schneider、Scott Goodson 等并说明随着时间推移更多来自多元化背景的社区成员将根据其社区参与和贡献记录被任命。Issues如何上报 Bug 与新功能已知问题在哪里Texture 使用 GitHub Issues 进行所有 bug 跟踪团队会密切跟踪并尽量明确标注内部修复进行中的状态。因此在提交新 Issue 之前先确认你的问题是否已经存在。上报新 Issue 的标准步骤先更新到最新 master 版本再复现团队可能已经修复了你的 bug搜索相似 Issue很可能别人已经遇到过同一个问题提供一个精简的复现用例reduced test case这个 demo 除了你要演示的 bug 之外应当完全可运行越精简越好。如果无法产出复现用例请给出非常具体的复现步骤。如果团队无法复现、且没有其他证据Issue 将被关闭你的 Issue 会被验证提供的示例会被测试正确性Texture 团队会与你协作直到问题得到验证跟进团队的反馈Issue 如果长期无人跟进stale可能被关闭如果可能提交一个带失败测试的 Pull Request更进一步如果能力允许直接尝试修复 bug。一句话总结提供的信息越多团队验证 bug 就越快采取行动也就越快。Issue 的 Triaging分流规则如果团队需要你补充复现信息Issue 会被标记为Needs More Info发出通知后14 天内未获回应会再次提醒首次提醒后两周仍无回应则可能关闭把功能请求直接提交为 Issue 的用户会被引导遵循 RFC 流程否则 Issue 将被关闭长期不活跃的 Issue 会被贴上相应标签以告知提交者该关闭了之后如恢复可操作性可重新打开可行时Issue 会按Status: X如 In Progress、On Hold或Priority: XP1/P2/P3从高到低前缀打标签便于状态与优先级管理。请求新功能RFC Issue 流程如果打算改变公开 API或对实现做非平凡改动官方强烈建议先走 RFC Issue 流程在投入大量精力实现之前先达成一致。如果只是修 bug可以直接提交 Pull Request但仍建议先提一个描述修复内容的 Issue以防团队不接受该修复但想跟踪该问题。RFC Issue 流程如下在 Slack 频道收集反馈或直接以 GitHub Issue 形式起草 RFCIssue 标题必须以[RFC]为前缀例如[RFC] Add new cool feature清晰、详细地说明你想要的功能及其重要性。注意项目优先采纳对大多数用户有用的功能如果只面向少数用户请考虑以 add-on 库的形式扩展 Texture复杂功能请务必写 RFC Issue——即使你自己无法实现RFC 也能为贡献者提供核心团队认可的实现规范文档。被接受accepted的 RFC 会标记Needs Volunteer讨论之后可以尝试提交 Pull Request。能写代码就尽快开始写团队永远有做不完的事动手写代码能显著加速整个流程。开发流程与 Pull Request所有 Texture 开发都直接在 GitHub 上进行核心团队成员与外部贡献者提交的 Pull Request 走同一套评审流程。master 分支处于活跃开发状态团队会尽力保持 master 分支良好状态、测试始终通过但为了快速迭代master 上可能存在与你应用不兼容的API 变更团队会尽力沟通这些变更并合理管理版本号方便你锁定特定版本。提交 Pull Request 的完整检查清单PR 应提交到 master 分支。稳定版本分支单独维护但不接受直接对稳定分支的 PR团队会从 master 把非破坏性变更 cherry-pick 到最新稳定大版本。提交 PR 前请确认以下事项在 GitHub 上搜索已打开或已关闭的PR避免重复劳动Fork 仓库并从 master 创建分支git checkout -b my-fix-branch master编写补丁包含合适的测试用例并遵循本文的编码规范确保每个提交信息commit message有意义便于评审者理解意图确保你的 PR 通过GitHub 上的 CI 测试若尚未签署先签署 CLA见下文。新文件的版权头在新建文件顶部粘贴以下版权声明// // ASDisplayNode.mm // Texture // // Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 //如果是修改已有文件将文件头改为// // ASDisplayNode.mm // Texture // // Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. // Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved. // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 //这反映了 Texture 从 Facebook 旗下的 AsyncDisplayKit 迁移至 Pinterest 旗下 Texture 的历史2017 年 4 月 13 日之后版权归属 Pinterest。CI 如何把关仓库的 .github/workflows/ci.yml 展示了 PR 与 push 触发的 CI 矩阵覆盖 8 种模式tests构建并运行测试、framework构建动态 framework、life-without-cocoapods构建静态库、carthage验证 Carthage 可用、以及examples-pt1到examples-pt4分四批构建示例工程。CI 运行在 macOS 上先 checkout 再执行./build.sh mode。此外 CI/build.sh 中的入口脚本会执行./build.sh all。这意味着贡献者的 PR 会同时被测试、框架构建和示例工程构建三重验证。语义化版本Semantic VersioningTexture 遵循语义化版本控制patch 版本bug 修复minor 版本新功能极少数情况下包含清晰且易修复的破坏性变更major 版本任何大的破坏性变更。关键约定在引入破坏性变更时先在一个 minor 版本中给出 deprecation 警告让用户提前了解变更并迁移代码。每个 PR 都会被贴上标签标明该变更应进入下一个 patch、minor 还是 major 版本。项目发布节奏约为每几周一次不含重大新功能或破坏性 API 变更时发 patch/minor反之发 major。编码规范Coding Guidelines这是文档中技术含量最高、最可落地执行的部分逐条列举如下并尽量与仓库源码相互印证。缩进、行宽与空白使用 2 空格缩进绝不用 tab在 Xcode 中设置该偏好行宽尽量控制在120 字符左右文件末尾以换行符结束不留尾部空白trailing whitespace。property 声明property声明后加一个空格且属性修饰符需符合固定顺序property (nonatomic, readonly, assign, getterisTracking) BOOL tracking; property (nonatomic, readwrite, strong, nullable) NSAttributedString *attributedText;注意文档后面关于 nullability 的补充约定声明属性时不要包含atomic、readwrite、strong、assign这些是默认值或冗余信息只标注NS_ASSUME_NONNULL未覆盖的可空性顺序为 (nullability, atomicity, storage class, writability, custom getter, custom setter)。方法签名方法类型符号-/之后加一个空格方法分段之间加空格与 Apple 风格一致每个参数前必须有关键字且关键字要能描述该参数interface SomeClass - (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height; - (void)setExampleText:(NSString *)text image:(UIImage *)image; - (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag; - (id)viewWithTag:(NSInteger)tag; end内部方法与括号风格内部方法必须以_前缀- (void)_internalMethodWithParameter:(id)param;方法与控制流的花括号if/else/switch/while等的左花括号与语句同行、右花括号独立成行if (foo bar) { //.. } else { //.. }方法、interface、implementation的花括号放在下一行implementation SomeClass - (void)someMethod { // Implementation } end函数的花括号与函数同行static void someFunction() { // Implementation }运算符与变量名同侧NSAttributedString *attributedText self.textNode.attributedText;锁定Locking约定Texture 是异步 UI 框架线程安全是核心问题因此锁定约定格外细致_locked_前缀约定需要在持有锁时调用的方法方法名前面加_locked_- (void)_locked_needsToBeCalledWithLock {}这一约定在仓库源码中大量真实存在例如 Source/ASDisplayNodeLayout.mm 中有 15 处、Source/ASDisplayNode.mm 中有 45 处、Source/ASNetworkImageNode.mm 中有 28 处_locked_前缀方法是团队实际执行的标准。锁定安全规则_locked_方法调用其他_locked_方法是允许的但禁止以下行为在_locked_方法内调用普通的、未加锁的方法在_locked_方法内调用面向开发者、供子类覆写override的钩子方法面向用户覆写的子类钩子不得在持锁状态下调用内部使用的钩子同样遵循上述约定。获取锁的两种方式方式一显式调用.lock()/.unlock()- (void)setContentSpacing:(CGFloat)contentSpacing { __instanceLock__.lock(); BOOL needsUpdate (contentSpacing ! _contentSpacing); if (needsUpdate) { _contentSpacing contentSpacing; } __instanceLock__.unlock(); if (needsUpdate) { [self setNeedsLayout]; } } - (CGFloat)contentSpacing { CGFloat contentSpacing 0.0; __instanceLock__.lock(); contentSpacing _contentSpacing; __instanceLock__.unlock(); return contentSpacing; }方式二创建AS::MutexLocker基于 RAII作用域结束时自动解锁可避免忘记 unlock- (void)setContentSpacing:(CGFloat)contentSpacing { { AS::MutexLocker l(__instanceLock__); if (contentSpacing _contentSpacing) { return; } _contentSpacing contentSpacing; } [self setNeedsLayout]; } - (CGFloat)contentSpacing { AS::MutexLocker l(__instanceLock__); return _contentSpacing; }从源码看AS::MutexLocker定义在 Source/Details/ASThread.h本质是typedef std::lock_guardMutex MutexLocker;即 C 标准库的std::lock_guard封装遵循 RAII 语义。而 Source/ASLocking.h 进一步提供了ASLocking协议在NSLocking基础上扩展-tryLock以及ASLockSequence宏——它通过反复尝试、失败则全部解锁并让出线程sched_yield的方式同时获取多把锁以避免锁顺序导致的死锁这也是_locked_体系之外的进阶锁定设施可用于需要一次性持有多把锁的场景。Nullability 标注所有头文件采用NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END包裹然后只对可以为空的指针标注 nullability除接口声明之外基本没有使用 nullability 注解的意义。完整示例属性、方法、函数、typedef、block 参数等各场景// Properties // Never include: atomic, readwrite, strong, assign. // Only specify nullability if it isnt assumed from NS_ASSUME. // (nullability, atomicity, storage class, writability, custom getter, custom setter) property (nullable, copy) NSNumber *status // Methods - (nullable NSNumber *)doSomethingWithString:(nullable NSString *)str; // Functions NSString * _Nullable ASStringWithQuotesIfMultiword(NSString * _Nullable string); // Typedefs typedef void (^RemoteCallback)(id _Nullable result, NSError * _Nullable error); // Block as parameter - (void)reloadDataWithCompletion:(void (^ _Nullable)())completion; // Block as parameter with parameter and return value - (void)convertObject:(id _Nonnull (^ _Nullable)(id _Nullable input))handler; // More complex pointer types - (void)allElementsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode displaySet:(NSSetASCollectionElement * *__autoreleasing _Nullable *)displaySet preloadSet:(NSSetASCollectionElement * *__autoreleasing _Nullable *)preloadSet map:(ASElementMap *)map;最后一个示例来自真实的 range controller 相关接口其中ASScrollDirection、ASLayoutRangeMode、ASCollectionElement、ASElementMap等类型都定义在仓库 Source/Details 与 Source 目录下可见这套 nullability 约定已贯穿 Texture 的公开 API。CLA 与 License签署贡献者许可协议CLA在发送 Pull Request 之前必须签署 CLA任何代码变更要被接受CLA 都必须已签署License通过向 Texture 贡献你同意你的贡献将在其Apache 2.0许可下授权。这一点同样体现在每个源文件的版权头中——例如 Source/ASLocking.h 头部即注明Copyright (c) Pinterest, Inc. All rights reserved.与Licensed under Apache 2.0与贡献指南中的文件头模板完全一致。结语Texture 的贡献流程是一个先沟通、再实现的完整闭环用法问题走 Slackbug 与功能走 Issue RFC代码走 master 分支 PR CI 验证 CLA 签署而编码规范中关于 2 空格缩进、_locked_前缀、AS::MutexLocker/ASLockSequence锁定约定、nullability 标注等细则都可以在仓库源码中找到大量真实落地的实例。按照这套规范提交代码不仅能显著提高 PR 被接受的概率也能让你的实现与 Texture 核心团队保持一致的工程质量标准。赞分享移动开发UI组件【免费下载链接】TextureSmooth asynchronous user interfaces for iOS apps.项目地址https://gitcode.com/gh_mirrors/te/Texture点击查看免费下载相关推荐pypdf 贡献指南从提交 Issue 到合并 Pull Request 的完整协作规范pypdf 贡献指南从提交 Issue 到合并 Pull Request 的完整协作规范 pypdf 是一个纯 Python 实现的 PDF 处理库可对 P后端Exposed 贡献指南从 Issue 提交到 Pull Request 合入的完整协作规范Exposed 贡献指南从 Issue 提交到 Pull Request 合入的完整协作规范 本指南以 ExposedKotlin SQL FrameworORM后端数据存储realm-swift 贡献指南从 Issue 提交到 Pull Request 合入的完整协作规范realm swift 贡献指南从 Issue 提交到 Pull Request 合入的完整协作规范 导读 本文基于 realm swift 仓库根目录的 C数据库移动开发嵌入式数据库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表