我成为开源维护者的旅程

Hacktoberfest 让我开始思考。我对开源的第一次贡献充满挑战,但从那时起我所学到的一切都让我成为了一个更好的开发者。
137 位读者喜欢这篇文章。
Why and how to handle exceptions in Python Flask

图片来自 Unsplash.com, Creative Commons Zero 

Hacktoberfest 是一项倡议,邀请世界各地的开发者参与并贡献开源项目。这是我连续第二年完成该挑战,它激励了我,我想分享我更长的开源软件之旅。

很久以前,在一个遥远的星系……

那是 2010 年。宇宙让我与我的好朋友 Jonas Abreu 相遇。 Jonas 是 Mirror 的创建者,这是一个简单的领域特定语言 (DSL) 层,基于 Java Reflection API,它使 元编程 更加容易。当时有一个关于代理创建功能的请求,Jonas 问我是否有兴趣实现它。我接受了挑战。

我痛苦了三天,处理着我不理解的代码……直到我理解了。我仍然记得那天我的胜利给我带来的感觉。那种痛苦是知识入侵我的大脑!

这段代码是我对开源的第一次贡献。我从为 Mirror 做贡献的经验中学到了很多

  • 关于 Java 元编程
  • 代理类的概念
  • Javassistcglib 框架
  • 如何接收和提供有用且尊重的反馈
  • 如何设计一个将被其他人使用的工具
  • 一些有趣的 黑暗魔法

最重要的是,我获得了一种使命感。 我喜欢在挑战自我,与比我聪明的杰出工程师合作的同时,为更大的利益做出贡献的想法。

探索为开源做贡献的方法

我开始参与社区活动,例如运行编程道场。 在这样做的时候,我遇到了更多优秀的开发者,我们组成了一个小组。 在某个时候,那个小组决定学习 Scala。 我们一起学习和编码,最终开始了 Scaladores,圣保罗的 Scala 用户组。

最终,Jonas 开始谈论一种不同的学习方法,称为 刻意练习

如果我们能将所有这些新获得的知识结合起来呢?

研究这种实践的结果是 Aprenda,一个将游戏化和刻意练习相结合的学习平台,使学习 HTML、正则表达式或 Git 变得更容易。 构建如此重要的东西感觉就像升级了我对开源贡献的追求。 我还发现我获得了更多关于编程和实践的知识,以激励他人和我自己。

尽管我很享受这种追求,但我无法投入大量时间在这个项目上。 在我在 Aprenda 上取得进展的同时,我不得不将注意力转移到一份新工作上。

通过我自己的 Ruby gem 贡献

我的新工作让我陷入了一种常见的模式:每个问题都通过编写创建、读取、更新或删除数据 (CRUD) 的代码来解决。 这给了我一个想法,所以我开始了一个新项目。 我想以与 Ruby on Rails(一个强大的 Web 框架)允许我使用一个简单的命令来设置环境的方式生成代码:rails g scaffold。 使用 Thor,为 Rails 生成器提供支持的相同 gem,我创建了 Spring MVC Scaffold。 现在,每当我需要创建一个 CRUD 时,我都输入

$ springmvc scaffold product name:string value:double active:boolean

我编写的代码减少了我的团队完成工作所需的工作量,并且我通过公开发布它来进一步分享它。 以下是我学到的一些重点

  • 使用 Thor 生成代码和文件
  • 为 CLI 定义命令
  • 组织 Ruby lib 代码
  • 创建 Ruby gem
  • 使用 Travis CI 构建项目
  • 发布到 RubyGems

在解决一个常见问题后,考虑提供该解决方案。 很可能其他人也有类似的问题。

即使它不再维护,Spring MVC Scaffold 仍然可以在 RubyGems 上找到。 我告诉你,在那个项目之后,我进入了一个充满技术问题的技术环境。

转变技术

我的新工作需要改变语言。 我开始使用 Microsoft .NET,我发现其他社区已经解决了这些问题。 这种认识让我很兴奋,因为我知道这是一个机会。 我贡献的新机会以移植这些解决方案的形式出现。

Selenia

Selenium 是以编程方式与网站交互的主要方式,就像代码是一个“真实”用户(通过 Web 浏览器访问它)。 我认为 API 一直过于复杂。 所以我构建了一个工具,我们称之为 Selenia,可以用来用 C# 编写简洁的 UI 测试,所以不用

IWebDriver driver;
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File("/path/to/extension.crx"));
ChromeDriver driver = new ChromeDriver(options);
driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://www.google.com/ncr");

IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys("Selenium");
query.Submit();

driver.Quit();

我们可以写成

Open("http://www.google.com/");
S(By.Name("q").Value("Selenia").Enter();

Selenium 用户此时可能会有一个问题。 如果你在想,答案是“否”。 不需要自己关闭驱动程序。

使用 Ioget 设计不可变性

不可变性,这意味着永远不要更改已存在的对象,这使开发人员的生活变得轻松。 然而,这种观点是比较新的。 过去,ASP.NET MVC 会建议就地更新信息。 实例化对象的唯一方法是通过 setters

我构建了 Ioget 以帮助在 Web 应用程序中解组请求参数。 HTTP 请求参数是字符串,因此 Ioget 寻找根据给定类解析这些参数的最佳方法,通过它们的构造函数实例化对象,从而使它们不可变。

我将这个项目公开发布到 NuGet,但我从未设法像我打算的那样将 Ioget 与 ASP.NET 集成。 我停止使用 Microsoft 技术,因此这个项目落后于其曾经的崇高目标。

继续我的刻意练习,我记录了沿途学到的经验教训。

  • 物化
  • ASP.NET MVC 内部结构
  • Monad 实现
  • .NET 框架内部结构

我还注意到我在 Selenia 中使用的一种模式。 我真的很喜欢这段代码,我用它来关闭驱动程序

private void MarkForAutoClose(IWebDriver driver) =>
  AppDomain.CurrentDomain.DomainUnload += (s, e) => driver.Quit();

为 Quill 贡献

我在 2016 年搬到了伦敦,这暂停了我的贡献一段时间。 最终,我观看了 Gustavo Amigo 关于他的项目 quill-pgsql 的演讲,该项目是支持 Quill 的 PostgreSQL 数据类型的扩展。 他提到这个项目还处于早期阶段,这意味着它是某人加入的理想选择,我对用 Scala 编写代码感兴趣。 经过几次 pull request 之后,我决定为主要项目做出贡献。

Quill 在编译时将常规的类集合代码转换为 SQL 查询。 我认为它是我贡献过的最具挑战性(也最有趣)的项目。 自我开始以来已经有几年了,今天我是 维护者之一

以下是我通过使用 Quill 学到的东西

  • 抽象语法树 (AST)
  • 黑暗艺术(也称为 Scala 宏
  • 如何通过 隐式 使代码可扩展
  • 独占且奇怪的 SQL 规则

Quill 有一个名为 quill-async 的模块,它使用 一个不再维护的异步数据库驱动程序。 Quill 的创建者 Flavio Brasil 建议我们可以编写一个新的异步驱动程序。 这就是 非阻塞数据库连接 (NDBC) 的启动方式。

NDBC 是 Java 数据库连接 (JDBC) 的完全异步替代方案。 其架构旨在提供高性能、非阻塞的数据库连接,基于 Trane.io FuturesNetty 4

// Create a Config with an Embedded Postgres
Config config = Config.create("io.trane.ndbc.postgres.netty4.DataSourceSupplier", "localhost", 0, "user")
                      .database("test_schema")
                      .password("test")
                      .embedded("io.trane.ndbc.postgres.embedded.EmbeddedSupplier");

// Create a DataSource
DataSource<PreparedStatement, Row> ds = DataSource.fromConfig(config);

// Define a timeout
Duration timeout = Duration.ofSeconds(10);

// Send a query to the db defining a timeout and receiving back a List
List<Row> rows = ds.query("SELECT 1 AS value").get(timeout);

// iterate over awesome strongly typed rows
rows.forEach(row -> System.out.println(row.getLong("value")));

沿途获得了更多知识

  • 理解二进制协议
  • 使用 Netty 4
  • Java 类型系统的弱点
  • 完全实现函数式结构

这就是我目前所处的位置。 我将我的注意力分配在 Quill 和 NDBC 之间,试图使它们协同工作。

未来计划

我计划在不久的将来实现的贡献是

  • Finagle Postgres 中支持数组
  • NDBC 的 Clojure 包装器
  • 一个 ndbc-spring 模块
  • 一个用 Rust 编写的 CLI

现在我已经有近 10 年的开源经验,它教会了我一些非常有价值的东西:开源是关于分享知识。 当我解决一个问题时,我正在获取知识。 当我发送 pull request 时,我正在传播这些知识。 知识带来更多知识!

我强烈建议你成为开源社区的一员。 这可能很困难,尤其是在一开始,但你将学到的一切都会让你成为一个更好的开发者。 我保证。

开源是关于分享知识。 当我解决一个问题时,我正在获取知识。 当我发送 pull request 时,我正在传播这些知识。 知识带来更多知识!

本文最初发布在 Juliano Alves 的编程博客上。 已对风格和清晰度进行了编辑。

接下来要阅读什么
User profile image.
一位开源爱好者,坚信未来属于多语言和函数式编程

2 条评论

你好!对于 Selenium 的 Selenia (非常聪明的关闭驱动程序) 非常感兴趣,请问存储库在哪里?提前感谢!

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.