-
-
Notifications
You must be signed in to change notification settings - Fork 67
Automate generation of outputs #248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
587c2ae
Use patched sphinxcontrib.runcmd to execute the commands.
kinow 25b8896
Migrate sections to use runcmd where possible.
kinow 5b87ec6
Include cwl_runner Python module for running the examples now
kinow 3f8ed21
Handle RTD paths
kinow 3781f20
USe CWLTOOL_OPTIONS to disable terminal colors (thanks @mr-c !)
kinow 6e6f580
Remove TODO/patched messages. Note that the original source is linked…
kinow 21a76ce
s/cwl-runner/cwltool (where appropriate)
kinow 382445d
Revert cwltool in shebang
kinow 00b81ff
Install nodejs on RTD
kinow 9b20c53
Trying to install docker in RTD (docker in docker?)
kinow fb846ca
Use Ubuntu 22.04
kinow 172b8a9
Try a fix for podman docker
kinow 04edaee
Add CWLTOOL_OPTIONS with udocker in GH Actions env property
kinow 44a23e1
try GH builds w/o udocker
mr-c 86106a0
pre-pull the containers
mr-c File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,5 @@ _site | |
|
||
_build/ | ||
*.egg-info/ | ||
|
||
src/_includes/cwl/**/output.txt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
import csv | ||
import os | ||
import re | ||
import shlex | ||
import subprocess | ||
import sys | ||
|
||
from pathlib import Path | ||
|
||
from docutils.parsers.rst import directives | ||
from sphinx.directives import code | ||
|
||
"""" | ||
Patched version of https://github.com/sphinx-contrib/sphinxcontrib-runcmd | ||
with default values to avoid having to re-type in every page. Also | ||
prepends commands with a value (``$``), see https://github.com/invenia/sphinxcontrib-runcmd/issues/1. | ||
Finally, it also checks if the command is ``cwltool``, and if then | ||
tries to remove any paths from the command-line (not the logs). | ||
""" | ||
|
||
__version__ = "0.2.0" | ||
|
||
# CONSTANTS | ||
RE_SPLIT = re.compile(r"(?P<pattern>.*)(?<!\\)/(?P<replacement>.*)") | ||
|
||
|
||
# These classes were in the .util module of the original directive. | ||
class _Singleton(type): | ||
_instances = {} | ||
|
||
def __call__(cls, *args, **kwargs): | ||
if cls not in cls._instances: | ||
cls._instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs) | ||
return cls._instances[cls] | ||
|
||
|
||
class Singleton(_Singleton("SingletonMeta", (object,), {})): | ||
pass | ||
|
||
|
||
class CMDCache(Singleton): | ||
cache = {} | ||
|
||
def get(self, cmd, working_directory): | ||
h = hash(cmd) | ||
if h in self.cache: | ||
return self.cache[h] | ||
else: | ||
result = run_command(cmd, working_directory) | ||
self.cache[h] = result | ||
return result | ||
|
||
|
||
def run_command(command, working_directory): | ||
true_cmd = shlex.split(command) | ||
try: | ||
# The subprocess Popen function takes a ``cwd`` argument that | ||
# conveniently changes the working directory to run the command. | ||
# | ||
# We also patched the stderr to redirect to STDOUT, | ||
# so that stderr and stdout appear in order, as you would see in | ||
# a terminal. | ||
# | ||
# Finally, note that ``cwltool`` by default emits ANSI colors in the | ||
# terminal, which are harder to be parsed and/or rendered in Sphinx. | ||
# For that reason, we define --disable-color in the CWLTOOL_OPTIONS | ||
# environment variable, which is used by ``cwltool``. | ||
env = os.environ | ||
cwl_options = set(env.get('CWLTOOL_OPTIONS', '').split(' ')) | ||
cwl_options.add('--disable-color') | ||
env['CWLTOOL_OPTIONS'] = ' '.join(cwl_options) | ||
subp = subprocess.Popen( | ||
true_cmd, | ||
cwd=working_directory, | ||
env=env, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT | ||
) | ||
except Exception as e: | ||
out = "" | ||
err = e | ||
else: | ||
out, err = subp.communicate() | ||
encoding = sys.getfilesystemencoding() | ||
out = out.decode(encoding, "replace").rstrip() | ||
# The stderr is now combined with stdout. | ||
# err = err.decode(encoding, "replace").rstrip() | ||
|
||
if err and err != "": | ||
print("Error in runcmd: {}".format(err)) | ||
out = "{}\n{}".format(out, err) | ||
|
||
return out | ||
|
||
|
||
class RunCmdDirective(code.CodeBlock): | ||
has_content = False | ||
final_argument_whitespace = False | ||
required_arguments = 1 | ||
optional_arguments = 99 | ||
|
||
option_spec = { | ||
# code.CodeBlock option_spec | ||
"linenos": directives.flag, | ||
"dedent": int, | ||
"lineno-start": int, | ||
"emphasize-lines": directives.unchanged_required, | ||
"caption": directives.unchanged_required, | ||
"class": directives.class_option, | ||
"name": directives.unchanged, | ||
# RunCmdDirective option_spec | ||
"syntax": directives.unchanged, | ||
"replace": directives.unchanged, | ||
"prompt": directives.flag, | ||
"dedent-output": int, | ||
"working-directory": directives.unchanged | ||
} | ||
|
||
def run(self): | ||
# Grab a cache singleton instance | ||
cache = CMDCache() | ||
|
||
# The examples in our User Guide are stored in ``src/_includes/cwl``. | ||
# For convenience, instead of including that in every command, we | ||
# allow the directive to receive a working directory, so that we | ||
# change to that working directory before running the desired command. | ||
# The working directory is omitted from the final output. | ||
working_directory = self.options.get('working-directory', 'src/_includes/cwl/') | ||
if working_directory == '': | ||
# subprocess default value, so that we can disable it if needed. | ||
working_directory = None | ||
else: | ||
# You can run Sphinx from the root directory, with `make watch` | ||
# for instance, or from the src directory (RTD does that). | ||
working_directory_path = Path(working_directory) | ||
if not working_directory_path.exists() and str(working_directory_path).startswith('src/'): | ||
working_directory = Path(working_directory[4:]) | ||
|
||
# Get the command output | ||
command = " ".join(self.arguments) | ||
output = cache.get(command, working_directory) | ||
|
||
# Grab our custom commands | ||
syntax = self.options.get("syntax", "bash") | ||
replace = self.options.get("replace", '') | ||
reader = csv.reader([replace], delimiter=",", escapechar="\\") | ||
# prompt = "prompt" in self.options | ||
# We patched this so that the prompt is displayed by default, similar | ||
# to how ``{code-block} console`` works. | ||
prompt = True | ||
dedent_output = self.options.get("dedent-output", 0) | ||
|
||
# Dedent the output if required | ||
if dedent_output > 0: | ||
output = "\n".join([x[dedent_output:] for x in output.split("\n")]) | ||
|
||
# Add the prompt to our output if required | ||
if prompt: | ||
output = "$ {}\n{}".format(command, output) | ||
|
||
# Do our "replace" syntax on the command output | ||
for items in reader: | ||
for regex in items: | ||
if regex != "": | ||
match = RE_SPLIT.match(regex) | ||
p = match.group("pattern") | ||
# Let's unescape the escape chars here as we don't need them to be | ||
# escaped in the replacement at this point | ||
r = match.group("replacement").replace("\\", "") | ||
output = re.sub(p, r, output) | ||
|
||
# Set up our arguments to run the CodeBlock parent run function | ||
self.arguments[0] = syntax | ||
self.content = [output] | ||
node = super(RunCmdDirective, self).run() | ||
|
||
return node | ||
|
||
|
||
def setup(app): | ||
app.add_directive("runcmd", RunCmdDirective) | ||
|
||
return {"version": __version__} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid the
make watch
command from refreshing multiple times as theoutput.txt
and other workflow outputs are written to this_includes
folder during the build.