Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude Individual Entity Properties #106

Merged
merged 12 commits into from
Aug 7, 2022
14 changes: 13 additions & 1 deletion Docs/ConfigOptions.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Sourcery/ConfigOptions.md.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
## {{ type.localName|lowercase }}.{{ variable.name }}
{% endif %}

**Type:** {{ variable.typeName|replace:"?","" }}<br />
**Type:** {{ variable.typeName|replace:"?",""|replace:"EntityExclude","String" }}<br />
LePips marked this conversation as resolved.
Show resolved Hide resolved
**Default:** `{{ variable.defaultValue }}`

{% call format_documentation variable.documentation %}
Expand Down
4 changes: 3 additions & 1 deletion Sources/CreateAPI/Generate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ struct Generate: ParsableCommand {
do {
let options = try GenerateOptions(data: data) { options in
options.entities.include = Set(options.entities.include.map { Template(arguments.entityNameTemplate).substitute($0) })
options.entities.exclude = Set(options.entities.exclude.map { Template(arguments.entityNameTemplate).substitute($0) })
options.entities.exclude = Set(options.entities.exclude.map {
EntityExclude(name: Template(arguments.entityNameTemplate).substitute($0.name), property: $0.property)
})
}

for message in options.warnings {
Expand Down
13 changes: 11 additions & 2 deletions Sources/CreateAPI/Generator/Generator+Schemas.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ extension Generator {
return options.entities.include.contains(name)
}
if !options.entities.exclude.isEmpty {
return !options.entities.exclude.contains(name)
return !options.entities.exclude.contains { $0.name == name && $0.property == nil }
}
return true
}
Expand Down Expand Up @@ -337,7 +337,16 @@ extension Generator {
}

private func makeInlineProperties(for type: TypeName, object: JSONSchema.ObjectContext, context: Context) throws -> [Property] {
var keys = object.properties.keys
let excludedProperties = options.entities.exclude
.filter { $0.name == type.rawValue }
.compactMap { $0.property }
let excludedDiff = Set(excludedProperties).subtracting(object.properties.keys)
LePips marked this conversation as resolved.
Show resolved Hide resolved

for diff in excludedDiff {
try handle(warning: "Excluded property \(type.rawValue).\(diff) does not exist on schema object \(type.rawValue)")
LePips marked this conversation as resolved.
Show resolved Hide resolved
}

var keys = object.properties.keys.filter { !excludedProperties.contains($0) }
if options.entities.sortPropertiesAlphabetically { keys.sort() }
return try keys.compactMap { key in
let schema = object.properties[key]!
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 14 additions & 2 deletions Sources/CreateOptions/ConfigOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,21 @@ public struct ConfigOptions: Encodable {
/// Strips the parent name of enum cases within objects that are `oneOf` / `allOf` / `anyOf` of nested references
public var stripParentNameInNestedObjects: Bool = false // sourcery: replacementFor = isStrippingParentNameInNestedObjects

/// When set to a non-empty value, entities with the given names will be ignored during generation.
/// When set to a non-empty value, entities and entity properties with the given names will be ignored during generation.
/// Cannot be used in conjunction with [`include`](#entitiesinclude).
public var exclude: Set<String> = []
///
/// <details>
/// <summary>Examples</summary>
///
/// ```yaml
/// entities:
/// exclude:
/// - Pet
/// - Store.id
/// ```
///
/// </details>
public var exclude: Set<EntityExclude> = []

/// When set to a non-empty value, only entities matching the given names will be generated.
/// This cannot be used in conjunction with [`exclude`](#entitiesexclude).
Expand Down
31 changes: 31 additions & 0 deletions Sources/CreateOptions/EntityExclude.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Foundation

public struct EntityExclude: RawRepresentable, Codable, Hashable {
public var name: String
public var property: String?

public init(name: String, property: String?) {
self.name = name
self.property = property
}

public init?(rawValue: String) {
let components = rawValue.components(separatedBy: ".")
switch components.count {
case 1:
self.init(name: components[0], property: nil)
case 2:
self.init(name: components[0], property: components[1])
default:
return nil
}
}

public var rawValue: String {
if let property = property {
return "\(name).\(property)"
} else {
return name
}
}
}
2 changes: 2 additions & 0 deletions Tests/CreateAPITests/AllPackages/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ let package = Package(
.package(path: "../Expected/petstore-disable-inlining"),
.package(path: "../Expected/petstore-disable-mutable-properties"),
.package(path: "../Expected/petstore-enable-mutable-properties"),
.package(path: "../Expected/petstore-entity-exclude"),
.package(path: "../Expected/petstore-filename-template"),
.package(path: "../Expected/petstore-generate-classes"),
.package(path: "../Expected/petstore-identifiable"),
Expand Down Expand Up @@ -83,6 +84,7 @@ let package = Package(
"petstore-disable-inlining",
"petstore-disable-mutable-properties",
"petstore-enable-mutable-properties",
"petstore-entity-exclude",
"petstore-filename-template",
"petstore-generate-classes",
"petstore-identifiable",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "petstore-entity-exclude",
platforms: [.iOS(.v13), .macCatalyst(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)],
products: [
.library(name: "petstore-entity-exclude", targets: ["petstore-entity-exclude"]),
],
dependencies: [
.package(url: "https://github.com/kean/Get", from: "1.0.2")
],
targets: [
.target(name: "petstore-entity-exclude", dependencies: [
.product(name: "Get", package: "Get")
], path: "Sources")
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Generated by Create API
// https://github.com/CreateAPI/CreateAPI

import Foundation

struct StringCodingKey: CodingKey, ExpressibleByStringLiteral {
private let string: String
private var int: Int?

var stringValue: String { return string }

init(string: String) {
self.string = string
}

init?(stringValue: String) {
self.string = stringValue
}

var intValue: Int? { return int }

init?(intValue: Int) {
self.string = String(describing: intValue)
self.int = intValue
}

init(stringLiteral value: String) {
self.string = value
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Generated by Create API
// https://github.com/CreateAPI/CreateAPI

import Foundation

/// A pet title
///
/// A pet description
public struct Pet: Codable {
/// Example: "Buddy"
public var id: String
public var tag: String?

public init(id: String, tag: String? = nil) {
self.id = id
self.tag = tag
}

private enum CodingKeys: String, CodingKey {
case id = "name"
case tag
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Generated by Create API
// https://github.com/CreateAPI/CreateAPI

import Foundation

public struct Store: Codable {
public init() {}
}
27 changes: 27 additions & 0 deletions Tests/CreateAPITests/GenerateOptionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -660,4 +660,31 @@ final class GenerateOptionsTests: GenerateBaseTests {
// THEN
try compare(package: "petstore-filename-template")
}

func testPetstoreEntityExclude() throws {
// GIVEN
let command = try Generate.parse([
pathForSpec(named: "petstore", ext: "yaml"),
"--output", temp.url.path,
"--package", "petstore-entity-exclude",
"--generate", "entities",
"--config", config("""
entities:
exclude:
- Error
- Pet.id
- Store.pets
rename:
properties:
Pet.id: notID
Pet.name: id
LePips marked this conversation as resolved.
Show resolved Hide resolved
""", ext: "yaml")
])

// WHEN
try command.run()

// THEN
try compare(package: "petstore-entity-exclude")
}
}