7272# Visit https://github.com/package-url/packageurl-python for support and
7373# download.
7474
75- from packageurl import PackageURL
76- from packageurl import normalize
7775from packageurl.contrib.route import Router
7876
7977"""
8280
8381class TypeValidator:
8482 @classmethod
85- def validate(cls, purl: PackageURL , strict=False):
83+ def validate(cls, purl, strict=False):
8684 if not strict:
8785 purl = cls.normalize(purl)
8886
8987 if cls.namespace_requirement == "prohibited" and purl.namespace:
9088 yield f"Namespace is prohibited for purl type: {cls.type!r}"
91-
92- if not cls.namespace_case_sensitive and purl.namespace and purl.namespace.lower() != purl.name:
89+
90+ elif cls.namespace_requirement == "required" and not purl.namespace:
91+ yield f"Namespace is required for purl type: {cls.type!r}"
92+
93+ if (
94+ cls.namespace_case_sensitive
95+ and purl.namespace
96+ and purl.namespace.lower() != purl.namespace
97+ ):
9398 yield f"Namespace is not lowercased for purl type: {cls.type!r}"
94-
95- if not cls.name_case_sensitive and purl.name and purl.name.lower() != purl.name:
99+
100+ if cls.name_case_sensitive and purl.name and purl.name.lower() != purl.name:
96101 yield f"Name is not lowercased for purl type: {cls.type!r}"
97102
98103 if not cls.version_case_sensitive and purl.version and purl.version.lower() != purl.version:
99104 yield f"Version is not lowercased for purl type: {cls.type!r}"
100-
101- yield from cls.validate_type(purl)
102-
103- @classmethod
104- def normalize_type(cls, type: str):
105- return type
106-
107- @classmethod
108- def normalize_namespace(cls, namespace: str):
109- return namespace
110-
111- @classmethod
112- def normalize_name(cls, name: str):
113- return name
114105
115- @classmethod
116- def normalize_version(cls, version: str):
117- return version
118-
119- @classmethod
120- def normalize_qualifiers(cls, qualifiers: dict):
121- return qualifiers
122-
123- @classmethod
124- def normalize_subpath(cls, subpath: str):
125- return subpath
106+ yield from cls.validate_type(purl, strict=strict)
126107
127108 @classmethod
128- def normalize(cls, purl: PackageURL):
129- type_norm, namespace_norm, name_norm, version_norm, qualifiers_norm, subpath_norm = normalize(purl.type,
130- purl.namespace,
131- purl.name,
132- purl.version,
133- purl.qualifiers,
134- purl.subpath,
135- encode=False,
109+ def normalize(cls, purl):
110+ from packageurl import PackageURL
111+ from packageurl import normalize
112+
113+ type_norm, namespace_norm, name_norm, version_norm, qualifiers_norm, subpath_norm = (
114+ normalize(
115+ purl.type,
116+ purl.namespace,
117+ purl.name,
118+ purl.version,
119+ purl.qualifiers,
120+ purl.subpath,
121+ encode=False,
122+ )
136123 )
137124
138125 return PackageURL(
139- type = type_norm,
140- namespace = namespace_norm,
141- name = name_norm,
142- version = version_norm,
143- qualifiers = qualifiers_norm,
144- subpath = subpath_norm,
126+ type= type_norm,
127+ namespace= namespace_norm,
128+ name= name_norm,
129+ version= version_norm,
130+ qualifiers= qualifiers_norm,
131+ subpath= subpath_norm,
145132 )
146133
147134 @classmethod
148- def validate_type(cls, purl: PackageURL):
149- yield from cls.validate_qualifiers(purl=purl)
150-
135+ def validate_type(cls, purl, strict=False):
136+ if strict:
137+ yield from cls.validate_qualifiers(purl=purl)
138+
151139 @classmethod
152- def validate_qualifiers(cls, purl: PackageURL ):
140+ def validate_qualifiers(cls, purl):
153141 if not purl.qualifiers:
154142 return
155-
143+
156144 purl_qualifiers_keys = set(purl.qualifiers.keys())
157145 allowed_qualifiers_set = cls.allowed_qualifiers
158146
159147 disallowed = purl_qualifiers_keys - allowed_qualifiers_set
160-
148+
161149 if disallowed:
162- yield (f"Invalid qualifiers found: {', '.join(disallowed)}. "
150+ yield (
151+ f"Invalid qualifiers found: {', '.join(disallowed)}. "
163152 f"Allowed qualifiers are: {', '.join(allowed_qualifiers_set)}"
164153 )
165154'''
166155
167- def validate_qualifiers (allowed_qualifiers , purl : PackageURL ):
168- if not purl .qualifiers :
169- return True
170-
171- purl_qualifiers_keys = set (purl .qualifiers .keys ())
172- allowed_qualifiers_set = set (allowed_qualifiers )
173-
174- disallowed = purl_qualifiers_keys - allowed_qualifiers_set
175-
176- if disallowed :
177- yield (f"Invalid qualifiers found: { ', ' .join (disallowed )} . "
178- f"Allowed qualifiers are: { ', ' .join (allowed_qualifiers_set )} "
179- )
180-
181-
182156
183157TEMPLATE = """
184158class {class_name}({validator_class}):
@@ -195,16 +169,6 @@ class {class_name}({validator_class}):
195169 purl_pattern = "{purl_pattern}"
196170"""
197171
198- TEMPLATE_NAME_RULES = '''
199- @override
200- @classmethod
201- def normalize_name(cls, name: str):
202- """
203- Normalize name according to type rules
204- {rules}
205- """
206- raise NotImplementedError()
207- '''
208172
209173def generate_validators ():
210174 """
@@ -260,24 +224,15 @@ def generate_validators():
260224 ))
261225
262226 script_parts .append (type_validator )
263-
264- # if name_normalization_rules:
265- # name_overrides = get_name_norm_rules(name_normalization_rules)
266- # script_parts.append(name_overrides)
267227
268228 script_parts .append (generate_validators_by_type (validators_by_type = validators_by_type ))
269- script_parts .append (attach_router (validators_by_type .values ()))
229+ # script_parts.append(attach_router(validators_by_type.values()))
270230
271231 validate_script = base_dir / "src" / "packageurl" / "validate.py"
272232
273233 validate_script .write_text ("\n " .join (script_parts ))
274234
275235
276- def get_name_norm_rules (name_normalization_rules ):
277- rules = "\n " .join (name_normalization_rules )
278- return TEMPLATE_NAME_RULES .format (rules = rules )
279-
280-
281236def generate_validators_by_type (validators_by_type ):
282237 """
283238 Return a python snippet that maps a type to it's TypeValidator class
0 commit comments