parallel/src/env_parallel.fish

143 lines
4.9 KiB
Fish
Raw Normal View History

#!/usr/bin/env fish
# This file must be sourced in fish:
#
# source (which env_parallel.fish)
#
# after which 'env_parallel' works
#
#
# Copyright (C) 2016
# Ole Tange and Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>
# or write to the Free Software Foundation, Inc., 51 Franklin St,
# Fifth Floor, Boston, MA 02110-1301 USA
# If you are a fisherman feel free to improve the code
#
# The code needs to deal with variables like:
# set funky (perl -e 'print pack "c*", 2..254')
#
# Problem:
# Tell the difference between:
# set tmp "a' 'b' 'c"
# set tmparr1 "a' 'b" 'c'
# set tmparr2 'a' "b' 'c"
# The output from `set` is exactly the same.
# Solution:
# for-loop for each variable. Each value is separated with a
# separator.
function env_parallel
# env_parallel.fish
setenv PARALLEL_ENV (
begin;
set _grep_REGEXP (
begin;
2016-07-22 18:39:12 +00:00
perl -e '
for(@ARGV){
/^_$/ and $next_is_env = 0;
$next_is_env and push @envvar, split/,/, $_;
$next_is_env = /^--env$/;
}
$vars = join "|",map { quotemeta $_ } @envvar;
print $vars ? "($vars)" : "(.*)";
' -- $argv;
end;
)
# Deal with --env _
set _ignore_UNDERSCORE (
begin;
perl -e '
for(@ARGV){
$next_is_env and push @envvar, split/,/, $_;
$next_is_env=/^--env$/;
}
if(grep { /^_$/ } @envvar) {
if(not open(IN, "<", "$ENV{HOME}/.parallel/ignored_vars")) {
2016-07-22 18:39:12 +00:00
print STDERR "parallel: Error: ",
"Run \"parallel --record-env\" in a clean environment first.\n";
} else {
chomp(@ignored_vars = <IN>);
2016-07-22 18:39:12 +00:00
$vars = join "|",map { quotemeta $_ } "env_parallel", @ignored_vars;
print $vars ? "($vars)" : "(,,nO,,VaRs,,)";
}
}
' -- $argv;
end;
)
# --record-env
perl -e 'exit grep { /^--record-env$/ } @ARGV' -- $argv; or begin;
begin;
functions -n | perl -pe 's/,/\n/g';
set -n;
end | cat > $HOME/.parallel/ignored_vars;
end;
# Export function definitions
functions -n | perl -pe 's/,/\n/g' | grep -E "^$_grep_REGEXP"\$ | grep -vE "^$_ignore_UNDERSCORE"\$ | while read d; functions $d; end;
# Convert scalar vars to fish \XX quoting
eval (set -L | grep -E "^$_grep_REGEXP " | grep -vE "^$_ignore_UNDERSCORE " | perl -ne 'chomp;
($name,$val)=split(/ /,$_,2);
$name=~/^(HOME|USER|COLUMNS|FISH_VERSION|LINES|PWD|SHLVL|_|history|status|version)$|\./ and next;
if($val=~/^'"'"'/) { next; }
print "set $name \"\$$name\";\n";
')
# Generate commands to set scalar variables
begin;
for v in (set -n | grep -E "^$_grep_REGEXP\$" | grep -vE "^$_ignore_UNDERSCORE\$");
# Separate variables with the string: \000
eval "for i in \$$v;
echo -n $v \$i;
perl -e print\\\"\\\\0\\\";
end;"
end;
# A final line to flush the last variable in Perl
perl -e print\"\\0\";
end | perl -0 -ne '
# Remove separator string
chop;
($name,$val)=split(/ /,$_,2);
# Ignore read-only vars
$name=~/^(HOME|USER|COLUMNS|FISH_VERSION|LINES|PWD|SHLVL|_|history|status|version)$/ and next;
# Quote $val
$val=~s/[\002-\011\013-\032\\\#\?\`\(\)\{\}\[\]\^\*\<\=\>\~\|\; \"\!\$\&\202-\377]/\\\$&/go;
# Quote single quote
$val=~s/'"'"'/\\\$&/go;
# Quote newline as '\n'
$val =~ s/[\n]/\\\n/go;
# Empty => 2 single quotes = \047\047
$val=~s/^$/\047\047/o;
if($name ne $last and $last) {
# The $name is different, so this is a new variable.
# Print the last one.
# Separate list elements by 2 spaces
$"=" ";
print "set $last @qval;\n";
@qval=();
}
push @qval,$val;
$last=$name;
';
end |perl -pe 's/\001/\\cb/g and print STDERR "env_parallel: Warning: ASCII value 1 in variables is not supported\n";
s/\n/\001/'
)
perl -e 'exit grep { /^--record-env$/ } @ARGV' -- $argv; and parallel $argv;
set _parallel_exit_CODE $status
set -e PARALLEL_ENV
return $_parallel_exit_CODE
end