Let's say I have this silly Procfile.
[marca@marca-mac2 ~]$ cat Procfile
find: find ./dev/git-repos -type f -mtime +3 -name '*.py' | xargs grep --max-count 1 'import' | head -n 3
[marca@marca-mac2 ~]$ foreman run find
./dev/git-repos/1pass/.tox/py26/bin/activate_this.py:import sys
./dev/git-repos/ansible/.tox/py26/lib/python2.6/site-packages/ansible/runner/action_plugins/copy.py:import os
./dev/git-repos/ansible/.tox/py34/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/timeout.py:from socket import _GLOBAL_DEFAULT_TIMEOUT
OK, it's silly but it works. Now let's say that I wanted to make it prettier, by breaking the command on to multiple lines. Backslash is a pretty standard line-continuation character...
[marca@marca-mac2 ~]$ cat Procfile
find: find \
./dev/git-repos \
-type f \
-mtime +3 \
-name '*.py' | \
xargs grep --max-count 1 'import' | \
head -n 3
[marca@marca-mac2 ~]$ foreman run find
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
No love.
I can work around this by putting the command in a separate shell script:
[marca@marca-mac2 ~]$ cat Procfile
find: ./find.sh
[marca@marca-mac2 ~]$ cat find.sh
#!/bin/sh
find \
./dev/git-repos \
-type f \
-mtime +3 \
-name '*.py' | \
xargs grep --max-count 1 'import' | \
head -n 3
[marca@marca-mac2 ~]$ foreman run find
./dev/git-repos/1pass/.tox/py26/bin/activate_this.py:import sys
./dev/git-repos/ansible/.tox/py26/lib/python2.6/site-packages/ansible/runner/action_plugins/copy.py:import os
./dev/git-repos/ansible/.tox/py34/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/timeout.py:from socket import _GLOBAL_DEFAULT_TIMEOUT
but then this loses some of the simplicity and beauty of the Procfile -- it would be nice if I could be done inline somehow. Could foreman interpret a backslash at the end of the line as a line continuation?
Cc: @sudarkoff
A simpler example since the first one was a little more complex in order to try and convey the motivation a little better.
[marca@marca-mac2 ~]$ cat Procfile
hello: echo \
"Hello world"
[marca@marca-mac2 ~]$ foreman check
valid procfile detected (hello)
[marca@marca-mac2 ~]$ foreman run hello
[marca@marca-mac2 ~]$
It's interesting that foreman check thinks the file is valid; however it doesn't run as one might expect.
Honestly I prefer the separate shell script in terms of beauty and simplicity. The Procfile should be short and sweet. Keep the complicated commands and logic in shell scripts. I personally tend to create bin/* scripts that map 1:1 with my Procfile entries.
OK, thanks for the quick response!
Then foreman check should fail if this is not a bug, me thinks.
Foreman ignores all lines that it does not parse as a valid Procfile entry. If you'd like to make this logic more restrictive I would consider a pull request but it would need to be backwards-compatible with any random comments, etc people have put into their Procfiles.
If it ignores invalid lines, that would seem to make the check command not too useful? Not a big deal to me except that I would know not to rely too heavily on it.
What if Foreman::Engine#check_procfile and Foreman::Procfile#parse took an optional strict argument that would default to false except it would be true for foreman check and strict would tell parse to not ignore lines that don't match the regex?
The above would allow foreman to be backwards-compatible with whatever crazy stuff people do (e.g: write comments without prefixing with #) while allowing check to enforce a stricter standard.
foreman check does enough checking to know if it would be able to run against a given Procfile and prints out the detected process types. The only information you should derive from it is whether or not foreman itself will run successfully.