Skip to content

Commit b390ee1

Browse files
authored
Merge pull request #280 from ligangty/overlap
fix: MMENG-4284 npm del error when deleting a package which has overlapped name with others
2 parents d6021e2 + c0f773a commit b390ee1

6 files changed

+124
-8
lines changed

charon/pkgs/npm.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,11 @@ def _gen_npm_package_metadata_for_del(
447447
if prefix and prefix != "/":
448448
prefix_meta_key = os.path.join(prefix, package_metadata_key)
449449
path_prefix = os.path.join(prefix, package_path_prefix)
450+
# MMENG-4284 we should make sure each path_prefix ends with "/" to avoid
451+
# overlapping, like "backstage-plugin-orchestrator" vs
452+
# "backstage-plugin-orchestrator-backend-dynamic"
453+
if not path_prefix.endswith("/"):
454+
path_prefix = path_prefix + "/"
450455
(existed_version_metas, success) = client.get_files(
451456
bucket_name=bucket, prefix=path_prefix, suffix=PACKAGE_JSON
452457
)
@@ -572,15 +577,23 @@ def _do_merge(original: NPMPackageMetadata, source: NPMPackageMetadata, is_lates
572577
original.repository = source.repository
573578
changed = True
574579
if source.maintainers:
575-
for m in source.maintainers:
576-
if m not in original.maintainers:
577-
original.maintainers.append(m)
578-
changed = True
580+
if not original.maintainers:
581+
original.maintainers = source.maintainers
582+
changed = True
583+
else:
584+
for m in source.maintainers:
585+
if m not in original.maintainers:
586+
original.maintainers.append(m)
587+
changed = True
579588
if source.keywords:
580-
for k in source.keywords:
581-
if k not in original.keywords:
582-
original.keywords.append(k)
583-
changed = True
589+
if not original.keywords:
590+
original.keywords = source.keywords
591+
changed = True
592+
else:
593+
for k in source.keywords:
594+
if k not in original.keywords:
595+
original.keywords.append(k)
596+
changed = True
584597
if source.users:
585598
for u in source.users.keys():
586599
original.users[u] = source.users.get(u)
87.6 KB
Binary file not shown.
110 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.

tests/test_npm_del.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,106 @@ def __prepare_content(self, prefix: str = None):
110110
targets=[('', TEST_BUCKET, prefix, DEFAULT_REGISTRY)],
111111
dir_=self.tempdir, do_index=False
112112
)
113+
114+
def test_overlap_prefix_del(self):
115+
self.__prepare_content_backstage()
116+
117+
test_bucket = self.mock_s3.Bucket(TEST_BUCKET)
118+
objs = list(test_bucket.objects.all())
119+
actual_files = [obj.key for obj in objs]
120+
self.assertEqual(18, len(actual_files))
121+
122+
meta_obj = test_bucket.Object("@janus-idp/backstage-plugin-orchestrator/package.json")
123+
meta_content_client = str(meta_obj.get()["Body"].read(), "utf-8")
124+
self.assertIn("\"name\": \"@janus-idp/backstage-plugin-orchestrator\"", meta_content_client)
125+
self.assertIn("\"version\": \"1.21.102\"", meta_content_client)
126+
self.assertIn("\"version\": \"1.21.103\"", meta_content_client)
127+
self.assertIn("\"1.21.103\": {\"name\":", meta_content_client)
128+
129+
meta_obj = test_bucket.Object(
130+
"@janus-idp/backstage-plugin-orchestrator-backend-dynamic/package.json")
131+
meta_content_client = str(meta_obj.get()["Body"].read(), "utf-8")
132+
self.assertIn(
133+
"\"name\": \"@janus-idp/backstage-plugin-orchestrator-backend-dynamic\"",
134+
meta_content_client)
135+
self.assertIn("\"version\": \"0.0.1\"", meta_content_client)
136+
self.assertIn("\"version\": \"2.3.0\"", meta_content_client)
137+
self.assertIn("\"2.3.0\": {\"name\":", meta_content_client)
138+
139+
test_prod = "backstage-plugin-orchestrator-1.21.103"
140+
test_tgz = os.path.join(INPUTS, test_prod+".tgz")
141+
handle_npm_del(
142+
test_tgz, test_prod,
143+
targets=[('', TEST_BUCKET, None, '')],
144+
dir_=self.tempdir, do_index=False
145+
)
146+
147+
test_bucket = self.mock_s3.Bucket(TEST_BUCKET)
148+
objs = list(test_bucket.objects.all())
149+
actual_files = [obj.key for obj in objs]
150+
self.assertEqual(14, len(actual_files))
151+
152+
meta_obj = test_bucket.Object("@janus-idp/backstage-plugin-orchestrator/package.json")
153+
meta_content_client = str(meta_obj.get()["Body"].read(), "utf-8")
154+
self.assertIn("\"name\": \"@janus-idp/backstage-plugin-orchestrator\"", meta_content_client)
155+
self.assertIn("\"version\": \"1.21.102\"", meta_content_client)
156+
self.assertNotIn("\"version\": \"1.21.103\"", meta_content_client)
157+
self.assertNotIn("\"1.21.103\": {\"name\":", meta_content_client)
158+
159+
meta_obj = test_bucket.Object(
160+
"@janus-idp/backstage-plugin-orchestrator-backend-dynamic/package.json")
161+
meta_content_client = str(meta_obj.get()["Body"].read(), "utf-8")
162+
self.assertIn(
163+
"\"name\": \"@janus-idp/backstage-plugin-orchestrator-backend-dynamic\"",
164+
meta_content_client)
165+
self.assertIn("\"version\": \"0.0.1\"", meta_content_client)
166+
self.assertIn("\"version\": \"2.3.0\"", meta_content_client)
167+
self.assertIn("\"2.3.0\": {\"name\":", meta_content_client)
168+
169+
test_prod = "backstage-plugin-orchestrator-backend-dynamic-2.3.0"
170+
test_tgz = os.path.join(INPUTS, test_prod+".tgz")
171+
handle_npm_del(
172+
test_tgz, test_prod,
173+
targets=[('', TEST_BUCKET, None, '')],
174+
dir_=self.tempdir, do_index=False
175+
)
176+
177+
test_bucket = self.mock_s3.Bucket(TEST_BUCKET)
178+
objs = list(test_bucket.objects.all())
179+
actual_files = [obj.key for obj in objs]
180+
self.assertEqual(10, len(actual_files))
181+
182+
meta_obj = test_bucket.Object(
183+
"@janus-idp/backstage-plugin-orchestrator/package.json")
184+
meta_content_client = str(meta_obj.get()["Body"].read(), "utf-8")
185+
self.assertIn(
186+
"\"name\": \"@janus-idp/backstage-plugin-orchestrator\"",
187+
meta_content_client)
188+
self.assertIn("\"version\": \"1.21.102\"", meta_content_client)
189+
self.assertNotIn("\"version\": \"1.21.103\"", meta_content_client)
190+
self.assertNotIn("\"1.21.103\": {\"name\":", meta_content_client)
191+
192+
meta_obj = test_bucket.Object(
193+
"@janus-idp/backstage-plugin-orchestrator-backend-dynamic/package.json")
194+
meta_content_client = str(meta_obj.get()["Body"].read(), "utf-8")
195+
self.assertIn(
196+
"\"name\": \"@janus-idp/backstage-plugin-orchestrator-backend-dynamic\"",
197+
meta_content_client)
198+
self.assertIn("\"version\": \"0.0.1\"", meta_content_client)
199+
self.assertNotIn("\"version\": \"2.3.0\"", meta_content_client)
200+
self.assertNotIn("\"2.3.0\": {\"name\":", meta_content_client)
201+
202+
def __prepare_content_backstage(self, prefix: str = None):
203+
test_prods = [
204+
"backstage-plugin-orchestrator-1.21.102",
205+
"backstage-plugin-orchestrator-1.21.103",
206+
"backstage-plugin-orchestrator-backend-dynamic-0.0.1",
207+
"backstage-plugin-orchestrator-backend-dynamic-2.3.0"
208+
]
209+
for p in test_prods:
210+
test_tgz = os.path.join(INPUTS, p+".tgz")
211+
handle_npm_uploading(
212+
test_tgz, p,
213+
targets=[('', TEST_BUCKET, prefix, DEFAULT_REGISTRY)],
214+
dir_=self.tempdir, do_index=False
215+
)

0 commit comments

Comments
 (0)