Skip to content

Commit

Permalink
Add templating for Listable and MetadataHaving protocols
Browse files Browse the repository at this point in the history
  • Loading branch information
iabudiab committed Oct 13, 2020
1 parent 6cac76b commit 2f2d28b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 19 deletions.
14 changes: 9 additions & 5 deletions Sources/SwiftkubeModelGen/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,9 @@ struct Resource: Decodable {
var properties: [Property]
var requiresCodableExtension: Bool
var hasMetadata: Bool
var listResource: Bool
var isListResource: Bool
var isAPIResource: Bool
var isListableResource: Bool

enum CodingKeys: String, CodingKey {
case type
Expand All @@ -396,8 +397,9 @@ struct Resource: Decodable {
self.properties = []
self.requiresCodableExtension = false
self.hasMetadata = false
self.listResource = false
self.isListResource = false
self.isAPIResource = false
self.isListableResource = false
return
}

Expand All @@ -411,8 +413,9 @@ struct Resource: Decodable {
self.properties = []
self.requiresCodableExtension = false
self.hasMetadata = false
self.listResource = false
self.isListResource = false
self.isAPIResource = false
self.isListableResource = false

guard container.allKeys.contains(.properties) else {
return
Expand Down Expand Up @@ -442,11 +445,12 @@ struct Resource: Decodable {
self.properties.append(contentsOf: props.sorted())
self.requiresCodableExtension = properties.contains { $0.type.requiresCodableExtension }
self.hasMetadata = properties.contains { $0.type.isMetadata && $0.isOptional }
self.listResource = properties.contains(where: { $0.name == "items" }) && gvk?.kind.hasSuffix("List") ?? false
self.isListResource = properties.contains(where: { $0.name == "items" }) && gvk?.kind.hasSuffix("List") ?? false
self.isAPIResource =
!self.listResource &&
!self.isListResource &&
properties.contains(where: { $0.name == "apiVersion" && $0.isContant }) &&
properties.contains(where: { $0.name == "kind" && $0.isContant })
self.isListableResource = false
}
}

Expand Down
23 changes: 16 additions & 7 deletions Sources/SwiftkubeModelGen/Stencil+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ extension Extension {
throw ModelGenError.RuntimeError(message: "Input must be a definition Schema")
}
var protocols = ["KubernetesResource"]
if schema.listResource {
if schema.isListResource {
protocols.append("KubernetesResourceList")
}
if schema.hasMetadata {
protocols.append("ResourceWithMetadata")
}
if schema.isAPIResource {
protocols.append("KubernetesAPIResource")
}
if schema.hasMetadata {
protocols.append("MetadataHavingResource")
}
if schema.isListableResource {
protocols.append("ListableResource")
}

return protocols.joined(separator: ", ")
}
Expand All @@ -67,15 +70,21 @@ extension Extension {
///
public static let apiVersion: APIVersion = .\(apiVersion)
"""
}
}

registerFilter("P.renderDescription") { input in
guard let property = input as? Property else {
throw ModelGenError.RuntimeError(message: "Input must be a Property: \(String(describing: input))")
}
let indentedNewLine = "\n\t\t///"
let description = property.description
let indented = description.replacingOccurrences(of: "\n", with: "\n\t\t/// ")
return "///\n\t\t/// \(indented)\n\t\t///"
let indented = description.replacingOccurrences(of: "\n", with: "\(indentedNewLine) ")

return """
///
/// \(indented)
///
"""
}

registerFilter("P.render") { input in
Expand Down
15 changes: 11 additions & 4 deletions Sources/SwiftkubeModelGen/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,25 @@ struct ModelGen: ParsableCommand {
throw ModelGenError.RuntimeError(message: "Output directory arleady exists and clear flag is not set")
}

let definitionsPath = try generateJSONSchema(outputPath: outputPath)
let schemas = try loadAndDecodeJson(url: definitionsPath.url, type: Definitions.self)
let environment = makeStencilEnv(templatesPath: templatesPath)

if clear {
try outputPath.delete()
}
try outputPath.mkpath()

let environment = makeStencilEnv(templatesPath: templatesPath)
let definitionsPath = try generateJSONSchema(outputPath: outputPath)
var schemas = try loadAndDecodeJson(url: definitionsPath.url, type: Definitions.self)

let allGroupVersions = Set(schemas.definitions.compactMap { $1.gvk?.makeGroupVersion() })
try renderAPIVersions(outputPath: outputPath, allGroupVersions: allGroupVersions, environment: environment)

schemas.definitions
.filter { $0.value.isListResource }
.forEach { key, resource in
let itemKind = key.deletingSuffix("List")
schemas.definitions[itemKind]?.isListableResource = true
}

try schemas.definitions
.filter { $0.value.type != .null }
.forEach { key, resource in
Expand Down
21 changes: 18 additions & 3 deletions templates/model/Resource.swift.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,29 @@ public extension {{ type.group }}.{{ type.version }} {

{{ resource|R.renderDescription }}
struct {{ type.kind }}: {{ resource|R.protocols }} {
{% if resource.listResource %}
public typealias Resource = {{ type.group }}.{{ type.version }}.{{ type.listItemKind }}
{% if resource.isListResource %}

///
/// KubernetesResourceList.Item associated type
///
public typealias Item = {{ type.group }}.{{ type.version }}.{{ type.listItemKind }}
{% endif %}
{% if resource.isListableResource %}

///
/// ListableResource.List associated type
///
public typealias List = {{ type.group }}.{{ type.version }}.{{ type.listItemKind }}List
///
/// The type of the associated KubernetesResourceList
///
public static let listType: List.Type = {{ type.group }}.{{ type.version }}.{{ type.listItemKind }}List.self
{% endif %}

{{ resource|R.staticAPIVersion }}

{% for property in resource.properties %}
{{ property|P.renderDescription }}
{{ property|P.renderDescription }}
{{ property|P.render}}{% endfor %}
///
/// Default memberwise initializer
Expand Down

0 comments on commit 2f2d28b

Please sign in to comment.