How to modify documentation built with sphinx via a script in readthedocs build - python-sphinx

I am trying to run a script to modify the documentation built by sphinx hosted by Read the Docs (because some links are not properly handled). The script works when I try to build it locally, but either fails on the Read the Docs build or the changes do not get propagated to the web site.
The script I'm trying to run is super simple, it replaces some html links that are not properly converted by sphinx-markdown-tables:
#!/bin/bash
# fix_table_links.sh
FILE="_build/html/api_reference.html"
if [[ "$1" != "" ]]; then
FILE="$1"
fi
sed -E 's/a href="(.*)\.md"/a href="\1\.html"/g' -i ${FILE}
My readthedocs.yml looks like this:
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optionally build your docs in additional formats such as PDF and ePub
formats: all
# Optionally set the version of Python and requirements required to build your docs
python:
install:
- requirements: docs/requirements.readthedocs.txt
build:
os: ubuntu-20.04
tools:
python: "3.8"
jobs:
post_build:
- echo "Running post-build commands."
- bash docs/fix_table_links.sh _readthedocs/html/api_reference.html
There are two cases:
Case 1) Using the readthedocs.yml as above, the build fails because _readthedocs/html/api_reference.html does not exist, despite this directory being the place the documentation claims will get uploaded from here. An example failure of this run is here.
Case 2) If I change the final of readthedocs.yml to bash docs/fix_table_links.sh docs/_build/html/api_reference.html, then the build passes (example here). But the links are not updated on the Read the Docs site: they still point to markdown pages rather than their corresponding HTML pages, so it must not be the version that gets uploaded to the Read the Docs web site.
Wading through documentation, I can't figure out how do this. Has anybody done this before or have a better grasp on how Read the Docs builds work? Thanks!

If you're willing to rewrite the script as a Python function, then you can do this super easily by connecting it as an event handler for the build-finished event.
I've done something similar in one of my own repos, except I post-process a .rst file. It's not actually used on RTD, but I can see it works in the build logs. So it should work to post-process your HTML files as well, since the build-finished event would occur after they've been generated.
First, define the script as a function in your conf.py. It needs to have app and exception as parameters.
def replace_html_links(app, exception):
with open(FILE, 'r') as f:
html = f.read()
# stuff to edit and save the html
Then either define or add to your setup function:
def setup(app):
app.connect('build-finished', replace_html_links)
And that's it!

Related

GitHub Tag Message Markdown

How do I make a tag commit/push message show up as markdown on GitHub?
The closest I’ve seen is someone suggesting to make a custom script defining the “body”
#VonC, that is good where gh is available, however, I'm in an environment where it's not... as such, I created the following bash script using the api. (clearly all below $vars need to be either defined or substituted for working example)
COMMIT_BODY can be markdown (e.g. COMMIT_BODY="**This is markdow**")
res=`curl --user "$USERNAME:$TOKEN" -X POST https://api.github.com/repos/${ORGANIZATION}/${REPO}/releases \
-d "
{
\"tag_name\": \"$VERSION\",
\"target_commitish\": \"$BRANCH\",
\"name\": \"$VERSION\",
\"body\": \"$COMMIT_BODY\",
\"draft\": false,
\"prerelease\": false
}"`
You could try and use the GitHub CLI gh (after installation, and login), and its gh release create command in order to pass a markdown file as release notes.
gh release create v1.2.3 -F changelog.md
That would do it all: tag, message tag, release notes and publication of said release to GitHub.
Right from your local workstation/repository.

Sphinx rst2pdf and role directives

In a reStructuredText on Sphinx 2.x, I want to put a content that changes depending on the output format.
In any source document, say, index.rst, add the following lines:
.. role:: pdf(raw)
:format: pdf
.. role:: latex(raw)
:format: latex
.. role:: html(raw)
:format: html
.. |foo| replace::
:pdf:`PDF!`
:latex:`LaTeX!`
:html:`HTML!`
I am |foo|
I expect it shows "I am HTML!" when the output format is in HTML, "I am LaTeX!" if it's LaTeX (even after converting the product to PDF via pdflatex) and "I am PDF!" if it's PDF.
I make the HTML version using make html and I see only "I am HTML!" in a web browser as I expect:
Install rst2pdf. Put the following lines in conf.py:
extensions = [
'rst2pdf.pdfbuilder'
]
pdf_documents = [(
'index',
u'testRst2Pdf',
u'Test Title',
u'Sarah Author')]
Make the PDF version with
sphinx-build -b pdf ./source/ ./build/
Update. Below is the output. No error. I ran this using WSL 1 (Ubuntu 18.04).
Running Sphinx v2.4.3
loading pickled environment... done
building [mo]: targets for 0 po files that are out of date
building [pdf]: targets for 1 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
processing testRst2Pdf...
index
resolving references...
done
writing testRst2Pdf...
done
build succeeded.
I see "I am PDF! LaTeX! HTML!" that includes all the three items.
Is there any way to get either "I am PDF!" or "I am LaTeX!" in the PDF file?
Note.
Before reporting this behavior as a bug, someone help me check if it's unexpected behavior or as-designed.
This question is derived from the other I asked earlier: StackOverflow: "Sphinx: Use a different directive for a different output format".
rst2pdf does not really have conditionals, but you might find the --strip-elements-with-class switch useful? Put the optional pieces into a class name and then if that class doesn't make sense for this format, remove it with the switch.
Manual is here https://rst2pdf.org/static/manual.html#command-line-options and I also blogged (basically a longer version of this first paragraph) about this https://rst2pdf.org/static/manual.html#command-line-options if more information would be useful.

Grub throws "can't find command `['." when adding conditional to grub.cfg

It was my understanding that grub supports a small subset of bash. Their documentation doesn't go into super detail, other than it "supports conditionals", etc.
I am trying to run a simple if.
grub> if [ "${myvar}" = "fred" ]; then
> echo "test"
> fi
error: can't find command `['.
Anybody have an idea? I am using grub2-efi 2.00.
You are missing a grub2 module in order to run if tests.
I'm running Gentoo on a PowerPC system (PPC64 G5 machine) and doing a default grub-mkconfig then booting from it gives me the error in your question.
Since bash has that syntax support, I figured it was simply a grub module that needed to be added (I had been doing work with grub modules recently).
tl;dr: You need to load the appropriate grub module and then the error goes away.
The first step is to find out what modules you have. For me, it's whatever is available in my /boot/grub/powerpc-ieee1275/ folder.
There's also modules in /usr/lib/grub/powerpc-ieee1275/.
I wrote up a list of modules I thought I needed:
normal
eval
read
test
test_blockarg
trig
true
I then added them to my /etc/default/grub file:
GRUB_PRELOAD_MODULES="normal eval read test test_blockarg trig true"
I did not find an entry for GRUB_PRELOAD_MODULES in the config file, so I had to do some searching to find out how. I want these modules to be added every time I generate the grub config file, which means putting them in the 00_header portion of grub.
Then I recreated the configuration file:
grub-mkconfig -o /boot/grub/grub.cfg
The modules were in the header and things worked perfectly on reboot.
If I had to guess: you probably only need the test module to enable if statements.

Cucumber.yml was found, but can't be parsed for Parallel_Tests

When running multiple features with the Ruby gem Parallel_Tests in cucumber using this command:
parallel_cucumber features/
with a cucumber.yml file under my project root>config folder, which looks like:
default: --format html --out report<%= ENV['TEST_ENV_NUMBER'] %>.html
I receive the following error message:
cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.
I have looked into this and some others have thought it was due to a rerun.txt file, but i have not created this file and a project file search returns nothing. I am currently at a loss of what is causing cucumber to fail reading in the yaml file. Any help would be great.
As described by another post, I went into lib/
cucumber/cli/profile_loader.rb and added a STDERR output like so:
begin
#cucumber_yml = YAML::load(#cucumber_erb)
rescue StandardError => e
STDERR.puts #cucumber_erb
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
end
Here is the result:
#parallel_reports: --format html --out reports/cukes_.html
cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.
#
default: --format htm#l
-
oduetf aruelpto:r t-2-.fhotrmmla #hptamrla l-l-eolu_tr erpeoprotrst:4 .-h-tfmolr a#tp ahrtamlll e-l-_oruetp orretpso:r t-s-/fcourkmeast_ .hhttmmll - ouctu cruempboerrt.sy/mclu kweass_ .fhotumnld, buctu ccuomubledr .nyomtl bwea sp afrosuendd., Pblueta sceo urledf enro tt ob ec upcaurmsbeedr.' sP ldeoacsuem ernetfaetri otno ocnu ccuomrbreerc'ts pdroocfuimleen tu astaigoen.
n correct profile usage.
I stumbled upon this problem and only found solutions that suggested removing rerun.txt. That was not an option for me because I rely on that file to rerun failing scenarios.
For some reason Cucumber outputs failing scenarios separated by \n in rerun.txt which is not accepted by the default command found in cucumber.yml.
My solution was to change the first line of cucumber.yml to substitute \n with a space:
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt').gsub(/\n/, ' ') : ""
I had the same issue with the tests of Rails-Cucumber itself. In my case, just running this line fixed the problem:
rm .cucumber.rerun
Caution, sometimes the rerun file can have a different name.
There is a suggestion to use gem update –system
For me, the error
cucumber.yml was found, but could not be parsed with ERB
meant that I was running my tests from RubyMine, and had set my Features folder not to the root of my project, but to a subfolder in the project called features.
When I changed this to the root of my project, it worked out fine!

Redirect Output of Capistrano

I have a Capistrano deploy file (Capfile) that is rather large, contains a few namespaces and generally has a lot of information already in it. My ultimate goal is, using the Tinder gem, paste the output of the entire deployment into Campfire. I have Tinder setup properly already.
I looked into using the Capistrano capture method, but that only works for the first host. Additionally that would be a lot of work to go through and add something like:
output << capture 'foocommand'
Specifically, I am looking to capture the output of any deployment from that file into a variable (in addition to putting it to STDOUT so I can see it), then pass that output in the variable into a function called notify_campfire. Since the notify_campfire function is getting called at the end of a task (every task regardless of the namespace), it should have the task name available to it and the output (which is stored in that output variable). Any thoughts on how to accomplish this would be greatly appreciated.
I recommend not messing with the Capistrano logger, Instead use what unix gives you and use pipes:
cap deploy | my_logger.rb
Where your logger reads STDIN and STDOUT and both records, and pipes it back to the appropriate stream.
For an alternative, the Engineyard cap recipies have a logger – this might be a useful reference if you do need to edit the code, but I recommend not doing.
It's sort of a hackish means of solving your problem, but you could try running the deploy task in a Rake task and capturing the output using %x.
# ...in your Rakefile...
task :deploy_and_notify do
output = %x[ cap deploy ] # Run your deploy task here.
notify_campfire(output)
puts output # Echo the output.
end

Resources