Permalink
Browse files

[enhance] manpages: created simple program for quick manpage generation

  • Loading branch information...
1 parent 9489580 commit c55ebd19cc30948db2e2cf0fc41a3fd0eec6fcd3 Mathieu Baudet committed Dec 16, 2011
Showing with 155 additions and 9 deletions.
  1. +30 −9 manpages/Makefile
  2. +3 −0 manpages/_tags
  3. +121 −0 manpages/genman.ml
  4. +1 −0 manpages/opa-cloud.summary
View
@@ -1,18 +1,39 @@
BLDDIR=../_build
-#MANDIR=$(BDLDIR)/manpages
+BINDIR=$(BLDDIR)/bin
-.PHONY: all
+.PHONY: all clean
-all: opa.1 opatop.1 opa-db-server.1 opa-db-tool.1 opa-plugin-browser.1 opa-plugin-builder.1 opadoc.1
+EXCLUDE=opa-bin mlstate_platform
+INCLUDE=opa
+BINS=$(INCLUDE) $(filter-out $(EXCLUDE), $(notdir $(wildcard $(BLDDIR)/bin/* $(BLDDIR)/lib/opa/bin/*)))
+
+TARGETS=$(BINS:=.1)
+
+all: $(TARGETS)
+
+clean:
+ rm -f $(TARGETS)
+
+GENMAN=$(BLDDIR)/manpages/genman.native
+
+$(GENMAN): genman.ml
+ cd ..; bld -cflags "-w -14" manpages/genman.native
+
+$(BLDDIR)/opa/gen_opa_manpage.native: ../opa/gen_opa_manpage.ml
+ cd ..; bld -cflags manpages/opa/gen_opa_manpage.native
opa.1: $(BLDDIR)/opa/gen_opa_manpage.native
$< > $@
-opatop.1: $(BLDDIR)/opatop/gen_opatop_manpage.native
- $< > $@
+#opatop.1: $(BLDDIR)/opatop/gen_opatop_manpage.native
+# $< > $@
+
+%.help: $(BLDDIR)/bin/%
+ $< --help >$@ 2>&1 ||true
+
+%.help: $(BLDDIR)/lib/opa/bin/%
+ $< --help >$@ 2>&1 ||true
-%.1: $(BLDDIR)/bin/%
- @echo ".TH \"$*\" \"1\" \"`date +"%Y-%m-%d"`\" \"\" \"Opa Manual\"" > $@
- @echo ".SH \"HELP\"" >> $@
- $< --help 2>> $@ ||true
+%.1: %.help $(GENMAN)
+ $(GENMAN) $* > $@
View
@@ -0,0 +1,3 @@
+# -*- conf -*- (for emacs)
+
+<genman.{ml,byte,native}>: use_unix, use_str, use_libbase
View
@@ -0,0 +1,121 @@
+(*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*)
+
+(** This program is meant to quickly build manpages either from existing sections in proper files, or by a quick-and-dirty parsing of the result of --help *)
+
+let cmdname =
+ try
+ Sys.argv.(1)
+ with
+ _ -> (Printf.eprintf ("Usage: genman %s <cmdname> [summary]\n") Sys.argv.(0); exit 1)
+
+let read_section name = File.content_opt (cmdname ^ "." ^ name)
+
+let help_summary, help_synopsis, help_description, help_options =
+ match read_section "help" with
+ None -> "","","",""
+ | Some help ->
+ let reg0 = (* one line summary ? *)
+ Str.regexp ("^.*"^ (Str.quote cmdname) ^"[ \t]*:[ \t]*\(.*\)$")
+ in
+ let is_blank x =
+ BaseString.contains " \n\t" x
+ in
+ let summary, pos0 =
+ try
+ if Str.string_partial_match reg0 help 0
+ then
+ BaseString.ltrim ~is_space:is_blank (Str.matched_group 1 help), (Str.match_end () + 1) (* +1 is meant to skip \n *)
+ else
+ "", 0
+ with
+ Not_found -> "", 0
+ in
+ let reg1 = (* one line synopsis ? *)
+ Str.regexp ("^[ \t]*[Uu]sage[ \t]*:.*\("^ (Str.quote cmdname) ^".*\)$")
+ in
+ let synopsis, pos1 =
+ try
+ if Str.string_partial_match reg1 help pos0
+ then
+ BaseString.ltrim ~is_space:is_blank (Str.matched_group 1 help), (Str.match_end () +1)
+ else
+ "", pos0
+ with
+ Not_found -> "", pos0
+ in
+ let reg2 = (* beginning of the list of options after the description ? *)
+ Str.regexp "^\(.*[Oo]ptions.*\):[ \t]*\n\([ \t]*--?[a-zA-Z0-0]+\)"
+ in
+ let description, options =
+ try
+ let pos1a = Str.search_forward reg2 help pos1
+ in
+ (* description *)
+ BaseString.ltrim ~is_space:is_blank (BaseString.sub help pos1 (pos1a-pos1)),
+ (* options *)
+ let first_words =
+ BaseString.trim ~is_space:is_blank (Str.matched_group 1 help)
+ in
+ (* N.B. we try keep the last line before the first option unless it's just "Options:" *)
+ let pos2 =
+ if first_words = "Options" || first_words = "options" then Str.group_beginning 2 else pos1a
+ in
+ BaseString.rtrim ~is_space:is_blank (Str.string_after help pos2)
+ with
+ Not_found ->
+ BaseString.ltrim ~is_space:is_blank (Str.string_after help pos1), ""
+ (* no option? then put everything in description *)
+ in
+ summary, synopsis, description, options
+
+let summary = try
+ Some(Sys.argv.(2))
+ with _ ->
+ begin match read_section "summary", help_summary with
+ None, s when s <> "" -> Some(s)
+ | x, _ -> x
+ end
+
+let synopsis =
+ match read_section "synopsis", help_synopsis with
+ | None, s when s <> "" -> Some(s)
+ | x, _ -> x
+(* | Some(s), _ -> Some(s)
+ | _, _ -> Some(Printf.sprintf "%s [options]" cmdname)
+*)
+
+let description =
+ match read_section "description", help_description with
+ None, s when s <> "" -> Some(s)
+ | x, _ -> x
+
+let options =
+ match read_section "options", help_options with
+ None, s when s <> "" -> Some(s)
+ | x, _ -> x
+
+let _ = BaseArg.write_simple_manpage
+ ~cmdname
+ ?summary
+ ~section:1
+ ~centerheader:"Opa Manual"
+ ?synopsis
+ ?description
+ ?other:(match options with Some(str) -> Some["OPTIONS", str] | None -> None)
+ stdout
@@ -0,0 +1 @@
+Dispatcher for a service across a network

0 comments on commit c55ebd1

Please sign in to comment.