Swiftpack.co - Package - cenode/ArgumentParser

ArgumentParser

A simple argument|config-file parser in Swift.

How to use:

///
/// MyConfigParser.swift
///
import Foundation
import ArgumentParser

public class MyConfigParser {
    public let parser: ArgumentParser
    
    private let host: Option<String>
    private let port: Option<Int>
    
    public init(_ arguments: [String], _ config: AppConfig) {
        self.parser = ArgumentParser(arguments: arguments)
        
        self.host = self.parser.add(
            name: "host",
            flag: "h",
            description: "The host to bind")
        
        self.port = self.parser.add(
            name: "port",
            flag: "p",
            description: "The port to bind")
    }
    
    public func parse(_ config: inout AppConfig) throws {
        try self.parser.parse()
        try self.process(&config)
    }
    
    private func process(_ config: inout AppConfig) throws {
        
        // host
        if let host = self.parser.get(self.host) {
            config.host = host
        }
        
        // port
        if let port = self.parser.get(self.port) {
            config.port = port
        }
        
    }
    
}

Or like this:

///
/// MyConfigParser.swift
///
import Foundation
import ArgumentParser

public class MyConfigParser {
    public let parser: ArgumentParser
    
    private let configFile: Option<String>
    private let host:       Option<String>
    private let port:       Option<Int>
    private let verbose:    Flag
    private let help:       Flag
    
    public init(_ config: AppConfig) {
        
        let arguments = Array(ProcessInfo.processInfo.arguments.dropFirst())
            .filter { (argument) -> Bool in
                return !(
                    argument.hasPrefix("-Apple") ||
                    argument.hasPrefix("NS")     ||
                    argument.hasSuffix(".xctest")
                )
            }
        
        self.parser = ArgumentParser(arguments: arguments)
            
        self.configFile = self.parser.add(
            name: "config-file",
            flag: "c",
            description: "Config file path",
            default: config.configFile)
        
        self.host = self.parser.add(
            name: "host",
            flag: "h",
            description: "The host to bind",
            default: config.host)
        
        self.port = self.parser.add(
            name: "port",
            flag: "p",
            description: "The port to bind",
            default: config.host)
        
        self.verbose = self.parser.add(
            name: "verbose",
            flag: nil,
            description: "Verbose mode",
            default: config.verbose)
            
        self.help = self.parser.add(
            name: "help",
            flag: nil,
            description: "Show this help text")
    }
    
    public func parse(_ config: inout AppConfig) throws {
        try self.parser.parse()
        try self.process(&config)
    }
    
    private func process(_ config: inout AppConfig) throws {
        
        // help
        if self.parser.get(self.help) != nil {
            self.parser.printUsage()
            exit(EXIT_SUCCESS)
        }
        
        // config file
        if let configFile = self.parser.get(self.configFile), config.configFile != configFile {
            config.configFile = configFile
            
            let arguments = try ConfigFileParser.default.parseFile(at: configFile)
            
            guard !arguments.contains(self.configFile.name) else {
                throw AppError.error("should not set argument [\(self.configFile.name))] in the config file")
            }
            
            if arguments.count > 0 {
                try MyConfigParser(arguments, config).parse(&config)
            }
        }
        
        // host
        if let host = self.parser.get(self.host) {
            config.host = host
        }
        
        // port
        if let port = self.parser.get(self.port) {
            guard (1...65535) ~= port else {
                throw ArgumentParserError.error("port value out of range: \(port), option: \(self.port.name)")
            }
            config.port = port
        }
        
        // verbose
        if let verbose = self.parser.get(self.verbose) {
            config.verbose = verbose
        }
    }
    
}

///
/// AppConfig.swift
///
public struct AppConfig {
    
    public var configFile: String = ""
    
    public var host: String = ""
    public var port: Int = 0
    
    public var verbose: Bool = false
    public var help: Bool = false
    
    public init() { }
}
///
/// main.swift
///

var config = AppConfig()
try MyConfigParser(config).parse(&config)

let app = App(config)


## 
## config.conf
##

## server
host            "127.0.0.1"  # or set to: "0.0.0.0"
port            8080

## format: "start, end, netmask"
address-pool    "10.10.1.10, 10.10.255.255, 255.255.0.0"

log-level       debug

daemon
verbose

$ ./MyApp --help

Usage: MyApp [options]

    --help           Show this help text          default: []
-c, --config-file    Config file path             default: []
-h, --host           The host to bind             default: []
-p, --port           The port to bind             default: [0]]
-l, --log-level      Log level                    default: [error]
    --log-file       Log file path                default: []
    --daemon         Daemon mode                  default: [false]
    --verbose        Verbose mode                 default: [false]

Ref:

  1. Commander: Compose beautiful command line interfaces in Swift
  2. LineReader: Class for reading text files line by line. Line Reader
  3. Apple SPM: The Package Manager for the Swift Programming Language

Thanks

Github

link
Stars: 0
Help us keep the lights on

Dependencies

Used By

Total: 0