Skip to content

Commit 80df84f

Browse files
authored
Finish Parser Implementation (#829)
1 parent aca3a39 commit 80df84f

File tree

2 files changed

+141
-31
lines changed

2 files changed

+141
-31
lines changed

src/code/HttpFindPSResource.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Linq;
12
using System.Xml;
23
using Microsoft.PowerShell.PowerShellGet.UtilClasses;
34
using NuGet.Versioning;
@@ -155,24 +156,27 @@ public PSResourceInfo FindName(string packageName, string repository, bool inclu
155156
var elemList = ConvertResponseToXML(response);
156157

157158
// Loop through and try to convert each xml entry into a PSResourceInfo object
158-
for (int i = 0; i < elemList.Length; i++)
159+
for (int i = elemList.Length - 1; i >= 0; i--)
159160
{
160161
PSResourceInfo.TryConvertFromXml(
161162
elemList[i],
163+
includePrerelease,
162164
out PSResourceInfo psGetInfo,
163165
"PSGallery",
164-
null,
165166
out string errorMsg);
166-
}
167-
168-
PSResourceInfo currentPkg = null;
169-
if (!string.IsNullOrEmpty(errRecord))
170-
{
171-
return currentPkg;
167+
168+
if (psGetInfo != null)
169+
{
170+
return psGetInfo;
171+
}
172+
else
173+
{
174+
// TODO: Write error for corresponding null scenario
175+
errRecord = errorMsg;
176+
}
172177
}
173178

174-
// Convert to PSResourceInfo object
175-
return currentPkg;
179+
return null;
176180
}
177181

178182
/// <summary>

src/code/PSResourceInfo.cs

Lines changed: 127 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,10 @@ public sealed class Dependency
181181

182182
#region Constructor
183183

184-
/// <summary>
185-
/// Parameterless constructor needed for XmlSerializer
186-
/// </summary>
187-
public Dependency() { }
188-
189184
/// <summary>
190185
/// Constructor
191-
///
186+
/// An object describes a package dependency
192187
/// </summary>
193-
/// <param name="includes">Hashtable of PSGet includes</param>
194188
public Dependency(string dependencyName, VersionRange dependencyVersionRange)
195189
{
196190
Name = dependencyName;
@@ -588,9 +582,9 @@ public static bool TryConvert(
588582
// write a serializer
589583
public static bool TryConvertFromXml(
590584
XmlNode entry,
585+
bool includePrerelease,
591586
out PSResourceInfo psGetInfo,
592587
string repositoryName,
593-
ResourceType? type,
594588
out string errorMsg)
595589
{
596590
psGetInfo = null;
@@ -604,40 +598,83 @@ public static bool TryConvertFromXml(
604598

605599
try
606600
{
607-
Hashtable metadata = new Hashtable();
601+
Hashtable metadata = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
602+
608603
var childNodes = entry.ChildNodes;
609604
foreach (XmlElement child in childNodes)
610605
{
611606
var key = child.LocalName;
612607
var value = child.InnerText;
613608

614-
615-
if (key.Equals("Version", StringComparison.InvariantCultureIgnoreCase))
609+
if (key.Equals("Version"))
616610
{
617611
metadata[key] = ParseHttpVersion(value, out string prereleaseLabel);
618612
metadata["Prerelease"] = prereleaseLabel;
619613
}
620-
else if (key.EndsWith("Url", StringComparison.InvariantCultureIgnoreCase))
614+
else if (key.EndsWith("Url"))
621615
{
622616
metadata[key] = ParseHttpUrl(value) as Uri;
623617
}
624-
else if (key.Equals("Tags", StringComparison.InvariantCultureIgnoreCase))
618+
else if (key.Equals("Tags"))
625619
{
626620
metadata[key] = value.Split(new char[]{' '});
627621
}
628-
else if (key.Equals("Published", StringComparison.InvariantCultureIgnoreCase))
622+
else if (key.Equals("Published"))
629623
{
630624
metadata[key] = ParseHttpDateTime(value);
631625
}
632-
else if (key.Equals("Dependencies", StringComparison.InvariantCultureIgnoreCase))
626+
else if (key.Equals("Dependencies"))
633627
{
634628
metadata[key] = ParseHttpDependencies(value);
635629
}
630+
else if (key.Equals("IsPrerelease"))
631+
{
632+
bool.TryParse(value, out bool isPrerelease);
633+
// For FindName
634+
if (!includePrerelease && isPrerelease)
635+
{
636+
return false;
637+
}
638+
metadata[key] = isPrerelease;
639+
}
636640
else
637641
{
638642
metadata[key] = value;
639643
}
640644
}
645+
646+
var typeInfo = ParseHttpMetadataType(metadata["Tags"] as string[], out ArrayList commandNames, out ArrayList dscResourceNames);
647+
var resourceHashtable = new Hashtable();
648+
resourceHashtable.Add(nameof(PSResourceInfo.Includes.Command), new PSObject(commandNames));
649+
resourceHashtable.Add(nameof(PSResourceInfo.Includes.DscResource), new PSObject(dscResourceNames));
650+
var includes = new ResourceIncludes(resourceHashtable);
651+
652+
psGetInfo = new PSResourceInfo(
653+
additionalMetadata: null,
654+
author: metadata["Author"] as String,
655+
companyName: metadata["CompanyName"] as String,
656+
copyright: metadata["Copyright"] as String,
657+
dependencies: metadata["Dependencies"] as Dependency[],
658+
description: metadata["Description"] as String,
659+
iconUri: metadata["IconUrl"] as Uri,
660+
includes: includes,
661+
installedDate: null,
662+
installedLocation: null,
663+
isPrelease: (bool) metadata["IsPrerelease"],
664+
licenseUri: metadata["LicenseUrl"] as Uri,
665+
name: metadata["Id"] as String,
666+
packageManagementProvider: null,
667+
powershellGetFormatVersion: null,
668+
prerelease: metadata["Prerelease"] as String,
669+
projectUri: metadata["ProjectUrl"] as Uri,
670+
publishedDate: metadata["Published"] as DateTime?,
671+
releaseNotes: metadata["ReleaseNotes"] as String,
672+
repository: repositoryName,
673+
repositorySourceLocation: null,
674+
tags: metadata["Tags"] as string[],
675+
type: typeInfo,
676+
updatedDate: null,
677+
version: metadata["Version"] as Version);
641678

642679
return true;
643680
}
@@ -1016,10 +1053,8 @@ private static Version ParseHttpVersion(string versionString, out string prerele
10161053
public static Uri ParseHttpUrl(string uriString)
10171054
{
10181055
Uri parsedUri;
1019-
if (!Uri.TryCreate(uriString, UriKind.Absolute, out parsedUri))
1020-
{
1021-
//return parsedUri;
1022-
}
1056+
Uri.TryCreate(uriString, UriKind.Absolute, out parsedUri);
1057+
10231058
return parsedUri;
10241059
}
10251060

@@ -1031,8 +1066,79 @@ public static Uri ParseHttpUrl(string uriString)
10311066

10321067
public static Dependency[] ParseHttpDependencies(string dependencyString)
10331068
{
1034-
string[] dependencies = dependencyString.Split(new string[]{":|"}, StringSplitOptions.None);
1035-
return new Dependency[]{};
1069+
/*
1070+
Az.Profile:[0.1.0, ):|Az.Aks:[0.1.0, ):|Az.AnalysisServices:[0.1.0, ):
1071+
Post 1st Split:
1072+
["Az.Profile:[0.1.0, ):", "Az.Aks:[0.1.0, ):", "Az.AnalysisServices:[0.1.0, ):"]
1073+
*/
1074+
string[] dependencies = dependencyString.Split(new char[]{'|'}, StringSplitOptions.RemoveEmptyEntries);
1075+
1076+
List<Dependency> dependencyList = new List<Dependency>();
1077+
foreach (string dependency in dependencies)
1078+
{
1079+
/*
1080+
The Element: "Az.Profile:[0.1.0, ):"
1081+
Post 2nd Split: ["Az.Profile", "[0.1.0, )"]
1082+
*/
1083+
string[] dependencyParts = dependency.Split(new char[]{':'}, StringSplitOptions.RemoveEmptyEntries);
1084+
1085+
VersionRange dependencyVersion;
1086+
if (dependencyParts.Length == 1)
1087+
{
1088+
dependencyVersion = VersionRange.All;
1089+
}
1090+
else
1091+
{
1092+
if (!Utils.TryParseVersionOrVersionRange(dependencyParts[1], out dependencyVersion))
1093+
{
1094+
dependencyVersion = VersionRange.All;
1095+
}
1096+
}
1097+
1098+
dependencyList.Add(new Dependency(dependencyParts[0], dependencyVersion));
1099+
}
1100+
1101+
return dependencyList.ToArray();
1102+
}
1103+
1104+
private static ResourceType ParseHttpMetadataType(
1105+
string[] tags,
1106+
out ArrayList commandNames,
1107+
out ArrayList dscResourceNames)
1108+
{
1109+
// possible type combinations:
1110+
// M, C
1111+
// M, D
1112+
// M
1113+
// S
1114+
1115+
commandNames = new ArrayList();
1116+
dscResourceNames = new ArrayList();
1117+
1118+
ResourceType pkgType = ResourceType.Module;
1119+
foreach (string tag in tags)
1120+
{
1121+
if(String.Equals(tag, "PSScript", StringComparison.InvariantCultureIgnoreCase))
1122+
{
1123+
// clear default Module tag, because a Script resource cannot be a Module resource also
1124+
pkgType = ResourceType.Script;
1125+
pkgType &= ~ResourceType.Module;
1126+
}
1127+
1128+
if (tag.StartsWith("PSCommand_", StringComparison.InvariantCultureIgnoreCase))
1129+
{
1130+
pkgType |= ResourceType.Command;
1131+
commandNames.Add(tag.Split('_')[1]);
1132+
}
1133+
1134+
if (tag.StartsWith("PSDscResource_", StringComparison.InvariantCultureIgnoreCase))
1135+
{
1136+
pkgType |= ResourceType.DscResource;
1137+
dscResourceNames.Add(tag.Split('_')[1]);
1138+
}
1139+
}
1140+
1141+
return pkgType;
10361142
}
10371143

10381144
#endregion

0 commit comments

Comments
 (0)