]> source.dussan.org Git - jgit.git/commitdiff
Factor out URL replacement from RemoteConfig 28/191928/1
authorThomas Wolf <thomas.wolf@paranor.ch>
Wed, 2 Mar 2022 19:47:49 +0000 (20:47 +0100)
committerThomas Wolf <thomas.wolf@paranor.ch>
Tue, 15 Mar 2022 19:43:51 +0000 (20:43 +0100)
Add a new UrlConfig that encapsulates the basic URL replacement logic
for git configs url.<base>.insteadOf and pushInsteadof.

Change-Id: Iecc61d1c5e6089533552afa1d1e684ae72393b38
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java [new file with mode: 0644]

index 2f3160bb8e09789fdcc8c139f93244412c4986a9..c4e105ec4ac7463a260d5fb3c01466cc8ce0829b 100644 (file)
@@ -16,10 +16,7 @@ import java.io.Serializable;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import org.eclipse.jgit.lib.Config;
 
@@ -54,10 +51,6 @@ public class RemoteConfig implements Serializable {
 
        private static final String KEY_TIMEOUT = "timeout"; //$NON-NLS-1$
 
-       private static final String KEY_INSTEADOF = "insteadof"; //$NON-NLS-1$
-
-       private static final String KEY_PUSHINSTEADOF = "pushinsteadof"; //$NON-NLS-1$
-
        private static final boolean DEFAULT_MIRROR = false;
 
        /** Default value for {@link #getUploadPack()} if not specified. */
@@ -135,10 +128,10 @@ public class RemoteConfig implements Serializable {
                String val;
 
                vlst = rc.getStringList(SECTION, name, KEY_URL);
-               Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
+               UrlConfig urls = new UrlConfig(rc);
                uris = new ArrayList<>(vlst.length);
                for (String s : vlst) {
-                       uris.add(new URIish(replaceUri(s, insteadOf)));
+                       uris.add(new URIish(urls.replace(s)));
                }
                String[] plst = rc.getStringList(SECTION, name, KEY_PUSHURL);
                pushURIs = new ArrayList<>(plst.length);
@@ -148,11 +141,9 @@ public class RemoteConfig implements Serializable {
                if (pushURIs.isEmpty()) {
                        // Would default to the uris. If we have pushinsteadof, we must
                        // supply rewritten push uris.
-                       Map<String, String> pushInsteadOf = getReplacements(rc,
-                                       KEY_PUSHINSTEADOF);
-                       if (!pushInsteadOf.isEmpty()) {
+                       if (urls.hasPushReplacements()) {
                                for (String s : vlst) {
-                                       String replaced = replaceUri(s, pushInsteadOf);
+                                       String replaced = urls.replacePush(s);
                                        if (!s.equals(replaced)) {
                                                pushURIs.add(new URIish(replaced));
                                        }
@@ -248,39 +239,6 @@ public class RemoteConfig implements Serializable {
                rc.unset(SECTION, getName(), key);
        }
 
-       private Map<String, String> getReplacements(final Config config,
-                       final String keyName) {
-               final Map<String, String> replacements = new HashMap<>();
-               for (String url : config.getSubsections(KEY_URL))
-                       for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
-                               replacements.put(insteadOf, url);
-               return replacements;
-       }
-
-       private String replaceUri(final String uri,
-                       final Map<String, String> replacements) {
-               if (replacements.isEmpty()) {
-                       return uri;
-               }
-               Entry<String, String> match = null;
-               for (Entry<String, String> replacement : replacements.entrySet()) {
-                       // Ignore current entry if not longer than previous match
-                       if (match != null
-                                       && match.getKey().length() > replacement.getKey()
-                                                       .length()) {
-                               continue;
-                       }
-                       if (!uri.startsWith(replacement.getKey())) {
-                               continue;
-                       }
-                       match = replacement;
-               }
-               if (match != null) {
-                       return match.getValue() + uri.substring(match.getKey().length());
-               }
-               return uri;
-       }
-
        /**
         * Get the local name this remote configuration is recognized as.
         *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java
new file mode 100644 (file)
index 0000000..574fcf8
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.jgit.lib.Config;
+
+/**
+ * Support for URL translations via git configs {@code url.<base>.insteadOf} and
+ * {@code url.<base>.pushInsteadOf}.
+ *
+ * @since 6.2
+ */
+public class UrlConfig {
+
+       private static final String KEY_INSTEADOF = "insteadof"; //$NON-NLS-1$
+
+       private static final String KEY_PUSHINSTEADOF = "pushinsteadof"; //$NON-NLS-1$
+
+       private static final String SECTION_URL = "url"; //$NON-NLS-1$
+
+       private final Config config;
+
+       private Map<String, String> insteadOf;
+
+       private Map<String, String> pushInsteadOf;
+
+       /**
+        * Creates a new {@link UrlConfig} instance.
+        *
+        * @param config
+        *            {@link Config} to read values from
+        */
+       public UrlConfig(Config config) {
+               this.config = config;
+       }
+
+       /**
+        * Performs replacements as defined by git config
+        * {@code url.<base>.insteadOf}. If there is no match, the input is returned
+        * unchanged.
+        *
+        * @param url
+        *            to substitute
+        * @return the {@code url} with substitution applied
+        */
+       public String replace(String url) {
+               if (insteadOf == null) {
+                       insteadOf = load(KEY_INSTEADOF);
+               }
+               return replace(url, insteadOf);
+       }
+
+       /**
+        * Tells whether there are push replacements.
+        *
+        * @return {@code true} if there are push replacements, {@code false}
+        *         otherwise
+        */
+       public boolean hasPushReplacements() {
+               if (pushInsteadOf == null) {
+                       pushInsteadOf = load(KEY_PUSHINSTEADOF);
+               }
+               return !pushInsteadOf.isEmpty();
+       }
+
+       /**
+        * Performs replacements as defined by git config
+        * {@code url.<base>.pushInsteadOf}. If there is no match, the input is
+        * returned unchanged.
+        *
+        * @param url
+        *            to substitute
+        * @return the {@code url} with substitution applied
+        */
+       public String replacePush(String url) {
+               if (pushInsteadOf == null) {
+                       pushInsteadOf = load(KEY_PUSHINSTEADOF);
+               }
+               return replace(url, pushInsteadOf);
+       }
+
+       private Map<String, String> load(String key) {
+               Map<String, String> replacements = new HashMap<>();
+               for (String url : config.getSubsections(SECTION_URL)) {
+                       for (String prefix : config.getStringList(SECTION_URL, url, key)) {
+                               replacements.put(prefix, url);
+                       }
+               }
+               return replacements;
+       }
+
+       private String replace(String uri, Map<String, String> replacements) {
+               Entry<String, String> match = null;
+               for (Entry<String, String> replacement : replacements.entrySet()) {
+                       // Ignore current entry if not longer than previous match
+                       if (match != null && match.getKey().length() > replacement.getKey()
+                                       .length()) {
+                               continue;
+                       }
+                       if (uri.startsWith(replacement.getKey())) {
+                               match = replacement;
+                       }
+               }
+               if (match != null) {
+                       return match.getValue() + uri.substring(match.getKey().length());
+               }
+               return uri;
+       }
+}