[spp] [PATCH 11/12] spp: refactor help messages in Shell class
ogawa.yasufumi at lab.ntt.co.jp
ogawa.yasufumi at lab.ntt.co.jp
Tue Mar 6 11:39:28 CET 2018
From: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
Each of help messages for command are defined as a comment of 'do_*'
method and referred from help command.
This update is adding or revising help messages for 'do_*' methods.
It also revise other comments in Shell class.
Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
---
src/spp.py | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 137 insertions(+), 22 deletions(-)
diff --git a/src/spp.py b/src/spp.py
index 232b528..935616f 100755
--- a/src/spp.py
+++ b/src/spp.py
@@ -369,6 +369,11 @@ class Shell(cmd.Cmd, object):
BYE_CMDS = ['sec', 'all']
def decorate_dir(self, curdir, filelist):
+ """Add '/' the end of dirname for path completion
+
+ 'filelist' is a list of files contained in a directory.
+ """
+
res = []
for f in filelist:
if os.path.isdir('%s/%s' % (curdir, f)):
@@ -378,21 +383,38 @@ class Shell(cmd.Cmd, object):
return res
def compl_common(self, text, line, ftype=None):
- if text == '':
+ """File path completion for 'complete_*' method
+
+ This method is called from 'complete_*' to complete 'do_*'.
+ 'text' and 'line' are arguments of 'complete_*'.
+
+ `complete_*` is a member method of builtin Cmd class and
+ called if tab key is pressed in a command defiend by 'do_*'.
+ 'text' and 'line' are contents of command line.
+ For example, if you type tab at 'command arg1 ar',
+ last token 'ar' is assigned to 'text' and whole line
+ 'command arg1 ar' is assigned to 'line'.
+
+ NOTE:
+ If tab is typed after '/', empty text '' is assigned to
+ 'text'. For example 'aaa b/', text is not 'b/' but ''.
+ """
+
+ if text == '': # tab is typed after command name or '/'
tokens = line.split(' ')
- target_dir = tokens[-1]
- if target_dir == '':
+ target_dir = tokens[-1] # get dirname for competion
+ if target_dir == '': # no dirname means current dir
res = self.decorate_dir(
'.', os.listdir(os.getcwd()))
- else:
+ else: # after '/'
res = self.decorate_dir(
target_dir, os.listdir(target_dir))
- else:
+ else: # tab is typed in the middle of a word
tokens = line.split(' ')
- target = tokens[-1]
+ target = tokens[-1] # target dir for completion
- if '/' in target:
- seg = target.split('/')[-1]
+ if '/' in target: # word is a path such as 'path/to/file'
+ seg = target.split('/')[-1] # word to be completed
target_dir = '/'.join(target.split('/')[0:-1])
else:
seg = text
@@ -400,11 +422,11 @@ class Shell(cmd.Cmd, object):
matched = []
for t in os.listdir(target_dir):
- if t.find(seg) == 0:
+ if t.find(seg) == 0: # get words matched with 'seg'
matched.append(t)
res = self.decorate_dir(target_dir, matched)
- if ftype is not None:
+ if ftype is not None: # filtering by ftype
completions = []
if ftype == 'directory':
for fn in res:
@@ -421,6 +443,14 @@ class Shell(cmd.Cmd, object):
return completions
def is_comment_line(self, line):
+ """Find commend line to not to interpret as a command
+
+ Return True if given line is a comment, or False.
+ Supported comment styles are
+ * python ('#')
+ * C ('//')
+ """
+
input_line = line.strip()
if len(input_line) > 0:
if (input_line[0] == '#') or (input_line[0:2] == '//'):
@@ -431,10 +461,8 @@ class Shell(cmd.Cmd, object):
def default(self, line):
"""Define defualt behaviour
- If user input is commend styled, controller simply echo as a comment.
- Supported styles are
- - python ('#')
- - C ('//')
+ If user input is commend styled, controller simply echo
+ as a comment.
"""
if self.is_comment_line(line):
@@ -451,7 +479,7 @@ class Shell(cmd.Cmd, object):
pass
def close_all_secondary(self):
- """Exit all secondary processes"""
+ """Terminate all secondary processes"""
global SECONDARY_COUNT
global SECONDARY_LIST
@@ -464,13 +492,19 @@ class Shell(cmd.Cmd, object):
SECONDARY_COUNT = 0
def get_status(self):
+ """Return status of primary and secondary processes
+
+ It is called from do_status() method and return primary status
+ and a list of secondary processes as status.
+ """
+
global SECONDARY_LIST
secondary = []
for i in SECONDARY_LIST:
secondary.append("%d" % i)
stat = {
- "primary": "%d" % PRIMARY,
+ "primary": "%d" % PRIMARY, # PRIMARY is 1 if it is running
"secondary": secondary
}
return stat
@@ -637,6 +671,7 @@ class Shell(cmd.Cmd, object):
def response(self, result, message):
"""Enqueue message from other than CLI"""
+
try:
rcmd = RCMD_EXECUTE_QUEUE.get(False)
except Empty:
@@ -650,14 +685,23 @@ class Shell(cmd.Cmd, object):
logger.debug("unknown remote command = %s" % rcmd)
def do_status(self, _):
- """Display Soft Patch Panel Status"""
+ """Display status info of SPP processes
+
+ spp > status
+ """
self.print_status()
stat = self.get_status()
self.response(self.CMD_OK, json.dumps(stat))
def do_pri(self, command):
- """Send command to primary process"""
+ """Send command to primary process
+
+ Spp primary takes sub commands.
+
+ spp > pri;status
+ spp > pri;clear
+ """
if command and command in self.PRI_CMDS:
result, message = self.command_primary(command)
@@ -668,7 +712,15 @@ class Shell(cmd.Cmd, object):
self.response(self.CMD_ERROR, message)
def do_sec(self, arg):
- """Send command to secondary process"""
+ """Send command to secondary process
+
+ SPP secondary process is specified with secondary ID and takes
+ sub commands.
+
+ spp > sec 1;status
+ spp > sec 1;add ring 0
+ spp > sec 1;patch 0 2
+ """
# remove unwanted spaces to avoid invalid command error
tmparg = clean_sec_cmd(arg)
@@ -695,7 +747,15 @@ class Shell(cmd.Cmd, object):
return self.compl_common(text, line)
def do_record(self, fname):
- """Save future commands to filename: RECORD filename.cmd"""
+ """Save commands to a log file
+
+ Save command history to a log file for loading from playback
+ command later as a config file.
+ Config is a series of SPP command and you can also create it
+ from scratch without playback command.
+
+ spp > record path/to/file
+ """
if fname == '':
print("Record file is required!")
@@ -707,7 +767,13 @@ class Shell(cmd.Cmd, object):
return self.compl_common(text, line)
def do_playback(self, fname):
- """Playback commands from a file: PLAYBACK filename.cmd"""
+ """Load a config file to reproduce network configuration
+
+ Config is a series of SPP command and you can also create it
+ from scratch without playback command.
+
+ spp > playback path/to/config
+ """
if fname == '':
print("Record file is required!")
@@ -728,6 +794,11 @@ class Shell(cmd.Cmd, object):
self.response(self.CMD_NG, message)
def precmd(self, line):
+ """Called before running a command
+
+ It is called for checking a contents of command line.
+ """
+
if self.recorded_file:
if not (
('playback' in line) or
@@ -745,12 +816,26 @@ class Shell(cmd.Cmd, object):
self.recorded_file = None
def do_pwd(self, args):
+ """Show corrent directory
+
+ It behaves as UNIX's pwd command.
+
+ spp > pwd
+ """
+
print(os.getcwd())
def complete_ls(self, text, line, begidx, endidx):
return self.compl_common(text, line)
def do_ls(self, args):
+ """Show a list of specified directory
+
+ It behaves as UNIX's ls command.
+
+ spp > ls path/to/dir
+ """
+
if args == '' or os.path.isdir(args):
c = 'ls -F %s' % args
subprocess.call(c, shell=True)
@@ -761,6 +846,11 @@ class Shell(cmd.Cmd, object):
return self.compl_common(text, line, 'directory')
def do_cd(self, args):
+ """Change current directory
+
+ spp > cd path/to/dir
+ """
+
if os.path.isdir(args):
os.chdir(args)
print(os.getcwd())
@@ -771,11 +861,30 @@ class Shell(cmd.Cmd, object):
return self.compl_common(text, line)
def do_mkdir(self, args):
+ """Create a new directory
+
+ It behaves as 'mkdir -p'.
+
+ spp > mkdir path/to/dir
+ """
+
c = 'mkdir -p %s' % args
subprocess.call(c, shell=True)
def do_bye(self, arg):
- """Stop recording, close SPP, and exit: BYE"""
+ """Terminate SPP processes and controller
+
+ It also terminates logging if you activate recording.
+
+ (1) Terminate secondary processes
+ spp > bye sec
+
+ (2) Terminate primary and secondary processes
+ spp > bye all
+
+ (3) Terminate SPP controller (not for primary and secondary)
+ spp > bye
+ """
cmds = arg.split(' ')
if cmds[0] == 'sec':
@@ -789,6 +898,12 @@ class Shell(cmd.Cmd, object):
return True
def do_exit(self, args):
+ """Terminate SPP controller
+
+ It is an alias for bye command and same as bye command.
+
+ spp > exit
+ """
self.close()
print('Thank you for using Soft Patch Panel')
return True
--
2.13.1
More information about the spp
mailing list