我发布了自己第一个由ChatGPT辅助开发的开源项目goattribute

新闻资讯   2023-07-19 19:04   70   0  

需求产生

前两天在工作过程中又遇到了一直以来困惑我的一个问题,就是Go配置项的管理问题。

在开发一个新项目的时候,往往涉及到配置项的管理。个人小项目可能会通过配置文件来传入、环境变量来传入,也可能通过命令行参数来传入,公司级别的项目还可能用到各种各样的config center。那么,如何来管理这些配置项就会很麻烦。

在我的习惯中,通常会使用至少两种方式来传入配置——如配置文件加命令行。原因有三:

  • 大部分情况下我运行的程序无需进行定制化,此时常使用默认配置文件。但有时候我们要临时修改一些选项,可以直接通过命令行参数传入覆盖默认配置
  • 我通常会将默认配置文件直接添加到Git仓库里,但其中有部分包含敏感信息的配置(如加密密钥),我需要通过其他方式传入,如环境变量、命令行等
  • 程序如果需要同时在测试环境和生产环境运行,我可以通过命令行选项来控制一些选项,而无需准备两个不同的配置文件

以往在命令行覆盖配置文件中配置项的时候,有一个很大的痛点就是,我不可能给每一个配置项都编写一个对应的命令行参数,而且随着项目的迭代,每次添加新的配置项都要添加对应的命令行参数,不太方便。

Go生态里有一个开源项目viper可以用于处理类似的问题,但是项目比较大,和pflagcobra的耦合也比较深。

其实我需要的功能很简单,一个类似Java -Dserver.port=8000中的-D这样的选项,让我可以动态的修改配置文件中的一些配置项。这样,不管配置来自哪里,里面有哪些字段,我都可以通过-Da.b.c=1这样的方式来修改。

ChatGPT辅助开发

按照我的这个痛点,我准备开发一个库,这个库的工作很简单,就是可以使用一定的语法,获取和设置任意对象中的属性。

比如,下面这个YAML对应的对象(这实际上是一个docker-compose.yml的配置文件):

version: "2.0"
services:
  web:
    image: openjdk:8-jre
    ports:
      - "8080:8080"
      - "8081:8081"

我要将web容器的镜像由openjdk:8-jre换成openjdk:8-jdk,可以编写这样的语句:services.web.image=openjdk:8-jdk;如果我想将8080端口修改成9090,则可以编写这样的语句:services.web.ports[0]=9090:8080

这并不是一个非常困难的项目,但作为一个尊贵的ChatGPT Plus会员,我想让GPT4辅助我完成这个项目代码的编写。

首先,我们需要将自己的需求清晰地描述给ChatGPT,比如,我将我的需求抽象成一个名为SetAttr的函数,并将这个函数的作用和例子发给它:

ChatGPT返回给我的函数,看起来大致没有什么问题。接着,我还让其帮忙生成了与SetAttr对应的GetAttr函数,由于前面已经生成过SetAttr,所以对于GetAttr函数的描述可以比较简单,GPT4具有一定逻辑思考能力:

这两个函数的代码主体上没有什么问题,但细节是否能完全满足我们的需求,还需要编写单元测试来验证。

我这里的建议是,如果代码由GPT生成,那么单元测试需要我们人工来编写;如果代码是我们人工编写,那么单元测试可以让GPT生成。人工编写的过程中,可以让GPT来生成一些辅助片段加快我们工作效率,但最好不要把这两部分全部都交给GPT来实现,否则很可能在它那里是逻辑自洽的,但实际上有很多情况没有被考虑,需要大量修改。

最后,我投入了一些时间在单元测试的编写上,处理了一些panic,让项目可以适应大部分情况。

项目取名与开源

完成了代码开发,我们可以让ChatGPT帮忙生成一下README:

这就是我第一个使用ChatGPT辅助生成的完整项目。ChatGPT的工作大概70%,我的工作大概30%,相比于正常实现一个类似的项目,我大概节省了50%时间。

我的贡献除了编写部分单元测试,我还优化了API,让其更方便被使用,用可以直接通过这样的方式来设置config对象的任意属性:

goattribute.New(&config).SetAttr("Services.Web.Ports[0]""9090:8080")

有这样一个库,我就可以比较方便地实现文章开头的需求了——从命令行获取-D参数的值后,使用=将其分割成键名和值,键名作为SetAttr的第一个参数,值作为SetAttr的第二个参数即可。

完整代码已经发布在https://github.com/phith0n/goattribute,如果你与我有相似需求,可以考虑使用这个库来优化你的配置管理流程。当然,goattribute并不仅限于我上面说到的场景,也可以用于操纵任意对象的值。

封面图片由MidJourney生成。喜欢这篇文章,点个在看再走吧~

文章引用微信公众号"代码审计",如有侵权,请联系管理员删除!

博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。