Skip to content

Commit

Permalink
Make '--help' output accurate & consistent with rest of CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
sadielbartholomew authored and Bruno P. Kinoshita committed Oct 18, 2018
1 parent 9e2d975 commit 0382b61
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 46 deletions.
28 changes: 4 additions & 24 deletions bin/cylc-review
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash

# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2018 NIWA
Expand All @@ -15,31 +15,11 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#-------------------------------------------------------------------------------
# NAME
# cylc review
#
# SYNOPSIS
# cylc review start [PORT] # start ad-hoc web service server (on PORT)
# cylc review stop # stop ad-hoc web service server
# cylc review stop -y # stop ad-hoc web service server w/o prompting
# cylc review # print status of ad-hoc web service server
#
# DESCRIPTION
# Start/stop ad-hoc Cylc Review web service server.
#
# For "cylc review start", if PORT is not specified, use port 8080.
#
# Cylc Review is a web service for browsing users' suite logs via
# an HTTP interface.
# cylc review
# Web service for browsing users' suite logs via an HTTP interface.
#
# OPTIONS
# --non-interactive, --yes, -y
# (For stop only.) Switch off interactive prompting (=answer yes to
# everything)
# --service-root, -R
# (For start only.) Include web service name under root of URL.
# ['lib/cylc/review.py' module has formal docstring output for '--help' option]
#-------------------------------------------------------------------------------

exec python -m cylc.review "$@"
11 changes: 9 additions & 2 deletions lib/cylc/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Web service for browsing users' suite logs via an HTTP interface."""
"""cylc [info] review [OPTIONS] ARGS
Start/stop ad-hoc Cylc Review web service server for browsing users' suite
logs via an HTTP interface.
With no arguments, the status of the ad-hoc web service server is printed.
For 'cylc review start', if 'PORT' is not specified, port 8080 is used."""

import cherrypy
from fnmatch import fnmatch
Expand Down Expand Up @@ -888,7 +895,7 @@ def _sort_summary_entries(suite1, suite2):

if __name__ == "__main__":
from cylc.ws import ws_cli
ws_cli(CylcReviewService)
ws_cli(CylcReviewService, __doc__)
elif 'doctest' not in sys.argv[0]:
# If called as a module but not by the doctest module.
from cylc.ws import wsgi_app
Expand Down
43 changes: 23 additions & 20 deletions lib/cylc/ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
wsgi_app - Return a WSGI application for a web service.
ws_cli - Parse CLI. Start/Stop ad-hoc server.
"""

import cherrypy
Expand Down Expand Up @@ -52,48 +51,52 @@ def wsgi_app(service_cls, *args, **kwargs):
cherrypy.engine.stop()


def ws_cli(service_cls, *args, **kwargs):
def ws_cli(service_cls, service_docstr, *args, **kwargs):
"""Parse command line, start/stop ad-hoc server.
service_cls - Class to launch web service. Must have the constants
service_cls.NS and service_cls.UTIL. *args and **kwargs are
passed to its constructor.
"""

parser = COP(
__doc__,
service_docstr,
argdoc=[
("[START]", "Start an ad-hoc server."),
("[STOP]", "Stop an ad-hoc server.")])
("[start [PORT]]", "Start ad-hoc web service server."),
("[stop]", "Stop ad-hoc web service server.")])

parser.add_option(
"--non-interactive", "--yes", "-y",
help="Switch off interactive prompting.",
help="Switch off interactive prompting i.e. answer yes to everything"
" (for stop only).",
action="store_true", default=False, dest="non_interactive")
parser.add_option(
"--service-root", "-R",
help="Include web service name under root of URL.",
help="Include web service name under root of URL (for start only).",
action="store_true", default=False, dest="service_root_mode")

opts, args = parser.parse_args()
opts, args = parser.parse_args(
remove_opts=['--host', '--user', '--verbose', '--debug'])
arg = None
if args:
arg = args[0]
status = _get_server_status(service_cls)
if arg == "start":
port = None
if args[1:]:
port = args[1]
_ws_init(service_cls, port, opts.service_root_mode, *args, **kwargs)
elif not status:
print "No %s service server running." % service_cls.TITLE
else:
status = _get_server_status(service_cls)
for key, value in sorted(status.items()):
print "%s=%s\n" % (key, value)
if (arg == "stop" and status.get("pid") and
(opts.non_interactive or
raw_input("Stop server? y/n (default=n)") == "y")):
print "%s=%s" % (key, value)
if (arg == "stop" and status.get("pid") and (opts.non_interactive or
raw_input("Stop server via termination? y/n (default=n)") == "y")):
try:
os.killpg(int(status["pid"]), signal.SIGTERM)
except OSError:
print "Already terminated."
print "Termination signal failed."


def _ws_init(service_cls, port, service_root_mode, *args, **kwargs):
Expand Down Expand Up @@ -136,11 +139,11 @@ def _ws_init(service_cls, port, service_root_mode, *args, **kwargs):
def _configure(service_cls):
"""Configure cherrypy and return a dict for the specified cherrypy app."""
# Environment variables (not normally defined in WSGI mode)
if not os.getenv("CYLC_HOME"):
if not os.getenv("CYLC_DIR"):
path = os.path.abspath(__file__)
while os.path.dirname(path) != path: # not root
if os.path.basename(path) == "lib":
os.environ["CYLC_HOME"] = os.path.dirname(path)
os.environ["CYLC_DIR"] = os.path.dirname(path)
break
path = os.path.dirname(path)
for key, value in (
Expand Down Expand Up @@ -168,7 +171,7 @@ def _configure(service_cls):


def _get_server_status(service_cls):
"""Return a dict containing 'cylc review' quick server status."""
"""Return a dict containing quick service server status."""
ret = {}
log_root_glob = os.path.expanduser(LOG_ROOT_TMPL % {
"ns": service_cls.NS,
Expand All @@ -187,15 +190,15 @@ def _get_server_status(service_cls):


def get_util_home(*args):
"""Return CYLC_HOME or the dirname of the dirname of sys.argv[0].
"""Return CYLC_DIR or the dirname of sys.argv[0].
If args are specified, they are added to the end of returned path.
"""
try:
value = os.environ["CYLC_HOME"]
value = os.environ["CYLC_DIR"]
except KeyError:
value = os.path.abspath(__file__)
for _ in range(3): # assume __file__ under $CYLC_HOME/lib/cylc
for _ in range(4): # assume __file__ under $CYLC_DIR/lib/cylc/
value = os.path.dirname(value)
return os.path.join(value, *args)

0 comments on commit 0382b61

Please sign in to comment.