Mercurial templates: have "{branches}" return "default"? - templates

What's the simplest way to have hg ... --template '{branches}' return default instead of an empty string when the changeset being printed is part of the default branch?

I've not found an in-template way to do that. If I'm in a shellscript I do something like:
BRANCH=$(hg log --revision 0 --template '{branches}')
echo ${BRANCH:=default}
Though if you have the excellent hg prompt extension in place you could do:
hg prompt '{branch}'

Related

Create PDF reports using R Markdown (TinyTeX) in Snakemake using Conda

I am currently having problems using TinyTeX in a conda environment with Snakemake. I have to install TinyTeX installation files using the command tinytex::install_tinytex() before running the pipeline. This installs TinyTeX outside of the created environment (which isn't that big of a problem... but not preferred either) . The main problem is that every time I execute my Snakemake pipeline it will try to reinstall this installation which I don't want. Could anyone tell me what the easiest way is for me to check whether it's installed already? Should I be using the command Rscript -e \"tinytex:::is_tinytex()\" with an if-statement? And what is the best way to write that if-statement by calling Rscript -e in Snakemake? Or should I just write a boolean text-file on first run which specifies whether TinyTeX has been installed before?
It kinda sucks that the TinyTeX conda dependency doesn't work on its own without additional installation...
Snakemake rule (ignore input/output):
rule assembly_report_rmarkdown:
input:
rules.assembly_graph2image_bandage.output,
rules.assembly_assessment_quast.output,
rules.coverage_calculator_shortreads.output,
rules.coverage_calculator_longreads.output
output:
config["outdir"] + "Hybrid_assembly_report.pdf"
conda:
"envs/r-rmarkdown.yaml"
shell:
"""
cp report/RMarkdown/Hybrid_assembly_report.Rmd {config[outdir]}Hybrid_assembly_report.Rmd
Rscript -e \"tinytex::install_tinytex()\"
Rscript -e \"rmarkdown::render('{config[outdir]}Hybrid_assembly_report.Rmd')\"
rm -f {config[outdir]}Hybrid_assembly_report.Rmd {config[outdir]}Hybrid_assembly_report.tex
"""
Conda YAML:
name: r-rmarkdown
channels:
- conda-forge
- bioconda
dependencies:
- r-base=4.0.3
- r-rmarkdown=2.5
- r-tinytex=0.27
Thanks in advance.
I think I've solved the issue. Instead of calling Rscript -e, I have put the following if-statement in the setup chunk in R Markdown (Which runs before running any other code if i'm correct). I then proceeded to uninstall TinyTeX to see whether it will install for once only which it did.
knitr::opts_chunk$set(echo = TRUE)
library(knitr)
if (!tinytex:::is_tinytex()){
tinytex::install_tinytex()
}

Symfony & AWS BS - Env vars for console outside .env files

I have a symfony API which runs on AWS beanstalk instances. My .env file registers the environment variables that I need in my app. I override all of them in the AWS console to adapt to my environments.
For exemple :
Env file : DEFAULT_CONNECTION_DSN=bolt://user:password#host:port
Test server : DEFAULT_CONNECTION_DSN=bolt://test:azerty#test.toto.com:7687
Prod server : DEFAULT_CONNECTION_DSN=bolt://prod:azerty#toto.com:7687
This works because AWS overrides the environment variables when the PHP server is started, so the values placed in the .env file are ignored.
The problem is that I try to create a CRON on the server. The CRON is executed from command line, and I saw that, in this case, the variables still have the value specified in the .env file at runtime.
If I list the environment variables on the server, I see that DEFAULT_CONNECTION_DSN has the value that I want, but if I dump the value in my code (or execute php bin/console debug:container --env-vars), DEFAULT_CONNECTION_DSN has the .env file value. I already tried to delete the entry from my .env file. In this case, I have an error saying my environment variable is not found.
I must precise that I work with a .env.local locally, file which is not versionned, and the deploys are based on git versionning, so it seems difficult to add a .env.env-name file for each environement.
What could I do ?
Symfony loads env vars only if they are not already present. Your problem looks like more how to add env vars with cron in AWS. As I don't know BS I can't help you with this.
In your cron I think you can still run DEFAULT_CONNECTION_DSN=bolt://prod:azerty#toto.com:7687 php bin/console ..., this will set your env var at runtime.
When you run something, from a bash, it inherits the exported variables, plus the ones given in the same command line.
Suppose this case:
xavi#bromo:~$ export -p
declare -x HOME="/home/xavi"
declare -x TERM="linux"
declare -x USER="xavi"
xavi#bromo:~$
Say you echo something not defined: You don't get anything, as expected:
xavi#bromo:~$ echo $ABC $XYZ
xavi#bromo:~$
You can place this echo inside a bash script, for example:
xavi#bromo:~$ cat /tmp/test.sh
#!/usr/bin/env bash
echo $ABC $XYZ
Then give it execution permissions:
xavi#bromo:~$ chmod a+x /tmp/test.sh
xavi#bromo:~$
Now, if you execute the script it also says nothing, but if you prefix them with variable assignment the value lives "exclussively" inside that call. See examples with hello-bye and orange-banana. If you later just show the values, they are not there:
xavi#bromo:~$ /tmp/test.sh
xavi#bromo:~$ ABC=hello XYZ=bye /tmp/test.sh
hello bye
xavi#bromo:~$ ABC=orange XYZ=banana /tmp/test.sh
orange banana
xavi#bromo:~$ echo $ABC $XYZ
xavi#bromo:~$
This would be a good approach for the solution of Fabien Papet: To prefix the cron call with the variable assignment.
But if you cannot do that, you can go furthter:
Env vars are not inherited when not exported but inherited when exported: See this:
xavi#bromo:~$ ABC=pita
xavi#bromo:~$ XYZ=pota
xavi#bromo:~$ /tmp/test.sh
xavi#bromo:~$ export ABC=pita
xavi#bromo:~$ export XYZ=pota
xavi#bromo:~$ /tmp/test.sh
pita pota
You could take advantage of bash dot-import command . to import variables.
Place in these files those contents:
xavi#bromo:~$ cat /tmp/fruits
export ABC=orange
export XYZ=tangerine
xavi#bromo:~$ cat /tmp/places
export ABC=Paris
export XYZ=Barcelona
xavi#bromo:~$
Note that the previous files do not have a she-bang as they are not meant to be executed, they do not have to create a bash instance. They are meant for inclussion from an existing bash instance.
Now edit the test.sh to make an inclusion of a file which we'll pass via the first command line parameter:
xavi#bromo:~$ cat /tmp/test.sh
#!/usr/bin/env bash
. $1
echo $ABC $XYZ
xavi#bromo:~$
You can now play with the invocation. I still have the pita-pota pair from the last test. See what happens:
xavi#bromo:~$ echo $ABC $XYZ
pita pota
xavi#bromo:~$ /tmp/test.sh /tmp/fruits
orange tangerine
xavi#bromo:~$ /tmp/test.sh /tmp/places
Paris Barcelona
xavi#bromo:~$ echo $ABC $XYZ
pita pota
xavi#bromo:~$
The first line echo $ABC $XYZ displays our current environment.
The second line invokes a new bash (via the she-bang of /tmp/test.sh) and as pita-pota were exported they are momentarily there. But as soon as . $1 is executed, it is expanded into . /tmp/fruits which overrides the environment by exporting new variables, thus the result.
The second scripts (the one with fruits) ends, so the bash is terminated and its environment is destroyed. We return to our main bash. In here we still have pota-pita. If we had printed now, we'd see the pita-pota. We go with the places, now.
The reasoning with the places is identical to the reasoning with the fruits.
As soon as we return to the main bash, the child env is destroyed, so the places have been blown away and we return to the first initial environment with pita-pota, which is then printed.
So...
With all this you can:
Setup a bash script that wraps:
loading the environment from some
place.
Call the php bin/console
In the cron, do not invoke the php but your wrapper script.
This allows you to
Change the script with different environments without depending on versioning.
Keep your credentials and configuration separated from the code.
In conclusion:
Make your source version control system to have the cron versioned, and the wrapper bash script versioned.
Make your deployer to place a different "includable" parameters file in each environment.
Make your cron to call the wrapper.
Make your wrapper to setup the env vars and call the php bin/console.
Does this solve your issue?

How to use scl command as a script shebang?

If I want to run a specific command (with arguments) under Software Collections, I can use this command:
scl enable python27 "ls /tmp"
However, if I try to make a shell script that has a similar command as its shebang line, I get errors:
$ cat myscript
#!/usr/bin/scl enable python27 "ls /tmp"
echo hello
$ ./myscript
Unable to open /etc/scl/prefixes/"ls!
What am I doing wrong?
You should try using -- instead of surrounding your command with quotes.
scl enable python27 -- ls /tmp
I was able to make a python script that uses the rh-python35 collection with this shebang:
#!/usr/bin/scl enable rh-python35 -- python
import sys
print(sys.version)
The parsing of arguments in the she-bang command is not really defined. From man execve:
The semantics of the optional-arg argument of an interpreter script vary across implementations. On Linux, the entire string following the interpreter name is passed as a single argument to the interpreter, and this string can include white space. However, behavior differs on some other systems. Some systems use the first white space to terminate optional-arg. On some systems, an interpreter script can have multiple arguments, and white spaces in optional-arg are used to delimit the arguments.
No matter what, argument splitting based on quote sis not supported. So when you write:
#!/usr/bin/scl enable python27 "ls /tmp"
It's very possible that what gets invoked is (using bash notation):
'/usr/bin/scl' 'enable' 'python27' '"ls' '/tmp"'
This is probably why it tries to open the "ls file at /etc/scl/prefixes/"ls
But it is just as likely that the shebang evaluates to:
'/usr/bin/scl' 'enable python27 "ls /tmp"'
And that would fail since it wont be able to find a command named enable python27 "ls /tmp" for scl to execute.
There's a few workarounds you can use.
You can call your script via scl:
$ cat myscript
#!/bin/bash
echo hello
$ scl enable python27 ./myscript
hello
You can also use the heredoc notation, but it might lead to subtle issues. I personally avoid this:
$ cat ./myscript
#!/bin/bash
scl enable python27 -- <<EOF
echo hi
echo \$X_SCLS
EOF
$ bash -x myscript
+ scl enable python27 --
hi
python27
You can see one of the gotcha's already: I had to write \$X_SCLS to access the environment variable instead of just $X_SCL.
Edit: Another option is two have two scripts. One that has the actual code, and the second that simply does scl enable python27 $FIRST_SCRIPT. Then you wont have to remember to enter scl ... manually.
The software collections documentation may also be helpful. In particular you can try
cat myscript.sh | scl enable python27 -
As well as permanently enabling a software collection
source scl_source enable python27
./myscript.sh

Parse branch name, initiate commit with name in the commit message

My team uses a common naming convention for branch names, which include the Jira task number in the branch name.
feature/ACD-1664_update-api-call
feature/VZ-1943_new-provider-template
hotfix/RV-977_fix-loading-issue
I want to create a git alias that will automatically stub out a commit message which includes the Jira task number. Ideally some bash script that will parse the branch name and echo out the commit -m command with the first part of the message pre-created.
I need to regex out the commmit message.
I need to pull ACD-1664 from feature/ACD-1664_update-api-call
Echo this string out into the terminal in a stubbed-out commit command like:
git commit -m "ACD-1664 | <cursor>"
Although this is not the solution you requested, I'd like to hint at another way to cover this, with a commit hook :
You can put in .git/hooks a commit-msg file with these contents :
#!/bin/bash
current_branch="$(git rev-parse --abbrev-ref HEAD)"
tmp=$(mktemp) || exit
echo "$current_branch $(cat "$1")" > "$tmp"
mv "$tmp" "$1"
(Thanks guys for the improvements in bash syntax made with your help here)
Then it would automatically prepend your commit messages with the branch name, which does the trick in JIRA.
For the rare occasions when you'd prefer NOT to trigger the hook, do this :
git commit -n -m"Your message"

Installed go with hombrew, can find $GOROOT causing package failures

I installed Go with homebrew and it usually works. Following the tutorial here on creating serverless api in Go. When I try to run the unit tests, I get the following error:
# _/Users/pro/Documents/Code/Go/ServerLess
main_test.go:6:2: cannot find package "github.com/strechr/testify/assert" in any of:
/usr/local/Cellar/go/1.9.2/libexec/src/github.com/strechr/testify/assert (from $GOROOT)
/Users/pro/go/src/github.com/strechr/testify/assert (from $GOPATH)
FAIL _/Users/pro/Documents/Code/Go/ServerLess [setup failed]
Pros-MBP:ServerLess Santi$ echo $GOROOT
I have installed the test library with : go get github.com/stretchr/testify
I would appreciate it if anyone could point me in the right direction.
Also confusing is when I run echo $GOPATH it doesnt return anything. same goes for echo $GOROOT
Some things to try/verify:
As JimB notes, starting with Go 1.8 the GOPATH env var is now optional and has default values: https://rakyll.org/default-gopath/
While you don't need to set it, the directory does need to have the Go workspace structure: https://golang.org/doc/code.html#Workspaces
Once that is created, create your source file in something like: $GOPATH/src/github.com/DataKid/sample/main.go
cd into that directory, and re-run the go get commands:
go get -u -v github.com/stretchr/testify
go get -u -v github.com/aws/aws-lambda-go/lambda
Then try running the test command again: go test -v
The -v option is for verbose output, the -u option ensures you download the latest package versions (https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies).