Skip to content

Commit eeaab32

Browse files
Address review feedback
Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
1 parent 2ee926a commit eeaab32

1 file changed

Lines changed: 44 additions & 13 deletions

File tree

minecode_pipelines/miners/cpan.py

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
from packageurl import PackageURL
1717

18-
from minecode_pipelines.utils import get_temp_file
19-
from minecode_pipelines.pipes import write_data_to_json_file
2018

2119
"""
2220
Visitors for cpan and cpan-like perl package repositories.
@@ -28,6 +26,12 @@
2826

2927

3028
def get_cpan_packages(cpan_repo=CPAN_REPO, logger=None):
29+
"""
30+
Get cpan package names parsed from the `02packages.details.txt`
31+
which conatins a list of all modules and their respective
32+
package archive paths. We parse the package names and their respective
33+
path_prefixes with author page path from this list.
34+
"""
3135
cpan_packages_url = cpan_repo + "modules/02packages.details.txt.gz"
3236
local_filename = "cpan_packages.gz"
3337

@@ -39,18 +43,36 @@ def get_cpan_packages(cpan_repo=CPAN_REPO, logger=None):
3943
for chunk in response.iter_content(chunk_size=8192):
4044
f.write(chunk)
4145

42-
with gzip.open("cpan_packages.gz", "rb") as f_in:
43-
with open("cpan_packages.txt", "wb") as f_out:
44-
f_out.writelines(f_in)
45-
46-
with open("cpan_packages.txt", encoding="utf-8") as file:
47-
packages_content = file.read()
46+
with gzip.open("cpan_packages.gz", "rb") as file_content:
47+
packages_content = file_content.read()
4848

4949
package_path_by_name = {}
5050

51+
# The ``modules/02packages.details.txt`` file has the following section
52+
# at the beginning of the file:
53+
#
54+
# File: 02packages.details.txt
55+
# URL: http://www.cpan.org/modules/02packages.details.txt
56+
# Description: Package names found in directory $CPAN/authors/id/
57+
# Columns: package name, version, path
58+
# Intended-For: Automated fetch routines, namespace documentation.
59+
# Written-By: PAUSE version 1.005
60+
# Line-Count: 268940
61+
# Last-Updated: Mon, 29 Sep 2025 22:29:02 GMT
62+
#
63+
# This information is there in first 10 lines, and the last line is an
64+
# empty line, both of which we are ignoring below
65+
5166
modules = packages_content.split("\n")[9:-1]
67+
68+
# A sample line from this module list looks like this:
69+
#
70+
# Crypt::Passphrase::SHA1::Base64 0.021 L/LE/LEONT/Crypt-Passphrase-0.021.tar.gz
71+
5272
for module in modules:
5373
info = [section for section in module.split(" ") if section]
74+
75+
# This is like: L/LE/LEONT/Crypt-Passphrase-0.021.tar.gz
5476
package_path = info[-1]
5577
path_segments = package_path.split("/")
5678
filename = path_segments.pop()
@@ -60,18 +82,24 @@ def get_cpan_packages(cpan_repo=CPAN_REPO, logger=None):
6082
_version = name_version.pop()
6183
name = "-".join(name_version)
6284

85+
# for the above example: name: Crypt-Passphrase, path_prefix: L/LE/LEONT/
6386
package_path_by_name[name] = path_prefix
6487

6588
return package_path_by_name
6689

6790

68-
def write_packages_json(packages, name):
69-
temp_file = get_temp_file(name)
70-
write_data_to_json_file(path=temp_file, data=packages)
71-
return temp_file
91+
def get_cpan_packageurls(name, path_prefix, logger=None):
92+
"""
93+
Given a package name and it's path_prefix (author page path)
94+
return a list of packageURLs for that package.
7295
96+
An author page (like https://www.cpan.org/authors/id/P/PT/PTC/) lists
97+
all versions of all packages released by the author, so we can scrape
98+
all the packageURLs from this author packages index.
99+
"""
100+
101+
author_name = path_prefix.split("/")[-1]
73102

74-
def get_cpan_packageurls(name, path_prefix, logger=None):
75103
packageurls = []
76104

77105
# file extensions found in cpan index
@@ -90,6 +118,8 @@ def get_cpan_packageurls(name, path_prefix, logger=None):
90118
logger(f"Getting package versions for {name} from {cpan_author_page_url}")
91119

92120
soup = BeautifulSoup(response.text, "html.parser")
121+
122+
# We get all the listed packages in the author page index
93123
package_list_elements = soup.find("ul").text.split("\n")
94124

95125
package_elements = [
@@ -116,6 +146,7 @@ def get_cpan_packageurls(name, path_prefix, logger=None):
116146
for version in unique_versions:
117147
purl = PackageURL(
118148
type=CPAN_TYPE,
149+
namespace=author_name,
119150
name=name,
120151
version=version,
121152
)

0 commit comments

Comments
 (0)