diff --git a/behave/features/steps/common.py b/behave/features/steps/common.py
index 03b42dd0..74777bbb 100644
--- a/behave/features/steps/common.py
+++ b/behave/features/steps/common.py
@@ -124,6 +124,28 @@ def step_impl(context):
raise AssertionError(f"Stdout is not:\n{expected_str}\n\nActual stdout:\n{found_str}")
+@behave.step("stdout matches")
+def step_impl(context):
+ expected = context.text.format(context=context).rstrip()
+ found = context.cmd_stdout.rstrip()
+
+ if re.match(expected, found, re.MULTILINE):
+ return
+
+ raise AssertionError(f"Stdout doesn't match:\n{expected}\n\nActual stdout:\n{found}")
+
+
+@behave.step("I search '{pattern}' in stdout and store named groups in '{context_attribute}'")
+def step_impl(context, pattern, context_attribute):
+ pattern = r"{}".format(pattern)
+
+ result = []
+ for match in re.finditer(pattern, context.cmd_stdout):
+ result.append(match.groupdict())
+
+ setattr(context, context_attribute, result)
+
+
@behave.step("stderr is")
def step_impl(context):
expected = context.text.format(context=context).rstrip().split("\n")
diff --git a/behave/features/token.feature b/behave/features/token.feature
new file mode 100644
index 00000000..72fefd6a
--- /dev/null
+++ b/behave/features/token.feature
@@ -0,0 +1,38 @@
+Feature: `osc token` command
+
+
+Scenario: Run `osc token` with no arguments
+ When I execute osc with args "token"
+ Then stdout is
+ """
+
+ """
+
+
+Scenario: Run `osc token --operation rebuild`
+ When I execute osc with args "token --create --operation rebuild test:factory test-pkgA"
+ Then stdout matches
+ """
+ Create a new token
+
+ Ok
+ .*
+ 1
+
+ """
+ Given I execute osc with args "token"
+ And stdout matches
+ """
+
+
+
+ """
+ And I search 'string="(?P[^"]+)' in stdout and store named groups in 'tokens'
+ When I execute osc with args "token --trigger {context.tokens[0][token]}"
+ Then stdout is
+ """
+ Trigger token
+
+ Ok
+
+ """
diff --git a/osc/commandline.py b/osc/commandline.py
index f488794e..9178bcf1 100644
--- a/osc/commandline.py
+++ b/osc/commandline.py
@@ -1659,7 +1659,7 @@ class Osc(cmdln.Cmdln):
@cmdln.option('-d', '--delete', metavar='TOKENID',
help='Delete a token')
@cmdln.option('-o', '--operation', metavar='OPERATION',
- help='Default is "runservice", but "branch", "release", "rebuild", or "workflow" can also be used')
+ help="Operation associated with the token. Choices: runservice, branch, release, rebuild, workflow")
@cmdln.option('-t', '--trigger', metavar='TOKENSTRING',
help='Trigger the action of a token')
@cmdln.option('', '--scm-token', metavar='SCM_TOKEN',
@@ -1673,7 +1673,7 @@ class Osc(cmdln.Cmdln):
usage:
osc token
- osc token --create [--operation ] [ ]
+ osc token --create --operation [ ]
osc token --delete
osc token --trigger [--operation ] [ ]
"""
@@ -1688,6 +1688,8 @@ class Osc(cmdln.Cmdln):
url_path = ['person', conf.get_apiurl_usr(apiurl), 'token']
if opts.create:
+ if not opts.operation:
+ self.argparser.error("Please specify --operation")
if opts.operation == 'workflow' and not opts.scm_token:
msg = 'The --operation=workflow option requires a --scm-token= option'
raise oscerr.WrongOptions(msg)
@@ -1716,12 +1718,14 @@ class Osc(cmdln.Cmdln):
http_DELETE(url)
elif opts.trigger:
print("Trigger token")
- operation = opts.operation or "runservice"
query = {}
if len(args) > 1:
query['project'] = args[0]
query['package'] = args[1]
- url = makeurl(apiurl, ['trigger', operation], query)
+ if opts.operation:
+ url = makeurl(apiurl, ["trigger", opts.operation], query)
+ else:
+ url = makeurl(apiurl, ["trigger"], query)
headers = {
'Content-Type': 'application/octet-stream',
'Authorization': "Token " + opts.trigger,