Skip to content

Commit 8c60d62

Browse files
Updated code changes
1 parent 5d05078 commit 8c60d62

File tree

16 files changed

+230
-119
lines changed

16 files changed

+230
-119
lines changed

src/AritfactoryUploader.UTest/ArtifactoryUploaderTest.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public async Task UploadPackageToRepo_InputEmptyCreds_ReturnsPackgeNotFound()
5454
JfrogApi = "https://abc.jfrog.io/artifactory",
5555
SrcRepoName = "org1-pythonhosted-pypi-remote-cache",
5656
SrcRepoPathWithFullName = "org1-pythonhosted-pypi-remote-cache/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl",
57-
PypiCompName = "html5lib-1.1-py2.py3-none-any.whl",
57+
PypiOrNpmCompName = "html5lib-1.1-py2.py3-none-any.whl",
5858
DestRepoName = "pypi-test",
5959
ApiKey = "",
6060
Email = "",
@@ -111,7 +111,7 @@ public async Task UploadPackageToRepo_WhenPackageInfoIsNull_ReturnsNotFoundRespo
111111
var timeout = 10000;
112112
var displayPackagesInfo = new DisplayPackagesInfo();
113113
var jFrogServiceMock = new Mock<IJFrogService>();
114-
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
114+
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), component))
115115
.ReturnsAsync((AqlResult)null);
116116
ArtfactoryUploader.jFrogService = jFrogServiceMock.Object;
117117
// Act
@@ -140,7 +140,7 @@ public async Task UploadPackageToRepo_WhenPackageTypeIsClearedThirdPartyOrDevelo
140140
var displayPackagesInfo = new DisplayPackagesInfo();
141141
var jFrogServiceMock = new Mock<IJFrogService>();
142142
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
143-
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
143+
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),component))
144144
.ReturnsAsync(new AqlResult());
145145
jfrogApicommunicationMock.Setup(x => x.CopyFromRemoteRepo(It.IsAny<ComponentsToArtifactory>()))
146146
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));
@@ -171,7 +171,7 @@ public async Task UploadPackageToRepo_WhenPackageTypeIsInternal_CallsMoveFromRep
171171
var displayPackagesInfo = new DisplayPackagesInfo();
172172
var jFrogServiceMock = new Mock<IJFrogService>();
173173
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
174-
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
174+
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), component))
175175
.ReturnsAsync(new AqlResult());
176176
jfrogApicommunicationMock.Setup(x => x.MoveFromRepo(It.IsAny<ComponentsToArtifactory>()))
177177
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));
@@ -227,7 +227,7 @@ public async Task UploadPackageToRepo_WhenHttpRequestExceptionOccurs_ReturnsErro
227227
var displayPackagesInfo = new DisplayPackagesInfo();
228228
var jFrogServiceMock = new Mock<IJFrogService>();
229229
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
230-
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
230+
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),component))
231231
.ThrowsAsync(new HttpRequestException());
232232
ArtfactoryUploader.jFrogService = jFrogServiceMock.Object;
233233
ArtfactoryUploader.JFrogApiCommInstance = jfrogApicommunicationMock.Object;
@@ -257,7 +257,7 @@ public async Task UploadPackageToRepo_WhenInvalidOperationExceptionOccurs_Return
257257
var displayPackagesInfo = new DisplayPackagesInfo();
258258
var jFrogServiceMock = new Mock<IJFrogService>();
259259
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
260-
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
260+
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), component))
261261
.ThrowsAsync(new InvalidOperationException());
262262
ArtfactoryUploader.jFrogService = jFrogServiceMock.Object;
263263
ArtfactoryUploader.JFrogApiCommInstance = jfrogApicommunicationMock.Object;

src/AritfactoryUploader.UTest/PackageUploadHelperTest.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -406,31 +406,31 @@ public void GetUploadPackageDetails_CoversAllScenarios()
406406
public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenPypiRepoExists_ReturnsArtifactoryRepoName()
407407
{
408408
// Arrange
409-
Property prop1 = new Property
409+
Property repoNameProperty = new Property
410410
{
411411
Name = Dataconstant.Cdx_ArtifactoryRepoName,
412412
Value = "Reponame"
413413
};
414-
List<Property> properties = new List<Property>() { prop1 };
414+
List<Property> properties = new List<Property>() { repoNameProperty };
415415
var item = new Component
416416
{
417417
Purl = "pypi://example-package",
418418
Properties = properties,
419419
Name = "pypi component",
420420
Version = "1.0.0"
421421
};
422-
AqlProperty property1 = new AqlProperty
422+
AqlProperty pypiNameProperty = new AqlProperty
423423
{
424424
key = "pypi.normalized.name",
425425
value = "pypi component"
426426
};
427427

428-
AqlProperty property2 = new AqlProperty
428+
AqlProperty pypiVersionProperty = new AqlProperty
429429
{
430430
key = "pypi.version",
431431
value = "1.0.0"
432432
};
433-
List<AqlProperty> propertys = new List<AqlProperty> { property1, property2 };
433+
List<AqlProperty> propertys = new List<AqlProperty> { pypiNameProperty, pypiVersionProperty };
434434
//GetInternalComponentDataByRepo
435435
var aqlResultList = new List<AqlResult>
436436
{
@@ -443,7 +443,9 @@ public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenPypiRepoExists_Ret
443443
}
444444
};
445445
var jFrogServiceMock = new Mock<IJFrogService>();
446+
446447
jFrogServiceMock.Setup(x => x.GetPypiComponentDataByRepo(It.IsAny<string>())).ReturnsAsync(aqlResultList);
448+
447449
PackageUploadHelper.jFrogService = jFrogServiceMock.Object;
448450

449451
// Act
@@ -454,16 +456,15 @@ public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenPypiRepoExists_Ret
454456
Assert.AreEqual("pypi-repo", result.Repo);
455457
Assert.AreEqual("path/to/package", result.Path);
456458
}
457-
458459
public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenConanRepoExists_ReturnsArtifactoryRepoName()
459460
{
460461
// Arrange
461-
Property prop1 = new Property
462+
Property reponameProperty = new Property
462463
{
463464
Name = Dataconstant.Cdx_ArtifactoryRepoName,
464465
Value = "Reponame"
465466
};
466-
List<Property> properties = new List<Property>() { prop1 };
467+
List<Property> properties = new List<Property>() { reponameProperty };
467468
var item = new Component
468469
{
469470
Purl = "conan://example-package",
@@ -756,7 +757,7 @@ public async Task GetJfrogRepoInfoForAllTypePackages_GivenDestRepoNames_ReturnsA
756757
}
757758

758759
[Test]
759-
[TestCase("NPM", "source-repo/package-name/-/package-name-1.0.0.tgz?to=/destination-repo/package-name/-/package-name-1.0.0.tgz")]
760+
[TestCase("NPM", "?to=/destination-repo//")]
760761
[TestCase("NUGET", "source-repo/package-name.1.0.0.nupkg?to=/destination-repo/package-name.1.0.0.nupkg")]
761762
[TestCase("MAVEN", "source-repo/package-name/1.0.0?to=/destination-repo/package-name/1.0.0")]
762763
[TestCase("CONAN", "source-repo/?to=/destination-repo/")]
@@ -810,7 +811,7 @@ public void GetCopyURL_GivenInvalidComponentType_ReturnsEmptyString()
810811

811812

812813
[Test]
813-
[TestCase("NPM", "source-repo/package-name/-/package-name-1.0.0.tgz?to=/destination-repo/package-name/-/package-name-1.0.0.tgz")]
814+
[TestCase("NPM", "?to=/destination-repo//")]
814815
[TestCase("NUGET", "source-repo/package-name.1.0.0.nupkg?to=/destination-repo/package-name.1.0.0.nupkg")]
815816
[TestCase("MAVEN", "source-repo/package-name/1.0.0?to=/destination-repo/package-name/1.0.0")]
816817
[TestCase("CONAN", "source-repo/?to=/destination-repo/")]
@@ -860,6 +861,6 @@ public void GetMoveURL_GivenInvalidComponentType_ReturnsEmptyString()
860861

861862
// Assert
862863
Assert.AreEqual(string.Empty, result);
863-
}
864+
}
864865
}
865866
}

src/ArtifactoryUploader/ArtifactoryUploader.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,14 @@ public static void SetConfigurationValues()
107107

108108
private static async Task<AqlResult> GetPackageInfoWithRetry(IJFrogService jFrogService, ComponentsToArtifactory component)
109109
{
110-
async Task<AqlResult> TryGetPackageInfo(string srcRepo, string packageName, string path)
111-
=> await jFrogService.GetPackageInfo(srcRepo, packageName, path);
110+
async Task<AqlResult> TryGetPackageInfo(string srcRepo, string packageName, string path, ComponentsToArtifactory component)
111+
=> await jFrogService.GetPackageInfo(srcRepo, packageName, path, component);
112112

113-
var packageInfo = await TryGetPackageInfo(component.SrcRepoName, component.JfrogPackageName, component.Path);
113+
114+
115+
116+
var packageInfo = await TryGetPackageInfo(component.SrcRepoName, component.JfrogPackageName, component.Path, component);
117+
114118

115119
// Handle DEBIAN package name mismatch
116120
if (component.ComponentType == "DEBIAN" && packageInfo?.Name != component.JfrogPackageName)
@@ -124,8 +128,9 @@ async Task<AqlResult> TryGetPackageInfo(string srcRepo, string packageName, stri
124128
var lowerSrcRepo = component.SrcRepoName.ToLower();
125129
var lowerPackageName = component.JfrogPackageName.ToLower();
126130
var lowerPath = component.Path.ToLower();
131+
127132

128-
packageInfo = await TryGetPackageInfo(lowerSrcRepo, lowerPackageName, lowerPath);
133+
packageInfo = await TryGetPackageInfo(lowerSrcRepo, lowerPackageName, lowerPath, component);
129134

130135
if (packageInfo != null)
131136
{
@@ -137,7 +142,7 @@ async Task<AqlResult> TryGetPackageInfo(string srcRepo, string packageName, stri
137142
// ToDo - A better way would need to be thought of in the future.
138143
if (packageInfo == null)
139144
{
140-
packageInfo = await TryGetPackageInfo(component.SrcRepoName, component.JfrogPackageName, $"{component.Path}*");
145+
packageInfo = await TryGetPackageInfo(component.SrcRepoName, component.JfrogPackageName, $"{component.Path}*", component);
141146

142147
if (packageInfo != null)
143148
{

src/ArtifactoryUploader/PackageUploadHelper.cs

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ public async static Task<List<ComponentsToArtifactory>> GetComponentsToBeUploade
9696
if (aqlResult != null)
9797
{
9898
components.SrcRepoPathWithFullName = aqlResult.Repo + "/" + aqlResult.Path + "/" + aqlResult.Name;
99-
components.PypiCompName = aqlResult.Name;
99+
components.PypiOrNpmCompName = aqlResult.Name;
100100
}
101101
else
102102
{
103103
components.SrcRepoPathWithFullName = string.Empty;
104-
components.PypiCompName = string.Empty;
104+
components.PypiOrNpmCompName = string.Empty;
105105
}
106106

107107
components.Path = GetPackagePath(components, aqlResult);
@@ -730,8 +730,11 @@ public static string GetCopyURL(ComponentsToArtifactory component)
730730
string url = string.Empty;
731731
if (component.ComponentType == "NPM")
732732
{
733-
url = $"{component.JfrogApi}{ApiConstant.CopyPackageApi}{component.SrcRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}" +
734-
$"{ApiConstant.NpmExtension}?to=/{component.DestRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}{ApiConstant.NpmExtension}";
733+
url = $"{component.JfrogApi}{ApiConstant.CopyPackageApi}{component.SrcRepoPathWithFullName}" +
734+
$"?to=/{component.DestRepoName}/{component.Path}/{component.PypiOrNpmCompName}";
735+
736+
// url = $"{component.JfrogApi}{ApiConstant.CopyPackageApi}{component.SrcRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}" +
737+
//$"{ApiConstant.NpmExtension}?to=/{component.DestRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}{ApiConstant.NpmExtension}";
735738
}
736739
else if (component.ComponentType == "NUGET")
737740
{
@@ -746,7 +749,7 @@ public static string GetCopyURL(ComponentsToArtifactory component)
746749
else if (component.ComponentType == "PYTHON")
747750
{
748751
url = $"{component.JfrogApi}{ApiConstant.CopyPackageApi}{component.SrcRepoPathWithFullName}" +
749-
$"?to=/{component.DestRepoName}/{component.PypiCompName}";
752+
$"?to=/{component.DestRepoName}/{component.PypiOrNpmCompName}";
750753
}
751754
else if (component.ComponentType == "CONAN")
752755
{
@@ -772,8 +775,11 @@ public static string GetMoveURL(ComponentsToArtifactory component)
772775
string url = string.Empty;
773776
if (component.ComponentType == "NPM")
774777
{
775-
url = $"{component.JfrogApi}{ApiConstant.MovePackageApi}{component.SrcRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}" +
776-
$"{ApiConstant.NpmExtension}?to=/{component.DestRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}{ApiConstant.NpmExtension}";
778+
url = $"{component.JfrogApi}{ApiConstant.MovePackageApi}{component.SrcRepoPathWithFullName}" +
779+
$"?to=/{component.DestRepoName}/{component.Path}/{component.PypiOrNpmCompName}";
780+
781+
// url = $"{component.JfrogApi}{ApiConstant.MovePackageApi}{component.SrcRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}" +
782+
//$"{ApiConstant.NpmExtension}?to=/{component.DestRepoName}/{component.Name}/-/{component.PackageName}-{component.Version}{ApiConstant.NpmExtension}";
777783
}
778784
else if (component.ComponentType == "NUGET")
779785
{
@@ -788,7 +794,7 @@ public static string GetMoveURL(ComponentsToArtifactory component)
788794
else if (component.ComponentType == "PYTHON")
789795
{
790796
url = $"{component.JfrogApi}{ApiConstant.MovePackageApi}{component.SrcRepoPathWithFullName}" +
791-
$"?to=/{component.DestRepoName}/{component.PypiCompName}";
797+
$"?to=/{component.DestRepoName}/{component.PypiOrNpmCompName}";
792798
}
793799
else if (component.ComponentType == "CONAN")
794800
{
@@ -814,7 +820,15 @@ private static string GetPackagePath(ComponentsToArtifactory component, AqlResul
814820
switch (component.ComponentType)
815821
{
816822
case "NPM":
817-
return $"{component.Name}/-";
823+
if(aqlResult != null)
824+
{
825+
return $"{aqlResult.Path}";
826+
}
827+
else
828+
{
829+
return $"{component.Name}/-";
830+
}
831+
818832

819833
case "CONAN" when aqlResult != null:
820834
string path = aqlResult.Path;
@@ -847,7 +861,7 @@ private static string GetJfrogPackageName(ComponentsToArtifactory component)
847861
switch (component.ComponentType)
848862
{
849863
case "NPM":
850-
packageName = $"{component.PackageName}-{component.Version}{ApiConstant.NpmExtension}";
864+
packageName = component.PypiOrNpmCompName;
851865
break;
852866

853867
case "NUGET":
@@ -859,7 +873,7 @@ private static string GetJfrogPackageName(ComponentsToArtifactory component)
859873
break;
860874

861875
case "PYTHON":
862-
packageName = component.PypiCompName;
876+
packageName = component.PypiOrNpmCompName;
863877
break;
864878

865879
default:
@@ -966,6 +980,15 @@ public async static Task<AqlResult> GetSrcRepoDetailsForPyPiOrConanPackages(Comp
966980
return GetArtifactoryRepoNameForConan(aqlConanResultList, item);
967981
}
968982
}
983+
else if (item.Purl.Contains("npm", StringComparison.OrdinalIgnoreCase))
984+
{
985+
var aqlNpmResultList = await GetNpmListOfComponentsFromRepo(new string[] { item.Properties.Find(x => x.Name == Dataconstant.Cdx_ArtifactoryRepoName)?.Value }, jFrogService);
986+
987+
if (aqlNpmResultList.Count > 0)
988+
{
989+
return GetNpmArtifactoryRepoName(aqlNpmResultList, item);
990+
}
991+
}
969992

970993
return null;
971994
}
@@ -1180,13 +1203,36 @@ public static async Task<List<AqlResult>> GetPypiListOfComponentsFromRepo(string
11801203
return aqlResultList;
11811204
}
11821205

1206+
public static async Task<List<AqlResult>> GetNpmListOfComponentsFromRepo(string[] repoList, IJFrogService jFrogService)
1207+
{
1208+
if (repoList != null && repoList.Length > 0)
1209+
{
1210+
foreach (var repo in repoList)
1211+
{
1212+
var componentRepoData = await jFrogService.GetNpmComponentDataByRepo(repo) ?? new List<AqlResult>();
1213+
aqlResultList.AddRange(componentRepoData);
1214+
}
1215+
}
1216+
1217+
return aqlResultList;
1218+
}
1219+
11831220
private static AqlResult GetArtifactoryRepoName(List<AqlResult> aqlResultList, Component component)
11841221
{
1185-
AqlResult repoName = aqlResultList.Find(x => x.properties.Any(p => p.key == "pypi.normalized.name" && p.value == component.Name) && x.properties.Any(p => p.key == "pypi.version" && p.value == component.Version));
1222+
string jfrogpackageName = GetFullNameOfComponent(component);
1223+
AqlResult repoName = aqlResultList.Find(x => x.properties.Any(p => p.key == "pypi.normalized.name" && p.value == jfrogpackageName) && x.properties.Any(p => p.key == "pypi.version" && p.value == component.Version));
11861224

11871225
return repoName;
11881226
}
1189-
1227+
1228+
private static AqlResult GetNpmArtifactoryRepoName(List<AqlResult> aqlResultList, Component component)
1229+
{
1230+
string jfrogpackageName = GetFullNameOfComponent(component);
1231+
AqlResult repoName = aqlResultList.Find(x => x.properties.Any(p => p.key == "npm.name" && p.value == jfrogpackageName) && x.properties.Any(p => p.key == "npm.version" && p.value == component.Version));
1232+
1233+
return repoName;
1234+
}
1235+
11901236

11911237
private static AqlResult GetArtifactoryRepoNameForConan(List<AqlResult> aqlResultList, Component component)
11921238
{
@@ -1198,6 +1244,17 @@ private static AqlResult GetArtifactoryRepoNameForConan(List<AqlResult> aqlResul
11981244
return repoName;
11991245
}
12001246

1247+
private static string GetFullNameOfComponent(Component item)
1248+
{
1249+
if (!string.IsNullOrEmpty(item.Group))
1250+
{
1251+
return $"{item.Group}/{item.Name}";
1252+
}
1253+
else
1254+
{
1255+
return item.Name;
1256+
}
1257+
}
12011258
public static void UpdateBomArtifactoryRepoUrl(ref Bom bom, List<ComponentsToArtifactory> componentsUploaded)
12021259
{
12031260
foreach (var component in componentsUploaded)

0 commit comments

Comments
 (0)