How can I change the default value string displayed in Help?

Here is my sample code:

extension URL: ExpressibleByArgument {
    public init?(argument: String) {
        guard let url = URL(string: argument) else {
            return nil
        }
        self = url
    }
}

struct MySample: ParsableCommand {
    @Option(default: URL(string: FileManager.default.currentDirectoryPath)!, help: "Directory")
    var directory: URL
}

Produces output:

USAGE: sample [--directory <directory>]

OPTIONS:
  -v, --version           Print version 
  --directory <directory> Directory (default:
                          /Users/stewie/Library/Developer/Xcode/DerivedData/sample-blghzaivmncuwahbbafbmsweltpy/Build/Products/Debug)
  -h, --help              Show help information.

Expected behavior

I would expect the following

  --directory <directory> Directory (default: current directory)

Actual behavior

I get:

  --directory <directory> Directory (default:
                          /Users/stewie/Library/Developer/Xcode/DerivedData/sample-blghzaivmncuwahbbafbmsweltpy/Build/Products/Debug)

defaultValueDescription is implemented at this commit

I would get my expected behavior if I can override this computed property, but I don't know how to do that.

Anyone have an idea?

Environment

ArgumentParser: HEAD.

It doesn't look like this is possible right now, since defaultValueDescription isn't a protocol requirement. We'd need to make that change, and then you could write:

extension URL: ExpressibleByArgument {
    public init?(argument: String) { ... }
    public var defaultValueDescription: String {
        self.absolutePath /*or whatever would make this a good comparison*/  == FileManager.default.currentDirectoryPath
            ? "current directory"
            : String(describing: self)
    }
}

As an alternative, you can make directory an optional URL? and put the (default: current directory) string directly into the help text:

struct MySample: ParsableCommand {
    @Option(name: .customLong("directory"), help: "Directory (default: current directory)")
    var _directory: URL

    var directory: URL {
        _directory ?? URL(string: FileManager.default.currentDirectoryPath)!
    }
}

Thank you Nate!

I'll take this workaround you gave at this moment. However if you think that ArgumentParser users often want to customize defaultValueDescription, it would be nice if you consider adding defaultValueDescription to the ExpressibleByArgument protocol.

Since v0.0.3, user can change the default value string displayed in help by implementing defaultValueDescription yourself. :tada:

1 Like