yonaskolb / SwagGen

OpenAPI/Swagger 3.0 Parser and Swift code generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Should Swaggen use Swift Argument Parser 🤔

mackoj opened this issue · comments

I don't know if it's needed but we could in the future move to ArgumentParser.

Implementation

import ArgumentParser

struct Swaggen: ParsableCommand {
  
  @Flag(name: .shortAndLong, help: "Prints the current version of this app.")
  var version: Bool

  static var configuration = CommandConfiguration(
    abstract: "Swagger code generator",
    subcommands: [Generate.self],
    defaultSubcommand: Generate.self
  )

  func run() throws {
    
  }
}

struct Generate: ParsableCommand {
  
  @Option(name: .shortAndLong, default: nil, parsing: .next, help: "An option that will be merged with template options, and overwrite any options of the same name.\nCan be repeated multiple times and must be in the format --option \"name:value\".\nThe key can have multiple parts separated by dots to set nested properties:\nfor example, --option \"typeAliases.ID:String\" would change the type alias of ID to String.")
  var option: String?
  
  enum CleaningOption: String, ExpressibleByArgument, CaseIterable {
    case none
    case leave_files = "leave.files"
    case all
    
    var defaultValueDescription: String {
      get {
        switch self {
        case .none:
          return "no files will be removed"
        case .leave_files:
          return "all other files will be removed except if starting with . in the destination directory"
        case .all:
          return "all other files will be removed"
        }
      }
    }
    
    static func usage() -> String {
      var usage : String = ""
      for elem in CleaningOption.allCases {
        usage.append("\(elem.rawValue): \(elem.defaultValueDescription)\n")
      }
      return usage
    }
  }
  
  @Option(name: .shortAndLong, default: .all, parsing: .next, help: "How the destination directory will be cleaned of non generated files:\n\(CleaningOption.usage())")
  var clean: CleaningOption

  @Option(name: .shortAndLong, default: nil, parsing: .next, help: "Path to the template config yaml file. If no template is passed a default template for the language will be used.")
  var template: String?

  @Option(name: .shortAndLong, default: "generated", parsing: .next, help: "The directory where the generated files will be created.")
  var destination: String

  @Option(name: .shortAndLong, default: "swift", parsing: .next, help: "The language of the template that will be generated.")
  var language: String

  @Flag(help: "Silence standard output")
  var silent: Bool

  @Flag(help: "Show verbose output")
  var verbose: Bool

  func run() throws {
    
  }
}

Swaggen.main()

Output of help

swaggen --help
OVERVIEW: Swagger code generator

USAGE: swaggen [--version] <subcommand>

OPTIONS:
  -v, --version           Prints the current version of this app. 
  -h, --help              Show help information.

SUBCOMMANDS:
  generate

Output of help for generate

swaggen generate --help
USAGE: swaggen generate [--option <option>] [--clean <clean>] [--template <template>] [--destination <destination>] [--language <language>] [--silent] [--verbose]

OPTIONS:
  -v, --version           Prints the current version of this app. 
  -o, --option <option>   An option that will be merged with template options, and overwrite any options of the same name.
Can be repeated multiple times and must be in the format --option "name:value".
                          The key can have multiple parts separated by dots to set nested properties:
                          for example, --option "typeAliases.ID:String" would change the type alias of ID to String. 
  -c, --clean <clean>     How the destination directory will be cleaned of non generated files:
                          none: no files will be removed
                          leave.files: all other files will be removed except if starting with . in the destination directory
                          all: all other files will be removed
                          (default: all other files will be removed)
  -t, --template <template>
                          Path to the template config yaml file. If no template is passed a default template for the language will be used. 
  -d, --destination <destination>
                          The directory where the generated files will be created. (default: generated)
  -l, --language <language>
                          The language of the template that will be generated. (default: swift)
  --silent                Silence standard output 
  --verbose               Show verbose output 
  -h, --help              Show help information.

My bad it's possible to handle option

Implementation

Just need to change option to this.

  @Option(name: .shortAndLong, parsing: ArrayParsingStrategy.singleValue, help: "An option that will be merged with template options, and overwrite any options of the same name.\nCan be repeated multiple times and must be in the format --option \"name:value\".\nThe key can have multiple parts separated by dots to set nested properties:\nfor example, --option \"typeAliases.ID:String\" would change the type alias of ID to String.", transform: { $0 })
  var option: [String]

Output

swaggen generate --help
USAGE: swaggen generate [--option <option> ...] [--clean <clean>] [--template <template>] [--destination <destination>] [--language <language>] [--silent] [--verbose]

OPTIONS:
  -v, --version           Prints the current version of this app. 
  -o, --option <option>   An option that will be merged with template options, and overwrite any options of the same name.
                          Can be repeated multiple times and must be in the format --option "name:value".
                          The key can have multiple parts separated by dots to set nested properties:
                          for example, --option "typeAliases.ID:String" would change the type alias of ID to String. 
  -c, --clean <clean>     How the destination directory will be cleaned of non generated files:
                          none: no files will be removed
                          leave.files: all other files will be removed except if starting with . in the destination directory
                          all: all other files will be removed
                          (default: all other files will be removed)
  -t, --template <template>
                          Path to the template config yaml file. If no template is passed a default template for the language will be used. 
  -d, --destination <destination>
                          The directory where the generated files will be created. (default: generated)
  -l, --language <language>
                          The language of the template that will be generated. (default: swift)
  --silent                Silence standard output 
  --verbose               Show verbose output 
  -h, --help              Show help information.

I just put a PR up to update SwiftCLI #241

The latest version has similar property wrapper support. You might have other motivations to change though 🤷‍♂

My motivation was to reducing 3rd party dependencies.

Since Argument Parser is made by Apple it will be used by more app and be more stable and feature full and more known than 3rd party solutions. And 3rd party solution tend to decline when a first party solution is available.

This issue is more an open question on this subject.