feat: Updates cli documentation to use the swift-cli-doc package.

This commit is contained in:
2024-12-09 11:27:27 -05:00
parent a39536364b
commit 357914ba93
27 changed files with 165 additions and 1198 deletions

View File

@@ -1,86 +1,127 @@
import CliDoc
extension CliDoc.Discussion {
extension CliDoc.Discussion where Content == AnyTextNode {
static func playbook(
examples: [(label: String, example: String)]
examples: [Example]
) -> Self {
.init {
Section {
VStack {
Note.mostOptionsNotRequired
Examples(examples: examples)
ExampleSection.default(examples: examples)
SeeAlso(label: "Ansible playbook options.", command: "ansible-playbook --help")
ImportantNote.passingExtraArgs
}
// .labeledContentStyle(.custom("foo:"))
.separator(.newLine(count: 2))
.eraseToAnyTextNode()
}
}
}
extension ShellCommand {
extension Array where Element == Example {
func addingPassingOptions(command: String) -> Self {
var output = self
output.append((
label: "Passing extra arguments / options",
example: "\(command) -- --vaultId=myId@$SCRIPTS/vault-gopass-client"
))
return output
}
}
extension ExampleSection where Header == String, Label == String {
static func `default`(examples: [Example], usesPassingExtraOptions: Bool = true) -> some TextNode {
var examples = examples
if usesPassingExtraOptions, let first = examples.first {
examples = examples.addingPassingOptions(command: first.example)
}
return Self(examples: examples) {
"EXAMPLES:"
} label: {
"Some common usage examples."
}
.exampleStyle(HPAExampleStyle())
}
}
struct HPAExampleStyle: ExampleStyle {
func render(content: ExampleConfiguration) -> some TextNode {
VStack {
content.examples.map { example in
VStack {
example.label.color(.green).bold()
ShellCommand.hpaCommand(example.example)
}
}
}
.separator(.newLine(count: 2))
}
}
extension ShellCommand where Content == String, Symbol == String {
static func hpaCommand(_ command: String) -> Self {
.init(command: "\(Constants.appName) \(command)")
.init { "\(Constants.appName) \(command)" } symbol: { "$" }
}
}
struct SeeAlso: NodeRepresentable {
struct SeeAlso<Label: TextNode, Content: TextNode>: TextNode {
let node: any NodeRepresentable
init(label: String, command: String) {
self.node = Group(separator: "\n") {
Note("SEE ALSO:") {
label
}
ShellCommand(command: command)
}
}
func render() -> String {
node.render()
}
}
struct Examples: NodeRepresentable {
typealias Example = (label: String, example: String)
let examples: [Example]
func render() -> String {
Group(separator: "\n") {
Note("EXAMPLES:") { "Common usage examples." }
for (label, command) in examples {
LabeledContent("\t\(label.green.bold)", separator: "\n") {
ShellCommand.hpaCommand(command)
}
}
if let first = examples.first {
LabeledContent("\n\tPassing extra options.".green.bold, separator: "\n") {
ShellCommand.hpaCommand("\(first.example) -- --vault-id \"myId@$SCRIPTS/vault-gopass-client\"")
}
}
}.render()
}
}
struct Note: NodeRepresentable {
let node: any NodeRepresentable
let title = "SEE ALSO:"
let label: Label
let content: Content
init(
_ label: String = "NOTE:",
@NodeBuilder _ content: () -> any NodeRepresentable
@TextBuilder content: () -> Content,
@TextBuilder label: () -> Label
) {
self.node = LabeledContent(
separator: " ",
label: { label.yellow.bold },
content: { content().style(.italic) }
)
self.content = content()
self.label = label()
}
func render() -> String {
node.render()
var body: some TextNode {
VStack {
LabeledContent {
label.italic()
} label: {
title.color(.yellow).bold().underline()
}
ShellCommand { content } symbol: { "$" }
}
}
}
extension SeeAlso where Content == String, Label == Empty {
init(command: String) {
self.init { "\(Constants.appName) \(command)" } label: { Empty() }
}
}
extension SeeAlso where Content == String, Label == String {
init(label: String, command: String) {
self.init { "\(Constants.appName) \(command)" } label: { label }
}
}
struct Note<Content: TextNode>: TextNode {
let label: String = "NOTE:"
let content: Content
init(
@TextBuilder _ content: () -> Content
) {
self.content = content()
}
var body: some TextNode {
HStack {
label.color(.yellow).bold()
content
}
}
}
extension Note where Content == String {
static var mostOptionsNotRequired: Self {
.init {
"Most options are not required if you have a configuration file setup."
@@ -88,26 +129,27 @@ struct Note: NodeRepresentable {
}
}
// TODO: Fix the text.
struct ImportantNote: NodeRepresentable {
struct ImportantNote<Content: TextNode>: TextNode {
let node: any NodeRepresentable
let label: String = "IMPORTANT NOTE:"
let content: Content
init(
_ label: String = "IMPORTANT NOTE:",
@NodeBuilder _ content: () -> any NodeRepresentable
@TextBuilder _ content: () -> Content
) {
self.node = LabeledContent(
separator: "\n",
label: { label.red.bold.underline },
content: { content().style(.italic) }
)
self.content = content()
}
func render() -> String {
node.render()
var body: some TextNode {
HStack {
label.color(.red).bold().underline()
content
}
}
}
extension ImportantNote where Content == String {
static var passingExtraArgs: Self {
.init {
"""