Skip to content

Commit

Permalink
Feature: Constrained GitWeb RepositoryUrl translation to SSH only
Browse files Browse the repository at this point in the history
  • Loading branch information
Glen-Nicol-Garmin committed Jan 30, 2020
1 parent 015d649 commit 18b13db
Show file tree
Hide file tree
Showing 20 changed files with 375 additions and 38 deletions.
6 changes: 6 additions & 0 deletions src/Common/CommonResources.resx
Expand Up @@ -141,4 +141,10 @@
<data name="UnableToDetermineRepositoryUrl" xml:space="preserve">
<value>Unable to determine repository url, the source code won't be available via source link.</value>
</data>
<data name="RepositoryUrlIsNotComplete" xml:space="preserve">
<value>The provided url '{0}' is not a complete URI</value>
</data>
<data name="RepositoryUrlIsNotSupportedByProvider" xml:space="preserve">
<value>The {0} provider does not support translating the '{1}' protocol to content URLs.</value>
</data>
</root>
71 changes: 58 additions & 13 deletions src/Common/TranslateRepositoryUrlGitTask.cs
Expand Up @@ -33,6 +33,9 @@ protected virtual string TranslateGitUrl(Uri uri)
protected virtual string TranslateHttpUrl(Uri uri)
=> uri.GetScheme() + "://" + uri.GetAuthority() + uri.GetPathAndQuery();

protected virtual bool IsProtocolSupportedByProvider(string protocol)
=> true;

public override bool Execute()
{
ExecuteImpl();
Expand All @@ -47,26 +50,45 @@ private void ExecuteImpl()
return;
}

bool getUri(string url, out Uri uri) => Uri.TryCreate(url, UriKind.Absolute, out uri);

bool isMatchingHostUri(Uri hostUri, Uri uri)
=> uri.GetHost().Equals(hostUri.GetHost(), StringComparison.OrdinalIgnoreCase) ||
=> uri.GetHost().Equals(hostUri.GetHost(), StringComparison.OrdinalIgnoreCase) ||
uri.GetHost().EndsWith("." + hostUri.GetHost(), StringComparison.OrdinalIgnoreCase);

// only need to translate valid ssh URLs that match one of our hosts:
string translate(string url)
string translate(Uri uri)
{
if (Uri.TryCreate(url, UriKind.Absolute, out var uri) &&
hostUris.Any(h => isMatchingHostUri(h, uri)))
if(hostUris.Any(h => isMatchingHostUri(h, uri)))
{
return (uri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase) ? TranslateHttpUrl(uri) :
uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) ? TranslateHttpUrl(uri) :
uri.Scheme.Equals("ssh", StringComparison.OrdinalIgnoreCase) ? TranslateSshUrl(uri) :
uri.Scheme.Equals("git", StringComparison.OrdinalIgnoreCase) ? TranslateGitUrl(uri) : null) ?? url;
uri.Scheme.Equals("git", StringComparison.OrdinalIgnoreCase) ? TranslateGitUrl(uri) : null) ?? uri.OriginalString;
}

return url;
return uri.OriginalString;
}

var providerName = this.GetType().Namespace;
if(getUri(RepositoryUrl, out var repoUrlUri))
{
if(!IsProtocolSupportedByProvider(repoUrlUri.Scheme))
{
// TODO should this be an error or a warning?
Log.LogError(CommonResources.RepositoryUrlIsNotSupportedByProvider, providerName, repoUrlUri.Scheme);
return;
}

TranslatedRepositoryUrl = translate(repoUrlUri);
}
else
{
// preserve previous behavior of using the URL as is if URI cannot be parsed.
TranslatedRepositoryUrl = RepositoryUrl;
Log.LogWarning(CommonResources.RepositoryUrlIsNotComplete, RepositoryUrl);
}

TranslatedRepositoryUrl = translate(RepositoryUrl);
TranslatedSourceRoots = SourceRoots;

if (TranslatedSourceRoots != null)
Expand All @@ -78,12 +100,35 @@ string translate(string url)
continue;
}

// Item metadata are stored msbuild-escaped. GetMetadata unescapes, SetMetadata stores the value as specified.
// When initializing the URL metadata from git information we msbuild-escaped the URL to preserve any URL escapes in it.
// Here, GetMetadata unescapes the msbuild escapes, then we translate the URL and finally msbuild-escape
// the resulting URL to preserve any URL escapes.
sourceRoot.SetMetadata(Names.SourceRoot.ScmRepositoryUrl,
Evaluation.ProjectCollection.Escape(translate(sourceRoot.GetMetadata(Names.SourceRoot.ScmRepositoryUrl))));
var scmRepoUrl = sourceRoot.GetMetadata(Names.SourceRoot.ScmRepositoryUrl);
if (getUri(scmRepoUrl, out var scmRepoUri))
{
if (!IsProtocolSupportedByProvider(scmRepoUri.Scheme))
{
// TODO should this be an error or a warning?
Log.LogError(CommonResources.RepositoryUrlIsNotSupportedByProvider, providerName, scmRepoUri.Scheme);
continue;
}

setScmRepoUrlMetaData(translate(scmRepoUri));
}
else
{
// preserve previous behavior of using the URL as is if URI cannot be parsed.
Log.LogWarning(CommonResources.RepositoryUrlIsNotComplete, scmRepoUrl);
setScmRepoUrlMetaData(scmRepoUrl);
}

void setScmRepoUrlMetaData(string url)
{
// Item metadata are stored msbuild-escaped. GetMetadata unescapes, SetMetadata
// stores the value as specified. When initializing the URL metadata from git
// information we msbuild-escaped the URL to preserve any URL escapes in it.
// Here, GetMetadata unescapes the msbuild escapes, then we translate the URL
// and finally msbuild-escape the resulting URL to preserve any URL escapes.
sourceRoot.SetMetadata(Names.SourceRoot.ScmRepositoryUrl,
Evaluation.ProjectCollection.Escape(url));
}
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.cs.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">Položka {0} ve skupině položek {1} musí uvádět metadata {2}.</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">Nejde určit adresu URL úložiště. Zdrojový kód nebude k dispozici přes zdrojový odkaz.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.de.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">Das Element "{0}" der Elementgruppe "{1}" muss die Metadaten "{2}" angeben.</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">Die URL für das Repository konnte nicht ermittelt werden. Daher ist der Quellcode nicht über den Link zur Quelle verfügbar.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.es.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">El elemento "{0}" del grupo de elementos "{1}" debe especificar los metadatos "{2}"</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">No se puede determinar la URL del repositorio, el código fuente no estará disponible a través del vínculo de origen.</target>
Expand Down
26 changes: 18 additions & 8 deletions src/Common/xlf/CommonResources.fr.xlf
Expand Up @@ -4,42 +4,52 @@
<body>
<trans-unit id="AtLeastOneRepositoryHostIsRequired">
<source>{0} item group is empty. At least one {1} repository host is required in order to generate SourceLink.</source>
<target state="translated">Le groupe d'éléments {0} est vide. Au moins un hôte de dépôt {1} est nécessaire pour générer SourceLink.</target>
<target state="new">{0} item group is empty. At least one {1} repository host is required in order to generate SourceLink.</target>
<note />
</trans-unit>
<trans-unit id="ItemOfItemGroupMustSpecifyMetadata">
<source>Item '{0}' of item group '{1}' must specify metadata '{2}'</source>
<target state="translated">L'élément '{0}' du groupe d'éléments '{1}' doit spécifier les métadonnées '{2}'</target>
<target state="new">Item '{0}' of item group '{1}' must specify metadata '{2}'</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">Impossible de déterminer l'URL du dépôt, le code source n'est pas disponible via le lien source.</target>
<target state="new">Unable to determine repository url, the source code won't be available via source link.</target>
<note />
</trans-unit>
<trans-unit id="ValueOfWithIdentityIsInvalid">
<source>The value of {0} with identity '{1}' is invalid: '{2}'</source>
<target state="translated">La valeur de {0} avec l'identité '{1}' n’est pas valide : '{2}'</target>
<target state="new">The value of {0} with identity '{1}' is invalid: '{2}'</target>
<note />
</trans-unit>
<trans-unit id="ValueOfWithIdentityIsNotValidCommitHash">
<source>The value of {0} with identity '{1}' is not a valid commit hash: '{2}'</source>
<target state="translated">La valeur de {0} avec l'identité '{1}' n'est pas un hachage de validation valide : '{2}'</target>
<target state="new">The value of {0} with identity '{1}' is not a valid commit hash: '{2}'</target>
<note />
</trans-unit>
<trans-unit id="ValuePassedToTaskParameterNotValidDomainName">
<source>The value passed to task parameter {0} is not a valid domain name: '{1}'</source>
<target state="translated">La valeur passée au paramètre de tâche {0} n'est pas un nom de domaine valide : '{1}'</target>
<target state="new">The value passed to task parameter {0} is not a valid domain name: '{1}'</target>
<note />
</trans-unit>
<trans-unit id="ValuePassedToTaskParameterNotValidHostUri">
<source>The value passed to task parameter {0} is not a valid host URI: '{1}'</source>
<target state="translated">La valeur passée au paramètre de tâche {0} n'est pas un URI d'hôte valide : '{1}'</target>
<target state="new">The value passed to task parameter {0} is not a valid host URI: '{1}'</target>
<note />
</trans-unit>
<trans-unit id="ValuePassedToTaskParameterNotValidUri">
<source>The value passed to task parameter {0} is not a valid URI: '{1}'</source>
<target state="translated">La valeur passée au paramètre de tâche {0} n'est pas un URI valide : '{1}'</target>
<target state="new">The value passed to task parameter {0} is not a valid URI: '{1}'</target>
<note />
</trans-unit>
</body>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.it.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">L'elemento '{0}' del gruppo di elementi '{1}' deve specificare i metadati '{2}'</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">Non è possibile determinare l'URL del repository. Il codice sorgente non sarà disponibile tramite il collegamento all'origine.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.ja.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">項目グループ '{1}' の項目 '{0}' には、メタデータ '{2}' を指定する必要があります</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">リポジトリのURLを特定できません。ソース リンクを使用してソース コードを利用できません。</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.ko.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">항목 그룹 '{1}'의 '{0}' 항목은 '{2}' 메타데이터를 지정해야 합니다.</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">리포지토리 URL을 확인할 수 없으며, 소스 링크를 통해 소스 코드를 사용할 수 없습니다.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.pl.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">Element „{0}” grupy elementów „{1}” musi określać metadane „{2}”.</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">Nie można określić adresu URL repozytorium, kod źródłowy nie będzie dostępny za pośrednictwem linku do źródła.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Common/xlf/CommonResources.pt-BR.xlf
Expand Up @@ -12,6 +12,16 @@
<target state="translated">Item '{0}' do grupo de item '{1}' deve especificar metadados '{2}'</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotComplete">
<source>The provided url '{0}' is not a complete URI</source>
<target state="new">The provided url '{0}' is not a complete URI</target>
<note />
</trans-unit>
<trans-unit id="RepositoryUrlIsNotSupportedByProvider">
<source>The {0} provider does not support translating the '{1}' protocol to content URLs.</source>
<target state="new">The {0} provider does not support translating the '{1}' protocol to content URLs.</target>
<note />
</trans-unit>
<trans-unit id="UnableToDetermineRepositoryUrl">
<source>Unable to determine repository url, the source code won't be available via source link.</source>
<target state="translated">Não é possível determinar a URL do repositório, o código-fonte não estará disponível através do link de origem.</target>
Expand Down

0 comments on commit 18b13db

Please sign in to comment.