ModelGen 🎰

ModelGen 是一个从 JSON Schema 生成模型的命令行工具。

Build Status GitHub codecov

为什么使用它?

模型通常是样板代码,为什么不生成它们然后一劳永逸呢? 它可以节省您编写样板代码的时间,并在您的应用程序复杂性扩展时消除模型错误。

这意味着向数据对象添加属性实际上是一个单行更改——无需复制粘贴。 如果你想重构所有的模型,只需要简单地更改模板然后重新生成即可。

我们支持以下语言

但您可以通过几行代码添加对任何其他语言的支持。

它是如何工作的?

与大多数模型生成器不同,它使用两个文件,.json.stencil,因此您可以完全控制模型的呈现方式。

模型在 JSON 中定义,基于 JSON Schema 但不限于此,基本上你在 schema 中添加的任何东西都可以用在模板中。 这是一个可扩展且与语言无关的规范。

示例?

请查看 Example 文件夹。

要求

安装

Homebrew

运行以下命令以使用 homebrew 安装

$ brew tap hebertialmeida/ModelGen https://github.com/hebertialmeida/ModelGen.git
$ brew install ModelGen

手动安装

运行以下命令以手动构建和安装

$ git clone https://github.com/hebertialmeida/ModelGen.git
$ cd ModelGen
$ make install

定义 Schema

ModelGen 接受一个 schema 文件作为输入。

{
  "title": "Company",
  "type": "object",
  "description": "Definition of a Company",
  "identifier": "id",
  "properties": {
    "id": {"type": "integer"},
    "name": {"type": "string"},
    "logo": {"type": "string", "format": "uri"},
    "subdomain": {"type": "string"}
  },
  "required": ["id", "name", "subdomain"]
}

定义模板

ModelGen 接受一个模板,以便以您想要的格式生成。

//
//  {{ spec.title }}.swift
//  ModelGen
//
//  Generated by [ModelGen]: https://github.com/hebertialmeida/ModelGen
//  Copyright © {% now "yyyy" %} ModelGen. All rights reserved.
//

{% if spec.description %}
/// {{ spec.description }}
{% endif %}
public struct {{ spec.title }} {
{% for property in spec.properties %}
{% if property.doc %}
    /**
     {{ property.doc }}
     */
{% endif %}
    public let {{ property.name }}: {{ property.type }}{% if not property.required %}?{% endif %}
{% endfor %}

    // MARK: - Initializers

{% map spec.properties into params using property %}{{ property.name }}: {{ property.type }}{% if not property.required %}?{% endif %}{% endmap %}
    public init({{ params|join:", " }}) {
{% for property in spec.properties %}
        self.{{ property.name }} = {{ property.name }}
{% endfor %}
    }
}

// MARK: - Equatable

extension {{ spec.title }}: Equatable {
    static public func == (lhs: {{spec.title}}, rhs: {{spec.title}}) -> Bool {
{% for property in spec.properties %}
        guard lhs.{{property.name}} == rhs.{{property.name}} else { return false }
{% endfor %}
        return true
    }
}

生成模型

为了方便起见,您可以创建一个 .modelgen.yml

spec: ../Specs/
output: ./Model/
template: template.stencil
language: swift

然后

$ modelgen

没有 .modelgen.yml 文件

从目录生成

$ modelgen --spec ./Specs --template template.stencil --output ./Model

生成单个文件

$ modelgen --spec company.json --template template.stencil --output Company.swift

生成的输出

//
//  Company.swift
//  ModelGen
//
//  Generated by [ModelGen]: https://github.com/hebertialmeida/ModelGen
//  Copyright © 2019 ModelGen. All rights reserved.
//

/// Definition of a Company
public struct Company {
    public let id: Int
    public let logo: URL?
    public let name: String
    public let subdomain: String

    // MARK: - Initializers

    public init(id: Int, logo: URL?, name: String, subdomain: String) {
        self.id = id
        self.logo = logo
        self.name = name
        self.subdomain = subdomain
    }
}

// MARK: - Equatable

extension Company: Equatable {
    static public func == (lhs: Company, rhs: Company) -> Bool {
        guard lhs.id == rhs.id else { return false }
        guard lhs.logo == rhs.logo else { return false }
        guard lhs.name == rhs.name else { return false }
        guard lhs.subdomain == rhs.subdomain else { return false }
        return true
    }
}

致谢

此工具由以下项目提供支持

最初的概念基于 Peter Livesey's pull request 并且受到了 Pinterest 的 plank 的启发。

如果您想贡献代码,请随时打开一个 pull request。

许可证

ModelGen 在 MIT 许可证下可用。 请参阅 LICENSE 文件。