用Darabonba一键生成7种语言的代码
0x1 介绍
最近在看阿里的SDK的时候,突然看到了一个好玩的东西,这玩意叫 Darabonba。是一种 OpenAPI 应用的领域特定语言。可以利用它为任意风格的接口生成多语言的 SDK、代码示例、测试用例、接口编排等。现在阿里云的多语言 SDK 就是用这个生成的。下面是官方的介绍流程图。
0x2 安装
我们按照官方的步骤来安装它,因为是用 Nodejs 写的,所以可以用 npm 来安装它
sudo npm install -g @darabonba/cli
安装完成后可以在终端输入 dara
,如果输出版本号就是说明安装成功了
➜ dara
The CLI for Darabonba 1.1.8
0x3 使用
安装完成后就可以使用了,首先创建一个文件夹来存放这个项目
mkdir demo && cd demo
然后用 dara
命令来进行初始化模块,然后依次输入包名等信息。
➜ dara init
package scope: demo
package name: demo
package version: 1.0.0
main entry: ./demo.dara
初始化完成后,我们就可以在 demo.dara
文件里进行 Darabonba DSL 表达式的编写里
比如我们编写一个经典的输出 hello world!
编写 Darabonba DSL 表达式
在 demo.dara
文件里写入如下代码
import Console;
init(){
}
function hello(): void {
Console.log("hello world!");
}
安装自定义模块
因为上面我们用到了 Console
模块,所以我们在当前文件路径下执行如下命令,进行模块的安装
dara install
# 执行后将显示下面这些信息
fetching from remote repository
1 libraries installed. (0 local, 1 remote)
执行完命令后,当前文件夹下就会出现一个 libraries 文件夹
配置 Darafile
Darafile
是 Darabonba
的模块管理文件,类似 Java
中的 pom.xml
或者 Node.js
中的 package.json
,这里我们要生成 Go
和 Java
的代码,所以只要做如下配置就可以了。具体的可以查看官方的详细介绍。
{
"scope": "demo",
"name": "demo",
"version": "1.0.0",
"main": "./demo.dara",
"libraries": {
"Console": "darabonba:Console:*"
},
"java": {
"package": "top.mjava.demo",
"className":"TestDemo"
}
}
在 libraries
里配置我们刚才所使用的 Console
依赖模块,在 java
对象字段里配置了包名和类文件名。
生成代码
官方暂时只支持 TypeScript、C#、Java、 Go、PHP、Python3、Python2、CPP 的代码生成,后续的话还会支持 Swift、Dart、Ruby、Lua、Kotlin。
我们这边只生成一下 Java 和 Go 代码,所以执行下面的命令就可以了
# 生成 Java 代码
dara codegen java ./java-demo
# 生成 Go 代码
dara codegen go ./go-demo
执行完命令后,当前文件夹就会出现 java-demo 和 go-demo 两个文件夹了。然后就可以进入文件夹看到相应生成的代码了
Java:
// This file is auto-generated, don't edit it. Thanks.
package top.mjava.demo;
import com.aliyun.tea.*;
import com.aliyun.teaconsole.*;
public class TestDemo {
public TestDemo() throws Exception {
}
public void hello() throws Exception {
com.aliyun.teaconsole.Client.log("hello world!");
}
}
Go:
// This file is auto-generated, don't edit it. Thanks.
package client
import (
console "github.com/alibabacloud-go/tea-console/client"
"github.com/alibabacloud-go/tea/tea"
)
type Client struct {
}
func NewClient()(*Client, error) {
client := new(Client)
err := client.Init()
return client, err
}
func (client *Client)Init()(_err error) {
return nil
}
0x3 自定义模块
上面所用到的 Console
就是通过自定义模块打包上传到了 Darabonba 的模块仓库,然后我们可以直接通过 libraries
来使用它。
所以我们可以自定义自己的模块上传到 Darabonba 模块仓库,接下来我们自定义一个获取 UUID 的模块,让它支持 Java 和 Go 语言来生成使用。
从上面的流程图可以知道,模块是由各个语言自己编写代码,然后通过 Darabonba 聚合后上传到模块仓库,然后使用者从仓库安装模块,并且下载对应语言的依赖包。
我们这边要编写 Java 和 Go 语言获取 UUID 的代码,然后通过 Darabonba 打包上传到模块仓库。
配置模版
编写模块我们也是用 Darabonba 先生成各个语言的模版代码,然后再编写相应的具体实现。
初始化
➜ dara init
package scope: greycode
package name: UUID
package version: 1.0.0
main entry: ./main.dara
我们先配置好 Darafile:
{
"scope": "greycode",
"name": "UUID",
"version": "1.0.0",
"main": "./main.dara",
"java": {
"package": "top.mjava.uuid",
"packageInfo": {
"description": "UUID generated for Darabonba moudle",
"url": "https://github.com/greycodee/tea-uuid",
"developerId": "greycode",
"developerName": "greycode",
"developerEmail": "zhengminghui99@gmail.com"
}
}
}
然后在 main.dara 里编写一个静态方法:
/**
* @return uuid
*/
static function uuid(): string;
编写 Java 模块
按上面的步骤配置好后就可以生成 Java 代码了,在当前目录下执行下面的命令
dara codegen java ./java
然后进入 java 文件夹,找到 Client.java,在 uuid()
方法里添加 UUID 生成的代码
// This file is auto-generated, don't edit it. Thanks.
package top.mjava.uuid;
import com.aliyun.tea.*;
public class Client {
public static String uuid() throws Exception {
// 添加这行代码
return UUID.randomUUID().toString();
}
}
编写好代码后,还需要配置 pom.xml 文件,然后把 Java 代码打包发布到 maven 仓库上。
配置好 pom.xml 文件到下面这几个配置
<groupId>top.mjava</groupId>
<artifactId>tea-uuid</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>tea-uuid</name>
还有把 pom.xml 里的仓库配置换成我们自己的,我这边也是用阿里云的 maven 参考。你们可以自己去阿里云 maven 注册自己的账号。
- <distributionManagement>
- <snapshotRepository>
- <id>sonatype-nexus-snapshots</id>
- <url>https://oss.sonatype.org/content/repositories/snapshots</url>
- </snapshotRepository>
- <repository>
- <id>sonatype-nexus-staging</id>
- <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
- </repository>
- </distributionManagement>
+ <distributionManagement>
+ <repository>
+ <id>rdc-releases_my</id>
+ <url>https://repo.rdc.aliyun.com/repository/102997-release-dTwmzu/</url>
+ </repository>
+ <snapshotRepository>
+ <id>rdc-snapshots_my</id>
+ <url>https://repo.rdc.aliyun.com/repository/102997-snapshot-d0gx8B/</url>
+ </snapshotRepository>
+ </distributionManagement>
配置好后就可以执行下面的命令将代码打包推送到远程 maven 仓库了
mvn clean source:jar javadoc:jar package deploy -Dmaven.test.skip=true -Dgpg.skip
看到下面的信息就说明部署成功了
[INFO] 阿里云Maven中央仓库为阿里云云效提供的公共代理仓库,云效也提供了免费、可靠的Maven私有仓库Packages,欢迎您体验使用。https://www.aliyun.com/product/yunxiao/packages?channel=pd_maven_download
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.538 s
[INFO] Finished at: 2021-06-05T16:00:28+08:00
[INFO] ------------------------------------------------------------------------
Maven 命令执行出现问题解决办法
如果执行 maven 命令进行部署时,出现下面的错误
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:1.6:sign (sign-artifacts) on project tea-uuid: Unable to execute gpg command: Error while executing process. Cannot run program "gpg": error=2, No such file or directory -> [Help 1]
可以通过添加
-Dgpg.skip
解决mvn clean source:jar javadoc:jar package deploy -Dmaven.test.skip=true -Dgpg.skip
如果出现下面的的错误
[ERROR] Failed to execute goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.3:deploy (injected-nexus-deploy) on project tea-uuid: Execution injected-nexus-deploy of goal org.sonatype.plugins:nexus-staging-maven-plugin:1.6.3:deploy failed: Server credentials with ID "sonatype-nexus-staging" not found! -
可以删除 pom.xml 文件里的
sonatype-nexus-staging
配置- <plugin> - <groupId>org.sonatype.plugins</groupId> - <artifactId>nexus-staging-maven-plugin</artifactId> - <version>1.6.3</version> - <extensions>true</extensions> - <configuration> - <serverId>sonatype-nexus-staging</serverId> - <nexusUrl>https://oss.sonatype.org/</nexusUrl> - <autoReleaseAfterClose>true</autoReleaseAfterClose> - </configuration> - </plugin>
编写 Go 模块
老规矩,首先先生成 Go 的代码
dara codegen go ./go
然后编辑 client.go
文件,改为如下代码
// This file is auto-generated, don't edit it. Thanks.
/**
* @return uuid
*/
package client
import (
"github.com/google/uuid"
)
func Uuid () (_result string) {
// V4 基于随机数
u4 := uuid.New()
return u4.String()
}
然后 go.mod
文件里的 module 改为我们的上传 Go 代码的仓库地址
module github.com/greycodee/tea-uuid-go
然后推送到 GitHub 并打上一个 Tag 作为这个 Go 库的版本号,这边我设置版本号为 v1.0.0
git tag v1.0.0
git push origin v1.0.0
上传 Darabonba 仓库
编写好相应模块的代码并打包上传到对应的原创仓库后,就可以配置 Darafile 文件了
在 Darafile 添加 releases 信息
{
"scope": "greycode",
"name": "UUID",
"version": "1.0.0",
"main": "./main.dara",
"releases": {
"go": "github.com/greycodee/tea-uuid-go/client:v1.0.0",
"java": "top.mjava:tea-uuid:1.0",
},
"java": {
"package": "top.mjava.uuid",
"packageInfo": {
"description": "UUID generated for Darabonba moudle",
"url": "https://github.com/greycodee/tea-uuid",
"developerId": "greycode",
"developerName": "greycode",
"developerEmail": "zhengminghui99@gmail.com"
}
}
}
然后去 Darabonba 模块仓库里注册一个账号,然后点击个人中心->Scope->添加scope
,添加一个 scope ,保持和 Darafile 文件里的 scope 一致。
注册完成后在项目目录下执行 dara login
命令,输入刚才注册的账号密码,进行登陆。
执行 dara pack
进行打包
再执行 dara publish
进行发布
发布完成后就可在 Darabonba 模块仓库里看到刚才发布的包了
Darabonba UUID 模块代码地址:https://github.com/greycodee/tea-uuid
Go 模块代码地址: https://github.com/greycodee/tea-uuid-go
使用自定义的模块
上传 Darabonba 模块仓库后,我们就可以向刚开始使用 Console 模块那样来使用 UUID 模块了
Darafile 添加 libraries
"libraries": {
"UUID": "greycode:UUID:*",
}
在 dara
代码里使用:
import Console;
import UUID;
init(){
}
function hello(): void {
Console.log(UUID.uuid());
}