Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions solr/solr-ref-guide/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,67 @@ String cliFileNameToNavLabel(String baseName) {
return baseName.split('-').last()
}

// Strip "[...]" (optional groups) and "(...)" (required groups whose members
// aren't *individually* required), repeating until no inner groups remain.
// Tokens left in the result are the ones the user must always provide.
String stripSynopsisGroups(String text) {
String s = text
String prev = null
while (s != prev) {
prev = s
s = s.replaceAll(/\[[^\[\]]*\]/, '')
s = s.replaceAll(/\([^()]*\)/, '')
}
return s
}

Set<String> extractRequiredTokens(String synopsis, java.util.regex.Pattern pattern) {
def result = new LinkedHashSet<String>()
def m = stripSynopsisGroups(synopsis) =~ pattern
while (m.find()) { result.add(m.group(1)) }
return result
}

// Parse the wrapped synopsis to find required (unbracketed) options and positional
// args, then prepend a "*(required)*" marker to their description lines in the
// Options and Arguments sections. Picocli's ManPageGenerator doesn't emit a
// per-option required marker, so we use the synopsis bracketing as the source of
// truth instead of reaching into the CommandSpec.
// See https://github.com/remkop/picocli/issues/2519.
String markRequiredOptionsAndArgs(String content) {
final String MARKER = '*(required)*'
final def OPTION_NAME = ~/(-{1,2}[a-zA-Z][a-zA-Z0-9-]*)/
final def POSITIONAL_NAME = ~/(<[^<>\s]+>)/

def synopsisMatch = content =~ /(?s)== Synopsis\n\n\.{4}\n(.*?)\n\.{4}/
if (!synopsisMatch.find()) return content

def synopsisText = synopsisMatch.group(1).replaceAll(/\s+/, ' ')
def requiredOpts = extractRequiredTokens(synopsisText, OPTION_NAME)
def requiredArgs = extractRequiredTokens(synopsisText, POSITIONAL_NAME)

if (!requiredOpts.isEmpty()) {
content = content.replaceAll(/(?m)^(\*-[^\n]+::)\n( +)([^\n]+)/) { List<String> m ->
def (label, indent, descLine) = [m[1], m[2], m[3]]
if (descLine.startsWith(MARKER)) return m[0]
def beforeEq = label.replaceAll(/[*_]/, '').split('=', 2)[0]
def names = (beforeEq =~ OPTION_NAME).collect { it[1] }
names.any { requiredOpts.contains(it) }
? "${label}\n${indent}${MARKER} ${descLine}" : m[0]
}
}

if (!requiredArgs.isEmpty()) {
content = content.replaceAll(/(?m)^_(<[^<>\n]+>)_::\n( +)([^\n]+)/) { List<String> m ->
def (name, indent, descLine) = [m[1], m[2], m[3]]
if (descLine.startsWith(MARKER)) return m[0]
requiredArgs.contains(name)
? "_${name}_::\n${indent}${MARKER} ${descLine}" : m[0]
}
}
return content
}

// Post-process a raw ManPageGenerator AsciiDoc file for Antora compatibility.
// The title lives inside the man-section-header block, so we replace the whole
// header block with an Antora-compatible page title + attributes.
Expand Down Expand Up @@ -631,6 +692,8 @@ String postProcessCliManPage(File rawFile, String asfHeader, String doNotEditNot
"${m[1]}....\n${synopsis}\n....${m[3]}"
}

content = markRequiredOptionsAndArgs(content)

// Strip the outer full-manpage tag wrappers
content = content.replace("// tag::picocli-generated-full-manpage[]\n", '')
content = content.replace("// end::picocli-generated-full-manpage[]\n", '')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Creates a core or collection depending on whether Solr is running in standalone
== Options

*-c*, *--name*=_<name>_::
Name of collection or core to create.
*(required)* Name of collection or core to create.

*-d*, *--conf-dir*=_<confDir>_::
Configuration directory to copy when creating the new collection; default is _default.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Deletes a collection or core depending on whether Solr is running in SolrCloud o
== Options

*-c*, *--name*=_<name>_::
Name of the core / collection to delete.
*(required)* Name of the core / collection to delete.

*--delete-config*::
Flag to indicate if the underlying configuration directory for a collection should also be deleted; default is false.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ and the last element of the <src> path will be appended unless <src> also ends i
== Arguments

_<src>_::
Source path: [file:][/]path/to/local/file or zk:/path/to/zk/node.
*(required)* Source path: [file:][/]path/to/local/file or zk:/path/to/zk/node.

_<dst>_::
Destination path: [file:][/]path/to/local/file or zk:/path/to/zk/node.
*(required)* Destination path: [file:][/]path/to/local/file or zk:/path/to/zk/node.

// end::picocli-generated-man-section-arguments[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ Download a configset from ZooKeeper to the local filesystem.
== Options

*-d*, *--conf-dir*=_DIR_::
Local directory with configs.
*(required)* Local directory with configs.

*-n*, *--conf-name*=_<confName>_::
Configset name in ZooKeeper.
*(required)* Configset name in ZooKeeper.

*-s*, *--solr-url*=_<solrUrl>_::
Base Solr URL, which can be used to determine the zk-host if --zk-host is not known
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ List the contents of a ZooKeeper node.
== Arguments

_<path>_::
The path of the ZooKeeper znode path to list.
*(required)* The path of the ZooKeeper znode path to list.

// end::picocli-generated-man-section-arguments[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Make a znode in ZooKeeper with no data. Can be used to make a path of arbitrary
== Arguments

_<path>_::
The ZooKeeper znode path to create.
*(required)* The ZooKeeper znode path to create.

// end::picocli-generated-man-section-arguments[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ and the last element of the <src> path will be appended.
== Arguments

_<src>_::
Source ZooKeeper znode path (zk: prefix optional).
*(required)* Source ZooKeeper znode path (zk: prefix optional).

_<dst>_::
Destination ZooKeeper znode path (zk: prefix optional).
*(required)* Destination ZooKeeper znode path (zk: prefix optional).

// end::picocli-generated-man-section-arguments[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Remove a znode from ZooKeeper.
== Arguments

_<path>_::
The ZooKeeper znode path to remove (zk: prefix optional).
*(required)* The ZooKeeper znode path to remove (zk: prefix optional).

// end::picocli-generated-man-section-arguments[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ Upload a configset from the local filesystem to ZooKeeper.
== Options

*-d*, *--conf-dir*=_DIR_::
Local directory with configs.
*(required)* Local directory with configs.

*-n*, *--conf-name*=_<confName>_::
Configset name in ZooKeeper.
*(required)* Configset name in ZooKeeper.

*-s*, *--solr-url*=_<solrUrl>_::
Base Solr URL, which can be used to determine the zk-host if --zk-host is not known
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Recursively re-applies ZooKeeper ACLs to a znode and all its descendants. The AC
== Arguments

_<path>_::
The ZooKeeper znode path to update ACLs for.
*(required)* The ZooKeeper znode path to update ACLs for.

// end::picocli-generated-man-section-arguments[]

Expand Down