16

I wanted to write an arara rule that will conditionally execute a command based on the existence of external files.

Here's an example rule that I was able to get working:

!config
# open rule for arara
# author: AEllett
# requires arara 3.0+
identifier: echo
name: echo
command: /bin/echo "-->@{getBasename(file)}<--"
arguments: []

I can also conditionally test for a file

!config
# open rule for arara
# author: AEllett
# requires arara 3.0+
identifier: test
name: testing
commands: 
  - <arara> /bin/echo @{ isTrue ( isFile ("./dir/file") , "TRUE" , "FALSE") }
arguments: []

I would like to change what I'm executing: namely, the "/bin/echo" part. But when I try something like:

!config
# open rule for arara
# author: AEllett
# requires arara 3.0+
identifier: test
name: testing
commands: 
  - <arara> @{mycommand} @{ isTrue ( isFile ("./dir/file") , "TRUE" , ".") }
arguments: 
  - identifier: mycommand
    flag: <arara> @{ isTrue ( isFile ("./dir/file") , "/bin/echo " , "/bin/ls ") }

This runs without error, but doesn't do what I want it to.

I've also tried something like:

!config
# open rule for arara
# author: AEllett
# requires arara 3.0+
identifier: test
name: testing
commands: 
  - <arara> @{mycommand} @{ isTrue ( isFile ("./dir/file") , "TRUE" , ".") }
arguments: 
  - identifier: mycommand
    flag: <arara> @{ isFile ("./dir/file") == true  ?  "/bin/echo " : "/bin/ls " }

This generates an error

It appears that the 'test' task has a YAML syntax error or an
invalid field. Could you take a look at the 'test.yaml' file
located at '/Users/acellett/projects/ini/arara/rules'. I tried my
best to dump the error message, so here it is:

Problem: mapping values are not allowed here
Error found in line 12, column 60.
     ... ("./dir/file")  ?  "/bin/echo " : "/bin/ls " }
                                         ^

My test file (named "example_01.tex") looks like:

%  arara: test: { files: [example_01.tex] }

from the command line I'm issuing

$ arara -v example_01.tex

The result of logging is:

01 Jan 2014 10:58:59.870 INFO  Arara - Welcome to arara!
01 Jan 2014 10:58:59.874 INFO  Arara - Processing file 'example_01.tex', please wait.
01 Jan 2014 10:58:59.875 INFO  DirectiveExtractor - Reading directives from example_01.tex.
01 Jan 2014 10:58:59.876 TRACE DirectiveExtractor - Directive found in line 1 with test: { files: [example_01.tex] }.
01 Jan 2014 10:58:59.884 INFO  DirectiveParser - Parsing directives.
01 Jan 2014 10:58:59.889 INFO  TaskDeployer - Deploying tasks into commands.
01 Jan 2014 10:58:59.889 TRACE TaskDeployer - Task 'test' found in '/Users/acellett/projects/ini/arara/rules'.
01 Jan 2014 10:58:59.933 INFO  CommandTrigger - Ready to run commands.
01 Jan 2014 10:58:59.934 INFO  CommandTrigger - Running 'testing'.
01 Jan 2014 10:58:59.934 TRACE CommandTrigger - Command:  TRUE
01 Jan 2014 10:59:00.063 TRACE CommandTrigger - Output logging:
01 Jan 2014 10:59:00.064 TRACE CommandTrigger - 
01 Jan 2014 10:59:00.064 INFO  CommandTrigger - 'testing' was successfully executed.
01 Jan 2014 10:59:00.064 INFO  CommandTrigger - All commands were successfully executed.
01 Jan 2014 10:59:00.065 INFO  Arara - Done.

though I'm not really sure how to interpret this.

So basically what I'd like to know is how to write a rule which executes differently contingent upon the existence of some other file.

Incidentally, I am able to write:

!config
# open rule for arara
# author: AEllett
# requires arara 3.0+
identifier: test
name: testing
commands: 
  - <arara> @{ isTrue ( isFile ("./dir/file") , "/bin/echo " , "/bin/ls ") } @{ isTrue ( isFile ("./dir/file") , "TRUE" , ".") }
arguments: []

But I really wanted to have the commands chosen via the arguments.

A.Ellett
  • 50,533

1 Answers1

16

Apparently, peer pressure works. :) I'm looking at you, Tom. :P

Plan B, let's see if I get 800 votes: I'm a security engineer at Facebook and this is my fault. :)

I should probably focus on how to optmize the code, but since I'm a hurry, I can't think of a direct approach right now. :)

The error raised is, under the sea the hood, one of the caveats of using <arara> in the beginning of a command: we can save a few quotes, but we can run into some problems coming from the YAML mapping.

The : character is heavily used by the YAML format and thus its occurrence later on the string causes the parser to get confused, hence the error. The solution is to rely on the good old quotes (single or double). Since you already have double quotes, go for single ones:

flag: '@{ isFile ("./dir/file") == true  ?  "/bin/echo " : "/bin/ls " }'

Now it should work. Well, kind of. :)

flag is only evaluated if the argument is presented in the directive, otherwise the argument will be resolved to an empty string. In order for this evaluation to happen, you have to have mycommand in the directive. If you don't provide it, @{mycommand} will be empty in the main command line, where it's called.

If you want mycommand to be evaluated regardless of its occurrence in a directive, go for default instead of flag. Let's see an example:

- identifier: engine
  flag: <arara> @{parameters.engine}
  default: pdflatex

Let's say I want to have a rule in which I can define which engine I want to use, so I have an engine argument. The first case:

% arara: foo

arara will do this:

  1. There's a default occurrence, so resolve engine to its evaluation.
  2. No engine occurrence in the directive, keep things as they are.

In the end of the day, engine will be pdflatex. Now let's see the second case:

% arara: foo: { engine: xelatex }

arara now behaves like this:

  1. There's a default occurrence, so resolve engine to its evaluation, which is pdflatex.
  2. There's an occurrence of engine in the directive, evaluate flag and replace the default value.

Now, engine will be xelatex. :)

With some minor edits,

!config
identifier: test
name: testing
commands: 
  - <arara> @{mycommand} @{ isTrue ( isFile ("./dir/file") , "TRUE" , ".") }
arguments: 
  - identifier: mycommand
    default: '@{ isFile ("./dir/file") == true  ?  "/bin/echo " : "/bin/ls " }'

your rule now works. :)

Hope it helps! :)

Paulo Cereda
  • 44,220