Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Joker library to support tools with multiple embedded commands

License

NotificationsYou must be signed in to change notification settings

hlship/multi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

net.lewisship.multi is a complement to joker.tools.cli that allows a single tool, a Joker script, tocontain multiple commands, each with its own command line options and arguments.

At the core is thenet.lewisship.multi/dispatch macro; this identifies the name of the tool, andoptionally, the namespaces to collect commands from.

Each command within the tool is provided via thenet.lewisship.multi/defcommand macro.

A command option,-h / --help, is added to all commands automatically.

Ahelp command is also added; it displays the list of commands available.The help command displays the first line of each command's docstring, as a summaryof the command.

Thehelp command displays a short summary of what the overall tool does; this is the docstringof the first namespace provided todispatch (again, if omitted, the current namespaceis used).

Whereas command option parsing is driven by the option names, command argumentparsing is positional. Each command option spec will consume one command line argument(exception: the last spec may be repeatable).

command argument specs are similar to command option specs; each spec is a vector that startswith one or two strings; the first string is always the label (by convention,in upper case). The optional second string is the documentation of the argument.

Following that are key/value pairs:

  • :id (keyword) - identifies which key is used in the arguments map; by default,this is the label converted to a lower case keyword

  • :doc (string) - documentation for the argument

  • :optional (boolean) -- if true, the argument may be omitted if there isn't acommand line argument to match

  • :repeatable (boolean) -- if true, then any remaining command line arguments are processedby the argument

  • :parse-fn - passed the command line argument, returns a value, or throws an exception

  • :validate - a vector of function/message pairs

  • :update-fn - optional function used to update the (initially nil) entry for the argument in the :arguments map

  • :assoc-fn - optional function used to update the arguments map; passed the map, the id, and the parsed value

  • :update-fn and:assoc-fn are mutually exclusive.

For repeatable arguments, the default update function will construct a vector of values.For non-repeatable arguments, the default update function simply sets the value.

Using multi

#!/usr/bin/env joker(ns-sources  {"net.lewisship.multi" {:url "https://raw.githubusercontent.com/hlship/multi/v1.4.0/src/net/lewisship/multi.joke"}})(ns example  "System management tool"  (:require [net.lewisship.multi :as multi]))(multi/defcommand configure  "Configures the system with keys and values"  [verbose ["-v" "--verbose" "Enable verbose logging"]   :args   host ["HOST" "System configuration URL"         :validate [#(re-matches #"https?://.+" %) "must be a URL"]]   key-values ["DATA" "Data to configure as KEY=VALUE"               :parse-fn (fn [s]                           (when-let [[_ k v] (re-matches #"(.+)=(.+)" s)]                             [(keyword k) v]))               :update-fn (fn [m [k v]]                            (assoc m k v))               :repeatable true]]  (prn :verbose verbose :host host :key-values key-values);; Execution:(multi/dispatch {:tool-name "example"]})

If this file is saved asbin/example, it can be executed directly:

> bin/example configure --helpUsage: example configure [OPTIONS] HOST DATA+Configures the system with keys and valuesOptions:  -v, --verbose  Enable verbose logging  -h, --help     This command summaryArguments:  HOST: System configuration URL  DATA: Data to configure as KEY=VALUE> bin/example configure http://localhost:9983 retries=3 alerts=on -v:verbose true :host "http://localhost:9983" :key-values {:retries "3", :alerts "on"}

Notes:

  • Withdefcommand a docstring is required
  • After the docstring comes theinterface, which defines options and arguments
  • The interface initially expects to consume a symbol then an option spec
  • The:args keyword switches over to consuming symbol and argument spec

Thedispatch macro normally searches fordefcommands in the same namespace, but this can beoverridden by providing a list of namespace symbols as the:namespaces option.

Tool documentation comes from the docstring of the first namespace.

defcommand extras

:as <symbol>

Inside the interface, you can request thecommand map using:as.This command map is used when invokingnet.lewisship.multi/show-summary,which a command may wish to do to present errors to the user.

:command-name <string>

You may also override the command name away from its default (the name of the function).

For example, if you had an existingconfigure function you didn't want to rename,then you could name the command functionconfigure-command:

(multi/defcommand configure-command  "Configures the system with keys and values"  [verbose ["-v" "--verbose" "Enable verbose logging"]   :args   host ["HOST" "System configuration URL"         :validate [#(re-matches #"https?://.+" %) "must be a URL"]]   key-values ["DATA" "Data to configure as KEY=VALUE"               :parse-fn (fn [s]                           (when-let [[_ k v] (re-matches #"(.+)=(.+)" s)]                             [(keyword k) v]))               :update-fn (fn [m [k v]]                            (assoc m k v))               :repeatable true]   :command-name "configure"]  ...)

Meta Data

Finally, you can specify additional meta data for the command by applyingit to the command's symbol. For example:

(multi/defcommand ^{:command-name "conf"} configure  ...

... though there's rarely a need to ever do this.

Function Metadata

Thedefcommand macro works by adding the following meta-data to the Var it creates:

  • :command (boolean) -- indicates the function is a command

  • :command-name (string, optional) -- overrides the name of the command, normally the symbol

  • :doc (string) -- the command's docstring is the command description, used when printing help

  • :command-opts - a list of option specs, passed to joker.tools.cli/parse-opts

  • :command-args - a list of positional argument specs

The command function is ultimately passed the command map containing two sub-maps:The :options map contains the command options, and the :argumentsmap contains a map of processed command line arguments;defcommand adds alet to pull values out of the command map and into theoption and argument symbols you define in the interface.

Other keys within the command map are private, used by multi.

Again,defcommand is the preferred way to define commands.

License

multi is (c) 2019-present Howard M. Lewis Ship.

It is released under the terms of the Apache Software License, 2.0.

About

Joker library to support tools with multiple embedded commands

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp