FS_Win32_Cygwin.java

  1. /*
  2.  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.util;

  11. import static java.nio.charset.StandardCharsets.UTF_8;

  12. import java.io.File;
  13. import java.io.OutputStream;
  14. import java.security.AccessController;
  15. import java.security.PrivilegedAction;
  16. import java.util.ArrayList;
  17. import java.util.Arrays;
  18. import java.util.List;

  19. import org.eclipse.jgit.api.errors.JGitInternalException;
  20. import org.eclipse.jgit.errors.CommandFailedException;
  21. import org.eclipse.jgit.lib.Repository;
  22. import org.slf4j.Logger;
  23. import org.slf4j.LoggerFactory;

  24. /**
  25.  * FS implementation for Cygwin on Windows
  26.  *
  27.  * @since 3.0
  28.  */
  29. public class FS_Win32_Cygwin extends FS_Win32 {
  30.     private static final Logger LOG = LoggerFactory
  31.             .getLogger(FS_Win32_Cygwin.class);

  32.     private static String cygpath;

  33.     /**
  34.      * Whether cygwin is found
  35.      *
  36.      * @return true if cygwin is found
  37.      */
  38.     public static boolean isCygwin() {
  39.         final String path = AccessController
  40.                 .doPrivileged((PrivilegedAction<String>) () -> System
  41.                         .getProperty("java.library.path") //$NON-NLS-1$
  42.                 );
  43.         if (path == null)
  44.             return false;
  45.         File found = FS.searchPath(path, "cygpath.exe"); //$NON-NLS-1$
  46.         if (found != null)
  47.             cygpath = found.getPath();
  48.         return cygpath != null;
  49.     }

  50.     /**
  51.      * Constructor
  52.      */
  53.     public FS_Win32_Cygwin() {
  54.         super();
  55.     }

  56.     /**
  57.      * Constructor
  58.      *
  59.      * @param src
  60.      *            instance whose attributes to copy
  61.      */
  62.     protected FS_Win32_Cygwin(FS src) {
  63.         super(src);
  64.     }

  65.     /** {@inheritDoc} */
  66.     @Override
  67.     public FS newInstance() {
  68.         return new FS_Win32_Cygwin(this);
  69.     }

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public File resolve(File dir, String pn) {
  73.         String useCygPath = System.getProperty("jgit.usecygpath"); //$NON-NLS-1$
  74.         if (useCygPath != null && useCygPath.equals("true")) { //$NON-NLS-1$
  75.             String w;
  76.             try {
  77.                 w = readPipe(dir, //
  78.                     new String[] { cygpath, "--windows", "--absolute", pn }, // //$NON-NLS-1$ //$NON-NLS-2$
  79.                     UTF_8.name());
  80.             } catch (CommandFailedException e) {
  81.                 LOG.warn(e.getMessage());
  82.                 return null;
  83.             }
  84.             if (!StringUtils.isEmptyOrNull(w)) {
  85.                 return new File(w);
  86.             }
  87.         }
  88.         return super.resolve(dir, pn);
  89.     }

  90.     /** {@inheritDoc} */
  91.     @Override
  92.     protected File userHomeImpl() {
  93.         final String home = AccessController.doPrivileged(
  94.                 (PrivilegedAction<String>) () -> System.getenv("HOME") //$NON-NLS-1$
  95.         );
  96.         if (home == null || home.length() == 0)
  97.             return super.userHomeImpl();
  98.         return resolve(new File("."), home); //$NON-NLS-1$
  99.     }

  100.     /** {@inheritDoc} */
  101.     @Override
  102.     public ProcessBuilder runInShell(String cmd, String[] args) {
  103.         List<String> argv = new ArrayList<>(4 + args.length);
  104.         argv.add("sh.exe"); //$NON-NLS-1$
  105.         argv.add("-c"); //$NON-NLS-1$
  106.         argv.add(cmd + " \"$@\""); //$NON-NLS-1$
  107.         argv.add(cmd);
  108.         argv.addAll(Arrays.asList(args));
  109.         ProcessBuilder proc = new ProcessBuilder();
  110.         proc.command(argv);
  111.         return proc;
  112.     }

  113.     @Override
  114.     String shellQuote(String cmd) {
  115.         return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/'));
  116.     }

  117.     /** {@inheritDoc} */
  118.     @Override
  119.     public String relativize(String base, String other) {
  120.         final String relativized = super.relativize(base, other);
  121.         return relativized.replace(File.separatorChar, '/');
  122.     }

  123.     /** {@inheritDoc} */
  124.     @Override
  125.     public ProcessResult runHookIfPresent(Repository repository, String hookName,
  126.             String[] args, OutputStream outRedirect, OutputStream errRedirect,
  127.             String stdinArgs) throws JGitInternalException {
  128.         return internalRunHookIfPresent(repository, hookName, args, outRedirect,
  129.                 errRedirect, stdinArgs);
  130.     }
  131. }