Merge branch 'bp/mediawiki-preview'
authorJunio C Hamano <gitster@pobox.com>
Thu, 18 Jul 2013 19:59:34 +0000 (12:59 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 18 Jul 2013 19:59:34 +0000 (12:59 -0700)
Add a command to allow previewing the contents locally before
pushing it out, when working with a MediaWiki remote.

I personally do not think this belongs to Git. If you are working
on a set of AsciiDoc source files, you sure do want to locally
format to preview what you will be pushing out, and if you are
working on a set of C or Java source files, you do want to test it
before pushing it out, too. That kind of thing belongs to your
build script, not to your SCM.

But I'll let it pass, as this is only a contrib/ thing.

* bp/mediawiki-preview:
git-remote-mediawiki: add preview subcommand into git mw
git-remote-mediawiki: add git-mw command
git-remote-mediawiki: factoring code between git-remote-mediawiki and Git::Mediawiki
git-remote-mediawiki: update tests to run with the new bin-wrapper
git-remote-mediawiki: add a git bin-wrapper for developement
wrap-for-bin: make bin-wrappers chainable
git-remote-mediawiki: introduction of Git::Mediawiki.pm

1  2 
contrib/mw-to-git/git-remote-mediawiki.perl
t/test-lib.sh
index d09f5da6681fa62dbb87582031c12fe9dceddb69,e40c0347df1f5f1bf9414c021074a8ef8eae9fb5..f8d7d2ca6c0926912200ddcadf8359c1b9bfef44
@@@ -14,6 -14,8 +14,8 @@@
  use strict;
  use MediaWiki::API;
  use Git;
+ use Git::Mediawiki qw(clean_filename smudge_filename connect_maybe
+                                       EMPTY HTTP_CODE_OK);
  use DateTime::Format::ISO8601;
  use warnings;
  
@@@ -23,9 -25,6 +25,6 @@@ binmode STDOUT, ':encoding(UTF-8)'
  
  use URI::Escape;
  
- # Mediawiki filenames can contain forward slashes. This variable decides by which pattern they should be replaced
- use constant SLASH_REPLACEMENT => '%2F';
  # It's not always possible to delete pages (may require some
  # privileges). Deleted pages are replaced with this content.
  use constant DELETED_CONTENT => "[[Category:Deleted]]\n";
@@@ -40,8 -39,6 +39,6 @@@ use constant NULL_SHA1 => '000000000000
  # Used on Git's side to reflect empty edit messages on the wiki
  use constant EMPTY_MESSAGE => '*Empty MediaWiki Message*';
  
- use constant EMPTY => q{};
  # Number of pages taken into account at once in submodule get_mw_page_list
  use constant SLICE_SIZE => 50;
  
@@@ -50,8 -47,6 +47,6 @@@
  # the number of links to be returned (500 links max).
  use constant BATCH_SIZE => 10;
  
- use constant HTTP_CODE_OK => 200;
  if (@ARGV != 2) {
        exit_error_usage();
  }
@@@ -199,37 -194,6 +194,6 @@@ sub parse_command 
  # MediaWiki API instance, created lazily.
  my $mediawiki;
  
- sub mw_connect_maybe {
-       if ($mediawiki) {
-               return;
-       }
-       $mediawiki = MediaWiki::API->new;
-       $mediawiki->{config}->{api_url} = "${url}/api.php";
-       if ($wiki_login) {
-               my %credential = (
-                       'url' => $url,
-                       'username' => $wiki_login,
-                       'password' => $wiki_passwd
-               );
-               Git::credential(\%credential);
-               my $request = {lgname => $credential{username},
-                              lgpassword => $credential{password},
-                              lgdomain => $wiki_domain};
-               if ($mediawiki->login($request)) {
-                       Git::credential(\%credential, 'approve');
-                       print {*STDERR} qq(Logged in mediawiki user "$credential{username}".\n);
-               } else {
-                       print {*STDERR} qq(Failed to log in mediawiki user "$credential{username}" on ${url}\n);
-                       print {*STDERR} '  (error ' .
-                               $mediawiki->{error}->{code} . ': ' .
-                               $mediawiki->{error}->{details} . ")\n";
-                       Git::credential(\%credential, 'reject');
-                       exit 1;
-               }
-       }
-       return;
- }
  sub fatal_mw_error {
        my $action = shift;
        print STDERR "fatal: could not $action.\n";
@@@ -339,7 -303,7 +303,7 @@@ sub get_mw_first_pages 
  
  # Get the list of pages to be fetched according to configuration.
  sub get_mw_pages {
-       mw_connect_maybe();
+       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
  
        print {*STDERR} "Listing pages on remote wiki...\n";
  
@@@ -529,7 -493,7 +493,7 @@@ sub get_last_local_revision 
  # avoid a loop onto all tracked pages. This is useful for the fetch-by-rev
  # option.
  sub get_last_global_remote_rev {
-       mw_connect_maybe();
+       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
  
        my $query = {
                action => 'query',
  # Get the last remote revision concerning the tracked pages and the tracked
  # categories.
  sub get_last_remote_revision {
-       mw_connect_maybe();
+       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
  
        my %pages_hash = get_mw_pages();
        my @pages = values(%pages_hash);
@@@ -601,29 -565,6 +565,6 @@@ sub mediawiki_smudge 
        return "${string}\n";
  }
  
- sub mediawiki_clean_filename {
-       my $filename = shift;
-       $filename =~ s{@{[SLASH_REPLACEMENT]}}{/}g;
-       # [, ], |, {, and } are forbidden by MediaWiki, even URL-encoded.
-       # Do a variant of URL-encoding, i.e. looks like URL-encoding,
-       # but with _ added to prevent MediaWiki from thinking this is
-       # an actual special character.
-       $filename =~ s/[\[\]\{\}\|]/sprintf("_%%_%x", ord($&))/ge;
-       # If we use the uri escape before
-       # we should unescape here, before anything
-       return $filename;
- }
- sub mediawiki_smudge_filename {
-       my $filename = shift;
-       $filename =~ s{/}{@{[SLASH_REPLACEMENT]}}g;
-       $filename =~ s/ /_/g;
-       # Decode forbidden characters encoded in mediawiki_clean_filename
-       $filename =~ s/_%_([0-9a-fA-F][0-9a-fA-F])/sprintf('%c', hex($1))/ge;
-       return $filename;
- }
  sub literal_data {
        my ($content) = @_;
        print {*STDOUT} 'data ', bytes::length($content), "\n", $content;
@@@ -635,9 -576,9 +576,9 @@@ sub literal_data_raw 
        my ($content) = @_;
        # Avoid confusion between size in bytes and in characters
        utf8::downgrade($content);
 -      binmode {*STDOUT}, ':raw';
 +      binmode STDOUT, ':raw';
        print {*STDOUT} 'data ', bytes::length($content), "\n", $content;
 -      binmode {*STDOUT}, ':encoding(UTF-8)';
 +      binmode STDOUT, ':encoding(UTF-8)';
        return;
  }
  
@@@ -831,7 -772,7 +772,7 @@@ sub mw_import_ref 
                return;
        }
  
-       mw_connect_maybe();
+       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
  
        print {*STDERR} "Searching revisions...\n";
        my $last_local = get_last_local_revision();
@@@ -945,7 -886,7 +886,7 @@@ sub mw_import_revids 
                my %commit;
                $commit{author} = $rev->{user} || 'Anonymous';
                $commit{comment} = $rev->{comment} || EMPTY_MESSAGE;
-               $commit{title} = mediawiki_smudge_filename($page_title);
+               $commit{title} = smudge_filename($page_title);
                $commit{mw_revision} = $rev->{revid};
                $commit{content} = mediawiki_smudge($rev->{'*'});
  
@@@ -1006,7 -947,7 +947,7 @@@ sub mw_upload_file 
        }
        # Deleting and uploading a file requires a priviledged user
        if ($file_deleted) {
-               mw_connect_maybe();
+               $mediawiki = connect_maybe($mediawiki, $remotename, $url);
                my $query = {
                        action => 'delete',
                        title => $path,
                # Don't let perl try to interpret file content as UTF-8 => use "raw"
                my $content = run_git("cat-file blob ${new_sha1}", 'raw');
                if ($content ne EMPTY) {
-                       mw_connect_maybe();
+                       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
                        $mediawiki->{config}->{upload_url} =
                                "${url}/index.php/Special:Upload";
                        $mediawiki->edit({
@@@ -1070,7 -1011,7 +1011,7 @@@ sub mw_push_file 
        my $old_sha1 = $diff_info_split[2];
        my $page_created = ($old_sha1 eq NULL_SHA1);
        my $page_deleted = ($new_sha1 eq NULL_SHA1);
-       $complete_file_name = mediawiki_clean_filename($complete_file_name);
+       $complete_file_name = clean_filename($complete_file_name);
  
        my ($title, $extension) = $complete_file_name =~ /^(.*)\.([^\.]*)$/;
        if (!defined($extension)) {
                        $file_content = run_git("cat-file blob ${new_sha1}");
                }
  
-               mw_connect_maybe();
+               $mediawiki = connect_maybe($mediawiki, $remotename, $url);
  
                my $result = $mediawiki->edit( {
                        action => 'edit',
@@@ -1279,7 -1220,7 +1220,7 @@@ sub mw_push_revision 
  }
  
  sub get_allowed_file_extensions {
-       mw_connect_maybe();
+       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
  
        my $query = {
                action => 'query',
@@@ -1303,7 -1244,7 +1244,7 @@@ my %cached_mw_namespace_id
  # Return MediaWiki id for a canonical namespace name.
  # Ex.: "File", "Project".
  sub get_mw_namespace_id {
-       mw_connect_maybe();
+       $mediawiki = connect_maybe($mediawiki, $remotename, $url);
        my $name = shift;
  
        if (!exists $namespace_id{$name}) {
diff --combined t/test-lib.sh
index 2d633073510c1f6a27fc3f7943fed5dafc717dcb,43e2a391aa4e0b8db88a43cbaede76f09585ac18..b490283182ce29f91519fd390f2a9639efa8c09c
@@@ -92,6 -92,7 +92,7 @@@ unset VISUAL EMAIL LANGUAGE COLUMNS $("
        print join("\n", @vars);
  ')
  unset XDG_CONFIG_HOME
+ unset GITPERLLIB
  GIT_AUTHOR_EMAIL=author@example.com
  GIT_AUTHOR_NAME='A U Thor'
  GIT_COMMITTER_EMAIL=committer@example.com
@@@ -184,9 -185,6 +185,9 @@@ d
                help=t; shift ;;
        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
                verbose=t; shift ;;
 +      --verbose-only=*)
 +              verbose_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
 +              shift ;;
        -q|--q|--qu|--qui|--quie|--quiet)
                # Ignore --quiet under a TAP::Harness. Saying how many tests
                # passed without the ok/not ok details is always an error.
        --valgrind=*)
                valgrind=$(expr "z$1" : 'z[^=]*=\(.*\)')
                shift ;;
 +      --valgrind-only=*)
 +              valgrind_only=$(expr "z$1" : 'z[^=]*=\(.*\)')
 +              shift ;;
 +      --valgrind-parallel=*)
 +              valgrind_parallel=$(expr "z$1" : 'z[^=]*=\(.*\)')
 +              shift ;;
 +      --valgrind-only-stride=*)
 +              valgrind_only_stride=$(expr "z$1" : 'z[^=]*=\(.*\)')
 +              shift ;;
 +      --valgrind-only-offset=*)
 +              valgrind_only_offset=$(expr "z$1" : 'z[^=]*=\(.*\)')
 +              shift ;;
        --tee)
                shift ;; # was handled already
        --root=*)
                root=$(expr "z$1" : 'z[^=]*=\(.*\)')
                shift ;;
 +      --statusprefix=*)
 +              statusprefix=$(expr "z$1" : 'z[^=]*=\(.*\)')
 +              shift ;;
        *)
                echo "error: unknown test option '$1'" >&2; exit 1 ;;
        esac
  done
  
 -test -n "$valgrind" && verbose=t
 +if test -n "$valgrind_only" || test -n "$valgrind_only_stride"
 +then
 +      test -z "$valgrind" && valgrind=memcheck
 +      test -z "$verbose" && verbose_only="$valgrind_only"
 +elif test -n "$valgrind"
 +then
 +      verbose=t
 +fi
  
  if test -n "$color"
  then
@@@ -328,12 -304,12 +329,12 @@@ trap 'die' EXI
  
  test_ok_ () {
        test_success=$(($test_success + 1))
 -      say_color "" "ok $test_count - $@"
 +      say_color "" "${statusprefix}ok $test_count - $@"
  }
  
  test_failure_ () {
        test_failure=$(($test_failure + 1))
 -      say_color error "not ok $test_count - $1"
 +      say_color error "${statusprefix}not ok $test_count - $1"
        shift
        echo "$@" | sed -e 's/^/#       /'
        test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
  
  test_known_broken_ok_ () {
        test_fixed=$(($test_fixed+1))
 -      say_color error "ok $test_count - $@ # TODO known breakage vanished"
 +      say_color error "${statusprefix}ok $test_count - $@ # TODO known breakage vanished"
  }
  
  test_known_broken_failure_ () {
        test_broken=$(($test_broken+1))
 -      say_color warn "not ok $test_count - $@ # TODO known breakage"
 +      say_color warn "${statusprefix}not ok $test_count - $@ # TODO known breakage"
  }
  
  test_debug () {
        test "$debug" = "" || eval "$1"
  }
  
 +match_pattern_list () {
 +      arg="$1"
 +      shift
 +      test -z "$*" && return 1
 +      for pattern_
 +      do
 +              case "$arg" in
 +              $pattern_)
 +                      return 0
 +              esac
 +      done
 +      return 1
 +}
 +
 +maybe_teardown_verbose () {
 +      test -z "$verbose_only" && return
 +      exec 4>/dev/null 3>/dev/null
 +      verbose=
 +}
 +
 +last_verbose=t
 +maybe_setup_verbose () {
 +      test -z "$verbose_only" && return
 +      if match_pattern_list $test_count $verbose_only ||
 +              { test -n "$valgrind_only_stride" &&
 +              expr $test_count "%" $valgrind_only_stride - $valgrind_only_offset = 0 >/dev/null; }
 +      then
 +              exec 4>&2 3>&1
 +              # Emit a delimiting blank line when going from
 +              # non-verbose to verbose.  Within verbose mode the
 +              # delimiter is printed by test_expect_*.  The choice
 +              # of the initial $last_verbose is such that before
 +              # test 1, we do not print it.
 +              test -z "$last_verbose" && echo >&3 ""
 +              verbose=t
 +      else
 +              exec 4>/dev/null 3>/dev/null
 +              verbose=
 +      fi
 +      last_verbose=$verbose
 +}
 +
 +maybe_teardown_valgrind () {
 +      test -z "$GIT_VALGRIND" && return
 +      GIT_VALGRIND_ENABLED=
 +}
 +
 +maybe_setup_valgrind () {
 +      test -z "$GIT_VALGRIND" && return
 +      if test -z "$valgrind_only" && test -z "$valgrind_only_stride"
 +      then
 +              GIT_VALGRIND_ENABLED=t
 +              return
 +      fi
 +      GIT_VALGRIND_ENABLED=
 +      if match_pattern_list $test_count $valgrind_only
 +      then
 +              GIT_VALGRIND_ENABLED=t
 +      elif test -n "$valgrind_only_stride" &&
 +              expr $test_count "%" $valgrind_only_stride - $valgrind_only_offset = 0 >/dev/null
 +      then
 +              GIT_VALGRIND_ENABLED=t
 +      fi
 +}
 +
  test_eval_ () {
        # This is a separate function because some tests use
        # "return" to end a test_expect_success block early.
  test_run_ () {
        test_cleanup=:
        expecting_failure=$2
 +      setup_malloc_check
        test_eval_ "$1"
        eval_ret=$?
 +      teardown_malloc_check
  
        if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
        then
        return "$eval_ret"
  }
  
 -test_skip () {
 +test_start_ () {
        test_count=$(($test_count+1))
 +      maybe_setup_verbose
 +      maybe_setup_valgrind
 +}
 +
 +test_finish_ () {
 +      echo >&3 ""
 +      maybe_teardown_valgrind
 +      maybe_teardown_verbose
 +}
 +
 +test_skip () {
        to_skip=
 -      for skp in $GIT_SKIP_TESTS
 -      do
 -              case $this_test.$test_count in
 -              $skp)
 -                      to_skip=t
 -                      break
 -              esac
 -      done
 +      if match_pattern_list $this_test.$test_count $GIT_SKIP_TESTS
 +      then
 +              to_skip=t
 +      fi
        if test -z "$to_skip" && test -n "$test_prereq" &&
           ! test_have_prereq "$test_prereq"
        then
                        of_prereq=" of $test_prereq"
                fi
  
 -              say_color skip >&3 "skipping test: $@"
 -              say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
 +              say_color skip >&3 "${statusprefix}skipping test: $@"
 +              say_color skip "${statusprefix}ok $test_count # skip $1 (missing $missing_prereq${of_prereq})"
                : true
                ;;
        *)
@@@ -494,8 -396,6 +495,8 @@@ test_at_end_hook_ () 
  test_done () {
        GIT_EXIT_OK=t
  
 +      # Note: t0000 relies on $HARNESS_ACTIVE disabling the .counts
 +      # output file
        if test -z "$HARNESS_ACTIVE"
        then
                test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
  
        if test "$test_fixed" != 0
        then
 -              say_color error "# $test_fixed known breakage(s) vanished; please update test(s)"
 +              say_color error "${statusprefix}# $test_fixed known breakage(s) vanished; please update test(s)"
        fi
        if test "$test_broken" != 0
        then
 -              say_color warn "# still have $test_broken known breakage(s)"
 +              say_color warn "${statusprefix}# still have $test_broken known breakage(s)"
        fi
        if test "$test_broken" != 0 || test "$test_fixed" != 0
        then
                then
                        if test $test_remaining -gt 0
                        then
 -                              say_color pass "# passed all $msg"
 +                              say_color pass "${statusprefix}# passed all $msg"
                        fi
 -                      say "1..$test_count$skip_all"
 +                      say "${statusprefix}1..$test_count$skip_all"
                fi
  
                test -d "$remove_trash" &&
        *)
                if test $test_external_has_tap -eq 0
                then
 -                      say_color error "# failed $test_failure among $msg"
 -                      say "1..$test_count"
 +                      say_color error "${statusprefix}# failed $test_failure among $msg"
 +                      say "${statusprefix}1..$test_count"
                fi
  
                exit 1 ;;
        esac
  }
  
 +
 +# Set up a directory that we can put in PATH which redirects all git
 +# calls to 'valgrind git ...'.
  if test -n "$valgrind"
  then
        make_symlink () {
                make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
        }
  
 -      # override all git executables in TEST_DIRECTORY/..
 -      GIT_VALGRIND=$TEST_DIRECTORY/valgrind
 -      mkdir -p "$GIT_VALGRIND"/bin
 -      for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
 -      do
 -              make_valgrind_symlink $file
 -      done
 -      # special-case the mergetools loadables
 -      make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
 -      OLDIFS=$IFS
 -      IFS=:
 -      for path in $PATH
 -      do
 -              ls "$path"/git-* 2> /dev/null |
 -              while read file
 +      # In the case of --valgrind-parallel, we only need to do the
 +      # wrapping once, in the main script.  The worker children all
 +      # have $valgrind_only_stride set, so we can skip based on that.
 +      if test -z "$valgrind_only_stride"
 +      then
 +              # override all git executables in TEST_DIRECTORY/..
 +              GIT_VALGRIND=$TEST_DIRECTORY/valgrind
 +              mkdir -p "$GIT_VALGRIND"/bin
 +              for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-*
                do
 -                      make_valgrind_symlink "$file"
 +                      make_valgrind_symlink $file
                done
 -      done
 -      IFS=$OLDIFS
 +              # special-case the mergetools loadables
 +              make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools"
 +              OLDIFS=$IFS
 +              IFS=:
 +              for path in $PATH
 +              do
 +                      ls "$path"/git-* 2> /dev/null |
 +                      while read file
 +                      do
 +                              make_valgrind_symlink "$file"
 +                      done
 +              done
 +              IFS=$OLDIFS
 +      fi
        PATH=$GIT_VALGRIND/bin:$PATH
        GIT_EXEC_PATH=$GIT_VALGRIND/bin
        export GIT_VALGRIND
        GIT_VALGRIND_MODE="$valgrind"
        export GIT_VALGRIND_MODE
 +      GIT_VALGRIND_ENABLED=t
 +      if test -n "$valgrind_only" || test -n "$valgrind_only_stride"
 +      then
 +              GIT_VALGRIND_ENABLED=
 +      fi
 +      export GIT_VALGRIND_ENABLED
  elif test -n "$GIT_TEST_INSTALLED"
  then
        GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
@@@ -738,53 -623,21 +739,53 @@@ the
  else
        mkdir -p "$TRASH_DIRECTORY"
  fi
 +
 +# Gross hack to spawn N sub-instances of the tests in parallel, and
 +# summarize the results.  Note that if this is enabled, the script
 +# terminates at the end of this 'if' block.
 +if test -n "$valgrind_parallel"
 +then
 +      for i in $(test_seq 1 $valgrind_parallel)
 +      do
 +              root="$TRASH_DIRECTORY/vgparallel-$i"
 +              mkdir "$root"
 +              TEST_OUTPUT_DIRECTORY="$root" \
 +                      ${SHELL_PATH} "$0" \
 +                      --root="$root" --statusprefix="[$i] " \
 +                      --valgrind="$valgrind" \
 +                      --valgrind-only-stride="$valgrind_parallel" \
 +                      --valgrind-only-offset="$i" &
 +              pids="$pids $!"
 +      done
 +      trap "kill $pids" INT TERM HUP
 +      wait $pids
 +      trap - INT TERM HUP
 +      for i in $(test_seq 1 $valgrind_parallel)
 +      do
 +              root="$TRASH_DIRECTORY/vgparallel-$i"
 +              eval "$(cat "$root/test-results/$(basename "$0" .sh)"-*.counts |
 +                      sed 's/^\([a-z][a-z]*\) \([0-9][0-9]*\)/inner_\1=\2/')"
 +              test_count=$(expr $test_count + $inner_total)
 +              test_success=$(expr $test_success + $inner_success)
 +              test_fixed=$(expr $test_fixed + $inner_fixed)
 +              test_broken=$(expr $test_broken + $inner_broken)
 +              test_failure=$(expr $test_failure + $inner_failed)
 +      done
 +      test_done
 +fi
 +
  # Use -P to resolve symlinks in our working directory so that the cwd
  # in subprocesses like git equals our $PWD (for pathname comparisons).
  cd -P "$TRASH_DIRECTORY" || exit 1
  
  this_test=${0##*/}
  this_test=${this_test%%-*}
 -for skp in $GIT_SKIP_TESTS
 -do
 -      case "$this_test" in
 -      $skp)
 -              say_color info >&3 "skipping test $this_test altogether"
 -              skip_all="skip all tests in $this_test"
 -              test_done
 -      esac
 -done
 +if match_pattern_list "$this_test" $GIT_SKIP_TESTS
 +then
 +      say_color info >&3 "skipping test $this_test altogether"
 +      skip_all="skip all tests in $this_test"
 +      test_done
 +fi
  
  # Provide an implementation of the 'yes' utility
  yes () {
@@@ -885,14 -738,7 +886,14 @@@ test_i18ngrep () 
  
  test_lazy_prereq PIPE '
        # test whether the filesystem supports FIFOs
 -      rm -f testfifo && mkfifo testfifo
 +      case $(uname -s) in
 +      CYGWIN*)
 +              false
 +              ;;
 +      *)
 +              rm -f testfifo && mkfifo testfifo
 +              ;;
 +      esac
  '
  
  test_lazy_prereq SYMLINKS '