... |
... |
@@ -37,7 +37,6 @@ import click |
37
|
37
|
|
38
|
38
|
from buildstream import _yaml
|
39
|
39
|
from buildstream import utils
|
40
|
|
-from buildstream._frontend import cli as bst_cli
|
41
|
40
|
from buildstream._exceptions import BstError
|
42
|
41
|
|
43
|
42
|
|
... |
... |
@@ -176,20 +175,6 @@ def ansi2html(text, palette='solarized'): |
176
|
175
|
return sub
|
177
|
176
|
|
178
|
177
|
|
179
|
|
-@contextmanager
|
180
|
|
-def capture_stdout_stderr():
|
181
|
|
- from io import StringIO
|
182
|
|
-
|
183
|
|
- capture = StringIO()
|
184
|
|
- oldstdout, sys.stdout = sys.stdout, capture
|
185
|
|
- oldstderr, sys.stderr = sys.stderr, capture
|
186
|
|
-
|
187
|
|
- yield capture
|
188
|
|
-
|
189
|
|
- sys.stdout = oldstdout
|
190
|
|
- sys.stderr = oldstderr
|
191
|
|
-
|
192
|
|
-
|
193
|
178
|
# workdir()
|
194
|
179
|
#
|
195
|
180
|
# Sets up a new temp directory with a config file
|
... |
... |
@@ -219,7 +204,7 @@ def workdir(source_cache=None): |
219
|
204
|
yield (tempdir, bst_config_file, source_cache)
|
220
|
205
|
|
221
|
206
|
|
222
|
|
-# run_command()
|
|
207
|
+# run_bst_command()
|
223
|
208
|
#
|
224
|
209
|
# Runs a command
|
225
|
210
|
#
|
... |
... |
@@ -231,18 +216,33 @@ def workdir(source_cache=None): |
231
|
216
|
# Returns:
|
232
|
217
|
# (str): The colorized combined stdout/stderr of BuildStream
|
233
|
218
|
#
|
234
|
|
-def run_command(config_file, directory, command):
|
235
|
|
- click.echo("Running command in directory '{}': bst {}".format(directory, command), err=True)
|
|
219
|
+def run_bst_command(config_file, directory, command):
|
|
220
|
+ click.echo("Running bst command in directory '{}': bst {}".format(directory, command), err=True)
|
236
|
221
|
|
237
|
|
- args = ['--colors', '--config', config_file, '--directory', directory] + shlex.split(command)
|
|
222
|
+ argv = ['python3', '-m', 'buildstream', '--colors', '--config', config_file] + shlex.split(command)
|
|
223
|
+ p = subprocess.Popen(argv, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
224
|
+ out, _ = p.communicate()
|
|
225
|
+ return out.decode('utf-8').strip()
|
238
|
226
|
|
239
|
|
- with capture_stdout_stderr() as capture:
|
240
|
|
- bst_cli.main(args=args, prog_name=bst_cli.name)
|
241
|
227
|
|
242
|
|
- capture.flush()
|
243
|
|
- out = capture.getvalue()
|
|
228
|
+# run_shell_command()
|
|
229
|
+#
|
|
230
|
+# Runs a command
|
|
231
|
+#
|
|
232
|
+# Args:
|
|
233
|
+# directory (str): The project directory
|
|
234
|
+# command (str): A shell command
|
|
235
|
+#
|
|
236
|
+# Returns:
|
|
237
|
+# (str): The combined stdout/stderr of the shell command
|
|
238
|
+#
|
|
239
|
+def run_shell_command(directory, command):
|
|
240
|
+ click.echo("Running shell command in directory '{}': {}".format(directory, command), err=True)
|
244
|
241
|
|
245
|
|
- return out.strip()
|
|
242
|
+ argv = shlex.split(command)
|
|
243
|
+ p = subprocess.Popen(argv, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
244
|
+ out, _ = p.communicate()
|
|
245
|
+ return out.decode('utf-8').strip()
|
246
|
246
|
|
247
|
247
|
|
248
|
248
|
# generate_html
|
... |
... |
@@ -393,12 +393,18 @@ def run_session(description, tempdir, source_cache, palette, config_file, force) |
393
|
393
|
# Get the command string
|
394
|
394
|
command_str = _yaml.node_get(command, str, 'command')
|
395
|
395
|
|
|
396
|
+ # Check whether this is a shell command and not a bst command
|
|
397
|
+ is_shell = _yaml.node_get(command, bool, 'shell', default_value=False)
|
|
398
|
+
|
396
|
399
|
# Check if there is fake output
|
397
|
400
|
command_fake_output = _yaml.node_get(command, str, 'fake-output', default_value=None)
|
398
|
401
|
|
399
|
402
|
# Run the command, or just use the fake output
|
400
|
403
|
if command_fake_output is None:
|
401
|
|
- command_out = run_command(config_file, directory, command_str)
|
|
404
|
+ if is_shell:
|
|
405
|
+ command_out = run_shell_command(directory, command_str)
|
|
406
|
+ else:
|
|
407
|
+ command_out = run_bst_command(config_file, directory, command_str)
|
402
|
408
|
else:
|
403
|
409
|
command_out = command_fake_output
|
404
|
410
|
|
... |
... |
@@ -434,14 +440,8 @@ def run_session(description, tempdir, source_cache, palette, config_file, force) |
434
|
440
|
@click.option('--palette', '-p', default='tango',
|
435
|
441
|
type=click.Choice(['solarized', 'solarized-xterm', 'tango', 'xterm', 'console']),
|
436
|
442
|
help="Selects a palette for the output style")
|
437
|
|
-@click.option('--output', '-o',
|
438
|
|
- type=click.Path(file_okay=True, dir_okay=False, writable=True),
|
439
|
|
- help="A file to store the output")
|
440
|
|
-@click.option('--description', '-d',
|
441
|
|
- type=click.Path(file_okay=True, dir_okay=False, readable=True),
|
442
|
|
- help="A file describing what to do")
|
443
|
|
-@click.argument('command', type=click.STRING, nargs=-1)
|
444
|
|
-def run_bst(directory, force, source_cache, description, palette, output, command):
|
|
443
|
+@click.argument('description', click.Path(file_okay=True, dir_okay=False, readable=True))
|
|
444
|
+def run_bst(directory, force, source_cache, description, palette):
|
445
|
445
|
"""Run a bst command and capture stdout/stderr in html
|
446
|
446
|
|
447
|
447
|
This command normally takes a description yaml file, see the HACKING
|
... |
... |
@@ -450,45 +450,8 @@ def run_bst(directory, force, source_cache, description, palette, output, comman |
450
|
450
|
if not source_cache and os.environ.get('BST_SOURCE_CACHE'):
|
451
|
451
|
source_cache = os.environ['BST_SOURCE_CACHE']
|
452
|
452
|
|
453
|
|
- if output is not None and not check_needs_build(None, output, force=force):
|
454
|
|
- click.echo("No need to rebuild {}".format(output))
|
455
|
|
- return 0
|
456
|
|
-
|
457
|
453
|
with workdir(source_cache=source_cache) as (tempdir, config_file, source_cache):
|
458
|
|
-
|
459
|
|
- if description:
|
460
|
|
- run_session(description, tempdir, source_cache, palette, config_file, force)
|
461
|
|
- return 0
|
462
|
|
-
|
463
|
|
- # Run a command specified on the CLI
|
464
|
|
- #
|
465
|
|
- if not directory:
|
466
|
|
- directory = os.getcwd()
|
467
|
|
- else:
|
468
|
|
- directory = os.path.abspath(directory)
|
469
|
|
- directory = os.path.realpath(directory)
|
470
|
|
-
|
471
|
|
- if not command:
|
472
|
|
- command = []
|
473
|
|
- command_str = " ".join(command)
|
474
|
|
-
|
475
|
|
- # Run the command
|
476
|
|
- #
|
477
|
|
- command_out = run_command(config_file, directory, command_str)
|
478
|
|
-
|
479
|
|
- # Generate a nice html div for this output
|
480
|
|
- #
|
481
|
|
- converted = generate_html(command_out, directory, config_file,
|
482
|
|
- source_cache, tempdir, palette,
|
483
|
|
- command_str)
|
484
|
|
-
|
485
|
|
- if output is None:
|
486
|
|
- click.echo(converted)
|
487
|
|
- else:
|
488
|
|
- outdir = os.path.dirname(output)
|
489
|
|
- os.makedirs(outdir, exist_ok=True)
|
490
|
|
- with open(output, 'wb') as f:
|
491
|
|
- f.write(converted.encode('utf-8'))
|
|
454
|
+ run_session(description, tempdir, source_cache, palette, config_file, force)
|
492
|
455
|
|
493
|
456
|
return 0
|
494
|
457
|
|