diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2022-03-22 12:15:33 -0400 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org <gerrit@eclipse.org> | 2022-03-22 12:15:33 -0400 |
commit | 30a137dfe5cfa02c8b8001e451148a183c79c19b (patch) | |
tree | 1dcdae50cb9497750b598edbf216364a823c096f /org.eclipse.jgit | |
parent | b12ec8f3776980241c7f7ba1a3e6faa427cf5330 (diff) | |
parent | 2c1a8798ca05ab7b9f5935e0323066ad361ab0f1 (diff) | |
download | jgit-30a137dfe5cfa02c8b8001e451148a183c79c19b.tar.gz jgit-30a137dfe5cfa02c8b8001e451148a183c79c19b.zip |
Merge changes I5df54a92,Iecc61d1c
* changes:
LsRemoteCommand: apply url.*.insteadOf
Factor out URL replacement from RemoteConfig
Diffstat (limited to 'org.eclipse.jgit')
3 files changed, 138 insertions, 52 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java index 0c691062f9..c3415581ef 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2020 Christoph Brill <egore911@egore911.de> and others + * Copyright (C) 2011, 2022 Christoph Brill <egore911@egore911.de> 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 @@ -9,6 +9,7 @@ */ package org.eclipse.jgit.api; +import java.io.IOException; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; @@ -20,8 +21,8 @@ import java.util.Map; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.NotSupportedException; -import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; @@ -30,6 +31,8 @@ import org.eclipse.jgit.transport.FetchConnection; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.UrlConfig; +import org.eclipse.jgit.util.SystemReader; /** * The ls-remote command @@ -153,7 +156,7 @@ public class LsRemoteCommand extends try (Transport transport = repo != null ? Transport.open(repo, remote) - : Transport.open(new URIish(remote))) { + : Transport.open(new URIish(translate(remote)))) { transport.setOptionUploadPack(uploadPack); configure(transport); Collection<RefSpec> refSpecs = new ArrayList<>(1); @@ -185,11 +188,16 @@ public class LsRemoteCommand extends throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand, e); - } catch (TransportException e) { + } catch (IOException | ConfigInvalidException e) { throw new org.eclipse.jgit.api.errors.TransportException( - e.getMessage(), - e); + e.getMessage(), e); } } + private String translate(String uri) + throws IOException, ConfigInvalidException { + UrlConfig urls = new UrlConfig( + SystemReader.getInstance().getUserConfig()); + return urls.replace(uri); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java index 2f3160bb8e..c4e105ec4a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java @@ -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 index 0000000000..574fcf806d --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java @@ -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; + } +} |